1 Commits
stack ... js-go

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 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);
JS_FreeValue(js,ret);
JS_FreeValue(js, exp);

View File

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

View File

@@ -12970,6 +12970,67 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
*sp++ = ret_val;
}
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):
{
call_argc = get_u16(pc);
@@ -15041,6 +15102,7 @@ enum {
TOK_IF,
TOK_ELSE,
TOK_RETURN,
TOK_GO,
TOK_VAR,
TOK_DEF,
TOK_THIS,
@@ -20630,6 +20692,29 @@ static __exception int js_parse_statement_or_decl(JSParseState *s,
goto fail;
}
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:
{
const uint8_t *op_token_ptr;
@@ -24998,6 +25083,7 @@ static __exception int js_parse_directives(JSParseState *s)
case TOK_TRUE:
case TOK_IF:
case TOK_RETURN:
case TOK_GO:
case TOK_VAR:
case TOK_THIS:
case TOK_DELETE: