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, 1, 1, 1, none)
123 DEF(         import, 1, 1, 1, none) /* dynamic module import */
124 
125 DEF(      check_var, 5, 0, 1, atom) /* check if a variable exists */
126 DEF(  get_var_undef, 5, 0, 1, atom) /* push undefined if the variable does not exist */
127 DEF(        get_var, 5, 0, 1, atom) /* throw an exception if the variable does not exist */
128 DEF(        put_var, 5, 1, 0, atom) /* must come after get_var */
129 DEF(   put_var_init, 5, 1, 0, atom) /* must come after put_var. Used to initialize a global lexical variable */
130 DEF( put_var_strict, 5, 2, 0, atom) /* for strict mode variable write */
131 
132 DEF(  get_ref_value, 1, 2, 3, none)
133 DEF(  put_ref_value, 1, 3, 0, none)
134 
135 DEF(     define_var, 6, 0, 0, atom_u8)
136 DEF(check_define_var, 6, 0, 0, atom_u8)
137 DEF(    define_func, 6, 1, 0, atom_u8)
138 DEF(      get_field, 5, 1, 1, atom)
139 DEF(     get_field2, 5, 1, 2, atom)
140 DEF(      put_field, 5, 2, 0, atom)
141 DEF( get_private_field, 1, 2, 1, none) /* obj prop -> value */
142 DEF( put_private_field, 1, 3, 0, none) /* obj value prop -> */
143 DEF(define_private_field, 1, 3, 1, none) /* obj prop value -> obj */
144 DEF(   get_array_el, 1, 2, 1, none)
145 DEF(  get_array_el2, 1, 2, 2, none) /* obj prop -> obj value */
146 DEF(   put_array_el, 1, 3, 0, none)
147 DEF(get_super_value, 1, 3, 1, none) /* this obj prop -> value */
148 DEF(put_super_value, 1, 4, 0, none) /* this obj prop value -> */
149 DEF(   define_field, 5, 2, 1, atom)
150 DEF(       set_name, 5, 1, 1, atom)
151 DEF(set_name_computed, 1, 2, 2, none)
152 DEF(      set_proto, 1, 2, 1, none)
153 DEF(set_home_object, 1, 2, 2, none)
154 DEF(define_array_el, 1, 3, 2, none)
155 DEF(         append, 1, 3, 2, none) /* append enumerated object, update length */
156 DEF(copy_data_properties, 2, 3, 3, u8)
157 DEF(  define_method, 6, 2, 1, atom_u8)
158 DEF(define_method_computed, 2, 3, 1, u8) /* must come after define_method */
159 DEF(   define_class, 6, 2, 2, atom_u8) /* parent ctor -> ctor proto */
160 DEF(   define_class_computed, 6, 3, 3, atom_u8) /* field_name parent ctor -> field_name ctor proto (class with computed name) */
161 
162 DEF(        get_loc, 3, 0, 1, loc)
163 DEF(        put_loc, 3, 1, 0, loc) /* must come after get_loc */
164 DEF(        set_loc, 3, 1, 1, loc) /* must come after put_loc */
165 DEF(        get_arg, 3, 0, 1, arg)
166 DEF(        put_arg, 3, 1, 0, arg) /* must come after get_arg */
167 DEF(        set_arg, 3, 1, 1, arg) /* must come after put_arg */
168 DEF(    get_var_ref, 3, 0, 1, var_ref)
169 DEF(    put_var_ref, 3, 1, 0, var_ref) /* must come after get_var_ref */
170 DEF(    set_var_ref, 3, 1, 1, var_ref) /* must come after put_var_ref */
171 DEF(set_loc_uninitialized, 3, 0, 0, loc)
172 DEF(  get_loc_check, 3, 0, 1, loc)
173 DEF(  put_loc_check, 3, 1, 0, loc) /* must come after get_loc_check */
174 DEF(  put_loc_check_init, 3, 1, 0, loc)
175 DEF(get_var_ref_check, 3, 0, 1, var_ref)
176 DEF(put_var_ref_check, 3, 1, 0, var_ref) /* must come after get_var_ref_check */
177 DEF(put_var_ref_check_init, 3, 1, 0, var_ref)
178 DEF(      close_loc, 3, 0, 0, loc)
179 DEF(       if_false, 5, 1, 0, label)
180 DEF(        if_true, 5, 1, 0, label) /* must come after if_false */
181 DEF(           goto, 5, 0, 0, label) /* must come after if_true */
182 DEF(          catch, 5, 0, 1, label)
183 DEF(          gosub, 5, 0, 0, label) /* used to execute the finally block */
184 DEF(            ret, 1, 1, 0, none) /* used to return from the finally block */
185 
186 DEF(      to_object, 1, 1, 1, none)
187 //DEF(      to_string, 1, 1, 1, none)
188 DEF(     to_propkey, 1, 1, 1, none)
189 DEF(    to_propkey2, 1, 2, 2, none)
190 
191 DEF(   with_get_var, 10, 1, 0, atom_label_u8)     /* must be in the same order as scope_xxx */
192 DEF(   with_put_var, 10, 2, 1, atom_label_u8)     /* must be in the same order as scope_xxx */
193 DEF(with_delete_var, 10, 1, 0, atom_label_u8)     /* must be in the same order as scope_xxx */
194 DEF(  with_make_ref, 10, 1, 0, atom_label_u8)     /* must be in the same order as scope_xxx */
195 DEF(   with_get_ref, 10, 1, 0, atom_label_u8)     /* must be in the same order as scope_xxx */
196 DEF(with_get_ref_undef, 10, 1, 0, atom_label_u8)
197 
198 DEF(   make_loc_ref, 7, 0, 2, atom_u16)
199 DEF(   make_arg_ref, 7, 0, 2, atom_u16)
200 DEF(make_var_ref_ref, 7, 0, 2, atom_u16)
201 DEF(   make_var_ref, 5, 0, 2, atom)
202 
203 DEF(   for_in_start, 1, 1, 1, none)
204 DEF(   for_of_start, 1, 1, 3, none)
205 DEF(for_await_of_start, 1, 1, 3, none)
206 DEF(    for_in_next, 1, 1, 3, none)
207 DEF(    for_of_next, 2, 3, 5, u8)
208 DEF(for_await_of_next, 1, 3, 4, none)
209 DEF(iterator_get_value_done, 1, 1, 2, none)
210 DEF( iterator_close, 1, 3, 0, none)
211 DEF(iterator_close_return, 1, 4, 4, none)
212 DEF(async_iterator_close, 1, 3, 2, none)
213 DEF(async_iterator_next, 1, 4, 4, none)
214 DEF(async_iterator_get, 2, 4, 5, u8)
215 DEF(  initial_yield, 1, 0, 0, none)
216 DEF(          yield, 1, 1, 2, none)
217 DEF(     yield_star, 1, 2, 2, none)
218 DEF(async_yield_star, 1, 1, 2, none)
219 DEF(          await, 1, 1, 1, none)
220 
221 /* arithmetic/logic operations */
222 DEF(            neg, 1, 1, 1, none)
223 DEF(           plus, 1, 1, 1, none)
224 DEF(            dec, 1, 1, 1, none)
225 DEF(            inc, 1, 1, 1, none)
226 DEF(       post_dec, 1, 1, 2, none)
227 DEF(       post_inc, 1, 1, 2, none)
228 DEF(        dec_loc, 2, 0, 0, loc8)
229 DEF(        inc_loc, 2, 0, 0, loc8)
230 DEF(        add_loc, 2, 1, 0, loc8)
231 DEF(            not, 1, 1, 1, none)
232 DEF(           lnot, 1, 1, 1, none)
233 DEF(         typeof, 1, 1, 1, none)
234 DEF(         delete, 1, 2, 1, none)
235 DEF(     delete_var, 5, 0, 1, atom)
236 
237 DEF(            mul, 1, 2, 1, none)
238 DEF(            div, 1, 2, 1, none)
239 DEF(            mod, 1, 2, 1, none)
240 DEF(            add, 1, 2, 1, none)
241 DEF(            sub, 1, 2, 1, none)
242 DEF(            pow, 1, 2, 1, none)
243 DEF(            shl, 1, 2, 1, none)
244 DEF(            sar, 1, 2, 1, none)
245 DEF(            shr, 1, 2, 1, none)
246 DEF(             lt, 1, 2, 1, none)
247 DEF(            lte, 1, 2, 1, none)
248 DEF(             gt, 1, 2, 1, none)
249 DEF(            gte, 1, 2, 1, none)
250 DEF(     instanceof, 1, 2, 1, none)
251 DEF(             in, 1, 2, 1, none)
252 DEF(             eq, 1, 2, 1, none)
253 DEF(            neq, 1, 2, 1, none)
254 DEF(      strict_eq, 1, 2, 1, none)
255 DEF(     strict_neq, 1, 2, 1, none)
256 DEF(            and, 1, 2, 1, none)
257 DEF(            xor, 1, 2, 1, none)
258 DEF(             or, 1, 2, 1, none)
259 DEF(is_undefined_or_null, 1, 1, 1, none)
260 #ifdef CONFIG_BIGNUM
261 DEF(      mul_pow10, 1, 2, 1, none)
262 DEF(       math_mod, 1, 2, 1, none)
263 #endif
264 /* must be the last non short and non temporary opcode */
265 DEF(            nop, 1, 0, 0, none)
266 
267 /* temporary opcodes: never emitted in the final bytecode */
268 
269 def(set_arg_valid_upto, 3, 0, 0, arg) /* emitted in phase 1, removed in phase 2 */
270 
271 def(    enter_scope, 3, 0, 0, u16)  /* emitted in phase 1, removed in phase 2 */
272 def(    leave_scope, 3, 0, 0, u16)  /* emitted in phase 1, removed in phase 2 */
273 
274 def(          label, 5, 0, 0, label) /* emitted in phase 1, removed in phase 3 */
275 
276 def(scope_get_var_undef, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
277 def(  scope_get_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
278 def(  scope_put_var, 7, 1, 0, atom_u16) /* emitted in phase 1, removed in phase 2 */
279 def(scope_delete_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
280 def( scope_make_ref, 11, 0, 2, atom_label_u16) /* emitted in phase 1, removed in phase 2 */
281 def(  scope_get_ref, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */
282 def(scope_put_var_init, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */
283 def(scope_get_private_field, 7, 1, 1, atom_u16) /* obj -> value, emitted in phase 1, removed in phase 2 */
284 def(scope_get_private_field2, 7, 1, 2, atom_u16) /* obj -> obj value, emitted in phase 1, removed in phase 2 */
285 def(scope_put_private_field, 7, 1, 1, atom_u16) /* obj value ->, emitted in phase 1, removed in phase 2 */
286 
287 def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */
288 
289 def(       line_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */
290 
291 #if SHORT_OPCODES
292 DEF(    push_minus1, 1, 0, 1, none_int)
293 DEF(         push_0, 1, 0, 1, none_int)
294 DEF(         push_1, 1, 0, 1, none_int)
295 DEF(         push_2, 1, 0, 1, none_int)
296 DEF(         push_3, 1, 0, 1, none_int)
297 DEF(         push_4, 1, 0, 1, none_int)
298 DEF(         push_5, 1, 0, 1, none_int)
299 DEF(         push_6, 1, 0, 1, none_int)
300 DEF(         push_7, 1, 0, 1, none_int)
301 DEF(        push_i8, 2, 0, 1, i8)
302 DEF(       push_i16, 3, 0, 1, i16)
303 DEF(    push_const8, 2, 0, 1, const8)
304 DEF(      fclosure8, 2, 0, 1, const8) /* must follow push_const8 */
305 DEF(push_empty_string, 1, 0, 1, none)
306 
307 DEF(       get_loc8, 2, 0, 1, loc8)
308 DEF(       put_loc8, 2, 1, 0, loc8)
309 DEF(       set_loc8, 2, 1, 1, loc8)
310 
311 DEF(       get_loc0, 1, 0, 1, none_loc)
312 DEF(       get_loc1, 1, 0, 1, none_loc)
313 DEF(       get_loc2, 1, 0, 1, none_loc)
314 DEF(       get_loc3, 1, 0, 1, none_loc)
315 DEF(       put_loc0, 1, 1, 0, none_loc)
316 DEF(       put_loc1, 1, 1, 0, none_loc)
317 DEF(       put_loc2, 1, 1, 0, none_loc)
318 DEF(       put_loc3, 1, 1, 0, none_loc)
319 DEF(       set_loc0, 1, 1, 1, none_loc)
320 DEF(       set_loc1, 1, 1, 1, none_loc)
321 DEF(       set_loc2, 1, 1, 1, none_loc)
322 DEF(       set_loc3, 1, 1, 1, none_loc)
323 DEF(       get_arg0, 1, 0, 1, none_arg)
324 DEF(       get_arg1, 1, 0, 1, none_arg)
325 DEF(       get_arg2, 1, 0, 1, none_arg)
326 DEF(       get_arg3, 1, 0, 1, none_arg)
327 DEF(       put_arg0, 1, 1, 0, none_arg)
328 DEF(       put_arg1, 1, 1, 0, none_arg)
329 DEF(       put_arg2, 1, 1, 0, none_arg)
330 DEF(       put_arg3, 1, 1, 0, none_arg)
331 DEF(       set_arg0, 1, 1, 1, none_arg)
332 DEF(       set_arg1, 1, 1, 1, none_arg)
333 DEF(       set_arg2, 1, 1, 1, none_arg)
334 DEF(       set_arg3, 1, 1, 1, none_arg)
335 DEF(   get_var_ref0, 1, 0, 1, none_var_ref)
336 DEF(   get_var_ref1, 1, 0, 1, none_var_ref)
337 DEF(   get_var_ref2, 1, 0, 1, none_var_ref)
338 DEF(   get_var_ref3, 1, 0, 1, none_var_ref)
339 DEF(   put_var_ref0, 1, 1, 0, none_var_ref)
340 DEF(   put_var_ref1, 1, 1, 0, none_var_ref)
341 DEF(   put_var_ref2, 1, 1, 0, none_var_ref)
342 DEF(   put_var_ref3, 1, 1, 0, none_var_ref)
343 DEF(   set_var_ref0, 1, 1, 1, none_var_ref)
344 DEF(   set_var_ref1, 1, 1, 1, none_var_ref)
345 DEF(   set_var_ref2, 1, 1, 1, none_var_ref)
346 DEF(   set_var_ref3, 1, 1, 1, none_var_ref)
347 
348 DEF(     get_length, 1, 1, 1, none)
349 
350 DEF(      if_false8, 2, 1, 0, label8)
351 DEF(       if_true8, 2, 1, 0, label8) /* must come after if_false8 */
352 DEF(          goto8, 2, 0, 0, label8) /* must come after if_true8 */
353 DEF(         goto16, 3, 0, 0, label16)
354 
355 DEF(          call0, 1, 1, 1, npopx)
356 DEF(          call1, 1, 1, 1, npopx)
357 DEF(          call2, 1, 1, 1, npopx)
358 DEF(          call3, 1, 1, 1, npopx)
359 
360 DEF(   is_undefined, 1, 1, 1, none)
361 DEF(        is_null, 1, 1, 1, none)
362 DEF(    is_function, 1, 1, 1, none)
363 #endif
364 
365 #undef DEF
366 #undef def
367 #endif  /* DEF */
368