1 Commits

Author SHA1 Message Date
John Alanbrook
e63115e152 initial attempt 2025-06-18 18:06:27 -05:00
4 changed files with 308 additions and 215 deletions

View File

@@ -788,6 +788,11 @@ int uncaught_exception(JSContext *js, JSValue v)
} }
JSValue exp = JS_GetException(js); JSValue exp = JS_GetException(js);
JSValue stack = JS_GetPropertyStr(js,exp,"stack");
const char *stackstr = JS_ToCString(js, stack);
printf("ERROR: %s\n", stackstr);
JS_FreeCString(js,stackstr);
JS_FreeValue(js,stack);
JSValue ret = JS_Call(js, rt->on_exception, JS_NULL, 1, &exp); JSValue ret = JS_Call(js, rt->on_exception, JS_NULL, 1, &exp);
JS_FreeValue(js,ret); JS_FreeValue(js,ret);
JS_FreeValue(js, exp); JS_FreeValue(js, exp);

View File

@@ -75,6 +75,7 @@ DEF(public, "public")
DEF(static, "static") DEF(static, "static")
DEF(yield, "yield") DEF(yield, "yield")
DEF(await, "await") DEF(await, "await")
DEF(go, "go")
/* empty string */ /* empty string */
DEF(empty_string, "") DEF(empty_string, "")

View File

@@ -62,174 +62,175 @@ FMT(label_u16)
#define def(id, size, n_pop, n_push, f) DEF(id, size, n_pop, n_push, f) #define def(id, size, n_pop, n_push, f) DEF(id, size, n_pop, n_push, f)
#endif #endif
DEF(invalid, 1, 0, 0, none) /* never emitted */ DEF(invalid, 1, 0, 0, none) /* never emitted */ //0
/* push values */ /* push values */
DEF( push_i32, 5, 0, 1, i32) DEF( push_i32, 5, 0, 1, i32) //1
DEF( push_const, 5, 0, 1, const) DEF( push_const, 5, 0, 1, const) //2
DEF( fclosure, 5, 0, 1, const) /* must follow push_const */ DEF( fclosure, 5, 0, 1, const) /* must follow push_const */ //3
DEF(push_atom_value, 5, 0, 1, atom) DEF(push_atom_value, 5, 0, 1, atom) //4
DEF( null, 1, 0, 1, none) DEF( null, 1, 0, 1, none) //5
DEF( push_this, 1, 0, 1, none) /* only used at the start of a function */ DEF( push_this, 1, 0, 1, none) /* only used at the start of a function */ //6
DEF( push_false, 1, 0, 1, none) DEF( push_false, 1, 0, 1, none) //7
DEF( push_true, 1, 0, 1, none) DEF( push_true, 1, 0, 1, none) //8
DEF( object, 1, 0, 1, none) DEF( object, 1, 0, 1, none) //9
DEF( special_object, 2, 0, 1, u8) /* only used at the start of a function */ DEF( special_object, 2, 0, 1, u8) /* only used at the start of a function */ //10
DEF( rest, 3, 0, 1, u16) /* only used at the start of a function */ DEF( rest, 3, 0, 1, u16) /* only used at the start of a function */ //11
DEF( drop, 1, 1, 0, none) /* a -> */ DEF( drop, 1, 1, 0, none) /* a -> */ //12
DEF( nip, 1, 2, 1, none) /* a b -> b */ DEF( nip, 1, 2, 1, none) /* a b -> b */ //13
DEF( nip1, 1, 3, 2, none) /* a b c -> b c */ DEF( nip1, 1, 3, 2, none) /* a b c -> b c */ //14
DEF( dup, 1, 1, 2, none) /* a -> a a */ DEF( dup, 1, 1, 2, none) /* a -> a a */ //15
DEF( dup1, 1, 2, 3, none) /* a b -> a a b */ DEF( dup1, 1, 2, 3, none) /* a b -> a a b */ //16
DEF( dup2, 1, 2, 4, none) /* a b -> a b a b */ DEF( dup2, 1, 2, 4, none) /* a b -> a b a b */ //17
DEF( dup3, 1, 3, 6, none) /* a b c -> a b c a b c */ DEF( dup3, 1, 3, 6, none) /* a b c -> a b c a b c */ //18
DEF( insert2, 1, 2, 3, none) /* obj a -> a obj a (dup_x1) */ DEF( insert2, 1, 2, 3, none) /* obj a -> a obj a (dup_x1) */ //19
DEF( insert3, 1, 3, 4, none) /* obj prop a -> a obj prop a (dup_x2) */ DEF( insert3, 1, 3, 4, none) /* obj prop a -> a obj prop a (dup_x2) */ //20
DEF( insert4, 1, 4, 5, none) /* this obj prop a -> a this obj prop a */ DEF( insert4, 1, 4, 5, none) /* this obj prop a -> a this obj prop a */ //21
DEF( perm3, 1, 3, 3, none) /* obj a b -> a obj b */ DEF( perm3, 1, 3, 3, none) /* obj a b -> a obj b */ //22
DEF( perm4, 1, 4, 4, none) /* obj prop a b -> a obj prop b */ DEF( perm4, 1, 4, 4, none) /* obj prop a b -> a obj prop b */ //23
DEF( perm5, 1, 5, 5, none) /* this obj prop a b -> a this obj prop b */ DEF( perm5, 1, 5, 5, none) /* this obj prop a b -> a this obj prop b */ //24
DEF( swap, 1, 2, 2, none) /* a b -> b a */ DEF( swap, 1, 2, 2, none) /* a b -> b a */ //25
DEF( swap2, 1, 4, 4, none) /* a b c d -> c d a b */ DEF( swap2, 1, 4, 4, none) /* a b c d -> c d a b */ //26
DEF( rot3l, 1, 3, 3, none) /* x a b -> a b x */ DEF( rot3l, 1, 3, 3, none) /* x a b -> a b x */ //27
DEF( rot3r, 1, 3, 3, none) /* a b x -> x a b */ DEF( rot3r, 1, 3, 3, none) /* a b x -> x a b */ //28
DEF( rot4l, 1, 4, 4, none) /* x a b c -> a b c x */ DEF( rot4l, 1, 4, 4, none) /* x a b c -> a b c x */ //29
DEF( rot5l, 1, 5, 5, none) /* x a b c d -> a b c d x */ DEF( rot5l, 1, 5, 5, none) /* x a b c d -> a b c d x */ //30
DEF(call_constructor, 3, 2, 1, npop) /* func new.target args -> ret. arguments are not counted in n_pop */ DEF(call_constructor, 3, 2, 1, npop) /* func new.target args -> ret. arguments are not counted in n_pop */ //31
DEF( call, 3, 1, 1, npop) /* arguments are not counted in n_pop */ DEF( call, 3, 1, 1, npop) /* arguments are not counted in n_pop */ //32
DEF( tail_call, 3, 1, 0, npop) /* arguments are not counted in n_pop */ DEF( tail_call, 3, 1, 0, npop) /* arguments are not counted in n_pop */ //33
DEF( call_method, 3, 2, 1, npop) /* arguments are not counted in n_pop */ DEF( go, 3, 1, 0, npop)
DEF(tail_call_method, 3, 2, 0, npop) /* arguments are not counted in n_pop */ DEF( call_method, 3, 2, 1, npop) /* arguments are not counted in n_pop */ //34
DEF( array_from, 3, 0, 1, npop) /* arguments are not counted in n_pop */ DEF(tail_call_method, 3, 2, 0, npop) /* arguments are not counted in n_pop */ //35
DEF( apply, 3, 3, 1, u16) DEF( array_from, 3, 0, 1, npop) /* arguments are not counted in n_pop */ //36
DEF( return, 1, 1, 0, none) DEF( apply, 3, 3, 1, u16) //37
DEF( return_undef, 1, 0, 0, none) DEF( return, 1, 1, 0, none) //38
DEF( throw, 1, 1, 0, none) DEF( return_undef, 1, 0, 0, none) //39
DEF( throw_error, 6, 0, 0, atom_u8) DEF( throw, 1, 1, 0, none) //40
DEF( eval, 5, 1, 1, npop_u16) /* func args... -> ret_val */ DEF( throw_error, 6, 0, 0, atom_u8) //41
DEF( apply_eval, 3, 2, 1, u16) /* func array -> ret_eval */ DEF( eval, 5, 1, 1, npop_u16) /* func args... -> ret_val */ //42
DEF( apply_eval, 3, 2, 1, u16) /* func array -> ret_eval */ //43
DEF( regexp, 1, 2, 1, none) /* create a RegExp object from the pattern and a DEF( regexp, 1, 2, 1, none) /* create a RegExp object from the pattern and a
bytecode string */ bytecode string */ //44
DEF( check_var, 5, 0, 1, atom) /* check if a variable exists */ DEF( check_var, 5, 0, 1, atom) /* check if a variable exists */ //45
DEF( get_var_undef, 5, 0, 1, atom) /* push undefined if the variable does not exist */ DEF( get_var_undef, 5, 0, 1, atom) /* push undefined if the variable does not exist */ //46
DEF( get_var, 5, 0, 1, atom) /* throw an exception if the variable does not exist */ DEF( get_var, 5, 0, 1, atom) /* throw an exception if the variable does not exist */ //47
DEF( put_var, 5, 1, 0, atom) /* must come after get_var */ DEF( put_var, 5, 1, 0, atom) /* must come after get_var */ //48
DEF( put_var_init, 5, 1, 0, atom) /* must come after put_var. Used to initialize a global lexical variable */ DEF( put_var_init, 5, 1, 0, atom) /* must come after put_var. Used to initialize a global lexical variable */ //49
DEF( put_var_strict, 5, 2, 0, atom) /* for strict mode variable write */ DEF( put_var_strict, 5, 2, 0, atom) /* for strict mode variable write */ //50
DEF( get_ref_value, 1, 2, 3, none) DEF( get_ref_value, 1, 2, 3, none) //51
DEF( put_ref_value, 1, 3, 0, none) DEF( put_ref_value, 1, 3, 0, none) //52
DEF( define_var, 6, 0, 0, atom_u8) DEF( define_var, 6, 0, 0, atom_u8) //53
DEF(check_define_var, 6, 0, 0, atom_u8) DEF(check_define_var, 6, 0, 0, atom_u8) //54
DEF( define_func, 6, 1, 0, atom_u8) DEF( define_func, 6, 1, 0, atom_u8) //55
DEF( get_field, 5, 1, 1, atom) DEF( get_field, 5, 1, 1, atom) //56
DEF( get_field2, 5, 1, 2, atom) DEF( get_field2, 5, 1, 2, atom) //57
DEF( put_field, 5, 2, 0, atom) DEF( put_field, 5, 2, 0, atom) //58
DEF( get_array_el, 1, 2, 1, none) DEF( get_array_el, 1, 2, 1, none) //59
DEF( get_array_el2, 1, 2, 2, none) /* obj prop -> obj value */ DEF( get_array_el2, 1, 2, 2, none) /* obj prop -> obj value */ //60
DEF( get_array_el3, 1, 2, 3, none) /* obj prop -> obj prop1 value */ DEF( get_array_el3, 1, 2, 3, none) /* obj prop -> obj prop1 value */ //61
DEF( put_array_el, 1, 3, 0, none) DEF( put_array_el, 1, 3, 0, none) //62
DEF( define_field, 5, 2, 1, atom) DEF( define_field, 5, 2, 1, atom) //63
DEF( set_name, 5, 1, 1, atom) DEF( set_name, 5, 1, 1, atom) //64
DEF(set_name_computed, 1, 2, 2, none) DEF(set_name_computed, 1, 2, 2, none) //65
DEF( set_proto, 1, 2, 1, none) DEF( set_proto, 1, 2, 1, none) //66
DEF(define_array_el, 1, 3, 2, none) DEF(define_array_el, 1, 3, 2, none) //67
DEF( append, 1, 3, 2, none) /* append enumerated object, update length */ DEF( append, 1, 3, 2, none) /* append enumerated object, update length */ //68
DEF(copy_data_properties, 2, 3, 3, u8) DEF(copy_data_properties, 2, 3, 3, u8) //69
DEF( define_method, 6, 2, 1, atom_u8) DEF( define_method, 6, 2, 1, atom_u8) //70
DEF(define_method_computed, 2, 3, 1, u8) /* must come after define_method */ DEF(define_method_computed, 2, 3, 1, u8) /* must come after define_method */ //71
DEF( define_class, 6, 2, 2, atom_u8) /* parent ctor -> ctor proto */ DEF( define_class, 6, 2, 2, atom_u8) /* parent ctor -> ctor proto */ //72
DEF( define_class_computed, 6, 3, 3, atom_u8) /* field_name parent ctor -> field_name ctor proto (class with computed name) */ DEF( define_class_computed, 6, 3, 3, atom_u8) /* field_name parent ctor -> field_name ctor proto (class with computed name) */ //73
DEF( get_loc, 3, 0, 1, loc) DEF( get_loc, 3, 0, 1, loc) //74
DEF( put_loc, 3, 1, 0, loc) /* must come after get_loc */ DEF( put_loc, 3, 1, 0, loc) /* must come after get_loc */ //75
DEF( set_loc, 3, 1, 1, loc) /* must come after put_loc */ DEF( set_loc, 3, 1, 1, loc) /* must come after put_loc */ //76
DEF( get_arg, 3, 0, 1, arg) DEF( get_arg, 3, 0, 1, arg) //77
DEF( put_arg, 3, 1, 0, arg) /* must come after get_arg */ DEF( put_arg, 3, 1, 0, arg) /* must come after get_arg */ //78
DEF( set_arg, 3, 1, 1, arg) /* must come after put_arg */ DEF( set_arg, 3, 1, 1, arg) /* must come after put_arg */ //79
DEF( get_var_ref, 3, 0, 1, var_ref) DEF( get_var_ref, 3, 0, 1, var_ref) //80
DEF( put_var_ref, 3, 1, 0, var_ref) /* must come after get_var_ref */ DEF( put_var_ref, 3, 1, 0, var_ref) /* must come after get_var_ref */ //81
DEF( set_var_ref, 3, 1, 1, var_ref) /* must come after put_var_ref */ DEF( set_var_ref, 3, 1, 1, var_ref) /* must come after put_var_ref */ //82
DEF(set_loc_uninitialized, 3, 0, 0, loc) DEF(set_loc_uninitialized, 3, 0, 0, loc) //83
DEF( get_loc_check, 3, 0, 1, loc) DEF( get_loc_check, 3, 0, 1, loc) //84
DEF( put_loc_check, 3, 1, 0, loc) /* must come after get_loc_check */ DEF( put_loc_check, 3, 1, 0, loc) /* must come after get_loc_check */ //85
DEF( put_loc_check_init, 3, 1, 0, loc) DEF( put_loc_check_init, 3, 1, 0, loc) //86
DEF(get_loc_checkthis, 3, 0, 1, loc) DEF(get_loc_checkthis, 3, 0, 1, loc) //87
DEF(get_var_ref_check, 3, 0, 1, var_ref) DEF(get_var_ref_check, 3, 0, 1, var_ref) //88
DEF(put_var_ref_check, 3, 1, 0, var_ref) /* must come after get_var_ref_check */ DEF(put_var_ref_check, 3, 1, 0, var_ref) /* must come after get_var_ref_check */ //89
DEF(put_var_ref_check_init, 3, 1, 0, var_ref) DEF(put_var_ref_check_init, 3, 1, 0, var_ref) //90
DEF( close_loc, 3, 0, 0, loc) DEF( close_loc, 3, 0, 0, loc) //91
DEF( if_false, 5, 1, 0, label) DEF( if_false, 5, 1, 0, label) //92
DEF( if_true, 5, 1, 0, label) /* must come after if_false */ DEF( if_true, 5, 1, 0, label) /* must come after if_false */ //93
DEF( goto, 5, 0, 0, label) /* must come after if_true */ DEF( goto, 5, 0, 0, label) /* must come after if_true */ //94
DEF( catch, 5, 0, 1, label) DEF( catch, 5, 0, 1, label) //95
DEF( gosub, 5, 0, 0, label) /* used to execute the finally block */ DEF( gosub, 5, 0, 0, label) /* used to execute the finally block */ //96
DEF( ret, 1, 1, 0, none) /* used to return from the finally block */ DEF( ret, 1, 1, 0, none) /* used to return from the finally block */ //97
DEF( nip_catch, 1, 2, 1, none) /* catch ... a -> a */ DEF( nip_catch, 1, 2, 1, none) /* catch ... a -> a */ //98
DEF( to_object, 1, 1, 1, none) DEF( to_object, 1, 1, 1, none) //99
//DEF( to_string, 1, 1, 1, none) //DEF( to_string, 1, 1, 1, none)
DEF( to_propkey, 1, 1, 1, none) DEF( to_propkey, 1, 1, 1, none) //100
DEF( make_loc_ref, 7, 0, 2, atom_u16) DEF( make_loc_ref, 7, 0, 2, atom_u16) //101
DEF( make_arg_ref, 7, 0, 2, atom_u16) DEF( make_arg_ref, 7, 0, 2, atom_u16) //102
DEF(make_var_ref_ref, 7, 0, 2, atom_u16) DEF(make_var_ref_ref, 7, 0, 2, atom_u16) //103
DEF( make_var_ref, 5, 0, 2, atom) DEF( make_var_ref, 5, 0, 2, atom) //104
DEF( for_in_start, 1, 1, 1, none) DEF( for_in_start, 1, 1, 1, none) //105
DEF( for_of_start, 1, 1, 3, none) DEF( for_of_start, 1, 1, 3, none) //106
DEF( for_in_next, 1, 1, 3, none) DEF( for_in_next, 1, 1, 3, none) //107
DEF( for_of_next, 2, 3, 5, u8) DEF( for_of_next, 2, 3, 5, u8) //108
DEF(iterator_check_object, 1, 1, 1, none) DEF(iterator_check_object, 1, 1, 1, none) //109
DEF(iterator_get_value_done, 1, 2, 3, none) /* catch_offset obj -> catch_offset value done */ DEF(iterator_get_value_done, 1, 2, 3, none) /* catch_offset obj -> catch_offset value done */ //110
DEF( iterator_close, 1, 3, 0, none) DEF( iterator_close, 1, 3, 0, none) //111
DEF( iterator_next, 1, 4, 4, none) DEF( iterator_next, 1, 4, 4, none) //112
DEF( iterator_call, 2, 4, 5, u8) DEF( iterator_call, 2, 4, 5, u8) //113
/* arithmetic/logic operations */ /* arithmetic/logic operations */
DEF( neg, 1, 1, 1, none) DEF( neg, 1, 1, 1, none) //114
DEF( plus, 1, 1, 1, none) DEF( plus, 1, 1, 1, none) //115
DEF( dec, 1, 1, 1, none) DEF( dec, 1, 1, 1, none) //116
DEF( inc, 1, 1, 1, none) DEF( inc, 1, 1, 1, none) //117
DEF( post_dec, 1, 1, 2, none) DEF( post_dec, 1, 1, 2, none) //118
DEF( post_inc, 1, 1, 2, none) DEF( post_inc, 1, 1, 2, none) //119
DEF( dec_loc, 2, 0, 0, loc8) DEF( dec_loc, 2, 0, 0, loc8) //120
DEF( inc_loc, 2, 0, 0, loc8) DEF( inc_loc, 2, 0, 0, loc8) //121
DEF( add_loc, 2, 1, 0, loc8) DEF( add_loc, 2, 1, 0, loc8) //122
DEF( not, 1, 1, 1, none) DEF( not, 1, 1, 1, none) //123
DEF( lnot, 1, 1, 1, none) DEF( lnot, 1, 1, 1, none) //124
DEF( typeof, 1, 1, 1, none) DEF( typeof, 1, 1, 1, none) //125
DEF( delete, 1, 2, 1, none) DEF( delete, 1, 2, 1, none) //126
DEF( delete_var, 5, 0, 1, atom) DEF( delete_var, 5, 0, 1, atom) //127
DEF( mul, 1, 2, 1, none) DEF( mul, 1, 2, 1, none) //128
DEF( div, 1, 2, 1, none) DEF( div, 1, 2, 1, none) //129
DEF( mod, 1, 2, 1, none) DEF( mod, 1, 2, 1, none) //130
DEF( add, 1, 2, 1, none) DEF( add, 1, 2, 1, none) //131
DEF( sub, 1, 2, 1, none) DEF( sub, 1, 2, 1, none) //132
DEF( pow, 1, 2, 1, none) DEF( pow, 1, 2, 1, none) //133
DEF( shl, 1, 2, 1, none) DEF( shl, 1, 2, 1, none) //134
DEF( sar, 1, 2, 1, none) DEF( sar, 1, 2, 1, none) //135
DEF( shr, 1, 2, 1, none) DEF( shr, 1, 2, 1, none) //136
DEF( lt, 1, 2, 1, none) DEF( lt, 1, 2, 1, none) //137
DEF( lte, 1, 2, 1, none) DEF( lte, 1, 2, 1, none) //138
DEF( gt, 1, 2, 1, none) DEF( gt, 1, 2, 1, none) //139
DEF( gte, 1, 2, 1, none) DEF( gte, 1, 2, 1, none) //140
DEF( instanceof, 1, 2, 1, none) DEF( instanceof, 1, 2, 1, none) //141
DEF( in, 1, 2, 1, none) DEF( in, 1, 2, 1, none) //142
DEF( eq, 1, 2, 1, none) DEF( eq, 1, 2, 1, none) //143
DEF( neq, 1, 2, 1, none) DEF( neq, 1, 2, 1, none) //144
DEF( strict_eq, 1, 2, 1, none) DEF( strict_eq, 1, 2, 1, none) //145
DEF( strict_neq, 1, 2, 1, none) DEF( strict_neq, 1, 2, 1, none) //146
DEF( and, 1, 2, 1, none) DEF( and, 1, 2, 1, none) //147
DEF( xor, 1, 2, 1, none) DEF( xor, 1, 2, 1, none) //148
DEF( or, 1, 2, 1, none) DEF( or, 1, 2, 1, none) //149
/* must be the last non short and non temporary opcode */ /* must be the last non short and non temporary opcode */
DEF( nop, 1, 0, 0, none) DEF( nop, 1, 0, 0, none) //150
/* temporary opcodes: never emitted in the final bytecode */ /* temporary opcodes: never emitted in the final bytecode */
@@ -255,76 +256,76 @@ 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 */
#if SHORT_OPCODES #if SHORT_OPCODES
DEF( push_minus1, 1, 0, 1, none_int) DEF( push_minus1, 1, 0, 1, none_int) //151
DEF( push_0, 1, 0, 1, none_int) DEF( push_0, 1, 0, 1, none_int) //152
DEF( push_1, 1, 0, 1, none_int) DEF( push_1, 1, 0, 1, none_int) //153
DEF( push_2, 1, 0, 1, none_int) DEF( push_2, 1, 0, 1, none_int) //154
DEF( push_3, 1, 0, 1, none_int) DEF( push_3, 1, 0, 1, none_int) //155
DEF( push_4, 1, 0, 1, none_int) DEF( push_4, 1, 0, 1, none_int) //156
DEF( push_5, 1, 0, 1, none_int) DEF( push_5, 1, 0, 1, none_int) //157
DEF( push_6, 1, 0, 1, none_int) DEF( push_6, 1, 0, 1, none_int) //158
DEF( push_7, 1, 0, 1, none_int) DEF( push_7, 1, 0, 1, none_int) //159
DEF( push_i8, 2, 0, 1, i8) DEF( push_i8, 2, 0, 1, i8) //160
DEF( push_i16, 3, 0, 1, i16) DEF( push_i16, 3, 0, 1, i16) //161
DEF( push_const8, 2, 0, 1, const8) DEF( push_const8, 2, 0, 1, const8) //162
DEF( fclosure8, 2, 0, 1, const8) /* must follow push_const8 */ DEF( fclosure8, 2, 0, 1, const8) /* must follow push_const8 */ //163
DEF(push_empty_string, 1, 0, 1, none) DEF(push_empty_string, 1, 0, 1, none) //164
DEF( get_loc8, 2, 0, 1, loc8) DEF( get_loc8, 2, 0, 1, loc8) //165
DEF( put_loc8, 2, 1, 0, loc8) DEF( put_loc8, 2, 1, 0, loc8) //166
DEF( set_loc8, 2, 1, 1, loc8) DEF( set_loc8, 2, 1, 1, loc8) //167
DEF( get_loc0, 1, 0, 1, none_loc) DEF( get_loc0, 1, 0, 1, none_loc) //168
DEF( get_loc1, 1, 0, 1, none_loc) DEF( get_loc1, 1, 0, 1, none_loc) //169
DEF( get_loc2, 1, 0, 1, none_loc) DEF( get_loc2, 1, 0, 1, none_loc) //170
DEF( get_loc3, 1, 0, 1, none_loc) DEF( get_loc3, 1, 0, 1, none_loc) //171
DEF( put_loc0, 1, 1, 0, none_loc) DEF( put_loc0, 1, 1, 0, none_loc) //172
DEF( put_loc1, 1, 1, 0, none_loc) DEF( put_loc1, 1, 1, 0, none_loc) //173
DEF( put_loc2, 1, 1, 0, none_loc) DEF( put_loc2, 1, 1, 0, none_loc) //174
DEF( put_loc3, 1, 1, 0, none_loc) DEF( put_loc3, 1, 1, 0, none_loc) //175
DEF( set_loc0, 1, 1, 1, none_loc) DEF( set_loc0, 1, 1, 1, none_loc) //176
DEF( set_loc1, 1, 1, 1, none_loc) DEF( set_loc1, 1, 1, 1, none_loc) //177
DEF( set_loc2, 1, 1, 1, none_loc) DEF( set_loc2, 1, 1, 1, none_loc) //178
DEF( set_loc3, 1, 1, 1, none_loc) DEF( set_loc3, 1, 1, 1, none_loc) //179
DEF( get_arg0, 1, 0, 1, none_arg) DEF( get_arg0, 1, 0, 1, none_arg) //180
DEF( get_arg1, 1, 0, 1, none_arg) DEF( get_arg1, 1, 0, 1, none_arg) //181
DEF( get_arg2, 1, 0, 1, none_arg) DEF( get_arg2, 1, 0, 1, none_arg) //182
DEF( get_arg3, 1, 0, 1, none_arg) DEF( get_arg3, 1, 0, 1, none_arg) //183
DEF( put_arg0, 1, 1, 0, none_arg) DEF( put_arg0, 1, 1, 0, none_arg) //184
DEF( put_arg1, 1, 1, 0, none_arg) DEF( put_arg1, 1, 1, 0, none_arg) //185
DEF( put_arg2, 1, 1, 0, none_arg) DEF( put_arg2, 1, 1, 0, none_arg) //186
DEF( put_arg3, 1, 1, 0, none_arg) DEF( put_arg3, 1, 1, 0, none_arg) //187
DEF( set_arg0, 1, 1, 1, none_arg) DEF( set_arg0, 1, 1, 1, none_arg) //188
DEF( set_arg1, 1, 1, 1, none_arg) DEF( set_arg1, 1, 1, 1, none_arg) //189
DEF( set_arg2, 1, 1, 1, none_arg) DEF( set_arg2, 1, 1, 1, none_arg) //190
DEF( set_arg3, 1, 1, 1, none_arg) DEF( set_arg3, 1, 1, 1, none_arg) //191
DEF( get_var_ref0, 1, 0, 1, none_var_ref) DEF( get_var_ref0, 1, 0, 1, none_var_ref) //192
DEF( get_var_ref1, 1, 0, 1, none_var_ref) DEF( get_var_ref1, 1, 0, 1, none_var_ref) //193
DEF( get_var_ref2, 1, 0, 1, none_var_ref) DEF( get_var_ref2, 1, 0, 1, none_var_ref) //194
DEF( get_var_ref3, 1, 0, 1, none_var_ref) DEF( get_var_ref3, 1, 0, 1, none_var_ref) //195
DEF( put_var_ref0, 1, 1, 0, none_var_ref) DEF( put_var_ref0, 1, 1, 0, none_var_ref) //196
DEF( put_var_ref1, 1, 1, 0, none_var_ref) DEF( put_var_ref1, 1, 1, 0, none_var_ref) //197
DEF( put_var_ref2, 1, 1, 0, none_var_ref) DEF( put_var_ref2, 1, 1, 0, none_var_ref) //198
DEF( put_var_ref3, 1, 1, 0, none_var_ref) DEF( put_var_ref3, 1, 1, 0, none_var_ref) //199
DEF( set_var_ref0, 1, 1, 1, none_var_ref) DEF( set_var_ref0, 1, 1, 1, none_var_ref) //200
DEF( set_var_ref1, 1, 1, 1, none_var_ref) DEF( set_var_ref1, 1, 1, 1, none_var_ref) //201
DEF( set_var_ref2, 1, 1, 1, none_var_ref) DEF( set_var_ref2, 1, 1, 1, none_var_ref) //202
DEF( set_var_ref3, 1, 1, 1, none_var_ref) DEF( set_var_ref3, 1, 1, 1, none_var_ref) //203
DEF( get_length, 1, 1, 1, none) DEF( get_length, 1, 1, 1, none) //204
DEF( if_false8, 2, 1, 0, label8) DEF( if_false8, 2, 1, 0, label8) //205
DEF( if_true8, 2, 1, 0, label8) /* must come after if_false8 */ DEF( if_true8, 2, 1, 0, label8) /* must come after if_false8 */ //206
DEF( goto8, 2, 0, 0, label8) /* must come after if_true8 */ DEF( goto8, 2, 0, 0, label8) /* must come after if_true8 */ //207
DEF( goto16, 3, 0, 0, label16) DEF( goto16, 3, 0, 0, label16) //208
DEF( call0, 1, 1, 1, npopx) DEF( call0, 1, 1, 1, npopx) //209
DEF( call1, 1, 1, 1, npopx) DEF( call1, 1, 1, 1, npopx) //210
DEF( call2, 1, 1, 1, npopx) DEF( call2, 1, 1, 1, npopx) //211
DEF( call3, 1, 1, 1, npopx) DEF( call3, 1, 1, 1, npopx) //212
DEF( is_null, 1, 1, 1, none) DEF( is_null, 1, 1, 1, none) //213
DEF( typeof_is_function, 1, 1, 1, none) DEF( typeof_is_function, 1, 1, 1, none) //214
#endif #endif
#undef DEF #undef DEF

View File

@@ -12970,6 +12970,67 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
*sp++ = ret_val; *sp++ = ret_val;
} }
BREAK; BREAK;
CASE(OP_go): /* … func arg0 … argN */
{
printf("GOING!!!\n");
/* ----- 1. decode operands exactly like the normal call -------- */
call_argc = get_u16(pc);
pc += 2;
call_argv = sp - call_argc; /* -> first argument */
JSValue callee = call_argv[-1]; /* function object */
/* ----- 2. can we recycle the current frame? ------------------ */
if (JS_VALUE_GET_TAG(callee) == JS_TAG_OBJECT) {
JSObject *obj = JS_VALUE_GET_OBJ(callee);
if (obj->class_id == JS_CLASS_BYTECODE_FUNCTION) {
/* ---- 2.a free *all* live values in the current frame */
for (pval = local_buf; pval < sp; ++pval)
JS_FreeValue(ctx, *pval);
for (i = -1; i < call_argc; ++i)
JS_FreeValue(ctx, call_argv[i]);
/* ---- 2.b overwrite the frame with the new function */
b = obj->u.func.function_bytecode;
sf->cur_func = JS_DupValue(ctx, callee); /* new func */
sf->arg_count = call_argc;
arg_buf = call_argv; /* reuse */
/* initialise formal parameters (extra args already NULL) */
for (i = 0; i < b->arg_count; ++i) {
if (i >= call_argc)
arg_buf[i] = JS_NULL;
}
/* place new var-&-stack segments right after argv */
var_buf = arg_buf + b->arg_count;
sf->var_buf = var_buf;
for (i = 0; i < b->var_count; ++i)
var_buf[i] = JS_NULL;
stack_buf = var_buf + b->var_count;
sp = stack_buf;
/* ---- 2.c jump to the callees byte-code entry point */
pc = b->byte_code_buf;
goto restart; /* ← no C recursion! */
}
}
/* ----- 3. fallback: native function or we gave up -------------- */
sf->cur_pc = pc;
ret_val = JS_CallInternal(ctx, callee,
JS_NULL, JS_NULL,
call_argc, call_argv, 0);
if (unlikely(JS_IsException(ret_val)))
goto exception;
/* behave like “return <call>” */
for (i = -1; i < call_argc; ++i)
JS_FreeValue(ctx, call_argv[i]);
sp = call_argv - 1; /* drop func+args */
goto done; /* return to caller */
}
BREAK;
CASE(OP_call_constructor): CASE(OP_call_constructor):
{ {
call_argc = get_u16(pc); call_argc = get_u16(pc);
@@ -15041,6 +15102,7 @@ enum {
TOK_IF, TOK_IF,
TOK_ELSE, TOK_ELSE,
TOK_RETURN, TOK_RETURN,
TOK_GO,
TOK_VAR, TOK_VAR,
TOK_DEF, TOK_DEF,
TOK_THIS, TOK_THIS,
@@ -20630,6 +20692,29 @@ static __exception int js_parse_statement_or_decl(JSParseState *s,
goto fail; goto fail;
} }
break; break;
case TOK_GO:
{
const uint8_t *op_token_ptr;
if (s->cur_func->is_eval) {
js_parse_error(s, "go not in a function");
goto fail;
}
op_token_ptr = s->token.ptr;
if (next_token(s))
goto fail;
if (s->token.val != ';' && s->token.val != '}' && !s->got_lf) {
if (js_parse_expr(s))
goto fail;
emit_source_pos(s, op_token_ptr);
emit_return(s, TRUE);
} else {
emit_source_pos(s, op_token_ptr);
emit_return(s, FALSE);
}
if (js_parse_expect_semi(s))
goto fail;
}
break;
case TOK_THROW: case TOK_THROW:
{ {
const uint8_t *op_token_ptr; const uint8_t *op_token_ptr;
@@ -24998,6 +25083,7 @@ static __exception int js_parse_directives(JSParseState *s)
case TOK_TRUE: case TOK_TRUE:
case TOK_IF: case TOK_IF:
case TOK_RETURN: case TOK_RETURN:
case TOK_GO:
case TOK_VAR: case TOK_VAR:
case TOK_THIS: case TOK_THIS:
case TOK_DELETE: case TOK_DELETE: