/* * QuickJS opcode definitions * * Copyright (c) 2017-2018 Fabrice Bellard * Copyright (c) 2017-2018 Charlie Gordon * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #ifdef FMT FMT(none) FMT(none_int) FMT(none_loc) FMT(none_arg) FMT(none_var_ref) FMT(u8) FMT(i8) FMT(loc8) FMT(const8) FMT(label8) FMT(u16) FMT(i16) FMT(label16) FMT(npop) FMT(npopx) FMT(npop_u16) FMT(loc) FMT(arg) FMT(var_ref) FMT(u32) FMT(i32) FMT(const) FMT(label) FMT(atom) FMT(atom_u8) FMT(atom_u16) FMT(atom_label_u8) FMT(atom_label_u16) FMT(label_u16) #undef FMT #endif /* FMT */ #ifdef DEF #ifndef def #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 */ //0 /* push values */ 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 -> */ //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 */ //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 */ //44 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) //51 DEF( put_ref_value, 1, 3, 0, none) //52 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) //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) //99 //DEF( to_string, 1, 1, 1, none) DEF( to_propkey, 1, 1, 1, none) //100 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) //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) //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) //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) //150 /* temporary opcodes: never emitted in the final bytecode */ def( enter_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */ def( leave_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */ def( label, 5, 0, 0, label) /* emitted in phase 1, removed in phase 3 */ /* the following opcodes must be in the same order as the 'with_x' and get_var_undef, get_var and put_var opcodes */ def(scope_get_var_undef, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */ def( scope_get_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */ def( scope_put_var, 7, 1, 0, atom_u16) /* emitted in phase 1, removed in phase 2 */ def(scope_delete_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */ def( scope_make_ref, 11, 0, 2, atom_label_u16) /* emitted in phase 1, removed in phase 2 */ def( scope_get_ref, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */ def(scope_put_var_init, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */ def(scope_get_var_checkthis, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2, only used to return 'this' in derived class constructors */ def(get_field_opt_chain, 5, 1, 1, atom) /* emitted in phase 1, removed in phase 2 */ def(get_array_el_opt_chain, 1, 2, 1, none) /* 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 */ #if SHORT_OPCODES 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) //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) //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) //204 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) //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) //213 DEF( typeof_is_function, 1, 1, 1, none) //214 #endif #undef DEF #undef def #endif /* DEF */