MIRROR: javascript for 馃悳's, a tiny runtime with big ambitions
1#ifdef OP_FMT
2OP_FMT(none)
3OP_FMT(u8)
4OP_FMT(i8)
5OP_FMT(u16)
6OP_FMT(i16)
7OP_FMT(u32)
8OP_FMT(i32)
9OP_FMT(atom)
10OP_FMT(atom_u8)
11OP_FMT(label)
12OP_FMT(label8)
13OP_FMT(loc)
14OP_FMT(loc8)
15OP_FMT(loc_atom)
16OP_FMT(arg)
17OP_FMT(const)
18OP_FMT(const8)
19OP_FMT(npop)
20OP_FMT(var_ref)
21#undef OP_FMT
22#endif
23
24#ifdef OP_DEF
25#ifndef op_def
26#define op_def(name, size, n_pop, n_push, f) OP_DEF(name, size, n_pop, n_push, f)
27#endif
28
29OP_DEF( INVALID, 1, 0, 0, none)
30OP_DEF( CONST, 5, 0, 1, const) /* push constant pool[idx] */
31OP_DEF( CONST_I8, 2, 0, 1, i8) /* push small integer */
32OP_DEF( CONST8, 2, 0, 1, const8) /* push constant pool[u8 idx] */
33OP_DEF( UNDEF, 1, 0, 1, none)
34OP_DEF( NULL, 1, 0, 1, none)
35OP_DEF( TRUE, 1, 0, 1, none)
36OP_DEF( FALSE, 1, 0, 1, none)
37OP_DEF( THIS, 1, 0, 1, none) /* push current 'this' */
38OP_DEF( GLOBAL, 1, 0, 1, none) /* push 'globalThis' (js->global) */
39OP_DEF( OBJECT, 1, 0, 1, none) /* push empty object {} */
40OP_DEF( ARRAY, 3, 0, 1, npop) /* push array from stack items */
41OP_DEF( SET_BRAND, 2, 1, 1, u8) /* obj -> obj (brand id) */
42OP_DEF( REGEXP, 1, 2, 1, none) /* pattern flags -> regexp */
43OP_DEF( CLOSURE, 5, 0, 1, const) /* push closure from func pool */
44
45OP_DEF( POP, 1, 1, 0, none) /* a -> */
46OP_DEF( DUP, 1, 1, 2, none) /* a -> a a */
47OP_DEF( DUP2, 1, 2, 4, none) /* a b -> a b a b */
48OP_DEF( SWAP, 1, 2, 2, none) /* a b -> b a */
49OP_DEF( ROT3L, 1, 3, 3, none) /* x a b -> a b x */
50OP_DEF( ROT3R, 1, 3, 3, none) /* a b x -> x a b */
51OP_DEF( NIP, 1, 2, 1, none) /* a b -> b */
52OP_DEF( NIP2, 1, 3, 1, none) /* a b c -> c */
53OP_DEF( INSERT2, 1, 2, 3, none) /* obj a -> a obj a */
54OP_DEF( INSERT3, 1, 3, 4, none) /* obj prop a -> a obj prop a */
55OP_DEF( SWAP_UNDER, 1, 3, 3, none) /* a b c -> b a c */
56OP_DEF( ROT4_UNDER, 1, 4, 4, none) /* a b c d -> c a b d */
57
58OP_DEF( GET_LOCAL, 3, 0, 1, loc)
59OP_DEF( PUT_LOCAL, 3, 1, 0, loc) /* store, consume */
60OP_DEF( SET_LOCAL, 3, 1, 1, loc) /* store, keep on stack */
61OP_DEF( GET_LOCAL8, 2, 0, 1, loc8) /* short encoding */
62OP_DEF( PUT_LOCAL8, 2, 1, 0, loc8)
63OP_DEF( SET_LOCAL8, 2, 1, 1, loc8)
64OP_DEF( SET_LOCAL_UNDEF, 3, 0, 0, loc) /* mark TDZ uninitialized */
65OP_DEF( GET_LOCAL_CHK, 7, 0, 1, loc_atom) /* get + TDZ check (u16 slot, u32 atom) */
66OP_DEF( PUT_LOCAL_CHK, 7, 1, 0, loc_atom) /* put + TDZ check (u16 slot, u32 atom) */
67OP_DEF( GET_SLOT_RAW, 3, 0, 1, loc) /* push raw frame slot value (no builder read) */
68
69OP_DEF( GET_ARG, 3, 0, 1, arg)
70OP_DEF( PUT_ARG, 3, 1, 0, arg)
71OP_DEF( SET_ARG, 3, 1, 1, arg)
72OP_DEF( REST, 3, 0, 1, u16) /* collect rest params */
73
74OP_DEF( GET_UPVAL, 3, 0, 1, var_ref)
75OP_DEF( PUT_UPVAL, 3, 1, 0, var_ref)
76OP_DEF( SET_UPVAL, 3, 1, 1, var_ref)
77OP_DEF( CLOSE_UPVAL, 3, 0, 0, loc) /* close upvalues >= loc */
78
79OP_DEF( GET_GLOBAL, 7, 0, 1, atom) /* push global[atom] (atom + ic_idx:u16) */
80OP_DEF( GET_GLOBAL_UNDEF, 7, 0, 1, atom) /* push undefined if missing (atom + ic_idx:u16) */
81OP_DEF( PUT_GLOBAL, 5, 1, 0, atom) /* global[atom] = TOS */
82
83OP_DEF( GET_FIELD, 7, 1, 1, atom) /* obj -> val (atom + ic_idx:u16) */
84OP_DEF( GET_FIELD2, 7, 1, 2, atom) /* obj -> obj val (atom + ic_idx:u16) */
85OP_DEF( PUT_FIELD, 7, 2, 0, atom) /* obj val -> (atom + ic_idx:u16) */
86OP_DEF( GET_ELEM, 1, 2, 1, none) /* obj key -> val */
87OP_DEF( GET_ELEM2, 1, 2, 2, none) /* obj key -> obj val */
88OP_DEF( PUT_ELEM, 1, 3, 0, none) /* obj key val -> */
89OP_DEF( DEFINE_FIELD, 5, 2, 1, atom) /* obj val -> obj (own prop) */
90OP_DEF( GET_LENGTH, 1, 1, 1, none) /* obj -> length */
91
92OP_DEF( GET_FIELD_OPT, 5, 1, 1, atom) /* null-safe obj -> val */
93OP_DEF( GET_ELEM_OPT, 1, 2, 1, none) /* null-safe obj key -> val */
94
95OP_DEF( GET_PRIVATE, 1, 2, 1, none) /* obj private_name -> value */
96OP_DEF( GET_PRIVATE_OPT, 1, 2, 1, none) /* obj private_name -> value|undefined */
97OP_DEF( PUT_PRIVATE, 1, 3, 1, none) /* obj value private_name -> value */
98OP_DEF( DEF_PRIVATE, 2, 3, 1, u8) /* obj private_name value -> obj */
99OP_DEF( HAS_PRIVATE, 1, 2, 1, none) /* obj private_name -> bool */
100
101OP_DEF( GET_SUPER, 1, 1, 1, none) /* obj -> super */
102OP_DEF( GET_SUPER_VAL, 1, 3, 1, none) /* this obj prop -> value */
103OP_DEF( PUT_SUPER_VAL, 1, 4, 0, none) /* this obj prop value -> */
104
105OP_DEF( ADD, 1, 2, 1, none)
106OP_DEF( SUB, 1, 2, 1, none)
107OP_DEF( MUL, 1, 2, 1, none)
108OP_DEF( DIV, 1, 2, 1, none)
109OP_DEF( ADD_NUM, 1, 2, 1, none) /* numeric-only fast path */
110OP_DEF( SUB_NUM, 1, 2, 1, none) /* numeric-only fast path */
111OP_DEF( MUL_NUM, 1, 2, 1, none) /* numeric-only fast path */
112OP_DEF( DIV_NUM, 1, 2, 1, none) /* numeric-only fast path */
113OP_DEF( MOD, 1, 2, 1, none)
114OP_DEF( EXP, 1, 2, 1, none)
115OP_DEF( NEG, 1, 1, 1, none) /* unary minus */
116OP_DEF( UPLUS, 1, 1, 1, none) /* unary plus (ToNumber) */
117OP_DEF( INC, 1, 1, 1, none) /* +1 */
118OP_DEF( DEC, 1, 1, 1, none) /* -1 */
119OP_DEF( POST_INC, 1, 1, 2, none) /* -> old new */
120OP_DEF( POST_DEC, 1, 1, 2, none) /* -> old new */
121OP_DEF( INC_LOCAL, 2, 0, 0, loc8) /* locals[i]++ in-place */
122OP_DEF( DEC_LOCAL, 2, 0, 0, loc8) /* locals[i]-- in-place */
123OP_DEF( ADD_LOCAL, 2, 1, 0, loc8) /* locals[i] += TOS */
124OP_DEF( STR_APPEND_LOCAL, 3, 1, 0, loc) /* logical slot += TOS via builder */
125OP_DEF( STR_ALC_SNAPSHOT, 3, 2, 0, loc) /* logical slot = snapshot + TOS */
126OP_DEF( STR_FLUSH_LOCAL, 3, 0, 0, loc) /* materialize logical slot builder */
127
128OP_DEF( EQ, 1, 2, 1, none) /* == (abstract) */
129OP_DEF( NE, 1, 2, 1, none) /* != */
130OP_DEF( SEQ, 1, 2, 1, none) /* === (strict, matches TOK_SEQ) */
131OP_DEF( SNE, 1, 2, 1, none) /* !== (strict, matches TOK_SNE) */
132OP_DEF( LT, 1, 2, 1, none)
133OP_DEF( LE, 1, 2, 1, none)
134OP_DEF( GT, 1, 2, 1, none)
135OP_DEF( GE, 1, 2, 1, none)
136OP_DEF( INSTANCEOF, 3, 2, 1, u16) /* l r -> bool (ic_idx:u16) */
137OP_DEF( IN, 1, 2, 1, none)
138OP_DEF( IS_NULLISH, 1, 1, 1, none) /* TOS is null|undefined? */
139OP_DEF( IS_UNDEF_OR_NULL, 1, 1, 1, none) /* same, for ?? chains */
140
141OP_DEF( BAND, 1, 2, 1, none) /* & (matches TOK_AND) */
142OP_DEF( BOR, 1, 2, 1, none) /* | (matches TOK_OR) */
143OP_DEF( BXOR, 1, 2, 1, none) /* ^ (matches TOK_XOR) */
144OP_DEF( BNOT, 1, 1, 1, none) /* ~ (matches TOK_TILDA) */
145OP_DEF( SHL, 1, 2, 1, none) /* << */
146OP_DEF( SHR, 1, 2, 1, none) /* >> (signed) */
147OP_DEF( USHR, 1, 2, 1, none) /* >>> (matches TOK_ZSHR) */
148
149OP_DEF( NOT, 1, 1, 1, none) /* ! */
150OP_DEF( TYPEOF, 1, 1, 1, none)
151OP_DEF( VOID, 1, 1, 1, none) /* eval + push undefined */
152OP_DEF( DELETE, 1, 2, 1, none) /* obj key -> bool */
153OP_DEF( DELETE_VAR, 5, 0, 1, atom) /* delete unqualified name */
154
155OP_DEF( JMP, 5, 0, 0, label) /* unconditional */
156OP_DEF( JMP_FALSE, 5, 1, 0, label) /* pop + branch if falsy */
157OP_DEF( JMP_TRUE, 5, 1, 0, label) /* pop + branch if truthy */
158OP_DEF( JMP_FALSE_PEEK, 5, 1, 1, label) /* peek + branch if falsy */
159OP_DEF( JMP_TRUE_PEEK, 5, 1, 1, label) /* peek + branch if truthy */
160OP_DEF( JMP_NOT_NULLISH, 5, 1, 1, label) /* peek + branch if NOT null/undefined */
161OP_DEF( JMP8, 2, 0, 0, label8) /* short unconditional */
162OP_DEF( JMP_FALSE8, 2, 1, 0, label8) /* short conditional */
163OP_DEF( JMP_TRUE8, 2, 1, 0, label8) /* short conditional */
164
165OP_DEF( CALL, 3, 1, 1, npop) /* func args... -> result */
166OP_DEF( CALL_METHOD, 3, 2, 1, npop) /* this func args... -> result */
167OP_DEF( CALL_IS_PROTO, 3, 3, 1, u16) /* this func arg -> bool (ic_idx:u16) */
168OP_DEF( CALL_ARRAY_INCLUDES, 3, 2, 1, npop) /* this func args... -> bool */
169OP_DEF( RE_EXEC_TRUTHY, 1, 3, 1, none) /* this func arg -> bool */
170OP_DEF( TAIL_CALL, 3, 1, 0, npop) /* tail-position call */
171OP_DEF( TAIL_CALL_METHOD, 3, 2, 0, npop)
172OP_DEF( NEW, 3, 2, 1, npop) /* func new.target args -> obj */
173OP_DEF( APPLY, 3, 3, 1, u16) /* func this [args] -> result */
174OP_DEF( SUPER_APPLY, 3, 3, 1, u16) /* super this [args] -> result */
175OP_DEF( NEW_APPLY, 3, 2, 1, u16) /* func new.target [args] -> obj */
176OP_DEF( EVAL, 5, 1, 1, npop) /* direct eval */
177OP_DEF( RETURN, 1, 1, 0, none)
178OP_DEF( RETURN_UNDEF, 1, 0, 0, none)
179OP_DEF( RETURN_ASYNC, 1, 1, 0, none) /* return from async func */
180OP_DEF( CHECK_CTOR, 1, 0, 0, none) /* verify called with new */
181OP_DEF( CHECK_CTOR_RET, 1, 1, 2, none) /* validate constructor return */
182OP_DEF( HALT, 1, 0, 0, none) /* stop execution */
183
184OP_DEF( THROW, 1, 1, 0, none)
185OP_DEF( THROW_ERROR, 6, 0, 0, atom_u8) /* throw built-in error */
186OP_DEF( TRY_PUSH, 5, 0, 0, label) /* push catch handler */
187OP_DEF( TRY_POP, 1, 0, 0, none) /* pop catch handler */
188OP_DEF( CATCH, 5, 0, 1, label) /* push caught value + finally addr */
189OP_DEF( FINALLY, 5, 0, 0, label) /* enter finally block */
190OP_DEF( FINALLY_RET, 1, 1, 0, none) /* return from finally */
191OP_DEF( NIP_CATCH, 1, 2, 1, none) /* catch ... a -> a */
192
193OP_DEF( USING_PUSH, 1, 2, 1, none) /* entries resource -> resource */
194OP_DEF( USING_PUSH_ASYNC, 1, 2, 1, none) /* entries resource -> resource */
195OP_DEF( DISPOSE_RESOURCE, 1, 1, 1, none) /* resource -> completion */
196OP_DEF( DISPOSE_RESOURCE_ASYNC, 1, 1, 1, none) /* resource -> promise/completion */
197
198OP_DEF( USING_DISPOSE, 1, 1, 1, none) /* entries -> completion */
199OP_DEF( USING_DISPOSE_ASYNC, 1, 1, 1, none) /* entries -> promise/completion */
200OP_DEF( USING_DISPOSE_SUPPRESSED, 1, 2, 1, none) /* entries completion -> completion */
201OP_DEF( USING_DISPOSE_ASYNC_SUPPRESSED, 1, 2, 1, none) /* entries completion -> promise/completion */
202
203OP_DEF( FOR_IN, 1, 1, 1, none) /* obj -> iterator */
204OP_DEF( FOR_OF, 1, 1, 3, none) /* iterable -> iter next catch_off */
205OP_DEF( FOR_AWAIT_OF, 1, 1, 3, none) /* async iterable -> iter next catch_off */
206OP_DEF( ITER_NEXT, 2, 3, 5, u8) /* advance iterator (u8 hint) */
207OP_DEF( ITER_GET_VALUE, 1, 2, 3, none) /* catch_off obj -> catch_off value done */
208OP_DEF( ITER_CLOSE, 1, 3, 0, none) /* close iterator */
209OP_DEF( ITER_CALL, 2, 4, 5, u8) /* call iterator method */
210OP_DEF( AWAIT_ITER_NEXT, 1, 3, 4, none) /* async iterator next */
211OP_DEF( DESTRUCTURE_INIT, 1, 1, 3, none) /* iterable -> iter next tag */
212OP_DEF( DESTRUCTURE_NEXT, 1, 3, 4, none) /* iter next tag -> iter next tag value|undef */
213OP_DEF( DESTRUCTURE_REST, 1, 3, 4, none) /* iter next tag -> iter next tag array */
214OP_DEF( DESTRUCTURE_CLOSE, 1, 3, 0, none) /* close destructuring iterator */
215
216OP_DEF( AWAIT, 1, 1, 1, none) /* promise -> resolved value */
217OP_DEF( YIELD, 1, 1, 2, none) /* val -> received */
218OP_DEF( YIELD_STAR_INIT, 3, 1, 0, loc) /* iterable -> delegate locals */
219OP_DEF( YIELD_STAR_NEXT, 3, 1, 2, loc) /* sent -> final value | suspend */
220OP_DEF( YIELD_STAR_THROW, 3, 1, 2, loc) /* thrown -> final value | suspend */
221OP_DEF( YIELD_STAR_RETURN, 3, 1, 2, loc) /* return value -> final value | suspend */
222OP_DEF( SPREAD, 1, 1, 0, none) /* arr iterable -> arr */
223
224OP_DEF( DEFINE_METHOD, 6, 2, 1, atom_u8) /* obj func -> obj (flags: get/set/static) */
225OP_DEF( DEFINE_METHOD_COMP,2, 3, 1, u8) /* obj key func -> obj (computed name) */
226OP_DEF( SET_NAME, 5, 1, 1, atom) /* set .name on function */
227OP_DEF( SET_NAME_COMP, 1, 2, 2, none) /* set .name from computed key */
228OP_DEF( SET_PROTO, 1, 2, 1, none) /* obj proto -> obj */
229OP_DEF( SET_HOME_OBJ, 1, 2, 2, none) /* func home -> func home */
230OP_DEF( APPEND, 1, 3, 2, none) /* append to array, update length */
231OP_DEF( COPY_DATA_PROPS, 2, 3, 3, u8) /* Object.assign-like */
232
233OP_DEF( DEFINE_CLASS, 14, 2, 2, atom_u8) /* parent ctor -> ctor proto */
234OP_DEF( DEFINE_CLASS_COMP, 14, 3, 3, atom_u8) /* computed name variant */
235
236OP_DEF( TO_OBJECT, 1, 1, 1, none) /* coerce to object wrapper */
237OP_DEF( TO_PROPKEY, 1, 1, 1, none) /* coerce to string/symbol */
238OP_DEF( IS_UNDEF, 1, 1, 1, none) /* TOS === undefined */
239OP_DEF( IS_NULL, 1, 1, 1, none) /* TOS === null */
240
241OP_DEF( IMPORT, 1, 2, 1, none) /* dynamic import(specifier) */
242OP_DEF( IMPORT_SYNC, 1, 1, 1, none) /* sync module load for static import */
243OP_DEF( IMPORT_DEFAULT, 1, 1, 1, none) /* ns -> default (SLOT_DEFAULT or ns) */
244OP_DEF( IMPORT_NAMED, 5, 1, 1, atom) /* ns -> named export (throw if missing) */
245OP_DEF( EXPORT, 5, 1, 0, atom) /* value -> (module namespace[name] = value) */
246OP_DEF( EXPORT_ALL, 1, 1, 0, none) /* ns -> (export all properties) */
247
248OP_DEF( ENTER_WITH, 1, 1, 0, none) /* enter with(obj) block */
249OP_DEF( EXIT_WITH, 1, 0, 0, none) /* exit with(obj) block */
250
251OP_DEF( WITH_GET_VAR, 8, 0, 1, atom) /* -> val (check with-obj then fallback) */
252OP_DEF( WITH_PUT_VAR, 8, 1, 0, atom) /* val -> (check with-obj then fallback) */
253OP_DEF( WITH_DEL_VAR, 5, 0, 1, atom) /* -> bool (delete from with-obj/global) */
254
255OP_DEF( SPECIAL_OBJ, 2, 0, 1, u8) /* arguments, new.target, super, module import */
256OP_DEF( EMPTY, 1, 0, 1, none) /* push T_EMPTY (array hole) */
257OP_DEF( DEBUGGER, 1, 0, 0, none)
258OP_DEF( NOP, 1, 0, 0, none)
259OP_DEF( PUT_CONST, 5, 1, 0, const) /* constant pool[idx] = TOS */
260
261op_def( LABEL, 5, 0, 0, label)
262op_def( LINE_NUM, 5, 0, 0, u32)
263op_def( COL_NUM, 5, 0, 0, u32)
264
265#undef OP_DEF
266#undef op_def
267#endif