mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-04-18 03:00:27 -04:00
Set up frame steps for exceptions
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::super::vs_value::{Val, ValTrait, LoadFunctionResult};
|
||||
use super::super::vs_array::VsArray;
|
||||
use super::super::stack_frame::{StackFrameTrait, FrameStepResult, CallResult};
|
||||
use crate::stack_frame::FrameStepResult;
|
||||
use crate::stack_frame::{CallResult, FrameStepOk, StackFrameTrait};
|
||||
use crate::vs_array::VsArray;
|
||||
use crate::vs_value::{LoadFunctionResult, Val, ValTrait};
|
||||
|
||||
pub trait ArrayMappingState {
|
||||
fn process(&mut self, i: usize, element: &Val, mapped: Val) -> Option<Val>;
|
||||
@@ -42,9 +43,13 @@ impl StackFrameTrait for ArrayMappingFrame {
|
||||
|
||||
fn write_param(&mut self, param: Val) {
|
||||
match self.param_i {
|
||||
0 => { self.mapper = param; }
|
||||
1 => { self.this_arg = param; }
|
||||
_ => {},
|
||||
0 => {
|
||||
self.mapper = param;
|
||||
}
|
||||
1 => {
|
||||
self.this_arg = param;
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
self.param_i += 1;
|
||||
@@ -57,10 +62,10 @@ impl StackFrameTrait for ArrayMappingFrame {
|
||||
};
|
||||
|
||||
for early_exit in &self.early_exit {
|
||||
return FrameStepResult::Pop(CallResult {
|
||||
return Ok(FrameStepOk::Pop(CallResult {
|
||||
return_: early_exit.clone(),
|
||||
this: Val::Array(array_data.clone()),
|
||||
})
|
||||
}));
|
||||
}
|
||||
|
||||
let array_i = self.array_i;
|
||||
@@ -69,12 +74,12 @@ impl StackFrameTrait for ArrayMappingFrame {
|
||||
match array_data.elements.get(array_i) {
|
||||
Some(el) => match el {
|
||||
Val::Void => {
|
||||
return FrameStepResult::Continue;
|
||||
},
|
||||
return Ok(FrameStepOk::Continue);
|
||||
}
|
||||
_ => match self.mapper.load_function() {
|
||||
LoadFunctionResult::NotAFunction =>
|
||||
LoadFunctionResult::NotAFunction => {
|
||||
std::panic!("Not implemented: exception: map fn is not a function")
|
||||
,
|
||||
}
|
||||
LoadFunctionResult::NativeFunction(native_fn) => {
|
||||
return match self.state.process(
|
||||
array_i,
|
||||
@@ -88,28 +93,28 @@ impl StackFrameTrait for ArrayMappingFrame {
|
||||
],
|
||||
),
|
||||
) {
|
||||
None => FrameStepResult::Continue,
|
||||
Some(val) => FrameStepResult::Pop(CallResult {
|
||||
None => Ok(FrameStepOk::Continue),
|
||||
Some(val) => Ok(FrameStepOk::Pop(CallResult {
|
||||
return_: val,
|
||||
this: Val::Array(array_data.clone()),
|
||||
}),
|
||||
})),
|
||||
};
|
||||
},
|
||||
}
|
||||
LoadFunctionResult::StackFrame(mut new_frame) => {
|
||||
new_frame.write_this(self.this_arg.clone());
|
||||
new_frame.write_param(el.clone());
|
||||
new_frame.write_param(Val::Number(array_i as f64));
|
||||
new_frame.write_param(Val::Array(array_data.clone()));
|
||||
return FrameStepResult::Push(new_frame);
|
||||
},
|
||||
return Ok(FrameStepOk::Push(new_frame));
|
||||
}
|
||||
},
|
||||
},
|
||||
None => {
|
||||
return FrameStepResult::Pop(CallResult {
|
||||
return Ok(FrameStepOk::Pop(CallResult {
|
||||
return_: self.state.finish(),
|
||||
this: Val::Array(array_data.clone()),
|
||||
});
|
||||
},
|
||||
}));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::super::vs_value::{Val, ValTrait, LoadFunctionResult};
|
||||
use super::super::vs_array::VsArray;
|
||||
use super::super::native_frame_function::NativeFrameFunction;
|
||||
use super::super::stack_frame::{StackFrameTrait, FrameStepResult, CallResult};
|
||||
use crate::native_frame_function::NativeFrameFunction;
|
||||
use crate::stack_frame::{CallResult, FrameStepOk, FrameStepResult, StackFrameTrait};
|
||||
use crate::vs_array::VsArray;
|
||||
use crate::vs_value::{LoadFunctionResult, Val, ValTrait};
|
||||
|
||||
pub static REDUCE: NativeFrameFunction = NativeFrameFunction {
|
||||
make_frame: || Box::new(ReduceFrame {
|
||||
this: None,
|
||||
array_i: 0,
|
||||
reducer: Val::Void,
|
||||
param_i: 0,
|
||||
value: None,
|
||||
}),
|
||||
make_frame: || {
|
||||
Box::new(ReduceFrame {
|
||||
this: None,
|
||||
array_i: 0,
|
||||
reducer: Val::Void,
|
||||
param_i: 0,
|
||||
value: None,
|
||||
})
|
||||
},
|
||||
};
|
||||
|
||||
struct ReduceFrame {
|
||||
@@ -31,9 +33,13 @@ impl StackFrameTrait for ReduceFrame {
|
||||
|
||||
fn write_param(&mut self, param: Val) {
|
||||
match self.param_i {
|
||||
0 => { self.reducer = param; }
|
||||
1 => { self.value = Some(param); }
|
||||
_ => {},
|
||||
0 => {
|
||||
self.reducer = param;
|
||||
}
|
||||
1 => {
|
||||
self.value = Some(param);
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
self.param_i += 1;
|
||||
@@ -51,17 +57,17 @@ impl StackFrameTrait for ReduceFrame {
|
||||
match array_data.elements.get(array_i) {
|
||||
Some(el) => match el {
|
||||
Val::Void => {
|
||||
return FrameStepResult::Continue;
|
||||
},
|
||||
return Ok(FrameStepOk::Continue);
|
||||
}
|
||||
_ => match &self.value {
|
||||
None => {
|
||||
self.value = Some(el.clone());
|
||||
return FrameStepResult::Continue;
|
||||
},
|
||||
return Ok(FrameStepOk::Continue);
|
||||
}
|
||||
Some(value) => match self.reducer.load_function() {
|
||||
LoadFunctionResult::NotAFunction =>
|
||||
LoadFunctionResult::NotAFunction => {
|
||||
std::panic!("Not implemented: exception: reduce fn is not a function")
|
||||
,
|
||||
}
|
||||
LoadFunctionResult::NativeFunction(native_fn) => {
|
||||
self.value = Some(native_fn(
|
||||
&mut Val::Undefined,
|
||||
@@ -72,29 +78,29 @@ impl StackFrameTrait for ReduceFrame {
|
||||
Val::Array(array_data.clone()),
|
||||
],
|
||||
));
|
||||
|
||||
return FrameStepResult::Continue;
|
||||
},
|
||||
|
||||
return Ok(FrameStepOk::Continue);
|
||||
}
|
||||
LoadFunctionResult::StackFrame(mut new_frame) => {
|
||||
new_frame.write_param(value.clone());
|
||||
new_frame.write_param(el.clone());
|
||||
new_frame.write_param(Val::Number(array_i as f64));
|
||||
new_frame.write_param(Val::Array(array_data.clone()));
|
||||
return FrameStepResult::Push(new_frame);
|
||||
},
|
||||
return Ok(FrameStepOk::Push(new_frame));
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
None => match &self.value {
|
||||
None => {
|
||||
std::panic!("Not implemented: exception: reduce of empty array with no initial value");
|
||||
},
|
||||
}
|
||||
Some(value) => {
|
||||
return FrameStepResult::Pop(CallResult {
|
||||
return Ok(FrameStepOk::Pop(CallResult {
|
||||
return_: value.clone(),
|
||||
this: Val::Array(array_data.clone()),
|
||||
});
|
||||
},
|
||||
}));
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::super::vs_value::{Val, ValTrait, LoadFunctionResult};
|
||||
use super::super::vs_array::VsArray;
|
||||
use super::super::native_frame_function::NativeFrameFunction;
|
||||
use super::super::stack_frame::{StackFrameTrait, FrameStepResult, CallResult};
|
||||
use crate::native_frame_function::NativeFrameFunction;
|
||||
use crate::stack_frame::{CallResult, FrameStepOk, FrameStepResult, StackFrameTrait};
|
||||
use crate::vs_array::VsArray;
|
||||
use crate::vs_value::{LoadFunctionResult, Val, ValTrait};
|
||||
|
||||
pub static REDUCE_RIGHT: NativeFrameFunction = NativeFrameFunction {
|
||||
make_frame: || Box::new(ReduceRightFrame {
|
||||
this: None,
|
||||
array_i: 0,
|
||||
reducer: Val::Void,
|
||||
param_i: 0,
|
||||
value: None,
|
||||
}),
|
||||
make_frame: || {
|
||||
Box::new(ReduceRightFrame {
|
||||
this: None,
|
||||
array_i: 0,
|
||||
reducer: Val::Void,
|
||||
param_i: 0,
|
||||
value: None,
|
||||
})
|
||||
},
|
||||
};
|
||||
|
||||
struct ReduceRightFrame {
|
||||
@@ -29,18 +31,20 @@ impl StackFrameTrait for ReduceRightFrame {
|
||||
self.this = this.as_array_data();
|
||||
|
||||
match &self.this {
|
||||
None => {},
|
||||
Some(ad) => {
|
||||
self.array_i = ad.elements.len()
|
||||
},
|
||||
None => {}
|
||||
Some(ad) => self.array_i = ad.elements.len(),
|
||||
};
|
||||
}
|
||||
|
||||
fn write_param(&mut self, param: Val) {
|
||||
match self.param_i {
|
||||
0 => { self.reducer = param; }
|
||||
1 => { self.value = Some(param); }
|
||||
_ => {},
|
||||
0 => {
|
||||
self.reducer = param;
|
||||
}
|
||||
1 => {
|
||||
self.value = Some(param);
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
self.param_i += 1;
|
||||
@@ -55,14 +59,16 @@ impl StackFrameTrait for ReduceRightFrame {
|
||||
if self.array_i == 0 {
|
||||
match &self.value {
|
||||
None => {
|
||||
std::panic!("Not implemented: exception: reduceRight of empty array with no initial value");
|
||||
},
|
||||
std::panic!(
|
||||
"Not implemented: exception: reduceRight of empty array with no initial value"
|
||||
);
|
||||
}
|
||||
Some(value) => {
|
||||
return FrameStepResult::Pop(CallResult {
|
||||
return Ok(FrameStepOk::Pop(CallResult {
|
||||
return_: value.clone(),
|
||||
this: Val::Array(array_data.clone()),
|
||||
});
|
||||
},
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,17 +79,17 @@ impl StackFrameTrait for ReduceRightFrame {
|
||||
|
||||
match el {
|
||||
Val::Void => {
|
||||
return FrameStepResult::Continue;
|
||||
},
|
||||
return Ok(FrameStepOk::Continue);
|
||||
}
|
||||
_ => match &self.value {
|
||||
None => {
|
||||
self.value = Some(el.clone());
|
||||
return FrameStepResult::Continue;
|
||||
},
|
||||
return Ok(FrameStepOk::Continue);
|
||||
}
|
||||
Some(value) => match self.reducer.load_function() {
|
||||
LoadFunctionResult::NotAFunction =>
|
||||
LoadFunctionResult::NotAFunction => {
|
||||
std::panic!("Not implemented: exception: reduceRight fn is not a function")
|
||||
,
|
||||
}
|
||||
LoadFunctionResult::NativeFunction(native_fn) => {
|
||||
self.value = Some(native_fn(
|
||||
&mut Val::Undefined,
|
||||
@@ -94,16 +100,16 @@ impl StackFrameTrait for ReduceRightFrame {
|
||||
Val::Array(array_data.clone()),
|
||||
],
|
||||
));
|
||||
|
||||
return FrameStepResult::Continue;
|
||||
},
|
||||
|
||||
return Ok(FrameStepOk::Continue);
|
||||
}
|
||||
LoadFunctionResult::StackFrame(mut new_frame) => {
|
||||
new_frame.write_param(value.clone());
|
||||
new_frame.write_param(el.clone());
|
||||
new_frame.write_param(Val::Number(array_i as f64));
|
||||
new_frame.write_param(Val::Array(array_data.clone()));
|
||||
return FrameStepResult::Push(new_frame);
|
||||
},
|
||||
return Ok(FrameStepOk::Push(new_frame));
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::super::vs_value::{Val, ValTrait, LoadFunctionResult};
|
||||
use super::super::vs_array::VsArray;
|
||||
use super::super::native_frame_function::NativeFrameFunction;
|
||||
use super::super::stack_frame::{StackFrameTrait, FrameStepResult, CallResult};
|
||||
use crate::native_frame_function::NativeFrameFunction;
|
||||
use crate::stack_frame::FrameStepResult;
|
||||
use crate::stack_frame::{CallResult, FrameStepOk, StackFrameTrait};
|
||||
use crate::vs_array::VsArray;
|
||||
use crate::vs_value::{LoadFunctionResult, Val, ValTrait};
|
||||
|
||||
pub static SORT: NativeFrameFunction = NativeFrameFunction {
|
||||
make_frame: || Box::new(SortFrame {
|
||||
this: None,
|
||||
comparator: Val::Void,
|
||||
param_i: 0,
|
||||
tree: SortTreeNode { data: SortTreeNodeData::Sorted(vec![]) },
|
||||
started: false,
|
||||
}),
|
||||
make_frame: || {
|
||||
Box::new(SortFrame {
|
||||
this: None,
|
||||
comparator: Val::Void,
|
||||
param_i: 0,
|
||||
tree: SortTreeNode {
|
||||
data: SortTreeNodeData::Sorted(vec![]),
|
||||
},
|
||||
started: false,
|
||||
})
|
||||
},
|
||||
};
|
||||
|
||||
struct SortFrame {
|
||||
@@ -46,14 +51,16 @@ impl SortTreeNode {
|
||||
|
||||
if len <= 1 {
|
||||
let mut sorted = vec![];
|
||||
|
||||
|
||||
for i in vals.start..vals.end {
|
||||
sorted.push(vals.vec[i].clone());
|
||||
}
|
||||
|
||||
return SortTreeNode { data: SortTreeNodeData::Sorted(sorted) };
|
||||
|
||||
return SortTreeNode {
|
||||
data: SortTreeNodeData::Sorted(sorted),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
if len == 2 {
|
||||
return SortTreeNode {
|
||||
data: SortTreeNodeData::Sorting(
|
||||
@@ -69,9 +76,9 @@ impl SortTreeNode {
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
let mid = vals.start + (vals.end - vals.start) / 2;
|
||||
|
||||
|
||||
return SortTreeNode {
|
||||
data: SortTreeNodeData::Branch(
|
||||
Box::new(SortTreeNode::new(VecSlice {
|
||||
@@ -91,9 +98,10 @@ impl SortTreeNode {
|
||||
fn get_compare_elements(&self) -> Option<(Val, Val)> {
|
||||
match &self.data {
|
||||
SortTreeNodeData::Branch(left, right) => {
|
||||
return left.get_compare_elements()
|
||||
return left
|
||||
.get_compare_elements()
|
||||
.or_else(|| right.get_compare_elements());
|
||||
},
|
||||
}
|
||||
SortTreeNodeData::Sorting(_vals, left, right) => {
|
||||
let lval_opt = left.vec.get(left.pos);
|
||||
let rval_opt = right.vec.get(right.pos);
|
||||
@@ -101,15 +109,15 @@ impl SortTreeNode {
|
||||
match (lval_opt, rval_opt) {
|
||||
(Some(lval), Some(rval)) => {
|
||||
return Some((lval.clone(), rval.clone()));
|
||||
},
|
||||
}
|
||||
_ => {
|
||||
std::panic!("Failed to get compare elements from sorting state");
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
SortTreeNodeData::Sorted(_) => {
|
||||
return None;
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -119,10 +127,10 @@ impl SortTreeNode {
|
||||
match &mut left.data {
|
||||
SortTreeNodeData::Branch(_, _) | SortTreeNodeData::Sorting(_, _, _) => {
|
||||
left.apply_outcome(should_swap);
|
||||
},
|
||||
}
|
||||
SortTreeNodeData::Sorted(left_vals) => {
|
||||
right.apply_outcome(should_swap);
|
||||
|
||||
|
||||
match &mut right.data {
|
||||
SortTreeNodeData::Sorted(right_vals) => {
|
||||
let mut owned_left_vals = vec![];
|
||||
@@ -132,19 +140,25 @@ impl SortTreeNode {
|
||||
|
||||
self.data = SortTreeNodeData::Sorting(
|
||||
vec![],
|
||||
VecPos { vec: owned_left_vals, pos: 0 },
|
||||
VecPos { vec: owned_right_vals, pos: 0 },
|
||||
VecPos {
|
||||
vec: owned_left_vals,
|
||||
pos: 0,
|
||||
},
|
||||
VecPos {
|
||||
vec: owned_right_vals,
|
||||
pos: 0,
|
||||
},
|
||||
);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
};
|
||||
},
|
||||
}
|
||||
|
||||
SortTreeNodeData::Sorted(_) => {
|
||||
std::panic!("Failed to apply outcome");
|
||||
},
|
||||
}
|
||||
|
||||
SortTreeNodeData::Sorting(vals, left, right) => {
|
||||
let lval_opt = left.vec.get(left.pos);
|
||||
@@ -155,11 +169,11 @@ impl SortTreeNode {
|
||||
false => {
|
||||
vals.push(lval.clone());
|
||||
left.pos += 1;
|
||||
},
|
||||
}
|
||||
true => {
|
||||
vals.push(rval.clone());
|
||||
right.pos += 1;
|
||||
},
|
||||
}
|
||||
},
|
||||
_ => std::panic!("Failed to apply outcome"),
|
||||
};
|
||||
@@ -178,7 +192,7 @@ impl SortTreeNode {
|
||||
|
||||
self.data = SortTreeNodeData::Sorted(owned_vals);
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -196,8 +210,10 @@ impl StackFrameTrait for SortFrame {
|
||||
|
||||
fn write_param(&mut self, param: Val) {
|
||||
match self.param_i {
|
||||
0 => { self.comparator = param; },
|
||||
_ => {},
|
||||
0 => {
|
||||
self.comparator = param;
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
self.param_i += 1;
|
||||
@@ -214,15 +230,15 @@ impl StackFrameTrait for SortFrame {
|
||||
Val::Void => {
|
||||
let array_data_mut = Rc::make_mut(array_data);
|
||||
|
||||
array_data_mut.elements.sort_by(|a, b|
|
||||
a.val_to_string().cmp(&b.val_to_string())
|
||||
);
|
||||
array_data_mut
|
||||
.elements
|
||||
.sort_by(|a, b| a.val_to_string().cmp(&b.val_to_string()));
|
||||
|
||||
return FrameStepResult::Pop(CallResult {
|
||||
return Ok(FrameStepOk::Pop(CallResult {
|
||||
return_: Val::Array(array_data.clone()),
|
||||
this: Val::Array(array_data.clone()),
|
||||
});
|
||||
},
|
||||
}));
|
||||
}
|
||||
_ => {
|
||||
self.tree = SortTreeNode::new(VecSlice {
|
||||
vec: &array_data.elements,
|
||||
@@ -231,7 +247,7 @@ impl StackFrameTrait for SortFrame {
|
||||
});
|
||||
|
||||
self.started = true;
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -242,17 +258,17 @@ impl StackFrameTrait for SortFrame {
|
||||
std::mem::swap(&mut owned_vals, vals);
|
||||
let res = Val::Array(Rc::new(VsArray::from(owned_vals)));
|
||||
|
||||
return FrameStepResult::Pop(CallResult {
|
||||
return Ok(FrameStepOk::Pop(CallResult {
|
||||
return_: res.clone(),
|
||||
this: res,
|
||||
});
|
||||
},
|
||||
}));
|
||||
}
|
||||
_ => std::panic!("This shouldn't happen"),
|
||||
},
|
||||
Some((left, right)) => match self.comparator.load_function() {
|
||||
LoadFunctionResult::NotAFunction => {
|
||||
std::panic!("Not implemented: exception: comparator is not a function");
|
||||
},
|
||||
}
|
||||
LoadFunctionResult::NativeFunction(native_fn) => {
|
||||
let res = native_fn(&mut Val::Undefined, vec![left, right]).to_number();
|
||||
|
||||
@@ -262,13 +278,13 @@ impl StackFrameTrait for SortFrame {
|
||||
};
|
||||
|
||||
self.tree.apply_outcome(should_swap);
|
||||
return FrameStepResult::Continue;
|
||||
},
|
||||
return Ok(FrameStepOk::Continue);
|
||||
}
|
||||
LoadFunctionResult::StackFrame(mut new_frame) => {
|
||||
new_frame.write_param(left);
|
||||
new_frame.write_param(right);
|
||||
return FrameStepResult::Push(new_frame);
|
||||
},
|
||||
return Ok(FrameStepOk::Push(new_frame));
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::bytecode_decoder::BytecodeDecoder;
|
||||
use super::bytecode_decoder::BytecodeType;
|
||||
use super::instruction::Instruction;
|
||||
use super::operations;
|
||||
use super::stack_frame::{CallResult, FrameStepResult, StackFrame, StackFrameTrait};
|
||||
use super::vs_object::VsObject;
|
||||
use super::vs_value::{LoadFunctionResult, Val, ValTrait};
|
||||
use crate::bytecode_decoder::BytecodeDecoder;
|
||||
use crate::bytecode_decoder::BytecodeType;
|
||||
use crate::instruction::Instruction;
|
||||
use crate::operations;
|
||||
use crate::stack_frame::FrameStepOk;
|
||||
use crate::stack_frame::FrameStepResult;
|
||||
use crate::stack_frame::{CallResult, StackFrame, StackFrameTrait};
|
||||
use crate::vs_object::VsObject;
|
||||
use crate::vs_value::{LoadFunctionResult, Val, ValTrait};
|
||||
|
||||
pub struct BytecodeStackFrame {
|
||||
pub decoder: BytecodeDecoder,
|
||||
@@ -90,10 +92,10 @@ impl StackFrameTrait for BytecodeStackFrame {
|
||||
|
||||
match self.decoder.decode_instruction() {
|
||||
End => {
|
||||
return FrameStepResult::Pop(CallResult {
|
||||
return Ok(FrameStepOk::Pop(CallResult {
|
||||
return_: self.registers[0].clone(),
|
||||
this: self.registers[1].clone(),
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Mov => {
|
||||
@@ -168,7 +170,7 @@ impl StackFrameTrait for BytecodeStackFrame {
|
||||
self.return_target = self.decoder.decode_register_index();
|
||||
self.this_target = None;
|
||||
|
||||
return FrameStepResult::Push(new_frame);
|
||||
return Ok(FrameStepOk::Push(new_frame));
|
||||
}
|
||||
LoadFunctionResult::NativeFunction(native_fn) => {
|
||||
let res = native_fn(&mut Val::Undefined, self.decode_parameters());
|
||||
@@ -208,7 +210,7 @@ impl StackFrameTrait for BytecodeStackFrame {
|
||||
|
||||
self.return_target = self.decoder.decode_register_index();
|
||||
|
||||
return FrameStepResult::Push(new_frame);
|
||||
return Ok(FrameStepOk::Push(new_frame));
|
||||
}
|
||||
LoadFunctionResult::NativeFunction(_native_fn) => {
|
||||
std::panic!("Not implemented");
|
||||
@@ -294,7 +296,7 @@ impl StackFrameTrait for BytecodeStackFrame {
|
||||
ThisArg::Val(_) => None,
|
||||
};
|
||||
|
||||
return FrameStepResult::Push(new_frame);
|
||||
return Ok(FrameStepOk::Push(new_frame));
|
||||
}
|
||||
LoadFunctionResult::NativeFunction(native_fn) => {
|
||||
let params = self.decode_parameters();
|
||||
@@ -369,7 +371,7 @@ impl StackFrameTrait for BytecodeStackFrame {
|
||||
self.return_target = None;
|
||||
self.this_target = self.decoder.decode_register_index();
|
||||
|
||||
return FrameStepResult::Push(new_frame);
|
||||
return Ok(FrameStepOk::Push(new_frame));
|
||||
}
|
||||
LoadFunctionResult::NativeFunction(native_fn) => {
|
||||
native_fn(&mut instance, self.decode_parameters());
|
||||
@@ -386,7 +388,7 @@ impl StackFrameTrait for BytecodeStackFrame {
|
||||
}
|
||||
};
|
||||
|
||||
return FrameStepResult::Continue;
|
||||
return Ok(FrameStepOk::Continue);
|
||||
}
|
||||
|
||||
fn apply_call_result(&mut self, call_result: CallResult) {
|
||||
|
||||
@@ -8,12 +8,14 @@ pub struct CallResult {
|
||||
pub this: Val,
|
||||
}
|
||||
|
||||
pub enum FrameStepResult {
|
||||
pub enum FrameStepOk {
|
||||
Continue,
|
||||
Pop(CallResult),
|
||||
Push(StackFrame),
|
||||
}
|
||||
|
||||
pub type FrameStepResult = Result<FrameStepOk, Val>;
|
||||
|
||||
pub trait StackFrameTrait {
|
||||
fn write_this(&mut self, this: Val);
|
||||
fn write_param(&mut self, param: Val);
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::bytecode_decoder::BytecodeDecoder;
|
||||
use super::first_stack_frame::FirstStackFrame;
|
||||
use super::stack_frame::{FrameStepResult, StackFrame};
|
||||
use super::vs_value::{LoadFunctionResult, Val, ValTrait};
|
||||
use crate::bytecode_decoder::BytecodeDecoder;
|
||||
use crate::first_stack_frame::FirstStackFrame;
|
||||
use crate::stack_frame::FrameStepOk;
|
||||
use crate::stack_frame::StackFrame;
|
||||
use crate::vs_value::{LoadFunctionResult, Val, ValTrait};
|
||||
|
||||
pub struct VirtualMachine {
|
||||
pub frame: StackFrame,
|
||||
@@ -11,7 +12,7 @@ pub struct VirtualMachine {
|
||||
}
|
||||
|
||||
impl VirtualMachine {
|
||||
pub fn run(&mut self, bytecode: &Rc<Vec<u8>>, params: &[String]) -> Val {
|
||||
pub fn run(&mut self, bytecode: &Rc<Vec<u8>>, params: &[String]) -> Result<Val, Val> {
|
||||
let mut bd = BytecodeDecoder {
|
||||
data: bytecode.clone(),
|
||||
pos: 0,
|
||||
@@ -31,10 +32,10 @@ impl VirtualMachine {
|
||||
self.push(frame);
|
||||
|
||||
while self.stack.len() > 0 {
|
||||
self.step();
|
||||
self.step()?;
|
||||
}
|
||||
|
||||
return self.frame.get_call_result().return_;
|
||||
return Ok(self.frame.get_call_result().return_);
|
||||
}
|
||||
|
||||
pub fn new() -> VirtualMachine {
|
||||
@@ -48,17 +49,19 @@ impl VirtualMachine {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn step(&mut self) {
|
||||
match self.frame.step() {
|
||||
FrameStepResult::Continue => {}
|
||||
FrameStepResult::Pop(call_result) => {
|
||||
pub fn step(&mut self) -> Result<(), Val> {
|
||||
match self.frame.step()? {
|
||||
FrameStepOk::Continue => {}
|
||||
FrameStepOk::Pop(call_result) => {
|
||||
self.pop();
|
||||
self.frame.apply_call_result(call_result);
|
||||
}
|
||||
FrameStepResult::Push(new_frame) => {
|
||||
FrameStepOk::Push(new_frame) => {
|
||||
self.push(new_frame);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn push(&mut self, mut frame: StackFrame) {
|
||||
|
||||
Reference in New Issue
Block a user