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