1mod arithmetic;
22mod call;
23mod call_named;
24mod call_support;
25mod collections;
26mod comparison;
27mod control_flow;
28mod exception;
29mod imports;
30mod iter;
31mod logical;
32mod method_call;
33mod misc;
34mod parallel;
35mod stack;
36
37use std::future::Future;
38use std::pin::Pin;
39use std::task::{Context, Poll};
40
41use pin_project_lite::pin_project;
42
43use crate::value::{VmError, VmValue};
44
45pin_project! {
46 struct OpcodeDispatchFuture<F> {
49 #[pin]
50 inner: F,
51 }
52}
53
54impl<F> OpcodeDispatchFuture<F> {
55 fn new(inner: F) -> Self {
56 Self { inner }
57 }
58}
59
60impl<F: Future> Future for OpcodeDispatchFuture<F> {
61 type Output = F::Output;
62
63 #[inline(never)]
64 fn poll(self: Pin<&mut Self>, context: &mut Context<'_>) -> Poll<Self::Output> {
65 self.project().inner.poll(context)
66 }
67}
68
69harn_opcode_macros::define_opcodes! {
70 Constant { sync(self.execute_constant()), disasm: const_pool_u16("CONSTANT") };
72 Nil { sync_void(self.execute_nil()), disasm: bare("NIL") };
73 True { sync_void(self.execute_true()), disasm: bare("TRUE") };
74 False { sync_void(self.execute_false()), disasm: bare("FALSE") };
75
76 RootHarness { sync(self.execute_root_harness()), disasm: bare("ROOT_HARNESS") };
78 GetVar { sync(self.execute_get_var()), disasm: const_pool_u16("GET_VAR"), flags: [reads_outer_name] };
79 DefLet { sync(self.execute_def_let()), disasm: const_pool_u16("DEF_LET") };
80 DefVar { sync(self.execute_def_var()), disasm: const_pool_u16("DEF_VAR") };
81 DefCell { sync(self.execute_def_cell()), disasm: const_pool_u16("DEF_CELL") };
82 SetVar { sync(self.execute_set_var()), disasm: const_pool_u16("SET_VAR"), flags: [reads_outer_name] };
83 PushScope { sync_void(self.execute_push_scope()), disasm: bare("PUSH_SCOPE") };
84 PopScope { sync_void(self.execute_pop_scope()), disasm: bare("POP_SCOPE") };
85
86 Add { sync(self.execute_add()), disasm: bare("ADD"), flags: [adaptive_binary] };
88 Sub { sync(self.execute_sub()), disasm: bare("SUB"), flags: [adaptive_binary] };
89 Mul { sync(self.execute_mul()), disasm: bare("MUL"), flags: [adaptive_binary] };
90 Div { sync(self.execute_div()), disasm: bare("DIV"), flags: [adaptive_binary] };
91 Mod { sync(self.execute_mod()), disasm: bare("MOD"), flags: [adaptive_binary] };
92 Pow { sync(self.execute_pow()), disasm: bare("POW") };
93 Negate { sync(self.execute_negate()), disasm: bare("NEGATE") };
94
95 Equal { sync(self.execute_equal()), disasm: bare("EQUAL"), flags: [adaptive_binary] };
97 NotEqual { sync(self.execute_not_equal()), disasm: bare("NOT_EQUAL"), flags: [adaptive_binary] };
98 Less { sync(self.execute_less()), disasm: bare("LESS"), flags: [adaptive_binary] };
99 Greater { sync(self.execute_greater()), disasm: bare("GREATER"), flags: [adaptive_binary] };
100 LessEqual { sync(self.execute_less_equal()), disasm: bare("LESS_EQUAL"), flags: [adaptive_binary] };
101 GreaterEqual { sync(self.execute_greater_equal()), disasm: bare("GREATER_EQUAL"), flags: [adaptive_binary] };
102
103 Not { sync(self.execute_not()), disasm: bare("NOT") };
105
106 Jump { sync_void(self.execute_jump()), disasm: u16("JUMP") };
108 JumpIfFalse { sync(self.execute_jump_if_false()), disasm: u16("JUMP_IF_FALSE") };
109 JumpIfTrue { sync(self.execute_jump_if_true()), disasm: u16("JUMP_IF_TRUE") };
110 Pop { sync(self.execute_pop()), disasm: bare("POP") };
111
112 Call { split(self.execute_call_sync(), self.execute_call_async().await), disasm: u8("CALL"), flags: [reads_outer_name] };
114 TailCall { split(self.execute_tail_call_sync(), self.execute_tail_call_async().await), disasm: u8("TAIL_CALL"), flags: [reads_outer_name] };
115 Return { sync_return(self.execute_return()), disasm: bare("RETURN") };
116 Closure { sync_void(self.execute_closure()), disasm: u16("CLOSURE") };
117
118 BuildList { sync_void(self.execute_build_list()), disasm: u16("BUILD_LIST") };
120 BuildDict { sync_void(self.execute_build_dict()), disasm: u16("BUILD_DICT") };
121 Subscript { sync(self.execute_subscript(false)), disasm: bare("SUBSCRIPT") };
122 SubscriptOpt { sync(self.execute_subscript(true)), disasm: bare("SUBSCRIPT_OPT") };
123 Slice { sync(self.execute_slice()), disasm: bare("SLICE") };
124
125 GetProperty { sync(self.execute_get_property(false)), disasm: const_pool_u16("GET_PROPERTY") };
127 GetPropertyOpt { sync(self.execute_get_property(true)), disasm: const_pool_u16("GET_PROPERTY_OPT") };
128 SetProperty { sync(self.execute_set_property()), disasm: const_pool_u16("SET_PROPERTY") };
129 SetSubscript { sync(self.execute_set_subscript()), disasm: const_pool_u16("SET_SUBSCRIPT") };
130 SetLocalSlotProperty { sync(self.execute_set_local_slot_property()), disasm: const_pool_local_slot("SET_LOCAL_SLOT_PROPERTY") };
131 SetLocalSlotSubscript { sync(self.execute_set_local_slot_subscript()), disasm: local_slot_u16("SET_LOCAL_SLOT_SUBSCRIPT") };
132 MethodCall { split(self.execute_method_call_sync(false), self.execute_method_call(false).await), disasm: method_call("METHOD_CALL") };
133 MethodCallOpt { split(self.execute_method_call_sync(true), self.execute_method_call(true).await), disasm: method_call("METHOD_CALL_OPT") };
134
135 Concat { sync_void(self.execute_concat()), disasm: u16("CONCAT") };
137
138 IterInit { sync(self.execute_iter_init()), disasm: bare("ITER_INIT") };
140 IterNext { split(self.execute_iter_next_sync(), self.execute_iter_next_async().await), disasm: u16("ITER_NEXT") };
141
142 Pipe { async_op(self.execute_pipe().await), disasm: bare("PIPE"), flags: [reads_outer_name] };
144
145 Throw { sync(self.execute_throw()), disasm: bare("THROW") };
147 TryCatchSetup { sync_void(self.execute_try_catch_setup()), disasm: try_catch_setup("TRY_CATCH_SETUP") };
148 PopHandler { sync_void(self.execute_pop_handler()), disasm: bare("POP_HANDLER") };
149
150 Parallel { async_op(self.execute_parallel().await), disasm: bare("PARALLEL") };
152 ParallelMap { async_op(self.execute_parallel_map().await), disasm: bare("PARALLEL_MAP") };
153 ParallelMapStream { async_op(self.execute_parallel_map_stream().await), disasm: bare("PARALLEL_MAP_STREAM") };
154 ParallelSettle { async_op(self.execute_parallel_settle().await), disasm: bare("PARALLEL_SETTLE") };
155 Spawn { sync(self.execute_spawn()), disasm: bare("SPAWN") };
156 SyncMutexEnter { async_op(self.execute_sync_mutex_enter().await), disasm: bare("SYNC_MUTEX_ENTER") };
157 SyncMutexEnterKeyed { async_op(self.execute_sync_mutex_enter_keyed().await), disasm: bare("SYNC_MUTEX_ENTER_KEYED") };
158 TaskScopeEnter { sync_void(self.execute_task_scope_enter()), disasm: bare("TASK_SCOPE_ENTER") };
159 TaskScopeExit { async_op(self.execute_task_scope_exit().await), disasm: bare("TASK_SCOPE_EXIT") };
160
161 Import { async_op(self.execute_import_op().await), disasm: const_pool_u16("IMPORT") };
163 SelectiveImport { async_op(self.execute_selective_import().await), disasm: selective_import("SELECTIVE_IMPORT") };
164 NamespaceImport { async_op(self.execute_namespace_import().await), disasm: selective_import("NAMESPACE_IMPORT") };
165
166 DeadlineSetup { sync(self.execute_deadline_setup()), disasm: bare("DEADLINE_SETUP") };
168 DeadlineEnd { sync_void(self.execute_deadline_end()), disasm: bare("DEADLINE_END") };
169
170 BuildEnum { sync(self.execute_build_enum()), disasm: build_enum("BUILD_ENUM") };
172 MatchEnum { sync(self.execute_match_enum()), disasm: match_enum("MATCH_ENUM") };
173
174 PopIterator { sync_void(self.execute_pop_iterator()), disasm: bare("POP_ITERATOR") };
176
177 GetArgc { sync_void(self.execute_get_argc()), disasm: bare("GET_ARGC") };
179
180 CheckType { sync(self.execute_check_type()), disasm: check_type("CHECK_TYPE"), flags: [reads_outer_name] };
182
183 TryUnwrap { sync(self.execute_try_unwrap()), disasm: bare("TRY_UNWRAP") };
185 TryWrapOk { sync(self.execute_try_wrap_ok()), disasm: bare("TRY_WRAP_OK") };
186
187 CallSpread { async_op(self.execute_call_spread().await), disasm: bare("CALL_SPREAD"), flags: [reads_outer_name] };
189 CallBuiltin { split(self.execute_call_builtin_sync(), self.execute_call_builtin_async().await), disasm: call_builtin("CALL_BUILTIN"), flags: [reads_outer_name] };
190 CallBuiltinSpread { async_op(self.execute_call_builtin_spread().await), disasm: call_builtin_spread("CALL_BUILTIN_SPREAD"), flags: [reads_outer_name] };
191 MethodCallSpread { async_op(self.execute_method_call_spread().await), disasm: method_call_spread("METHOD_CALL_SPREAD") };
192
193 Dup { sync(self.execute_dup()), disasm: bare("DUP") };
195 Swap { sync_void(self.execute_swap()), disasm: bare("SWAP") };
196 Contains { sync(self.execute_contains()), disasm: bare("CONTAINS") };
197
198 AddInt { sync(self.execute_add_int()), disasm: bare("ADD_INT") };
200 SubInt { sync(self.execute_sub_int()), disasm: bare("SUB_INT") };
201 MulInt { sync(self.execute_mul_int()), disasm: bare("MUL_INT") };
202 DivInt { sync(self.execute_div_int()), disasm: bare("DIV_INT") };
203 ModInt { sync(self.execute_mod_int()), disasm: bare("MOD_INT") };
204 AddFloat { sync(self.execute_add_float()), disasm: bare("ADD_FLOAT") };
205 SubFloat { sync(self.execute_sub_float()), disasm: bare("SUB_FLOAT") };
206 MulFloat { sync(self.execute_mul_float()), disasm: bare("MUL_FLOAT") };
207 DivFloat { sync(self.execute_div_float()), disasm: bare("DIV_FLOAT") };
208 ModFloat { sync(self.execute_mod_float()), disasm: bare("MOD_FLOAT") };
209
210 EqualInt { sync(self.execute_equal_int()), disasm: bare("EQUAL_INT") };
212 NotEqualInt { sync(self.execute_not_equal_int()), disasm: bare("NOT_EQUAL_INT") };
213 LessInt { sync(self.execute_less_int()), disasm: bare("LESS_INT") };
214 GreaterInt { sync(self.execute_greater_int()), disasm: bare("GREATER_INT") };
215 LessEqualInt { sync(self.execute_less_equal_int()), disasm: bare("LESS_EQUAL_INT") };
216 GreaterEqualInt { sync(self.execute_greater_equal_int()), disasm: bare("GREATER_EQUAL_INT") };
217 EqualFloat { sync(self.execute_equal_float()), disasm: bare("EQUAL_FLOAT") };
218 NotEqualFloat { sync(self.execute_not_equal_float()), disasm: bare("NOT_EQUAL_FLOAT") };
219 LessFloat { sync(self.execute_less_float()), disasm: bare("LESS_FLOAT") };
220 GreaterFloat { sync(self.execute_greater_float()), disasm: bare("GREATER_FLOAT") };
221 LessEqualFloat { sync(self.execute_less_equal_float()), disasm: bare("LESS_EQUAL_FLOAT") };
222 GreaterEqualFloat { sync(self.execute_greater_equal_float()), disasm: bare("GREATER_EQUAL_FLOAT") };
223 EqualBool { sync(self.execute_equal_bool()), disasm: bare("EQUAL_BOOL") };
224 NotEqualBool { sync(self.execute_not_equal_bool()), disasm: bare("NOT_EQUAL_BOOL") };
225 EqualString { sync(self.execute_equal_string()), disasm: bare("EQUAL_STRING") };
226 NotEqualString { sync(self.execute_not_equal_string()), disasm: bare("NOT_EQUAL_STRING") };
227
228 Yield { async_op(self.execute_yield().await), disasm: bare("YIELD") };
230
231 GetLocalSlot { sync(self.execute_get_local_slot()), disasm: local_slot_u16("GET_LOCAL_SLOT") };
233 DefLocalSlot { sync(self.execute_def_local_slot()), disasm: local_slot_u16("DEF_LOCAL_SLOT") };
234 SetLocalSlot { sync(self.execute_set_local_slot()), disasm: local_slot_u16("SET_LOCAL_SLOT") };
235 ConcatAssignLocal { sync(self.execute_concat_assign_local()), disasm: local_slot_u16("CONCAT_ASSIGN_LOCAL") };
236}
237
238impl super::Vm {
239 pub(super) async fn execute_op(&mut self, op_byte: u8) -> Result<Option<VmValue>, VmError> {
244 let op = Op::from_byte(op_byte).ok_or(VmError::InvalidInstruction(op_byte))?;
245 if let Some(result) = self.execute_op_sync(op) {
246 result?;
247 return Ok(None);
248 }
249 self.execute_op_async(op).await?;
250 Ok(None)
251 }
252}