tci/runtime/
interpreter.rs1use super::error::*;
2use super::memory::*;
3use super::types::*;
4use crate::util::*;
5
6pub fn run_op_count(memory: &mut Memory, count: u32) -> (u32, Result<Option<EcallExt>, IError>) {
7 for idx in 0..count {
8 match run_op(memory) {
9 Ok(None) => {}
10 Ok(Some(ecall)) => return (idx + 1, Ok(Some(ecall))),
11 Err(ierr) => return (idx, Err(ierr)),
12 }
13 }
14
15 return (count, Ok(None));
16}
17
18pub fn run_op(memory: &mut Memory) -> Result<Option<EcallExt>, IError> {
19 let op: Opcode = memory.read_pc()?;
20
21 match op {
22 Opcode::Func => {
23 return Err(ierror!(
25 "InvalidOpcode",
26 "Found Func opcode (this is an error in TCI)"
27 ));
28 }
29 Opcode::Loc => {
30 let loc = memory.read_pc()?;
31 memory.set_loc(loc);
32 }
33 Opcode::StackAlloc => {
34 let bytes: u32 = memory.read_pc()?;
35 memory.add_stack_var(bytes)?;
36 }
37 Opcode::StackDealloc => {
38 memory.pop_stack_var()?;
39 }
40
41 Opcode::Make8 => {
42 let val: u8 = memory.read_pc()?;
43 memory.push(val);
44 }
45 Opcode::Make16 => {
46 let val: u16 = memory.read_pc()?;
47 memory.push(val);
48 }
49 Opcode::Make32 => {
50 let val: u32 = memory.read_pc()?;
51 memory.push(val);
52 }
53 Opcode::Make64 => {
54 let val: u64 = memory.read_pc()?;
55 memory.push(val);
56 }
57 Opcode::MakeSp => {
58 let var_offset: i16 = memory.read_pc()?;
59 let stack_len = memory.stack.len() as u16;
60 let var = (stack_len as i16 + var_offset) as u16;
61
62 memory.push(VarPointer::new_stack(var, 0));
63 }
64 Opcode::MakeFp => {
65 let var_offset: i16 = memory.read_pc()?;
66 let var = (memory.fp as i16 + var_offset) as u16;
67
68 memory.push(VarPointer::new_stack(var, 0));
69 }
70
71 Opcode::PushUndef => {
72 let bytes: u32 = memory.read_pc()?;
73 let stack_len = memory.expr_stack.len();
74 memory.expr_stack.resize(stack_len + bytes as usize, 0);
75 }
76 Opcode::Pop => {
77 let bytes = memory.read_pc()?;
78 memory.pop_bytes(bytes)?;
79 }
80 Opcode::Swap => {
81 let top_bytes = memory.read_pc()?;
82 let bottom_bytes = memory.read_pc()?;
83 memory.swap_bytes(top_bytes, bottom_bytes)?;
84 }
85 Opcode::Dup => {
86 let bytes = memory.read_pc()?;
87 memory.dup_bytes(bytes)?;
88 }
89 Opcode::PushDyn => {
90 let ptr: VarPointer = memory.pop()?;
91 let size: u32 = memory.pop()?;
92 memory.read_bytes_to_stack(ptr, size)?;
93 }
94
95 Opcode::I8ToF32 => {
96 let n: i8 = memory.pop()?;
97 memory.push(n as f32);
98 }
99 Opcode::U8ToF32 => {
100 let n: u8 = memory.pop()?;
101 memory.push(n as f32);
102 }
103 Opcode::I8ToF64 => {
104 let n: i8 = memory.pop()?;
105 memory.push(n as f64);
106 }
107 Opcode::U8ToF64 => {
108 let n: i8 = memory.pop()?;
109 memory.push(n as f64);
110 }
111 Opcode::I16ToF32 => {
112 let n: i16 = memory.pop()?;
113 memory.push(n as f32);
114 }
115 Opcode::U16ToF32 => {
116 let n: u16 = memory.pop()?;
117 memory.push(n as f32);
118 }
119 Opcode::I16ToF64 => {
120 let n: i16 = memory.pop()?;
121 memory.push(n as f64);
122 }
123 Opcode::U16ToF64 => {
124 let n: i16 = memory.pop()?;
125 memory.push(n as f64);
126 }
127 Opcode::I32ToF32 => {
128 let n: i32 = memory.pop()?;
129 memory.push(n as f32);
130 }
131 Opcode::U32ToF32 => {
132 let n: u32 = memory.pop()?;
133 memory.push(n as f32);
134 }
135 Opcode::I32ToF64 => {
136 let n: i32 = memory.pop()?;
137 memory.push(n as f64);
138 }
139 Opcode::U32ToF64 => {
140 let n: i32 = memory.pop()?;
141 memory.push(n as f64);
142 }
143 Opcode::I64ToF32 => {
144 let n: i64 = memory.pop()?;
145 memory.push(n as f32);
146 }
147 Opcode::U64ToF32 => {
148 let n: u64 = memory.pop()?;
149 memory.push(n as f32);
150 }
151 Opcode::I64ToF64 => {
152 let n: i64 = memory.pop()?;
153 memory.push(n as f64);
154 }
155 Opcode::U64ToF64 => {
156 let n: i64 = memory.pop()?;
157 memory.push(n as f64);
158 }
159
160 Opcode::F32ToI8 => {
161 let f: f32 = memory.pop()?;
162 memory.push(f as i8);
163 }
164 Opcode::F32ToU8 => {
165 let f: f32 = memory.pop()?;
166 memory.push(f as u8);
167 }
168 Opcode::F64ToI8 => {
169 let f: f64 = memory.pop()?;
170 memory.push(f as i8);
171 }
172 Opcode::F64ToU8 => {
173 let f: f64 = memory.pop()?;
174 memory.push(f as u8);
175 }
176 Opcode::F32ToI16 => {
177 let f: f32 = memory.pop()?;
178 memory.push(f as i16);
179 }
180 Opcode::F32ToU16 => {
181 let f: f32 = memory.pop()?;
182 memory.push(f as u16);
183 }
184 Opcode::F64ToI16 => {
185 let f: f64 = memory.pop()?;
186 memory.push(f as i16);
187 }
188 Opcode::F64ToU16 => {
189 let f: f64 = memory.pop()?;
190 memory.push(f as u16);
191 }
192 Opcode::F32ToI32 => {
193 let f: f32 = memory.pop()?;
194 memory.push(f as i32);
195 }
196 Opcode::F32ToU32 => {
197 let f: f32 = memory.pop()?;
198 memory.push(f as u32);
199 }
200 Opcode::F64ToI32 => {
201 let f: f64 = memory.pop()?;
202 memory.push(f as i32);
203 }
204 Opcode::F64ToU32 => {
205 let f: f64 = memory.pop()?;
206 memory.push(f as u32);
207 }
208 Opcode::F32ToI64 => {
209 let f: f32 = memory.pop()?;
210 memory.push(f as i64);
211 }
212 Opcode::F32ToU64 => {
213 let f: f32 = memory.pop()?;
214 memory.push(f as u64);
215 }
216 Opcode::F64ToI64 => {
217 let f: f64 = memory.pop()?;
218 memory.push(f as i64);
219 }
220 Opcode::F64ToU64 => {
221 let f: f64 = memory.pop()?;
222 memory.push(f as u64);
223 }
224
225 Opcode::F32ToF64 => {
226 let f: f32 = memory.pop()?;
227 memory.push(f as f64);
228 }
229 Opcode::F64ToF32 => {
230 let f: f64 = memory.pop()?;
231 memory.push(f as f32);
232 }
233
234 Opcode::SExtend8To16 => {
235 let val = memory.pop::<i8>()?;
236 memory.push(val as i16);
237 }
238 Opcode::SExtend8To32 => {
239 let val = memory.pop::<i8>()?;
240 memory.push(val as i32);
241 }
242 Opcode::SExtend8To64 => {
243 let val = memory.pop::<i8>()?;
244 memory.push(val as i64);
245 }
246 Opcode::SExtend16To32 => {
247 let val: i16 = memory.pop()?;
248 memory.push(val as i32);
249 }
250 Opcode::SExtend16To64 => {
251 let val: i16 = memory.pop()?;
252 memory.push(val as i64);
253 }
254 Opcode::SExtend32To64 => {
255 let val: i32 = memory.pop()?;
256 memory.push(val as i64);
257 }
258
259 Opcode::ZExtend8To16 => {
260 let val = memory.pop::<u8>()?;
261 memory.push(val as u16);
262 }
263 Opcode::ZExtend8To32 => {
264 let val = memory.pop::<u8>()?;
265 memory.push(val as u32);
266 }
267 Opcode::ZExtend8To64 => {
268 let val = memory.pop::<u8>()?;
269 memory.push(val as u64);
270 }
271 Opcode::ZExtend16To32 => {
272 let val: u16 = memory.pop()?;
273 memory.push(val as u32);
274 }
275 Opcode::ZExtend16To64 => {
276 let val: u16 = memory.pop()?;
277 memory.push(val as u64);
278 }
279 Opcode::ZExtend32To64 => {
280 let val: u32 = memory.pop()?;
281 memory.push(val as u64);
282 }
283
284 Opcode::Get => {
285 let bytes = memory.read_pc()?;
286 let ptr: VarPointer = memory.pop()?;
287
288 memory.read_bytes_to_stack(ptr, bytes)?;
289 }
290 Opcode::Set => {
291 let bytes = memory.read_pc()?;
292 let ptr: VarPointer = memory.pop()?;
293 memory.write_bytes_from_stack(ptr, bytes)?;
294 }
295
296 Opcode::BoolNorm8 => {
297 let bytes: u8 = memory.pop()?;
298 memory.push(if bytes != 0 { 1u8 } else { 0u8 });
299 }
300 Opcode::BoolNorm16 => {
301 let bytes: u16 = memory.pop()?;
302 memory.push(if bytes != 0 { 1u8 } else { 0u8 });
303 }
304 Opcode::BoolNorm32 => {
305 let bytes: u32 = memory.pop()?;
306 memory.push(if bytes != 0 { 1u8 } else { 0u8 });
307 }
308 Opcode::BoolNorm64 => {
309 let bytes: u64 = memory.pop()?;
310 memory.push(if bytes != 0 { 1u8 } else { 0u8 });
311 }
312
313 Opcode::BoolNot8 => {
314 let bytes: u8 = memory.pop()?;
315 memory.push(if bytes == 0 { 1u8 } else { 0u8 });
316 }
317 Opcode::BoolNot16 => {
318 let bytes: u16 = memory.pop()?;
319 memory.push(if bytes == 0 { 1u8 } else { 0u8 });
320 }
321 Opcode::BoolNot32 => {
322 let bytes: u32 = memory.pop()?;
323 memory.push(if bytes == 0 { 1u8 } else { 0u8 });
324 }
325 Opcode::BoolNot64 => {
326 let bytes: u64 = memory.pop()?;
327 memory.push(if bytes == 0 { 1u8 } else { 0u8 });
328 }
329
330 Opcode::CompLeqI8 => {
331 let word2: i8 = memory.pop()?;
332 let word1: i8 = memory.pop()?;
333 memory.push(if word1 <= word2 { 1u8 } else { 0u8 });
334 }
335 Opcode::CompLeqU8 => {
336 let word2: u8 = memory.pop()?;
337 let word1: u8 = memory.pop()?;
338 memory.push(if word1 <= word2 { 1u8 } else { 0u8 });
339 }
340 Opcode::CompLeqI16 => {
341 let word2: i16 = memory.pop()?;
342 let word1: i16 = memory.pop()?;
343 memory.push(if word1 <= word2 { 1u8 } else { 0u8 });
344 }
345 Opcode::CompLeqU16 => {
346 let word2: u16 = memory.pop()?;
347 let word1: u16 = memory.pop()?;
348 memory.push(if word1 <= word2 { 1u8 } else { 0u8 });
349 }
350 Opcode::CompLeqI32 => {
351 let word2: i32 = memory.pop()?;
352 let word1: i32 = memory.pop()?;
353 memory.push(if word1 <= word2 { 1u8 } else { 0u8 });
354 }
355 Opcode::CompLeqU32 => {
356 let word2: u32 = memory.pop()?;
357 let word1: u32 = memory.pop()?;
358 memory.push(if word1 <= word2 { 1u8 } else { 0u8 });
359 }
360 Opcode::CompLeqI64 => {
361 let word2: i64 = memory.pop()?;
362 let word1: i64 = memory.pop()?;
363 memory.push(if word1 <= word2 { 1u8 } else { 0u8 });
364 }
365 Opcode::CompLeqU64 => {
366 let word2: u64 = memory.pop()?;
367 let word1: u64 = memory.pop()?;
368 memory.push(if word1 <= word2 { 1u8 } else { 0u8 });
369 }
370 Opcode::CompLeqF32 => {
371 let word2: f32 = memory.pop()?;
372 let word1: f32 = memory.pop()?;
373 memory.push(if word1 < word2 { 1u8 } else { 0u8 });
374 }
375 Opcode::CompLeqF64 => {
376 let word2: f64 = memory.pop()?;
377 let word1: f64 = memory.pop()?;
378 memory.push(if word1 <= word2 { 1u8 } else { 0u8 });
379 }
380
381 Opcode::CompLtI8 => {
382 let word2: i8 = memory.pop()?;
383 let word1: i8 = memory.pop()?;
384 memory.push(if word1 <= word2 { 1u8 } else { 0u8 });
385 }
386 Opcode::CompLtU8 => {
387 let word2: u8 = memory.pop()?;
388 let word1: u8 = memory.pop()?;
389 memory.push(if word1 < word2 { 1u8 } else { 0u8 });
390 }
391 Opcode::CompLtI16 => {
392 let word2: i16 = memory.pop()?;
393 let word1: i16 = memory.pop()?;
394 memory.push(if word1 < word2 { 1u8 } else { 0u8 });
395 }
396 Opcode::CompLtU16 => {
397 let word2: u16 = memory.pop()?;
398 let word1: u16 = memory.pop()?;
399 memory.push(if word1 < word2 { 1u8 } else { 0u8 });
400 }
401 Opcode::CompLtI32 => {
402 let word2: i32 = memory.pop()?;
403 let word1: i32 = memory.pop()?;
404 memory.push(if word1 < word2 { 1u8 } else { 0u8 });
405 }
406 Opcode::CompLtU32 => {
407 let word2: u32 = memory.pop()?;
408 let word1: u32 = memory.pop()?;
409 memory.push(if word1 < word2 { 1u8 } else { 0u8 });
410 }
411 Opcode::CompLtI64 => {
412 let word2: i64 = memory.pop()?;
413 let word1: i64 = memory.pop()?;
414 memory.push(if word1 < word2 { 1u8 } else { 0u8 });
415 }
416 Opcode::CompLtU64 => {
417 let word2: u64 = memory.pop()?;
418 let word1: u64 = memory.pop()?;
419 memory.push(if word1 < word2 { 1u8 } else { 0u8 });
420 }
421 Opcode::CompLtF32 => {
422 let word2: f32 = memory.pop()?;
423 let word1: f32 = memory.pop()?;
424 memory.push(if word1 < word2 { 1u8 } else { 0u8 });
425 }
426 Opcode::CompLtF64 => {
427 let word2: f64 = memory.pop()?;
428 let word1: f64 = memory.pop()?;
429 memory.push(if word1 < word2 { 1u8 } else { 0u8 });
430 }
431
432 Opcode::CompEq8 => {
433 let word2: u8 = memory.pop()?;
434 let word1: u8 = memory.pop()?;
435 memory.push(if word1 == word2 { 1u8 } else { 0u8 });
436 }
437 Opcode::CompEq16 => {
438 let word2: u16 = memory.pop()?;
439 let word1: u16 = memory.pop()?;
440 memory.push(if word1 == word2 { 1u8 } else { 0u8 });
441 }
442 Opcode::CompEq32 => {
443 let word2: u32 = memory.pop()?;
444 let word1: u32 = memory.pop()?;
445 memory.push(if word1 == word2 { 1u8 } else { 0u8 });
446 }
447 Opcode::CompEq64 => {
448 let word2: u64 = memory.pop()?;
449 let word1: u64 = memory.pop()?;
450 memory.push(if word1 == word2 { 1u8 } else { 0u8 });
451 }
452 Opcode::CompEqF32 => {
453 let word2: f32 = memory.pop()?;
454 let word1: f32 = memory.pop()?;
455 memory.push(if word1 == word2 { 1u8 } else { 0u8 });
456 }
457 Opcode::CompEqF64 => {
458 let word2: f64 = memory.pop()?;
459 let word1: f64 = memory.pop()?;
460 memory.push(if word1 == word2 { 1u8 } else { 0u8 });
461 }
462
463 Opcode::CompNeq8 => {
464 let word2: i8 = memory.pop()?;
465 let word1: i8 = memory.pop()?;
466 memory.push(if word1 != word2 { 1u8 } else { 0u8 });
467 }
468 Opcode::CompNeq16 => {
469 let word2: i16 = memory.pop()?;
470 let word1: i16 = memory.pop()?;
471 memory.push(if word1 != word2 { 1u8 } else { 0u8 });
472 }
473 Opcode::CompNeq32 => {
474 let word2: i32 = memory.pop()?;
475 let word1: i32 = memory.pop()?;
476 memory.push(if word1 != word2 { 1u8 } else { 0u8 });
477 }
478 Opcode::CompNeq64 => {
479 let word2: i64 = memory.pop()?;
480 let word1: i64 = memory.pop()?;
481 memory.push(if word1 != word2 { 1u8 } else { 0u8 });
482 }
483 Opcode::CompNeqF32 => {
484 let word2: f32 = memory.pop()?;
485 let word1: f32 = memory.pop()?;
486 memory.push(if word1 != word2 { 1u8 } else { 0u8 });
487 }
488 Opcode::CompNeqF64 => {
489 let word2: f64 = memory.pop()?;
490 let word1: f64 = memory.pop()?;
491 memory.push(if word1 != word2 { 1u8 } else { 0u8 });
492 }
493
494 Opcode::Add8 => {
495 let word2: u8 = memory.pop()?;
496 let word1: u8 = memory.pop()?;
497 memory.push(word1.wrapping_add(word2));
498 }
499 Opcode::Add16 => {
500 let word2: u16 = memory.pop()?;
501 let word1: u16 = memory.pop()?;
502
503 memory.push(word1.wrapping_add(word2));
504 }
505 Opcode::Add32 => {
506 let word2: u32 = memory.pop()?;
507 let word1: u32 = memory.pop()?;
508 memory.push(word1.wrapping_add(word2));
509 }
510 Opcode::Add64 => {
511 let word2: u64 = memory.pop()?;
512 let word1: u64 = memory.pop()?;
513 memory.push(word1.wrapping_add(word2));
514 }
515 Opcode::AddF32 => {
516 let word2: f32 = memory.pop()?;
517 let word1: f32 = memory.pop()?;
518 memory.push(word1 + word2);
519 }
520 Opcode::AddF64 => {
521 let word2: f64 = memory.pop()?;
522 let word1: f64 = memory.pop()?;
523 memory.push(word1 + word2);
524 }
525
526 Opcode::SubI8 => {
527 let word2: i8 = memory.pop()?;
528 let word1: i8 = memory.pop()?;
529 memory.push(word1.wrapping_sub(word2));
530 }
531 Opcode::SubU8 => {
532 let word2: u8 = memory.pop()?;
533 let word1: u8 = memory.pop()?;
534 memory.push(word1.wrapping_sub(word2));
535 }
536 Opcode::SubI16 => {
537 let word2: i16 = memory.pop()?;
538 let word1: i16 = memory.pop()?;
539 memory.push(word1.wrapping_sub(word2));
540 }
541 Opcode::SubU16 => {
542 let word2: u16 = memory.pop()?;
543 let word1: u16 = memory.pop()?;
544 memory.push(word1.wrapping_sub(word2));
545 }
546 Opcode::SubI32 => {
547 let word2: i32 = memory.pop()?;
548 let word1: i32 = memory.pop()?;
549 memory.push(word1.wrapping_sub(word2));
550 }
551 Opcode::SubU32 => {
552 let word2: u32 = memory.pop()?;
553 let word1: u32 = memory.pop()?;
554 memory.push(word1.wrapping_sub(word2));
555 }
556 Opcode::SubI64 => {
557 let word2: i64 = memory.pop()?;
558 let word1: i64 = memory.pop()?;
559 memory.push(word1.wrapping_sub(word2));
560 }
561 Opcode::SubU64 => {
562 let word2: u64 = memory.pop()?;
563 let word1: u64 = memory.pop()?;
564 memory.push(word1.wrapping_sub(word2));
565 }
566 Opcode::SubF32 => {
567 let word2: f32 = memory.pop()?;
568 let word1: f32 = memory.pop()?;
569 memory.push(word1 - word2);
570 }
571 Opcode::SubF64 => {
572 let word2: f64 = memory.pop()?;
573 let word1: f64 = memory.pop()?;
574 memory.push(word1 - word2);
575 }
576
577 Opcode::MulU8 => {
578 let word2: u8 = memory.pop()?;
579 let word1: u8 = memory.pop()?;
580 memory.push(word1.wrapping_mul(word2));
581 }
582 Opcode::MulI8 => {
583 let word2: i8 = memory.pop()?;
584 let word1: i8 = memory.pop()?;
585 memory.push(word1.wrapping_mul(word2));
586 }
587 Opcode::MulI16 => {
588 let word2: i16 = memory.pop()?;
589 let word1: i16 = memory.pop()?;
590 memory.push(word1.wrapping_mul(word2));
591 }
592 Opcode::MulU16 => {
593 let word2: u16 = memory.pop()?;
594 let word1: u16 = memory.pop()?;
595 memory.push(word1.wrapping_mul(word2));
596 }
597 Opcode::MulU32 => {
598 let word2: u32 = memory.pop()?;
599 let word1: u32 = memory.pop()?;
600 memory.push(word1.wrapping_mul(word2));
601 }
602 Opcode::MulI32 => {
603 let word2: i32 = memory.pop()?;
604 let word1: i32 = memory.pop()?;
605 memory.push(word1.wrapping_mul(word2));
606 }
607 Opcode::MulI64 => {
608 let word2: i64 = memory.pop()?;
609 let word1: i64 = memory.pop()?;
610 memory.push(word1.wrapping_mul(word2));
611 }
612 Opcode::MulU64 => {
613 let word2: u64 = memory.pop()?;
614 let word1: u64 = memory.pop()?;
615 memory.push(word1.wrapping_mul(word2));
616 }
617 Opcode::MulF32 => {
618 let word2: f32 = memory.pop()?;
619 let word1: f32 = memory.pop()?;
620 memory.push(word1 * word2);
621 }
622 Opcode::MulF64 => {
623 let word2: f64 = memory.pop()?;
624 let word1: f64 = memory.pop()?;
625 memory.push(word1 * word2);
626 }
627
628 Opcode::DivU8 => {
629 let word2: u8 = memory.pop()?;
630 let word1: u8 = memory.pop()?;
631 memory.push(word1.wrapping_div(word2));
632 }
633 Opcode::DivI8 => {
634 let word2: i8 = memory.pop()?;
635 let word1: i8 = memory.pop()?;
636 memory.push(word1.wrapping_div(word2));
637 }
638 Opcode::DivI16 => {
639 let word2: i16 = memory.pop()?;
640 let word1: i16 = memory.pop()?;
641 memory.push(word1.wrapping_div(word2));
642 }
643 Opcode::DivU16 => {
644 let word2: u16 = memory.pop()?;
645 let word1: u16 = memory.pop()?;
646 memory.push(word1.wrapping_div(word2));
647 }
648 Opcode::DivU32 => {
649 let word2: u32 = memory.pop()?;
650 let word1: u32 = memory.pop()?;
651 memory.push(word1.wrapping_div(word2));
652 }
653 Opcode::DivI32 => {
654 let word2: i32 = memory.pop()?;
655 let word1: i32 = memory.pop()?;
656 memory.push(word1.wrapping_div(word2));
657 }
658 Opcode::DivI64 => {
659 let word2: i64 = memory.pop()?;
660 let word1: i64 = memory.pop()?;
661 memory.push(word1.wrapping_div(word2));
662 }
663 Opcode::DivU64 => {
664 let word2: u64 = memory.pop()?;
665 let word1: u64 = memory.pop()?;
666 memory.push(word1.wrapping_div(word2));
667 }
668 Opcode::DivF32 => {
669 let word2: f32 = memory.pop()?;
670 let word1: f32 = memory.pop()?;
671 memory.push(word1 / word2);
672 }
673 Opcode::DivF64 => {
674 let word2: f64 = memory.pop()?;
675 let word1: f64 = memory.pop()?;
676 memory.push(word1 / word2);
677 }
678
679 Opcode::ModU8 => {
680 let word2: u8 = memory.pop()?;
681 let word1: u8 = memory.pop()?;
682 memory.push(word1 % word2);
683 }
684 Opcode::ModI8 => {
685 let word2: i8 = memory.pop()?;
686 let word1: i8 = memory.pop()?;
687 memory.push(word1 % word2);
688 }
689 Opcode::ModI16 => {
690 let word2: i16 = memory.pop()?;
691 let word1: i16 = memory.pop()?;
692 memory.push(word1 % word2);
693 }
694 Opcode::ModU16 => {
695 let word2: u16 = memory.pop()?;
696 let word1: u16 = memory.pop()?;
697 memory.push(word1 % word2);
698 }
699 Opcode::ModU32 => {
700 let word2: u32 = memory.pop()?;
701 let word1: u32 = memory.pop()?;
702 memory.push(word1 % word2);
703 }
704 Opcode::ModI32 => {
705 let word2: i32 = memory.pop()?;
706 let word1: i32 = memory.pop()?;
707 memory.push(word1 % word2);
708 }
709 Opcode::ModI64 => {
710 let word2: i64 = memory.pop()?;
711 let word1: i64 = memory.pop()?;
712 memory.push(word1 % word2);
713 }
714 Opcode::ModU64 => {
715 let word2: u64 = memory.pop()?;
716 let word1: u64 = memory.pop()?;
717 memory.push(word1 % word2);
718 }
719 Opcode::ModF32 => {
720 let word2: f32 = memory.pop()?;
721 let word1: f32 = memory.pop()?;
722 memory.push(word1 % word2);
723 }
724 Opcode::ModF64 => {
725 let word2: f64 = memory.pop()?;
726 let word1: f64 = memory.pop()?;
727 memory.push(word1 % word2);
728 }
729
730 Opcode::RShiftI8 => {
731 let word2: u8 = memory.pop()?;
732 let word1: i8 = memory.pop()?;
733 memory.push(word1.wrapping_shr(word2 as u32));
734 }
735 Opcode::RShiftU8 => {
736 let word2: u8 = memory.pop()?;
737 let word1: u8 = memory.pop()?;
738 memory.push(word1.wrapping_shr(word2 as u32));
739 }
740 Opcode::RShiftI16 => {
741 let word2: u8 = memory.pop()?;
742 let word1: i16 = memory.pop()?;
743 memory.push(word1.wrapping_shr(word2 as u32));
744 }
745 Opcode::RShiftU16 => {
746 let word2: u8 = memory.pop()?;
747 let word1: u16 = memory.pop()?;
748 memory.push(word1.wrapping_shr(word2 as u32));
749 }
750 Opcode::RShiftI32 => {
751 let word2: u8 = memory.pop()?;
752 let word1: i32 = memory.pop()?;
753 memory.push(word1.wrapping_shr(word2 as u32));
754 }
755 Opcode::RShiftU32 => {
756 let word2: u8 = memory.pop()?;
757 let word1: u32 = memory.pop()?;
758 memory.push(word1.wrapping_shr(word2 as u32));
759 }
760 Opcode::RShiftI64 => {
761 let word2: u8 = memory.pop()?;
762 let word1: i64 = memory.pop()?;
763 memory.push(word1.wrapping_shr(word2 as u32));
764 }
765 Opcode::RShiftU64 => {
766 let word2: u8 = memory.pop()?;
767 let word1: u64 = memory.pop()?;
768 memory.push(word1.wrapping_shr(word2 as u32));
769 }
770
771 Opcode::LShiftI8 => {
772 let word2: u8 = memory.pop()?;
773 let word1: i8 = memory.pop()?;
774 memory.push(word1.wrapping_shl(word2 as u32));
775 }
776 Opcode::LShiftU8 => {
777 let word2: u8 = memory.pop()?;
778 let word1: u8 = memory.pop()?;
779 memory.push(word1.wrapping_shl(word2 as u32));
780 }
781 Opcode::LShiftI16 => {
782 let word2: u8 = memory.pop()?;
783 let word1: i16 = memory.pop()?;
784 memory.push(word1.wrapping_shl(word2 as u32));
785 }
786 Opcode::LShiftU16 => {
787 let word2: u8 = memory.pop()?;
788 let word1: u16 = memory.pop()?;
789 memory.push(word1.wrapping_shl(word2 as u32));
790 }
791 Opcode::LShiftI32 => {
792 let word2: u8 = memory.pop()?;
793 let word1: i32 = memory.pop()?;
794 memory.push(word1.wrapping_shl(word2 as u32));
795 }
796 Opcode::LShiftU32 => {
797 let word2: u8 = memory.pop()?;
798 let word1: u32 = memory.pop()?;
799 memory.push(word1.wrapping_shl(word2 as u32));
800 }
801 Opcode::LShiftI64 => {
802 let word2: u8 = memory.pop()?;
803 let word1: i64 = memory.pop()?;
804 memory.push(word1.wrapping_shl(word2 as u32));
805 }
806 Opcode::LShiftU64 => {
807 let word2: u8 = memory.pop()?;
808 let word1: u64 = memory.pop()?;
809 memory.push(word1.wrapping_shl(word2 as u32));
810 }
811
812 Opcode::BitAnd8 => {
813 let word2: u8 = memory.pop()?;
814 let word1: u8 = memory.pop()?;
815 memory.push(word1 & word2);
816 }
817 Opcode::BitAnd16 => {
818 let word2: u16 = memory.pop()?;
819 let word1: u16 = memory.pop()?;
820 memory.push(word1 & word2);
821 }
822 Opcode::BitAnd32 => {
823 let word2: u32 = memory.pop()?;
824 let word1: u32 = memory.pop()?;
825 memory.push(word1 & word2);
826 }
827 Opcode::BitAnd64 => {
828 let word2: u64 = memory.pop()?;
829 let word1: u64 = memory.pop()?;
830 memory.push(word1 & word2);
831 }
832
833 Opcode::BitOr8 => {
834 let word2: u8 = memory.pop()?;
835 let word1: u8 = memory.pop()?;
836 memory.push(word1 | word2);
837 }
838 Opcode::BitOr16 => {
839 let word2: u16 = memory.pop()?;
840 let word1: u16 = memory.pop()?;
841 memory.push(word1 | word2);
842 }
843 Opcode::BitOr32 => {
844 let word2: u32 = memory.pop()?;
845 let word1: u32 = memory.pop()?;
846 memory.push(word1 | word2);
847 }
848 Opcode::BitOr64 => {
849 let word2: u64 = memory.pop()?;
850 let word1: u64 = memory.pop()?;
851 memory.push(word1 | word2);
852 }
853
854 Opcode::BitXor8 => {
855 let word2: u8 = memory.pop()?;
856 let word1: u8 = memory.pop()?;
857 memory.push(word1 ^ word2);
858 }
859 Opcode::BitXor16 => {
860 let word2: u16 = memory.pop()?;
861 let word1: u16 = memory.pop()?;
862 memory.push(word1 ^ word2);
863 }
864 Opcode::BitXor32 => {
865 let word2: u32 = memory.pop()?;
866 let word1: u32 = memory.pop()?;
867 memory.push(word1 ^ word2);
868 }
869 Opcode::BitXor64 => {
870 let word2: u64 = memory.pop()?;
871 let word1: u64 = memory.pop()?;
872 memory.push(word1 ^ word2);
873 }
874
875 Opcode::BitNot8 => {
876 let word: u8 = memory.pop()?;
877 memory.push(!word);
878 }
879 Opcode::BitNot16 => {
880 let word: u16 = memory.pop()?;
881 memory.push(!word);
882 }
883 Opcode::BitNot32 => {
884 let word: u32 = memory.pop()?;
885 memory.push(!word);
886 }
887 Opcode::BitNot64 => {
888 let word: u64 = memory.pop()?;
889 memory.push(!word);
890 }
891
892 Opcode::Jump => {
893 let target = memory.read_pc()?;
894 memory.jump(target);
895 }
896
897 Opcode::JumpIfZero8 => {
898 let target = memory.read_pc()?;
899 let value: u8 = memory.pop()?;
900 if value == 0 {
901 memory.jump(target);
902 }
903 }
904 Opcode::JumpIfZero16 => {
905 let target = memory.read_pc()?;
906 let value: u16 = memory.pop()?;
907 if value == 0 {
908 memory.jump(target);
909 }
910 }
911 Opcode::JumpIfZero32 => {
912 let target = memory.read_pc()?;
913 let value: u32 = memory.pop()?;
914 if value == 0 {
915 memory.jump(target);
916 }
917 }
918 Opcode::JumpIfZero64 => {
919 let target = memory.read_pc()?;
920 let value: u64 = memory.pop()?;
921 if value == 0 {
922 memory.jump(target);
923 }
924 }
925
926 Opcode::JumpIfNotZero8 => {
927 let target = memory.read_pc()?;
928 let value: u8 = memory.pop()?;
929 if value != 0 {
930 memory.jump(target);
931 }
932 }
933 Opcode::JumpIfNotZero16 => {
934 let target = memory.read_pc()?;
935 let value: u16 = memory.pop()?;
936 if value != 0 {
937 memory.jump(target);
938 }
939 }
940 Opcode::JumpIfNotZero32 => {
941 let target = memory.read_pc()?;
942 let value: u32 = memory.pop()?;
943 if value != 0 {
944 memory.jump(target);
945 }
946 }
947 Opcode::JumpIfNotZero64 => {
948 let target = memory.read_pc()?;
949 let value: u64 = memory.pop()?;
950 if value != 0 {
951 memory.jump(target);
952 }
953 }
954
955 Opcode::Ret => {
956 memory.ret()?;
957 }
958 Opcode::Call => {
959 let func: VarPointer = memory.pop()?;
960 memory.call(func)?;
961 }
962
963 Opcode::Throw => {
964 let skip_frames: u32 = memory.pop()?;
965 let message_ptr: VarPointer = memory.pop()?;
966 let name_ptr: VarPointer = memory.pop()?;
967
968 let message_bytes = memory.cstring_bytes(message_ptr)?;
969 let name_bytes = memory.cstring_bytes(name_ptr)?;
970
971 let mut message = String::new();
972 string_append_utf8_lossy(&mut message, message_bytes);
973 let mut name = String::new();
974 string_append_utf8_lossy(&mut name, name_bytes);
975
976 for _ in 0..skip_frames {
977 memory.ret()?;
978 }
979
980 return Err(IError::new(name, message));
981 }
982
983 Opcode::AllocBegin => {
984 let var_pointer: VarPointer = memory.pop()?;
985 if memory.read::<u8>(var_pointer).is_ok() {
986 memory.push(var_pointer.with_offset(0));
987 } else {
988 memory.push(0 as u64);
989 }
990 }
991 Opcode::AllocEnd => {
992 let var_pointer: VarPointer = memory.pop()?;
993 if let Some(ptr) = memory.upper_bound(var_pointer) {
994 memory.push(ptr);
995 } else {
996 memory.push(0 as u64);
997 }
998 }
999
1000 Opcode::CopySrcToDest => {
1001 let destination: VarPointer = memory.pop()?;
1002 let source: VarPointer = memory.pop()?;
1003 let length: u64 = memory.pop()?;
1004
1005 memory.push(destination);
1006 }
1007 Opcode::Memset => {
1008 let destination: VarPointer = memory.pop()?;
1009 let value: u8 = memory.pop()?;
1010 let length: u64 = memory.pop()?;
1011
1012 memory.push(destination);
1013 }
1014
1015 Opcode::HeapAlloc => {
1016 let skip: u32 = memory.pop()?;
1017 let size: u64 = memory.pop()?;
1018 let ptr = memory.add_heap_var(size as u32, skip)?;
1019 memory.push(ptr);
1020 }
1021 Opcode::HeapDealloc => {
1022 let skip: u32 = memory.pop()?;
1023 let ptr: VarPointer = memory.pop()?;
1024 memory.free(ptr, skip)?;
1025 memory.push(0u64);
1026 }
1027
1028 Opcode::Ecall => match memory.pop()? {
1029 Ecall::Exit => {
1030 let exit: i32 = memory.pop()?;
1031 return Ok(Some(EcallExt::Exit(exit)));
1032 }
1033
1034 Ecall::OpenFd => {
1035 let open_mode: OpenMode = memory.pop()?;
1036 let name: VarPointer = memory.pop()?;
1037 return Ok(Some(EcallExt::OpenFd { name, open_mode }));
1038 }
1039 Ecall::ReadFd => {
1040 let len: u32 = memory.pop()?;
1041 let buf: VarPointer = memory.pop()?;
1042 let begin: u32 = memory.pop()?;
1043 let fd: u32 = memory.pop()?;
1044
1045 #[rustfmt::skip]
1046 return Ok(Some(EcallExt::ReadFd { len, buf, begin, fd, }));
1047 }
1048 Ecall::WriteFd => {
1049 let len: u32 = memory.pop()?;
1050 let buf: VarPointer = memory.pop()?;
1051 let begin: u32 = memory.pop()?;
1052 let fd: u32 = memory.pop()?;
1053
1054 #[rustfmt::skip]
1055 return Ok(Some(EcallExt::WriteFd { buf, len, begin, fd }));
1056 }
1057 Ecall::AppendFd => {
1058 let len: u32 = memory.pop()?;
1059 let buf: VarPointer = memory.pop()?;
1060 let fd: u32 = memory.pop()?;
1061
1062 #[rustfmt::skip]
1063 return Ok(Some(EcallExt::AppendFd { buf, len, fd }));
1064 }
1065
1066 call => {
1067 return ierr!(
1068 "InvalidEnviromentCall",
1069 "invalid ecall value of {}",
1070 call as u32
1071 )
1072 }
1073 },
1074
1075 Opcode::AssertStr => {
1076 let string = memory.pop()?;
1077 memory.cstring_bytes(string)?;
1078 }
1079 }
1080
1081 return Ok(None);
1082}