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
27FMT(none)
28FMT(none_int)
29FMT(none_loc)
30FMT(none_arg)
31FMT(none_var_ref)
32FMT(u8)
33FMT(i8)
34FMT(loc8)
35FMT(const8)
36FMT(label8)
37FMT(u16)
38FMT(i16)
39FMT(label16)
40FMT(npop)
41FMT(npopx)
42FMT(npop_u16)
43FMT(loc)
44FMT(arg)
45FMT(var_ref)
46FMT(u32)
47FMT(i32)
48FMT(const)
49FMT(label)
50FMT(atom)
51FMT(atom_u8)
52FMT(atom_u16)
53FMT(atom_label_u8)
54FMT(atom_label_u16)
55FMT(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
65DEF(invalid, 1, 0, 0, none) /* never emitted */
66
67/* push values */
68DEF( push_i32, 5, 0, 1, i32)
69DEF( push_const, 5, 0, 1, const)
70DEF( fclosure, 5, 0, 1, const) /* must follow push_const */
71DEF(push_atom_value, 5, 0, 1, atom)
72DEF( private_symbol, 5, 0, 1, atom)
73DEF( undefined, 1, 0, 1, none)
74DEF( null, 1, 0, 1, none)
75DEF( push_this, 1, 0, 1, none) /* only used at the start of a function */
76DEF( push_false, 1, 0, 1, none)
77DEF( push_true, 1, 0, 1, none)
78DEF( object, 1, 0, 1, none)
79DEF( special_object, 2, 0, 1, u8) /* only used at the start of a function */
80DEF( rest, 3, 0, 1, u16) /* only used at the start of a function */
81
82DEF( drop, 1, 1, 0, none) /* a -> */
83DEF( nip, 1, 2, 1, none) /* a b -> b */
84DEF( nip1, 1, 3, 2, none) /* a b c -> b c */
85DEF( dup, 1, 1, 2, none) /* a -> a a */
86DEF( dup1, 1, 2, 3, none) /* a b -> a a b */
87DEF( dup2, 1, 2, 4, none) /* a b -> a b a b */
88DEF( dup3, 1, 3, 6, none) /* a b c -> a b c a b c */
89DEF( insert2, 1, 2, 3, none) /* obj a -> a obj a (dup_x1) */
90DEF( insert3, 1, 3, 4, none) /* obj prop a -> a obj prop a (dup_x2) */
91DEF( insert4, 1, 4, 5, none) /* this obj prop a -> a this obj prop a */
92DEF( perm3, 1, 3, 3, none) /* obj a b -> a obj b */
93DEF( perm4, 1, 4, 4, none) /* obj prop a b -> a obj prop b */
94DEF( perm5, 1, 5, 5, none) /* this obj prop a b -> a this obj prop b */
95DEF( swap, 1, 2, 2, none) /* a b -> b a */
96DEF( swap2, 1, 4, 4, none) /* a b c d -> c d a b */
97DEF( rot3l, 1, 3, 3, none) /* x a b -> a b x */
98DEF( rot3r, 1, 3, 3, none) /* a b x -> x a b */
99DEF( rot4l, 1, 4, 4, none) /* x a b c -> a b c x */
100DEF( rot5l, 1, 5, 5, none) /* x a b c d -> a b c d x */
101
102DEF(call_constructor, 3, 2, 1, npop) /* func new.target args -> ret. arguments are not counted in n_pop */
103DEF( call, 3, 1, 1, npop) /* arguments are not counted in n_pop */
104DEF( tail_call, 3, 1, 0, npop) /* arguments are not counted in n_pop */
105DEF( call_method, 3, 2, 1, npop) /* arguments are not counted in n_pop */
106DEF(tail_call_method, 3, 2, 0, npop) /* arguments are not counted in n_pop */
107DEF( array_from, 3, 0, 1, npop) /* arguments are not counted in n_pop */
108DEF( apply, 3, 3, 1, u16)
109DEF( return, 1, 1, 0, none)
110DEF( return_undef, 1, 0, 0, none)
111DEF(check_ctor_return, 1, 1, 2, none)
112DEF( check_ctor, 1, 0, 0, none)
113DEF( init_ctor, 1, 0, 1, none)
114DEF( check_brand, 1, 2, 2, none) /* this_obj func -> this_obj func */
115DEF( add_brand, 1, 2, 0, none) /* this_obj home_obj -> */
116DEF( return_async, 1, 1, 0, none)
117DEF( throw, 1, 1, 0, none)
118DEF( throw_error, 6, 0, 0, atom_u8)
119DEF( eval, 5, 1, 1, npop_u16) /* func args... -> ret_val */
120DEF( apply_eval, 3, 2, 1, u16) /* func array -> ret_eval */
121DEF( regexp, 1, 2, 1, none) /* create a RegExp object from the pattern and a
122 bytecode string */
123DEF( get_super, 1, 1, 1, none)
124DEF( import, 1, 1, 1, none) /* dynamic module import */
125
126DEF( check_var, 5, 0, 1, atom) /* check if a variable exists */
127DEF( get_var_undef, 5, 0, 1, atom) /* push undefined if the variable does not exist */
128DEF( get_var, 5, 0, 1, atom) /* throw an exception if the variable does not exist */
129DEF( put_var, 5, 1, 0, atom) /* must come after get_var */
130DEF( put_var_init, 5, 1, 0, atom) /* must come after put_var. Used to initialize a global lexical variable */
131DEF( put_var_strict, 5, 2, 0, atom) /* for strict mode variable write */
132
133DEF( get_ref_value, 1, 2, 3, none)
134DEF( put_ref_value, 1, 3, 0, none)
135
136DEF( define_var, 6, 0, 0, atom_u8)
137DEF(check_define_var, 6, 0, 0, atom_u8)
138DEF( define_func, 6, 1, 0, atom_u8)
139DEF( get_field, 5, 1, 1, atom)
140DEF( get_field2, 5, 1, 2, atom)
141DEF( put_field, 5, 2, 0, atom)
142DEF( get_private_field, 1, 2, 1, none) /* obj prop -> value */
143DEF( put_private_field, 1, 3, 0, none) /* obj value prop -> */
144DEF(define_private_field, 1, 3, 1, none) /* obj prop value -> obj */
145DEF( get_array_el, 1, 2, 1, none)
146DEF( get_array_el2, 1, 2, 2, none) /* obj prop -> obj value */
147DEF( put_array_el, 1, 3, 0, none)
148DEF(get_super_value, 1, 3, 1, none) /* this obj prop -> value */
149DEF(put_super_value, 1, 4, 0, none) /* this obj prop value -> */
150DEF( define_field, 5, 2, 1, atom)
151DEF( set_name, 5, 1, 1, atom)
152DEF(set_name_computed, 1, 2, 2, none)
153DEF( set_proto, 1, 2, 1, none)
154DEF(set_home_object, 1, 2, 2, none)
155DEF(define_array_el, 1, 3, 2, none)
156DEF( append, 1, 3, 2, none) /* append enumerated object, update length */
157DEF(copy_data_properties, 2, 3, 3, u8)
158DEF( define_method, 6, 2, 1, atom_u8)
159DEF(define_method_computed, 2, 3, 1, u8) /* must come after define_method */
160DEF( define_class, 6, 2, 2, atom_u8) /* parent ctor -> ctor proto */
161DEF( define_class_computed, 6, 3, 3, atom_u8) /* field_name parent ctor -> field_name ctor proto (class with computed name) */
162
163DEF( get_loc, 3, 0, 1, loc)
164DEF( put_loc, 3, 1, 0, loc) /* must come after get_loc */
165DEF( set_loc, 3, 1, 1, loc) /* must come after put_loc */
166DEF( get_arg, 3, 0, 1, arg)
167DEF( put_arg, 3, 1, 0, arg) /* must come after get_arg */
168DEF( set_arg, 3, 1, 1, arg) /* must come after put_arg */
169DEF( get_var_ref, 3, 0, 1, var_ref)
170DEF( put_var_ref, 3, 1, 0, var_ref) /* must come after get_var_ref */
171DEF( set_var_ref, 3, 1, 1, var_ref) /* must come after put_var_ref */
172DEF(set_loc_uninitialized, 3, 0, 0, loc)
173DEF( get_loc_check, 3, 0, 1, loc)
174DEF( put_loc_check, 3, 1, 0, loc) /* must come after get_loc_check */
175DEF( put_loc_check_init, 3, 1, 0, loc)
176DEF(get_loc_checkthis, 3, 0, 1, loc)
177DEF(get_var_ref_check, 3, 0, 1, var_ref)
178DEF(put_var_ref_check, 3, 1, 0, var_ref) /* must come after get_var_ref_check */
179DEF(put_var_ref_check_init, 3, 1, 0, var_ref)
180DEF( close_loc, 3, 0, 0, loc)
181DEF( if_false, 5, 1, 0, label)
182DEF( if_true, 5, 1, 0, label) /* must come after if_false */
183DEF( goto, 5, 0, 0, label) /* must come after if_true */
184DEF( catch, 5, 0, 1, label)
185DEF( gosub, 5, 0, 0, label) /* used to execute the finally block */
186DEF( ret, 1, 1, 0, none) /* used to return from the finally block */
187DEF( nip_catch, 1, 2, 1, none) /* catch ... a -> a */
188
189DEF( to_object, 1, 1, 1, none)
190//DEF( to_string, 1, 1, 1, none)
191DEF( to_propkey, 1, 1, 1, none)
192DEF( to_propkey2, 1, 2, 2, none)
193
194DEF( with_get_var, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */
195DEF( with_put_var, 10, 2, 1, atom_label_u8) /* must be in the same order as scope_xxx */
196DEF(with_delete_var, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */
197DEF( with_make_ref, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */
198DEF( with_get_ref, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */
199
200DEF( make_loc_ref, 7, 0, 2, atom_u16)
201DEF( make_arg_ref, 7, 0, 2, atom_u16)
202DEF(make_var_ref_ref, 7, 0, 2, atom_u16)
203DEF( make_var_ref, 5, 0, 2, atom)
204
205DEF( for_in_start, 1, 1, 1, none)
206DEF( for_of_start, 1, 1, 3, none)
207DEF(for_await_of_start, 1, 1, 3, none)
208DEF( for_in_next, 1, 1, 3, none)
209DEF( for_of_next, 2, 3, 5, u8)
210DEF(for_await_of_next, 1, 3, 4, none) /* iter next catch_offset -> iter next catch_offset obj */
211DEF(iterator_check_object, 1, 1, 1, none)
212DEF(iterator_get_value_done, 1, 2, 3, none) /* catch_offset obj -> catch_offset value done */
213DEF( iterator_close, 1, 3, 0, none)
214DEF( iterator_next, 1, 4, 4, none)
215DEF( iterator_call, 2, 4, 5, u8)
216DEF( initial_yield, 1, 0, 0, none)
217DEF( yield, 1, 1, 2, none)
218DEF( yield_star, 1, 1, 2, none)
219DEF(async_yield_star, 1, 1, 2, none)
220DEF( await, 1, 1, 1, none)
221
222/* arithmetic/logic operations */
223DEF( neg, 1, 1, 1, none)
224DEF( plus, 1, 1, 1, none)
225DEF( dec, 1, 1, 1, none)
226DEF( inc, 1, 1, 1, none)
227DEF( post_dec, 1, 1, 2, none)
228DEF( post_inc, 1, 1, 2, none)
229DEF( dec_loc, 2, 0, 0, loc8)
230DEF( inc_loc, 2, 0, 0, loc8)
231DEF( add_loc, 2, 1, 0, loc8)
232DEF( not, 1, 1, 1, none)
233DEF( lnot, 1, 1, 1, none)
234DEF( typeof, 1, 1, 1, none)
235DEF( delete, 1, 2, 1, none)
236DEF( delete_var, 5, 0, 1, atom)
237
238DEF( mul, 1, 2, 1, none)
239DEF( div, 1, 2, 1, none)
240DEF( mod, 1, 2, 1, none)
241DEF( add, 1, 2, 1, none)
242DEF( sub, 1, 2, 1, none)
243DEF( pow, 1, 2, 1, none)
244DEF( shl, 1, 2, 1, none)
245DEF( sar, 1, 2, 1, none)
246DEF( shr, 1, 2, 1, none)
247DEF( lt, 1, 2, 1, none)
248DEF( lte, 1, 2, 1, none)
249DEF( gt, 1, 2, 1, none)
250DEF( gte, 1, 2, 1, none)
251DEF( instanceof, 1, 2, 1, none)
252DEF( in, 1, 2, 1, none)
253DEF( eq, 1, 2, 1, none)
254DEF( neq, 1, 2, 1, none)
255DEF( strict_eq, 1, 2, 1, none)
256DEF( strict_neq, 1, 2, 1, none)
257DEF( and, 1, 2, 1, none)
258DEF( xor, 1, 2, 1, none)
259DEF( or, 1, 2, 1, none)
260DEF(is_undefined_or_null, 1, 1, 1, none)
261DEF( private_in, 1, 2, 1, none)
262DEF(push_bigint_i32, 5, 0, 1, i32)
263/* must be the last non short and non temporary opcode */
264DEF( nop, 1, 0, 0, none)
265
266/* temporary opcodes: never emitted in the final bytecode */
267
268def( enter_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */
269def( leave_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */
270
271def( label, 5, 0, 0, label) /* emitted in phase 1, removed in phase 3 */
272
273/* the following opcodes must be in the same order as the 'with_x' and
274 get_var_undef, get_var and put_var opcodes */
275def(scope_get_var_undef, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
276def( scope_get_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
277def( scope_put_var, 7, 1, 0, atom_u16) /* emitted in phase 1, removed in phase 2 */
278def(scope_delete_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
279def( scope_make_ref, 11, 0, 2, atom_label_u16) /* emitted in phase 1, removed in phase 2 */
280def( scope_get_ref, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */
281def(scope_put_var_init, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */
282def(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 */
283def(scope_get_private_field, 7, 1, 1, atom_u16) /* obj -> value, emitted in phase 1, removed in phase 2 */
284def(scope_get_private_field2, 7, 1, 2, atom_u16) /* obj -> obj value, emitted in phase 1, removed in phase 2 */
285def(scope_put_private_field, 7, 2, 0, atom_u16) /* obj value ->, emitted in phase 1, removed in phase 2 */
286def(scope_in_private_field, 7, 1, 1, atom_u16) /* obj -> res emitted in phase 1, removed in phase 2 */
287def(get_field_opt_chain, 5, 1, 1, atom) /* emitted in phase 1, removed in phase 2 */
288def(get_array_el_opt_chain, 1, 2, 1, none) /* emitted in phase 1, removed in phase 2 */
289def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */
290
291def( line_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */
292
293#if SHORT_OPCODES
294DEF( push_minus1, 1, 0, 1, none_int)
295DEF( push_0, 1, 0, 1, none_int)
296DEF( push_1, 1, 0, 1, none_int)
297DEF( push_2, 1, 0, 1, none_int)
298DEF( push_3, 1, 0, 1, none_int)
299DEF( push_4, 1, 0, 1, none_int)
300DEF( push_5, 1, 0, 1, none_int)
301DEF( push_6, 1, 0, 1, none_int)
302DEF( push_7, 1, 0, 1, none_int)
303DEF( push_i8, 2, 0, 1, i8)
304DEF( push_i16, 3, 0, 1, i16)
305DEF( push_const8, 2, 0, 1, const8)
306DEF( fclosure8, 2, 0, 1, const8) /* must follow push_const8 */
307DEF(push_empty_string, 1, 0, 1, none)
308
309DEF( get_loc8, 2, 0, 1, loc8)
310DEF( put_loc8, 2, 1, 0, loc8)
311DEF( set_loc8, 2, 1, 1, loc8)
312
313DEF( get_loc0, 1, 0, 1, none_loc)
314DEF( get_loc1, 1, 0, 1, none_loc)
315DEF( get_loc2, 1, 0, 1, none_loc)
316DEF( get_loc3, 1, 0, 1, none_loc)
317DEF( put_loc0, 1, 1, 0, none_loc)
318DEF( put_loc1, 1, 1, 0, none_loc)
319DEF( put_loc2, 1, 1, 0, none_loc)
320DEF( put_loc3, 1, 1, 0, none_loc)
321DEF( set_loc0, 1, 1, 1, none_loc)
322DEF( set_loc1, 1, 1, 1, none_loc)
323DEF( set_loc2, 1, 1, 1, none_loc)
324DEF( set_loc3, 1, 1, 1, none_loc)
325DEF( get_arg0, 1, 0, 1, none_arg)
326DEF( get_arg1, 1, 0, 1, none_arg)
327DEF( get_arg2, 1, 0, 1, none_arg)
328DEF( get_arg3, 1, 0, 1, none_arg)
329DEF( put_arg0, 1, 1, 0, none_arg)
330DEF( put_arg1, 1, 1, 0, none_arg)
331DEF( put_arg2, 1, 1, 0, none_arg)
332DEF( put_arg3, 1, 1, 0, none_arg)
333DEF( set_arg0, 1, 1, 1, none_arg)
334DEF( set_arg1, 1, 1, 1, none_arg)
335DEF( set_arg2, 1, 1, 1, none_arg)
336DEF( set_arg3, 1, 1, 1, none_arg)
337DEF( get_var_ref0, 1, 0, 1, none_var_ref)
338DEF( get_var_ref1, 1, 0, 1, none_var_ref)
339DEF( get_var_ref2, 1, 0, 1, none_var_ref)
340DEF( get_var_ref3, 1, 0, 1, none_var_ref)
341DEF( put_var_ref0, 1, 1, 0, none_var_ref)
342DEF( put_var_ref1, 1, 1, 0, none_var_ref)
343DEF( put_var_ref2, 1, 1, 0, none_var_ref)
344DEF( put_var_ref3, 1, 1, 0, none_var_ref)
345DEF( set_var_ref0, 1, 1, 1, none_var_ref)
346DEF( set_var_ref1, 1, 1, 1, none_var_ref)
347DEF( set_var_ref2, 1, 1, 1, none_var_ref)
348DEF( set_var_ref3, 1, 1, 1, none_var_ref)
349
350DEF( get_length, 1, 1, 1, none)
351
352DEF( if_false8, 2, 1, 0, label8)
353DEF( if_true8, 2, 1, 0, label8) /* must come after if_false8 */
354DEF( goto8, 2, 0, 0, label8) /* must come after if_true8 */
355DEF( goto16, 3, 0, 0, label16)
356
357DEF( call0, 1, 1, 1, npopx)
358DEF( call1, 1, 1, 1, npopx)
359DEF( call2, 1, 1, 1, npopx)
360DEF( call3, 1, 1, 1, npopx)
361
362DEF( is_undefined, 1, 1, 1, none)
363DEF( is_null, 1, 1, 1, none)
364DEF(typeof_is_undefined, 1, 1, 1, none)
365DEF( typeof_is_function, 1, 1, 1, none)
366#endif
367
368#undef DEF
369#undef def
370#endif /* DEF */
371