mirror of
				https://github.com/bellard/quickjs.git
				synced 2025-05-29 01:49:18 +08:00 
			
		
		
		
	feat: add column number
This commit is contained in:
		
							parent
							
								
									2788d71e82
								
							
						
					
					
						commit
						00ed5215e2
					
				
							
								
								
									
										10
									
								
								cutils.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								cutils.c
									
									
									
									
									
								
							@ -303,6 +303,16 @@ int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp)
 | 
				
			|||||||
    return c;
 | 
					    return c;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int utf8_str_len(const uint8_t *p_start, const uint8_t *p_end) {
 | 
				
			||||||
 | 
					    int count = 0;
 | 
				
			||||||
 | 
					    while (p_start < p_end) {
 | 
				
			||||||
 | 
					        if (!unicode_from_utf8(p_start, UTF8_CHAR_LEN_MAX, &p_start))
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        count += 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return count;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if 0
 | 
					#if 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(EMSCRIPTEN) || defined(__ANDROID__)
 | 
					#if defined(EMSCRIPTEN) || defined(__ANDROID__)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								cutils.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								cutils.h
									
									
									
									
									
								
							@ -277,6 +277,7 @@ static inline void dbuf_set_error(DynBuf *s)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int unicode_to_utf8(uint8_t *buf, unsigned int c);
 | 
					int unicode_to_utf8(uint8_t *buf, unsigned int c);
 | 
				
			||||||
int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp);
 | 
					int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp);
 | 
				
			||||||
 | 
					int utf8_str_len(const uint8_t *p_start, const uint8_t *p_end);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int from_hex(int c)
 | 
					static inline int from_hex(int c)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -81,6 +81,7 @@ DEF(empty_string, "")
 | 
				
			|||||||
DEF(length, "length")
 | 
					DEF(length, "length")
 | 
				
			||||||
DEF(fileName, "fileName")
 | 
					DEF(fileName, "fileName")
 | 
				
			||||||
DEF(lineNumber, "lineNumber")
 | 
					DEF(lineNumber, "lineNumber")
 | 
				
			||||||
 | 
					DEF(columnNumber, "columnNumber")
 | 
				
			||||||
DEF(message, "message")
 | 
					DEF(message, "message")
 | 
				
			||||||
DEF(errors, "errors")
 | 
					DEF(errors, "errors")
 | 
				
			||||||
DEF(stack, "stack")
 | 
					DEF(stack, "stack")
 | 
				
			||||||
 | 
				
			|||||||
@ -284,6 +284,7 @@ def(scope_put_private_field, 7, 1, 1, atom_u16) /* obj value ->, emitted in phas
 | 
				
			|||||||
def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */
 | 
					def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
def(       line_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */
 | 
					def(       line_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */
 | 
				
			||||||
 | 
					def(       column_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if SHORT_OPCODES
 | 
					#if SHORT_OPCODES
 | 
				
			||||||
DEF(    push_minus1, 1, 0, 1, none_int)
 | 
					DEF(    push_minus1, 1, 0, 1, none_int)
 | 
				
			||||||
 | 
				
			|||||||
@ -407,6 +407,7 @@ typedef struct JSMemoryUsage {
 | 
				
			|||||||
    int64_t shape_count, shape_size;
 | 
					    int64_t shape_count, shape_size;
 | 
				
			||||||
    int64_t js_func_count, js_func_size, js_func_code_size;
 | 
					    int64_t js_func_count, js_func_size, js_func_code_size;
 | 
				
			||||||
    int64_t js_func_pc2line_count, js_func_pc2line_size;
 | 
					    int64_t js_func_pc2line_count, js_func_pc2line_size;
 | 
				
			||||||
 | 
					    int64_t js_func_pc2column_count, js_func_pc2column_size;
 | 
				
			||||||
    int64_t c_func_count, array_count;
 | 
					    int64_t c_func_count, array_count;
 | 
				
			||||||
    int64_t fast_array_count, fast_array_elements;
 | 
					    int64_t fast_array_count, fast_array_elements;
 | 
				
			||||||
    int64_t binary_object_count, binary_object_size;
 | 
					    int64_t binary_object_count, binary_object_size;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										240
									
								
								tests/test_line_column.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										240
									
								
								tests/test_line_column.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,240 @@
 | 
				
			|||||||
 | 
					"use strict";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function assert(actual, expected, message) {
 | 
				
			||||||
 | 
					    if (arguments.length == 1) expected = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (actual === expected) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (actual !== null && expected !== null && typeof actual == 'object' &&
 | 
				
			||||||
 | 
					        typeof expected == 'object' && actual.toString() === expected.toString())
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    throw Error(
 | 
				
			||||||
 | 
					        'assertion failed: got |' + actual + '|' +
 | 
				
			||||||
 | 
					        ', expected |' + expected + '|' + (message ? ' (' + message + ')' : ''));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** id not exists -> should be located at id */
 | 
				
			||||||
 | 
					function test_line_column1() {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        eval(`'【';A;`);
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					        assert(e.lineNumber, 1, 'test_line_column1');
 | 
				
			||||||
 | 
					        assert(e.columnNumber, 5, 'test_line_column1');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * memeber call should be located at id:
 | 
				
			||||||
 | 
					 * a.b.c() and c is null -> c will be located
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function test_line_column2() {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        eval(`
 | 
				
			||||||
 | 
					var a = { b: { c: { d: null }} };
 | 
				
			||||||
 | 
					a.b.c.d();
 | 
				
			||||||
 | 
					        `);
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					        assert(e.lineNumber, 3, 'test_line_column2');
 | 
				
			||||||
 | 
					        assert(e.columnNumber, 7, 'test_line_column2');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * memeber call should be located at id:
 | 
				
			||||||
 | 
					 * a.b.c() and b is null -> c will be located
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function test_line_column3() {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        eval(`
 | 
				
			||||||
 | 
					var a = { b: { c: { d: null }} };
 | 
				
			||||||
 | 
					a.f.c.d();
 | 
				
			||||||
 | 
					        `);
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					        assert(e.lineNumber, 3, 'test_line_column3');
 | 
				
			||||||
 | 
					        assert(e.columnNumber, 5, 'test_line_column3');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** if id not exists -> should be located at id */
 | 
				
			||||||
 | 
					function test_line_column4() {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        eval(`(function(){'use strict';a;}());`);
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					        assert(e.lineNumber, 1, 'test_line_column4');
 | 
				
			||||||
 | 
					        assert(e.columnNumber, 26, 'test_line_column4');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** if id not exists -> should be located at id */
 | 
				
			||||||
 | 
					function test_line_column5() {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        eval(`'【';1+1;new A();`);
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					        assert(e.lineNumber, 1, 'test_line_column5');
 | 
				
			||||||
 | 
					        assert(e.columnNumber, 13, 'test_line_column5');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** new call should be located at 'new' */
 | 
				
			||||||
 | 
					function test_line_column6() {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        eval(`'【';1+1;throw new Error();`);
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					        assert(e.lineNumber, 1, 'test_line_column6');
 | 
				
			||||||
 | 
					        assert(e.columnNumber, 15, 'test_line_column6');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * normal call should be located at function name:
 | 
				
			||||||
 | 
					 * a() and a is null or occur error -> a will be located
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function test_line_column7() {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        eval(`1+1;a();`);
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					        assert(e.lineNumber, 1, 'test_line_column7');
 | 
				
			||||||
 | 
					        assert(e.columnNumber, 5, 'test_line_column7');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** 
 | 
				
			||||||
 | 
					 * if comment is first line, 
 | 
				
			||||||
 | 
					 * the line number of one line should be locate at next line 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function test_line_column8() {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        eval(`
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * something
 | 
				
			||||||
 | 
					 * comment
 | 
				
			||||||
 | 
					 * here
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					1+1;a();
 | 
				
			||||||
 | 
					        `);
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					        assert(e.lineNumber, 7, 'test_line_column8');
 | 
				
			||||||
 | 
					        assert(e.columnNumber, 5, 'test_line_column8');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** nest function call */
 | 
				
			||||||
 | 
					function test_line_column9() {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        eval(`(function(){'【'(function(){'use strict';a;}())}())`);
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					        assert(e.lineNumber, 1, 'test_line_column9');
 | 
				
			||||||
 | 
					        assert(e.columnNumber, 41, 'test_line_column9');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** multi function call */
 | 
				
			||||||
 | 
					function test_line_column10() {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        eval(`
 | 
				
			||||||
 | 
					function a(){
 | 
				
			||||||
 | 
					    throw new Error();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function b(){
 | 
				
			||||||
 | 
					    a();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					b();
 | 
				
			||||||
 | 
					        `);
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					        assert(e.lineNumber, 3, 'test_line_column10');
 | 
				
			||||||
 | 
					        assert(e.columnNumber, 11, 'test_line_column10');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** syntax error should be located at latest token position */
 | 
				
			||||||
 | 
					function test_line_column11() {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        eval(`
 | 
				
			||||||
 | 
					var a = {
 | 
				
			||||||
 | 
					    b: if(1){}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					        `);
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					        assert(e.lineNumber, 3, 'test_line_column11');
 | 
				
			||||||
 | 
					        assert(e.columnNumber, 7, 'test_line_column11');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** string template cases */
 | 
				
			||||||
 | 
					function test_line_column12() {
 | 
				
			||||||
 | 
					// case 1
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        eval(`
 | 
				
			||||||
 | 
					var a = \`\$\{b;\}
 | 
				
			||||||
 | 
					1+1
 | 
				
			||||||
 | 
					\`;
 | 
				
			||||||
 | 
					        `);
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					        assert(e.lineNumber, 2, 'test_line_column12');
 | 
				
			||||||
 | 
					        assert(e.columnNumber, 12, 'test_line_column12');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// case 2
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        eval(`
 | 
				
			||||||
 | 
					var a = \`1+1
 | 
				
			||||||
 | 
					\$\{b;\}
 | 
				
			||||||
 | 
					2+2
 | 
				
			||||||
 | 
					\`;
 | 
				
			||||||
 | 
					        `);
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					        assert(e.lineNumber, 3, 'test_line_column12');
 | 
				
			||||||
 | 
					        assert(e.columnNumber, 3, 'test_line_column12');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// case 3
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        eval(`
 | 
				
			||||||
 | 
					var a = \`1+1
 | 
				
			||||||
 | 
					2+2
 | 
				
			||||||
 | 
					\${b\}\`;
 | 
				
			||||||
 | 
					            `);
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					        assert(e.lineNumber, 4, 'test_line_column12');
 | 
				
			||||||
 | 
					        assert(e.columnNumber, 3, 'test_line_column12');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// case 4
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        eval(`
 | 
				
			||||||
 | 
					var a = \`1+1
 | 
				
			||||||
 | 
					2+2
 | 
				
			||||||
 | 
					\${3+3\}\`;b;
 | 
				
			||||||
 | 
					            `);
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					        assert(e.lineNumber, 4, 'test_line_column12');
 | 
				
			||||||
 | 
					        assert(e.columnNumber, 9, 'test_line_column12');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** dynamic Function parse error should be located the latest token */
 | 
				
			||||||
 | 
					function test_line_column13() {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        eval(`Function("===>", "a");`);
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					        assert(e.lineNumber, 1, 'test_line_column13');
 | 
				
			||||||
 | 
					        assert(e.columnNumber, 20, 'test_line_column13');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_line_column1();
 | 
				
			||||||
 | 
					test_line_column2();
 | 
				
			||||||
 | 
					test_line_column3();
 | 
				
			||||||
 | 
					test_line_column4();
 | 
				
			||||||
 | 
					test_line_column5();
 | 
				
			||||||
 | 
					test_line_column6();
 | 
				
			||||||
 | 
					test_line_column7();
 | 
				
			||||||
 | 
					test_line_column8();
 | 
				
			||||||
 | 
					test_line_column9();
 | 
				
			||||||
 | 
					test_line_column10();
 | 
				
			||||||
 | 
					test_line_column11();
 | 
				
			||||||
 | 
					test_line_column12();
 | 
				
			||||||
 | 
					test_line_column13();
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user