watson/
interpreter.rs

1use crate::core::*;
2use alloc::string::{String, ToString};
3use alloc::sync::Arc;
4use alloc::vec::Vec;
5use core::convert::TryInto;
6use serde::{Deserialize, Serialize};
7use spin::Mutex;
8
9pub struct Interpreter<T>
10where
11    T: InterpretableProgram,
12{
13    pub memory: Arc<Mutex<Vec<u8>>>,
14    pub program: Arc<Mutex<T>>,
15}
16
17#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
18pub enum WasmValue {
19    I32(i32),
20    I64(i64),
21    F32(f32),
22    F64(f64),
23}
24
25pub trait ToWasmValue {
26    fn to_wasm_value(&self) -> WasmValue;
27}
28
29impl ToWasmValue for usize {
30    fn to_wasm_value(&self) -> WasmValue {
31        WasmValue::I32(*self as i32)
32    }
33}
34
35impl ToWasmValue for u32 {
36    fn to_wasm_value(&self) -> WasmValue {
37        WasmValue::I32((*self as u32).try_into().unwrap())
38    }
39}
40
41impl ToWasmValue for i32 {
42    fn to_wasm_value(&self) -> WasmValue {
43        WasmValue::I32(*self)
44    }
45}
46
47impl ToWasmValue for i64 {
48    fn to_wasm_value(&self) -> WasmValue {
49        WasmValue::I64(*self)
50    }
51}
52
53impl ToWasmValue for f32 {
54    fn to_wasm_value(&self) -> WasmValue {
55        WasmValue::F32(*self)
56    }
57}
58
59impl ToWasmValue for f64 {
60    fn to_wasm_value(&self) -> WasmValue {
61        WasmValue::F64(*self)
62    }
63}
64
65impl WasmValue {
66    pub fn to_i32(&self) -> i32 {
67        match self {
68            WasmValue::I32(i) => *i,
69            WasmValue::I64(i) => *i as i32,
70            WasmValue::F32(i) => *i as i32,
71            WasmValue::F64(i) => *i as i32,
72        }
73    }
74
75    pub fn to_i64(&self) -> i64 {
76        match self {
77            WasmValue::I32(i) => *i as i64,
78            WasmValue::I64(i) => *i,
79            WasmValue::F32(i) => *i as i64,
80            WasmValue::F64(i) => *i as i64,
81        }
82    }
83
84    pub fn to_f32(&self) -> f32 {
85        match self {
86            WasmValue::I32(i) => *i as f32,
87            WasmValue::I64(i) => *i as f32,
88            WasmValue::F32(i) => *i,
89            WasmValue::F64(i) => *i as f32,
90        }
91    }
92
93    pub fn to_f64(&self) -> f64 {
94        match self {
95            WasmValue::I32(i) => *i as f64,
96            WasmValue::I64(i) => *i as f64,
97            WasmValue::F32(i) => *i as f64,
98            WasmValue::F64(i) => *i,
99        }
100    }
101}
102
103#[derive(Debug)]
104pub struct ImportCall {
105    pub module_name: String,
106    pub name: String,
107    pub params: Vec<WasmValue>,
108}
109
110pub enum ExecutionResponse {
111    DoNothing,
112    AddValues(Vec<WasmValue>),
113    ValueStackModification(fn(&mut Vec<WasmValue>) -> Result<(), &'static str>),
114    GetRegister(u32),
115    SetRegister(u32),
116    TeeRegister(u32),
117    ThrowError(&'static str),
118    GetMemorySize,
119    GetMemoryGrow,
120}
121
122#[derive(Debug)]
123pub enum ExecutionUnit {
124    CallImport(ImportCall),
125    BasicInstruction(Instruction),
126    Unreachable,
127    Complete(Vec<WasmValue>),
128}
129
130pub trait InterpretableProgram {
131    fn load_data_into_memory(&self, mem: &mut Vec<u8>) -> Result<(), &'static str>;
132    fn initial_memory_size(&self) -> usize;
133    fn import_fn_details(&self, index: usize) -> Result<(&str, &str, usize), &'static str>;
134    fn import_fn_count(&self) -> usize;
135    fn fetch_export_fn_index(&self, name: &str) -> Result<(usize, usize), &'static str>;
136    fn fetch_instruction<'a>(
137        &'a self,
138        position: &[usize],
139    ) -> Result<Option<&'a Instruction>, &'static str>;
140    fn create_locals(&self, position: &[usize]) -> Result<Vec<WasmValue>, &'static str>;
141}
142
143impl InterpretableProgram for Program {
144    fn import_fn_details(&self, index: usize) -> Result<(&str, &str, usize), &'static str> {
145        for s in self.sections.iter() {
146            if let Section::Import(import_section) = s {
147                let l: Vec<_> = import_section
148                    .imports
149                    .iter()
150                    .filter(|x| matches!(x, WasmImport::Function(_)))
151                    .collect();
152                if index < l.len() {
153                    if let WasmImport::Function(x) = l[index] {
154                        return Ok((&x.module_name, &x.name, 1));
155                    }
156                } else {
157                    return Err("import does not exist with that index");
158                }
159            }
160        }
161        Err("import section does not exist")
162    }
163
164    fn load_data_into_memory(&self, mem: &mut Vec<u8>) -> Result<(), &'static str> {
165        for s in self.sections.iter() {
166            if let Section::Data(d) = s {
167                for db in d.data_blocks.iter() {
168                    match db.offset_expression[0] {
169                        Instruction::I32Const(x) => {
170                            let offset = x as usize;
171                            for (i, b) in db.data.iter().enumerate() {
172                                mem[offset + i] = *b;
173                            }
174                        }
175                        _ => return Err("I don't know how to build this memory yet"),
176                    }
177                }
178            }
179        }
180        Ok(())
181    }
182
183    fn initial_memory_size(&self) -> usize {
184        for s in self.sections.iter() {
185            if let Section::Memory(m) = s {
186                if !m.memories.is_empty() {
187                    return m.memories[0].min_pages * 1024;
188                }
189            }
190        }
191        0
192    }
193
194    fn import_fn_count(&self) -> usize {
195        for s in self.sections.iter() {
196            if let Section::Import(import_section) = s {
197                let l: Vec<_> = import_section
198                    .imports
199                    .iter()
200                    .filter(|x| matches!(x, WasmImport::Function(_)))
201                    .collect();
202                return l.len();
203            }
204        }
205        0
206    }
207
208    fn fetch_export_fn_index(&self, name: &str) -> Result<(usize, usize), &'static str> {
209        let ct = self.import_fn_count();
210        let result = self
211            .sections
212            .iter()
213            .enumerate()
214            .find(|(_, x)| matches!(x, Section::Code(_)));
215        let code_section_idx = match result {
216            Some((i, _)) => i,
217            None => return Err("Code section did not exist"),
218        };
219        for s in self.sections.iter() {
220            if let Section::Export(export_section) = s {
221                for e in export_section.exports.iter() {
222                    if let WasmExport::Function(f) = e {
223                        if f.name == name {
224                            return Ok((code_section_idx, f.index - ct));
225                        }
226                    }
227                }
228            }
229        }
230        Err("could not find export section")
231    }
232
233    fn fetch_instruction<'a>(
234        &'a self,
235        position: &[usize],
236    ) -> Result<Option<&'a Instruction>, &'static str> {
237        if let Section::Code(code_section) = &self.sections[position[0]] {
238            let b = &code_section.code_blocks[position[1]];
239            // TODO: handle nesting
240            if position.len() > 2 {
241                let i = 2;
242                let instruction_index = position[i];
243                let len = &b.instructions.len();
244                if instruction_index < *len {
245                    Ok(Some(&b.instructions[instruction_index]))
246                } else {
247                    Ok(None)
248                }
249            } else {
250                Ok(None)
251            }
252        } else {
253            Err("cannot find code section")
254        }
255    }
256
257    fn create_locals(&self, position: &[usize]) -> Result<Vec<WasmValue>, &'static str> {
258        let mut locals = vec![];
259        if let Section::Code(code_section) = &self.sections[position[0]] {
260            let b = &code_section.code_blocks[position[1]];
261            for l in b.locals.iter() {
262                for _ in 0..l.count {
263                    let v = match l.value_type {
264                        ValueType::I32 => 0i32.to_wasm_value(),
265                        ValueType::I64 => 0i64.to_wasm_value(),
266                        ValueType::F32 => 0f32.to_wasm_value(),
267                        ValueType::F64 => 0f64.to_wasm_value(),
268                    };
269                    locals.push(v);
270                }
271            }
272        } else {
273            return Err("cannot find code section");
274        }
275        Ok(locals)
276    }
277}
278
279impl InterpretableProgram for ProgramView<'_> {
280    fn import_fn_details(&self, index: usize) -> Result<(&str, &str, usize), &'static str> {
281        for s in self.sections.iter() {
282            if let SectionView::Import(import_section) = s {
283                let l: Vec<_> = import_section
284                    .imports
285                    .iter()
286                    .filter(|x| matches!(x, WasmImportView::Function(_)))
287                    .collect();
288                if index < l.len() {
289                    if let WasmImportView::Function(x) = l[index] {
290                        return Ok((x.module_name, x.name, 1));
291                    }
292                } else {
293                    return Err("import does not exist with that index");
294                }
295            }
296        }
297        Err("import section does not exist")
298    }
299
300    fn load_data_into_memory(&self, mem: &mut Vec<u8>) -> Result<(), &'static str> {
301        for s in self.sections.iter() {
302            if let SectionView::Data(d) = s {
303                for db in d.data_blocks.iter() {
304                    match db.offset_expression[0] {
305                        Instruction::I32Const(x) => {
306                            let offset = x as usize;
307                            for (i, b) in db.data.iter().enumerate() {
308                                mem[offset + i] = *b;
309                            }
310                        }
311                        _ => return Err("I don't know how to build this memory yet"),
312                    }
313                }
314            }
315        }
316        Ok(())
317    }
318
319    fn initial_memory_size(&self) -> usize {
320        for s in self.sections.iter() {
321            if let SectionView::Memory(m) = s {
322                if !m.memories.is_empty() {
323                    return m.memories[0].min_pages * 1024;
324                }
325            }
326        }
327        0
328    }
329
330    fn import_fn_count(&self) -> usize {
331        for s in self.sections.iter() {
332            if let SectionView::Import(import_section) = s {
333                let l: Vec<_> = import_section
334                    .imports
335                    .iter()
336                    .filter(|x| matches!(x, WasmImportView::Function(_)))
337                    .collect();
338                return l.len();
339            }
340        }
341        0
342    }
343
344    fn fetch_export_fn_index(&self, name: &str) -> Result<(usize, usize), &'static str> {
345        let ct = self.import_fn_count();
346        let result = self
347            .sections
348            .iter()
349            .enumerate()
350            .find(|(_, x)| matches!(x, SectionView::Code(_)));
351        let code_section_idx = match result {
352            Some((i, _)) => i,
353            None => return Err("Code section did not exist"),
354        };
355        for s in self.sections.iter() {
356            if let SectionView::Export(export_section) = s {
357                for e in export_section.exports.iter() {
358                    if let WasmExportView::Function(f) = e {
359                        if f.name == name {
360                            return Ok((code_section_idx, f.index - ct));
361                        }
362                    }
363                }
364            }
365        }
366        Err("could not find export section")
367    }
368
369    fn fetch_instruction<'a>(
370        &'a self,
371        position: &[usize],
372    ) -> Result<Option<&'a Instruction>, &'static str> {
373        if let SectionView::Code(code_section) = &self.sections[position[0]] {
374            let b = &code_section.code_blocks[position[1]];
375            // TODO: handle nesting
376            if position.len() > 2 {
377                let i = 2;
378                let instruction_index = position[i];
379                let len = &b.instructions.len();
380                if instruction_index < *len {
381                    Ok(Some(&b.instructions[instruction_index]))
382                } else {
383                    Ok(None)
384                }
385            } else {
386                Ok(None)
387            }
388        } else {
389            Err("cannot find code section")
390        }
391    }
392
393    fn create_locals(&self, position: &[usize]) -> Result<Vec<WasmValue>, &'static str> {
394        let mut locals = vec![];
395        if let SectionView::Code(code_section) = &self.sections[position[0]] {
396            let b = &code_section.code_blocks[position[1]];
397            for l in b.locals.iter() {
398                for _ in 0..l.count {
399                    let v = match l.value_type {
400                        ValueType::I32 => 0i32.to_wasm_value(),
401                        ValueType::I64 => 0i64.to_wasm_value(),
402                        ValueType::F32 => 0f32.to_wasm_value(),
403                        ValueType::F64 => 0f64.to_wasm_value(),
404                    };
405                    locals.push(v);
406                }
407            }
408        } else {
409            return Err("cannot find code section");
410        }
411        Ok(locals)
412    }
413}
414
415impl<T> Interpreter<T>
416where
417    T: InterpretableProgram,
418{
419    pub fn new(p: T) -> Result<Self, &'static str> {
420        let mem_size = p.initial_memory_size();
421        let mut mem = vec![0; mem_size];
422        p.load_data_into_memory(&mut mem)?;
423        Ok(Interpreter {
424            memory: Arc::new(Mutex::new(mem)),
425            program: Arc::new(Mutex::new(p)),
426        })
427    }
428    pub fn call(
429        &mut self,
430        name: &str,
431        params: &[WasmValue],
432    ) -> Result<WasmExecution<T>, &'static str> {
433        WasmExecution::new(name, params, self.program.clone(), self.memory.clone())
434    }
435}
436
437#[derive(Deserialize, Serialize)]
438pub struct WasmExecution<T>
439where
440    T: InterpretableProgram,
441{
442    #[serde(skip)]
443    import_fn_count: usize,
444    pub call_stack: (usize, Vec<WasmValue>),
445    pub value_stack: Vec<WasmValue>,
446    pub current_position: Vec<usize>,
447    #[serde(skip)]
448    pub memory: Arc<Mutex<Vec<u8>>>,
449    #[serde(skip)]
450    pub program: Arc<Mutex<T>>,
451}
452
453impl<T> WasmExecution<T>
454where
455    T: InterpretableProgram,
456{
457    pub fn new(
458        name: &str,
459        params: &[WasmValue],
460        program: Arc<Mutex<T>>,
461        memory: Arc<Mutex<Vec<u8>>>,
462    ) -> Result<Self, &'static str> {
463        let p = program.lock();
464        let (section_index, function_index) = p.fetch_export_fn_index(name)?;
465        let position = vec![section_index, function_index];
466        let locals = p.create_locals(&position)?;
467        let import_fn_count = p.import_fn_count();
468        Ok(WasmExecution {
469            call_stack: (function_index, locals),
470            import_fn_count,
471            value_stack: params.to_vec(),
472            current_position: position,
473            memory,
474            program: program.clone(),
475        })
476    }
477
478    pub fn next_unit(&mut self) -> Result<ExecutionUnit, &'static str> {
479        let p = self.program.lock();
480        if self.current_position.len() == 2 {
481            self.current_position.push(0);
482        } else {
483            let len = self.current_position.len() - 1;
484            self.current_position[len] += 1;
485        }
486        let first_function_instruction = p.fetch_instruction(&self.current_position)?;
487        if let Some(instruction) = first_function_instruction {
488            let unit = match instruction {
489                Instruction::Call(fn_index) => {
490                    if ((*fn_index) as usize) < self.import_fn_count {
491                        let (module_name, name, param_ct) =
492                            p.import_fn_details((*fn_index) as usize)?;
493                        let mut params = vec![];
494                        for _ in 0..param_ct {
495                            let p = match self.value_stack.pop() {
496                                Some(p) => p,
497                                None => return Err("ran out of values on value stack"),
498                            };
499                            params.push(p);
500                        }
501                        ExecutionUnit::CallImport(ImportCall {
502                            module_name: module_name.to_string(),
503                            name: name.to_string(),
504                            params,
505                        })
506                    } else {
507                        return Err("cannot call non-imports yet");
508                    }
509                }
510                Instruction::Unreachable => ExecutionUnit::Unreachable,
511                x => ExecutionUnit::BasicInstruction(x.clone()),
512            };
513            Ok(unit)
514        } else {
515            // TODO: handle nested function call
516            Ok(ExecutionUnit::Complete(vec![]))
517        }
518    }
519
520    pub fn execute(&mut self, r: ExecutionResponse) -> Result<(), &'static str> {
521        match r {
522            ExecutionResponse::GetMemorySize => self.value_stack.push(
523                (self.memory.lock().len().to_wasm_value().to_i32() / 1024i32).to_wasm_value(),
524            ),
525            ExecutionResponse::GetMemoryGrow => {
526                let _page_delta = self.value_stack.pop().unwrap().to_i32();
527                return Err("do not know how to extend memory");
528            }
529            ExecutionResponse::ValueStackModification(f) => f(&mut self.value_stack)?,
530            ExecutionResponse::AddValues(mut v) => {
531                while let Some(wv) = v.pop() {
532                    self.value_stack.push(wv);
533                }
534            }
535            ExecutionResponse::GetRegister(v) => {
536                self.value_stack.push(self.call_stack.1[v as usize]);
537            }
538            ExecutionResponse::SetRegister(v) => {
539                if let Some(p) = self.value_stack.pop() {
540                    self.call_stack.1[v as usize] = p;
541                } else {
542                    return Err("can't set register because value stack is empty");
543                }
544            }
545            ExecutionResponse::TeeRegister(v) => {
546                if let Some(p) = self.value_stack.pop() {
547                    self.call_stack.1[v as usize] = p;
548                    self.value_stack.push(p);
549                } else {
550                    return Err("can't tee register because value stack is empty");
551                }
552            }
553            ExecutionResponse::ThrowError(msg) => return Err(msg),
554            ExecutionResponse::DoNothing => {}
555        }
556        Ok(())
557    }
558
559    pub fn memory(&mut self) -> Option<Arc<Mutex<Vec<u8>>>> {
560        Some(self.memory.clone())
561    }
562}
563
564impl ExecutionUnit {
565    pub fn evaluate(&mut self) -> Result<ExecutionResponse, &'static str> {
566        let response = match self {
567            ExecutionUnit::Unreachable => ExecutionResponse::ThrowError("Reached unreachable"),
568            ExecutionUnit::BasicInstruction(i) => match i {
569                Instruction::Raw(b) => {
570                    return Err("Cannot handle raw instruction.");
571                }
572                Instruction::Unreachable => {
573                    return Err("Cannot handle unreachable.");
574                }
575                Instruction::Nop => ExecutionResponse::DoNothing,
576                Instruction::Block(block_type, instructions) => {
577                    return Err("no default evaluation for basic instruction yet");
578                }
579                Instruction::Loop(block_type, instructions) => {
580                    return Err("no default evaluation for basic instruction yet");
581                }
582                Instruction::If(block_type, if_instructions, else_instructions) => {
583                    return Err("no default evaluation for basic instruction yet");
584                }
585                Instruction::Br(i) => {
586                    return Err("no default evaluation for basic instruction yet");
587                }
588                Instruction::BrIf(i) => {
589                    return Err("no default evaluation for basic instruction yet");
590                }
591                Instruction::BrTable(labels, label_index) => {
592                    return Err("no default evaluation for basic instruction yet");
593                }
594                Instruction::Return => {
595                    return Err("no default evaluation for basic instruction yet");
596                }
597                Instruction::Call(i) => {
598                    return Err("Cannot handle call.");
599                }
600                Instruction::CallIndirect(i) => {
601                    return Err("no default evaluation for basic instruction yet");
602                }
603                Instruction::Drop => ExecutionResponse::ValueStackModification(|stack| {
604                    stack.pop();
605                    Ok(())
606                }),
607                Instruction::Select => ExecutionResponse::ValueStackModification(|stack| {
608                    let cond = stack.pop().unwrap().to_i32();
609                    let b = stack.pop().unwrap();
610                    let a = stack.pop().unwrap();
611                    if cond != 0 {
612                        stack.push(a);
613                    } else {
614                        stack.push(b);
615                    }
616                    Ok(())
617                }),
618                Instruction::LocalGet(i) => ExecutionResponse::GetRegister(*i),
619                Instruction::LocalSet(i) => ExecutionResponse::SetRegister(*i),
620                Instruction::LocalTee(i) => ExecutionResponse::TeeRegister(*i),
621                Instruction::GlobalGet(i) => {
622                    return Err("no default evaluation for basic instruction yet");
623                }
624                Instruction::GlobalSet(i) => {
625                    return Err("no default evaluation for basic instruction yet");
626                }
627                Instruction::I32Load(align, offset) => {
628                    return Err("no default evaluation for basic instruction yet");
629                }
630                Instruction::I64Load(align, offset) => {
631                    return Err("no default evaluation for basic instruction yet");
632                }
633                Instruction::F32Load(align, offset) => {
634                    return Err("no default evaluation for basic instruction yet");
635                }
636                Instruction::F64Load(align, offset) => {
637                    return Err("no default evaluation for basic instruction yet");
638                }
639                Instruction::I32Load8S(align, offset) => {
640                    return Err("no default evaluation for basic instruction yet");
641                }
642                Instruction::I32Load8U(align, offset) => {
643                    return Err("no default evaluation for basic instruction yet");
644                }
645                Instruction::I32Load16S(align, offset) => {
646                    return Err("no default evaluation for basic instruction yet");
647                }
648                Instruction::I32Load16U(align, offset) => {
649                    return Err("no default evaluation for basic instruction yet");
650                }
651                Instruction::I64Load8S(align, offset) => {
652                    return Err("no default evaluation for basic instruction yet");
653                }
654                Instruction::I64Load8U(align, offset) => {
655                    return Err("no default evaluation for basic instruction yet");
656                }
657                Instruction::I64Load16S(align, offset) => {
658                    return Err("no default evaluation for basic instruction yet");
659                }
660                Instruction::I64Load16U(align, offset) => {
661                    return Err("no default evaluation for basic instruction yet");
662                }
663                Instruction::I64Load32S(align, offset) => {
664                    return Err("no default evaluation for basic instruction yet");
665                }
666                Instruction::I64Load32U(align, offset) => {
667                    return Err("no default evaluation for basic instruction yet");
668                }
669                Instruction::I32Store(align, offset) => {
670                    return Err("no default evaluation for basic instruction yet");
671                }
672                Instruction::I64Store(align, offset) => {
673                    return Err("no default evaluation for basic instruction yet");
674                }
675                Instruction::F32Store(align, offset) => {
676                    return Err("no default evaluation for basic instruction yet");
677                }
678                Instruction::F64Store(align, offset) => {
679                    return Err("no default evaluation for basic instruction yet");
680                }
681                Instruction::I32Store8(align, offset) => {
682                    return Err("no default evaluation for basic instruction yet");
683                }
684                Instruction::I32Store16(align, offset) => {
685                    return Err("no default evaluation for basic instruction yet");
686                }
687                Instruction::I64Store8(align, offset) => {
688                    return Err("no default evaluation for basic instruction yet");
689                }
690                Instruction::I64Store16(align, offset) => {
691                    return Err("no default evaluation for basic instruction yet");
692                }
693                Instruction::I64Store32(align, offset) => {
694                    return Err("no default evaluation for basic instruction yet");
695                }
696                Instruction::MemorySize => ExecutionResponse::GetMemorySize,
697                Instruction::MemoryGrow => ExecutionResponse::GetMemoryGrow,
698                Instruction::I32Const(i) => ExecutionResponse::AddValues(vec![i.to_wasm_value()]),
699                Instruction::I64Const(i) => ExecutionResponse::AddValues(vec![i.to_wasm_value()]),
700                Instruction::F32Const(f) => ExecutionResponse::AddValues(vec![f.to_wasm_value()]),
701                Instruction::F64Const(f) => ExecutionResponse::AddValues(vec![f.to_wasm_value()]),
702                Instruction::I32Eqz => {
703                    return Err("no default evaluation for basic instruction yet");
704                }
705                Instruction::I32Eq => {
706                    return Err("no default evaluation for basic instruction yet");
707                }
708                Instruction::I32Ne => {
709                    return Err("no default evaluation for basic instruction yet");
710                }
711                Instruction::I32LtS => {
712                    return Err("no default evaluation for basic instruction yet");
713                }
714                Instruction::I32LtU => {
715                    return Err("no default evaluation for basic instruction yet");
716                }
717                Instruction::I32GtS => {
718                    return Err("no default evaluation for basic instruction yet");
719                }
720                Instruction::I32GtU => {
721                    return Err("no default evaluation for basic instruction yet");
722                }
723                Instruction::I32LeS => {
724                    return Err("no default evaluation for basic instruction yet");
725                }
726                Instruction::I32LeU => {
727                    return Err("no default evaluation for basic instruction yet");
728                }
729                Instruction::I32GeS => {
730                    return Err("no default evaluation for basic instruction yet");
731                }
732                Instruction::I32GeU => {
733                    return Err("no default evaluation for basic instruction yet");
734                }
735                Instruction::I64Eqz => {
736                    return Err("no default evaluation for basic instruction yet");
737                }
738                Instruction::I64Eq => {
739                    return Err("no default evaluation for basic instruction yet");
740                }
741                Instruction::I64Ne => {
742                    return Err("no default evaluation for basic instruction yet");
743                }
744                Instruction::I64LtS => {
745                    return Err("no default evaluation for basic instruction yet");
746                }
747                Instruction::I64LtU => {
748                    return Err("no default evaluation for basic instruction yet");
749                }
750                Instruction::I64GtS => {
751                    return Err("no default evaluation for basic instruction yet");
752                }
753                Instruction::I64GtU => {
754                    return Err("no default evaluation for basic instruction yet");
755                }
756                Instruction::I64LeS => {
757                    return Err("no default evaluation for basic instruction yet");
758                }
759                Instruction::I64LeU => {
760                    return Err("no default evaluation for basic instruction yet");
761                }
762                Instruction::I64GeS => {
763                    return Err("no default evaluation for basic instruction yet");
764                }
765                Instruction::I64GeU => {
766                    return Err("no default evaluation for basic instruction yet");
767                }
768                Instruction::F32Eq => {
769                    return Err("no default evaluation for basic instruction yet");
770                }
771                Instruction::F32Ne => {
772                    return Err("no default evaluation for basic instruction yet");
773                }
774                Instruction::F32Lt => {
775                    return Err("no default evaluation for basic instruction yet");
776                }
777                Instruction::F32Gt => {
778                    return Err("no default evaluation for basic instruction yet");
779                }
780                Instruction::F32Le => {
781                    return Err("no default evaluation for basic instruction yet");
782                }
783                Instruction::F32Ge => {
784                    return Err("no default evaluation for basic instruction yet");
785                }
786                Instruction::F64Eq => {
787                    return Err("no default evaluation for basic instruction yet");
788                }
789                Instruction::F64Ne => {
790                    return Err("no default evaluation for basic instruction yet");
791                }
792                Instruction::F64Lt => {
793                    return Err("no default evaluation for basic instruction yet");
794                }
795                Instruction::F64Gt => {
796                    return Err("no default evaluation for basic instruction yet");
797                }
798                Instruction::F64Le => {
799                    return Err("no default evaluation for basic instruction yet");
800                }
801                Instruction::F64Ge => {
802                    return Err("no default evaluation for basic instruction yet");
803                }
804                Instruction::I32Clz => {
805                    return Err("no default evaluation for basic instruction yet");
806                }
807                Instruction::I32Ctz => {
808                    return Err("no default evaluation for basic instruction yet");
809                }
810                Instruction::I32Popcnt => {
811                    return Err("no default evaluation for basic instruction yet");
812                }
813                Instruction::I32Add => {
814                    return Err("no default evaluation for basic instruction yet");
815                }
816                Instruction::I32Sub => {
817                    return Err("no default evaluation for basic instruction yet");
818                }
819                Instruction::I32Mul => {
820                    return Err("no default evaluation for basic instruction yet");
821                }
822                Instruction::I32DivS => {
823                    return Err("no default evaluation for basic instruction yet");
824                }
825                Instruction::I32DivU => {
826                    return Err("no default evaluation for basic instruction yet");
827                }
828                Instruction::I32RemS => {
829                    return Err("no default evaluation for basic instruction yet");
830                }
831                Instruction::I32RemU => {
832                    return Err("no default evaluation for basic instruction yet");
833                }
834                Instruction::I32And => {
835                    return Err("no default evaluation for basic instruction yet");
836                }
837                Instruction::I32Or => {
838                    return Err("no default evaluation for basic instruction yet");
839                }
840                Instruction::I32Xor => {
841                    return Err("no default evaluation for basic instruction yet");
842                }
843                Instruction::I32Shl => {
844                    return Err("no default evaluation for basic instruction yet");
845                }
846                Instruction::I32ShrS => {
847                    return Err("no default evaluation for basic instruction yet");
848                }
849                Instruction::I32ShrU => {
850                    return Err("no default evaluation for basic instruction yet");
851                }
852                Instruction::I32Rotl => {
853                    return Err("no default evaluation for basic instruction yet");
854                }
855                Instruction::I32Rotr => {
856                    return Err("no default evaluation for basic instruction yet");
857                }
858                Instruction::I64Clz => {
859                    return Err("no default evaluation for basic instruction yet");
860                }
861                Instruction::I64Ctz => {
862                    return Err("no default evaluation for basic instruction yet");
863                }
864                Instruction::I64Popcnt => {
865                    return Err("no default evaluation for basic instruction yet");
866                }
867                Instruction::I64Add => {
868                    return Err("no default evaluation for basic instruction yet");
869                }
870                Instruction::I64Sub => {
871                    return Err("no default evaluation for basic instruction yet");
872                }
873                Instruction::I64Mul => {
874                    return Err("no default evaluation for basic instruction yet");
875                }
876                Instruction::I64DivS => {
877                    return Err("no default evaluation for basic instruction yet");
878                }
879                Instruction::I64DivU => {
880                    return Err("no default evaluation for basic instruction yet");
881                }
882                Instruction::I64RemS => {
883                    return Err("no default evaluation for basic instruction yet");
884                }
885                Instruction::I64RemU => {
886                    return Err("no default evaluation for basic instruction yet");
887                }
888                Instruction::I64And => {
889                    return Err("no default evaluation for basic instruction yet");
890                }
891                Instruction::I64Or => {
892                    return Err("no default evaluation for basic instruction yet");
893                }
894                Instruction::I64Xor => {
895                    return Err("no default evaluation for basic instruction yet");
896                }
897                Instruction::I64Shl => {
898                    return Err("no default evaluation for basic instruction yet");
899                }
900                Instruction::I64ShrS => {
901                    return Err("no default evaluation for basic instruction yet");
902                }
903                Instruction::I64ShrU => {
904                    return Err("no default evaluation for basic instruction yet");
905                }
906                Instruction::I64Rotl => {
907                    return Err("no default evaluation for basic instruction yet");
908                }
909                Instruction::I64Rotr => {
910                    return Err("no default evaluation for basic instruction yet");
911                }
912                Instruction::F32Abs => {
913                    return Err("no default evaluation for basic instruction yet");
914                }
915                Instruction::F32Neg => {
916                    return Err("no default evaluation for basic instruction yet");
917                }
918                Instruction::F32Ceil => {
919                    return Err("no default evaluation for basic instruction yet");
920                }
921                Instruction::F32Floor => {
922                    return Err("no default evaluation for basic instruction yet");
923                }
924                Instruction::F32Trunc => {
925                    return Err("no default evaluation for basic instruction yet");
926                }
927                Instruction::F32Nearest => {
928                    return Err("no default evaluation for basic instruction yet");
929                }
930                Instruction::F32Sqrt => {
931                    return Err("no default evaluation for basic instruction yet");
932                }
933                Instruction::F32Add => {
934                    return Err("no default evaluation for basic instruction yet");
935                }
936                Instruction::F32Sub => {
937                    return Err("no default evaluation for basic instruction yet");
938                }
939                Instruction::F32Mul => {
940                    return Err("no default evaluation for basic instruction yet");
941                }
942                Instruction::F32Div => {
943                    return Err("no default evaluation for basic instruction yet");
944                }
945                Instruction::F32Min => {
946                    return Err("no default evaluation for basic instruction yet");
947                }
948                Instruction::F32Max => {
949                    return Err("no default evaluation for basic instruction yet");
950                }
951                Instruction::F32Copysign => {
952                    return Err("no default evaluation for basic instruction yet");
953                }
954                Instruction::F64Abs => {
955                    return Err("no default evaluation for basic instruction yet");
956                }
957                Instruction::F64Neg => {
958                    return Err("no default evaluation for basic instruction yet");
959                }
960                Instruction::F64Ceil => {
961                    return Err("no default evaluation for basic instruction yet");
962                }
963                Instruction::F64Floor => {
964                    return Err("no default evaluation for basic instruction yet");
965                }
966                Instruction::F64Trunc => {
967                    return Err("no default evaluation for basic instruction yet");
968                }
969                Instruction::F64Nearest => {
970                    return Err("no default evaluation for basic instruction yet");
971                }
972                Instruction::F64Sqrt => {
973                    return Err("no default evaluation for basic instruction yet");
974                }
975                Instruction::F64Add => {
976                    return Err("no default evaluation for basic instruction yet");
977                }
978                Instruction::F64Sub => {
979                    return Err("no default evaluation for basic instruction yet");
980                }
981                Instruction::F64Mul => {
982                    return Err("no default evaluation for basic instruction yet");
983                }
984                Instruction::F64Div => {
985                    return Err("no default evaluation for basic instruction yet");
986                }
987                Instruction::F64Min => {
988                    return Err("no default evaluation for basic instruction yet");
989                }
990                Instruction::F64Max => {
991                    return Err("no default evaluation for basic instruction yet");
992                }
993                Instruction::F64Copysign => {
994                    return Err("no default evaluation for basic instruction yet");
995                }
996                Instruction::I32wrapF64 => {
997                    return Err("no default evaluation for basic instruction yet");
998                }
999                Instruction::I32TruncSF32 => {
1000                    return Err("no default evaluation for basic instruction yet");
1001                }
1002                Instruction::I32TruncUF32 => {
1003                    return Err("no default evaluation for basic instruction yet");
1004                }
1005                Instruction::I32TruncSF64 => {
1006                    return Err("no default evaluation for basic instruction yet");
1007                }
1008                Instruction::I32TruncUF64 => {
1009                    return Err("no default evaluation for basic instruction yet");
1010                }
1011                Instruction::I64ExtendSI32 => {
1012                    return Err("no default evaluation for basic instruction yet");
1013                }
1014                Instruction::I64ExtendUI32 => {
1015                    return Err("no default evaluation for basic instruction yet");
1016                }
1017                Instruction::I64TruncSF32 => {
1018                    return Err("no default evaluation for basic instruction yet");
1019                }
1020                Instruction::I64TruncUF32 => {
1021                    return Err("no default evaluation for basic instruction yet");
1022                }
1023                Instruction::I64TruncSF64 => {
1024                    return Err("no default evaluation for basic instruction yet");
1025                }
1026                Instruction::I64TruncUF64 => {
1027                    return Err("no default evaluation for basic instruction yet");
1028                }
1029                Instruction::F32ConvertSI32 => {
1030                    return Err("no default evaluation for basic instruction yet");
1031                }
1032                Instruction::F32ConvertUI32 => {
1033                    return Err("no default evaluation for basic instruction yet");
1034                }
1035                Instruction::F32ConvertSI64 => {
1036                    return Err("no default evaluation for basic instruction yet");
1037                }
1038                Instruction::F32ConvertUI64 => {
1039                    return Err("no default evaluation for basic instruction yet");
1040                }
1041                Instruction::F32DemoteF64 => {
1042                    return Err("no default evaluation for basic instruction yet");
1043                }
1044                Instruction::F64ConvertSI32 => {
1045                    return Err("no default evaluation for basic instruction yet");
1046                }
1047                Instruction::F64ConvertUI32 => {
1048                    return Err("no default evaluation for basic instruction yet");
1049                }
1050                Instruction::F64ConvertSI64 => {
1051                    return Err("no default evaluation for basic instruction yet");
1052                }
1053                Instruction::F64ConvertUI64 => {
1054                    return Err("no default evaluation for basic instruction yet");
1055                }
1056                Instruction::F64PromoteF32 => {
1057                    return Err("no default evaluation for basic instruction yet");
1058                }
1059                Instruction::I32ReinterpretF32 => {
1060                    return Err("no default evaluation for basic instruction yet");
1061                }
1062                Instruction::I64ReinterpretF64 => {
1063                    return Err("no default evaluation for basic instruction yet");
1064                }
1065                Instruction::F32ReinterpretI32 => {
1066                    return Err("no default evaluation for basic instruction yet");
1067                }
1068                Instruction::F64ReinterpretI64 => {
1069                    return Err("no default evaluation for basic instruction yet");
1070                }
1071            },
1072            _ => return Err("no default evaluation"),
1073        };
1074        Ok(response)
1075    }
1076}