1 /* 2 * QuickJS opcode definitions 3 * 4 * Copyright (c) 2017-2018 Fabrice Bellard 5 * Copyright (c) 2017-2018 Charlie Gordon 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in 15 * all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 * THE SOFTWARE. 24 */ 25 26 #ifdef FMT 27 FMT(none) 28 FMT(none_int) 29 FMT(none_loc) 30 FMT(none_arg) 31 FMT(none_var_ref) 32 FMT(u8) 33 FMT(i8) 34 FMT(loc8) 35 FMT(const8) 36 FMT(label8) 37 FMT(u16) 38 FMT(i16) 39 FMT(label16) 40 FMT(npop) 41 FMT(npopx) 42 FMT(npop_u16) 43 FMT(loc) 44 FMT(arg) 45 FMT(var_ref) 46 FMT(u32) 47 FMT(i32) 48 FMT(const) 49 FMT(label) 50 FMT(atom) 51 FMT(atom_u8) 52 FMT(atom_u16) 53 FMT(atom_label_u8) 54 FMT(atom_label_u16) 55 FMT(label_u16) 56 #undef FMT 57 #endif /* FMT */ 58 59 #ifdef DEF 60 61 #ifndef def 62 #define def(id, size, n_pop, n_push, f) DEF(id, size, n_pop, n_push, f) 63 #endif 64 65 DEF(invalid, 1, 0, 0, none) /* never emitted */ 66 67 /* push values */ 68 DEF( push_i32, 5, 0, 1, i32) 69 DEF( push_const, 5, 0, 1, const) 70 DEF( fclosure, 5, 0, 1, const) /* must follow push_const */ 71 DEF(push_atom_value, 5, 0, 1, atom) 72 DEF( private_symbol, 5, 0, 1, atom) 73 DEF( undefined, 1, 0, 1, none) 74 DEF( null, 1, 0, 1, none) 75 DEF( push_this, 1, 0, 1, none) /* only used at the start of a function */ 76 DEF( push_false, 1, 0, 1, none) 77 DEF( push_true, 1, 0, 1, none) 78 DEF( object, 1, 0, 1, none) 79 DEF( special_object, 2, 0, 1, u8) /* only used at the start of a function */ 80 DEF( rest, 3, 0, 1, u16) /* only used at the start of a function */ 81 82 DEF( drop, 1, 1, 0, none) /* a -> */ 83 DEF( nip, 1, 2, 1, none) /* a b -> b */ 84 DEF( nip1, 1, 3, 2, none) /* a b c -> b c */ 85 DEF( dup, 1, 1, 2, none) /* a -> a a */ 86 DEF( dup1, 1, 2, 3, none) /* a b -> a a b */ 87 DEF( dup2, 1, 2, 4, none) /* a b -> a b a b */ 88 DEF( dup3, 1, 3, 6, none) /* a b c -> a b c a b c */ 89 DEF( insert2, 1, 2, 3, none) /* obj a -> a obj a (dup_x1) */ 90 DEF( insert3, 1, 3, 4, none) /* obj prop a -> a obj prop a (dup_x2) */ 91 DEF( insert4, 1, 4, 5, none) /* this obj prop a -> a this obj prop a */ 92 DEF( perm3, 1, 3, 3, none) /* obj a b -> a obj b */ 93 DEF( perm4, 1, 4, 4, none) /* obj prop a b -> a obj prop b */ 94 DEF( perm5, 1, 5, 5, none) /* this obj prop a b -> a this obj prop b */ 95 DEF( swap, 1, 2, 2, none) /* a b -> b a */ 96 DEF( swap2, 1, 4, 4, none) /* a b c d -> c d a b */ 97 DEF( rot3l, 1, 3, 3, none) /* x a b -> a b x */ 98 DEF( rot3r, 1, 3, 3, none) /* a b x -> x a b */ 99 DEF( rot4l, 1, 4, 4, none) /* x a b c -> a b c x */ 100 DEF( rot5l, 1, 5, 5, none) /* x a b c d -> a b c d x */ 101 102 DEF(call_constructor, 3, 2, 1, npop) /* func new.target args -> ret. arguments are not counted in n_pop */ 103 DEF( call, 3, 1, 1, npop) /* arguments are not counted in n_pop */ 104 DEF( tail_call, 3, 1, 0, npop) /* arguments are not counted in n_pop */ 105 DEF( call_method, 3, 2, 1, npop) /* arguments are not counted in n_pop */ 106 DEF(tail_call_method, 3, 2, 0, npop) /* arguments are not counted in n_pop */ 107 DEF( array_from, 3, 0, 1, npop) /* arguments are not counted in n_pop */ 108 DEF( apply, 3, 3, 1, u16) 109 DEF( return, 1, 1, 0, none) 110 DEF( return_undef, 1, 0, 0, none) 111 DEF(check_ctor_return, 1, 1, 2, none) 112 DEF( check_ctor, 1, 0, 0, none) 113 DEF( check_brand, 1, 2, 2, none) /* this_obj func -> this_obj func */ 114 DEF( add_brand, 1, 2, 0, none) /* this_obj home_obj -> */ 115 DEF( return_async, 1, 1, 0, none) 116 DEF( throw, 1, 1, 0, none) 117 DEF( throw_var, 6, 0, 0, atom_u8) 118 DEF( eval, 5, 1, 1, npop_u16) /* func args... -> ret_val */ 119 DEF( apply_eval, 3, 2, 1, u16) /* func array -> ret_eval */ 120 DEF( regexp, 1, 2, 1, none) /* create a RegExp object from the pattern and a 121 bytecode string */ 122 DEF( get_super_ctor, 1, 1, 1, none) 123 DEF( get_super, 1, 1, 1, none) 124 DEF( import, 1, 1, 1, none) /* dynamic module import */ 125 126 DEF( check_var, 5, 0, 1, atom) /* check if a variable exists */ 127 DEF( get_var_undef, 5, 0, 1, atom) /* push undefined if the variable does not exist */ 128 DEF( get_var, 5, 0, 1, atom) /* throw an exception if the variable does not exist */ 129 DEF( put_var, 5, 1, 0, atom) /* must come after get_var */ 130 DEF( put_var_init, 5, 1, 0, atom) /* must come after put_var. Used to initialize a global lexical variable */ 131 DEF( put_var_strict, 5, 2, 0, atom) /* for strict mode variable write */ 132 133 DEF( get_ref_value, 1, 2, 3, none) 134 DEF( put_ref_value, 1, 3, 0, none) 135 136 DEF( define_var, 6, 0, 0, atom_u8) 137 DEF(check_define_var, 6, 0, 0, atom_u8) 138 DEF( define_func, 6, 1, 0, atom_u8) 139 DEF( get_field, 5, 1, 1, atom) 140 DEF( get_field2, 5, 1, 2, atom) 141 DEF( put_field, 5, 2, 0, atom) 142 DEF( get_private_field, 1, 2, 1, none) /* obj prop -> value */ 143 DEF( put_private_field, 1, 3, 0, none) /* obj value prop -> */ 144 DEF(define_private_field, 1, 3, 1, none) /* obj prop value -> obj */ 145 DEF( get_array_el, 1, 2, 1, none) 146 DEF( get_array_el2, 1, 2, 2, none) /* obj prop -> obj value */ 147 DEF( put_array_el, 1, 3, 0, none) 148 DEF(get_super_value, 1, 3, 1, none) /* this obj prop -> value */ 149 DEF(put_super_value, 1, 4, 0, none) /* this obj prop value -> */ 150 DEF( define_field, 5, 2, 1, atom) 151 DEF( set_name, 5, 1, 1, atom) 152 DEF(set_name_computed, 1, 2, 2, none) 153 DEF( set_proto, 1, 2, 1, none) 154 DEF(set_home_object, 1, 2, 2, none) 155 DEF(define_array_el, 1, 3, 2, none) 156 DEF( append, 1, 3, 2, none) /* append enumerated object, update length */ 157 DEF(copy_data_properties, 2, 3, 3, u8) 158 DEF( define_method, 6, 2, 1, atom_u8) 159 DEF(define_method_computed, 2, 3, 1, u8) /* must come after define_method */ 160 DEF( define_class, 6, 2, 2, atom_u8) /* parent ctor -> ctor proto */ 161 DEF( define_class_computed, 6, 3, 3, atom_u8) /* field_name parent ctor -> field_name ctor proto (class with computed name) */ 162 163 DEF( get_loc, 3, 0, 1, loc) 164 DEF( put_loc, 3, 1, 0, loc) /* must come after get_loc */ 165 DEF( set_loc, 3, 1, 1, loc) /* must come after put_loc */ 166 DEF( get_arg, 3, 0, 1, arg) 167 DEF( put_arg, 3, 1, 0, arg) /* must come after get_arg */ 168 DEF( set_arg, 3, 1, 1, arg) /* must come after put_arg */ 169 DEF( get_var_ref, 3, 0, 1, var_ref) 170 DEF( put_var_ref, 3, 1, 0, var_ref) /* must come after get_var_ref */ 171 DEF( set_var_ref, 3, 1, 1, var_ref) /* must come after put_var_ref */ 172 DEF(set_loc_uninitialized, 3, 0, 0, loc) 173 DEF( get_loc_check, 3, 0, 1, loc) 174 DEF( put_loc_check, 3, 1, 0, loc) /* must come after get_loc_check */ 175 DEF( put_loc_check_init, 3, 1, 0, loc) 176 DEF(get_var_ref_check, 3, 0, 1, var_ref) 177 DEF(put_var_ref_check, 3, 1, 0, var_ref) /* must come after get_var_ref_check */ 178 DEF(put_var_ref_check_init, 3, 1, 0, var_ref) 179 DEF( close_loc, 3, 0, 0, loc) 180 DEF( if_false, 5, 1, 0, label) 181 DEF( if_true, 5, 1, 0, label) /* must come after if_false */ 182 DEF( goto, 5, 0, 0, label) /* must come after if_true */ 183 DEF( catch, 5, 0, 1, label) 184 DEF( gosub, 5, 0, 0, label) /* used to execute the finally block */ 185 DEF( ret, 1, 1, 0, none) /* used to return from the finally block */ 186 187 DEF( to_object, 1, 1, 1, none) 188 //DEF( to_string, 1, 1, 1, none) 189 DEF( to_propkey, 1, 1, 1, none) 190 DEF( to_propkey2, 1, 2, 2, none) 191 192 DEF( with_get_var, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */ 193 DEF( with_put_var, 10, 2, 1, atom_label_u8) /* must be in the same order as scope_xxx */ 194 DEF(with_delete_var, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */ 195 DEF( with_make_ref, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */ 196 DEF( with_get_ref, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */ 197 DEF(with_get_ref_undef, 10, 1, 0, atom_label_u8) 198 199 DEF( make_loc_ref, 7, 0, 2, atom_u16) 200 DEF( make_arg_ref, 7, 0, 2, atom_u16) 201 DEF(make_var_ref_ref, 7, 0, 2, atom_u16) 202 DEF( make_var_ref, 5, 0, 2, atom) 203 204 DEF( for_in_start, 1, 1, 1, none) 205 DEF( for_of_start, 1, 1, 3, none) 206 DEF(for_await_of_start, 1, 1, 3, none) 207 DEF( for_in_next, 1, 1, 3, none) 208 DEF( for_of_next, 2, 3, 5, u8) 209 DEF(for_await_of_next, 1, 3, 4, none) 210 DEF(iterator_get_value_done, 1, 1, 2, none) 211 DEF( iterator_close, 1, 3, 0, none) 212 DEF(iterator_close_return, 1, 4, 4, none) 213 DEF(async_iterator_close, 1, 3, 2, none) 214 DEF(async_iterator_next, 1, 4, 4, none) 215 DEF(async_iterator_get, 2, 4, 5, u8) 216 DEF( initial_yield, 1, 0, 0, none) 217 DEF( yield, 1, 1, 2, none) 218 DEF( yield_star, 1, 2, 2, none) 219 DEF(async_yield_star, 1, 1, 2, none) 220 DEF( await, 1, 1, 1, none) 221 222 /* arithmetic/logic operations */ 223 DEF( neg, 1, 1, 1, none) 224 DEF( plus, 1, 1, 1, none) 225 DEF( dec, 1, 1, 1, none) 226 DEF( inc, 1, 1, 1, none) 227 DEF( post_dec, 1, 1, 2, none) 228 DEF( post_inc, 1, 1, 2, none) 229 DEF( dec_loc, 2, 0, 0, loc8) 230 DEF( inc_loc, 2, 0, 0, loc8) 231 DEF( add_loc, 2, 1, 0, loc8) 232 DEF( not, 1, 1, 1, none) 233 DEF( lnot, 1, 1, 1, none) 234 DEF( typeof, 1, 1, 1, none) 235 DEF( delete, 1, 2, 1, none) 236 DEF( delete_var, 5, 0, 1, atom) 237 238 DEF( mul, 1, 2, 1, none) 239 DEF( div, 1, 2, 1, none) 240 DEF( mod, 1, 2, 1, none) 241 DEF( add, 1, 2, 1, none) 242 DEF( sub, 1, 2, 1, none) 243 DEF( pow, 1, 2, 1, none) 244 DEF( shl, 1, 2, 1, none) 245 DEF( sar, 1, 2, 1, none) 246 DEF( shr, 1, 2, 1, none) 247 DEF( lt, 1, 2, 1, none) 248 DEF( lte, 1, 2, 1, none) 249 DEF( gt, 1, 2, 1, none) 250 DEF( gte, 1, 2, 1, none) 251 DEF( instanceof, 1, 2, 1, none) 252 DEF( in, 1, 2, 1, none) 253 DEF( eq, 1, 2, 1, none) 254 DEF( neq, 1, 2, 1, none) 255 DEF( strict_eq, 1, 2, 1, none) 256 DEF( strict_neq, 1, 2, 1, none) 257 DEF( and, 1, 2, 1, none) 258 DEF( xor, 1, 2, 1, none) 259 DEF( or, 1, 2, 1, none) 260 DEF(is_undefined_or_null, 1, 1, 1, none) 261 #ifdef CONFIG_BIGNUM 262 DEF( mul_pow10, 1, 2, 1, none) 263 DEF( math_div, 1, 2, 1, none) 264 DEF( math_mod, 1, 2, 1, none) 265 DEF( math_pow, 1, 2, 1, none) 266 #endif 267 /* must be the last non short and non temporary opcode */ 268 DEF( nop, 1, 0, 0, none) 269 270 /* temporary opcodes: never emitted in the final bytecode */ 271 272 def(set_arg_valid_upto, 3, 0, 0, arg) /* emitted in phase 1, removed in phase 2 */ 273 274 def(close_var_object, 1, 0, 0, none) /* emitted in phase 1, removed in phase 2 */ 275 def( enter_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */ 276 def( leave_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */ 277 278 def( label, 5, 0, 0, label) /* emitted in phase 1, removed in phase 3 */ 279 280 def(scope_get_var_undef, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */ 281 def( scope_get_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */ 282 def( scope_put_var, 7, 1, 0, atom_u16) /* emitted in phase 1, removed in phase 2 */ 283 def(scope_delete_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */ 284 def( scope_make_ref, 11, 0, 2, atom_label_u16) /* emitted in phase 1, removed in phase 2 */ 285 def( scope_get_ref, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */ 286 def(scope_put_var_init, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */ 287 def(scope_get_private_field, 7, 1, 1, atom_u16) /* obj -> value, emitted in phase 1, removed in phase 2 */ 288 def(scope_get_private_field2, 7, 1, 2, atom_u16) /* obj -> obj value, emitted in phase 1, removed in phase 2 */ 289 def(scope_put_private_field, 7, 1, 1, atom_u16) /* obj value ->, emitted in phase 1, removed in phase 2 */ 290 291 def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */ 292 293 def( line_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */ 294 295 #if SHORT_OPCODES 296 DEF( push_minus1, 1, 0, 1, none_int) 297 DEF( push_0, 1, 0, 1, none_int) 298 DEF( push_1, 1, 0, 1, none_int) 299 DEF( push_2, 1, 0, 1, none_int) 300 DEF( push_3, 1, 0, 1, none_int) 301 DEF( push_4, 1, 0, 1, none_int) 302 DEF( push_5, 1, 0, 1, none_int) 303 DEF( push_6, 1, 0, 1, none_int) 304 DEF( push_7, 1, 0, 1, none_int) 305 DEF( push_i8, 2, 0, 1, i8) 306 DEF( push_i16, 3, 0, 1, i16) 307 DEF( push_const8, 2, 0, 1, const8) 308 DEF( fclosure8, 2, 0, 1, const8) /* must follow push_const8 */ 309 DEF(push_empty_string, 1, 0, 1, none) 310 311 DEF( get_loc8, 2, 0, 1, loc8) 312 DEF( put_loc8, 2, 1, 0, loc8) 313 DEF( set_loc8, 2, 1, 1, loc8) 314 315 DEF( get_loc0, 1, 0, 1, none_loc) 316 DEF( get_loc1, 1, 0, 1, none_loc) 317 DEF( get_loc2, 1, 0, 1, none_loc) 318 DEF( get_loc3, 1, 0, 1, none_loc) 319 DEF( put_loc0, 1, 1, 0, none_loc) 320 DEF( put_loc1, 1, 1, 0, none_loc) 321 DEF( put_loc2, 1, 1, 0, none_loc) 322 DEF( put_loc3, 1, 1, 0, none_loc) 323 DEF( set_loc0, 1, 1, 1, none_loc) 324 DEF( set_loc1, 1, 1, 1, none_loc) 325 DEF( set_loc2, 1, 1, 1, none_loc) 326 DEF( set_loc3, 1, 1, 1, none_loc) 327 DEF( get_arg0, 1, 0, 1, none_arg) 328 DEF( get_arg1, 1, 0, 1, none_arg) 329 DEF( get_arg2, 1, 0, 1, none_arg) 330 DEF( get_arg3, 1, 0, 1, none_arg) 331 DEF( put_arg0, 1, 1, 0, none_arg) 332 DEF( put_arg1, 1, 1, 0, none_arg) 333 DEF( put_arg2, 1, 1, 0, none_arg) 334 DEF( put_arg3, 1, 1, 0, none_arg) 335 DEF( set_arg0, 1, 1, 1, none_arg) 336 DEF( set_arg1, 1, 1, 1, none_arg) 337 DEF( set_arg2, 1, 1, 1, none_arg) 338 DEF( set_arg3, 1, 1, 1, none_arg) 339 DEF( get_var_ref0, 1, 0, 1, none_var_ref) 340 DEF( get_var_ref1, 1, 0, 1, none_var_ref) 341 DEF( get_var_ref2, 1, 0, 1, none_var_ref) 342 DEF( get_var_ref3, 1, 0, 1, none_var_ref) 343 DEF( put_var_ref0, 1, 1, 0, none_var_ref) 344 DEF( put_var_ref1, 1, 1, 0, none_var_ref) 345 DEF( put_var_ref2, 1, 1, 0, none_var_ref) 346 DEF( put_var_ref3, 1, 1, 0, none_var_ref) 347 DEF( set_var_ref0, 1, 1, 1, none_var_ref) 348 DEF( set_var_ref1, 1, 1, 1, none_var_ref) 349 DEF( set_var_ref2, 1, 1, 1, none_var_ref) 350 DEF( set_var_ref3, 1, 1, 1, none_var_ref) 351 352 DEF( get_length, 1, 1, 1, none) 353 354 DEF( if_false8, 2, 1, 0, label8) 355 DEF( if_true8, 2, 1, 0, label8) /* must come after if_false8 */ 356 DEF( goto8, 2, 0, 0, label8) /* must come after if_true8 */ 357 DEF( goto16, 3, 0, 0, label16) 358 359 DEF( call0, 1, 1, 1, npopx) 360 DEF( call1, 1, 1, 1, npopx) 361 DEF( call2, 1, 1, 1, npopx) 362 DEF( call3, 1, 1, 1, npopx) 363 364 DEF( is_undefined, 1, 1, 1, none) 365 DEF( is_null, 1, 1, 1, none) 366 DEF( is_function, 1, 1, 1, none) 367 #endif 368 369 #undef DEF 370 #undef def 371 #endif /* DEF */ 372