Simplify vm.run

This commit is contained in:
Andrew Morris
2023-11-02 11:36:25 +11:00
parent a5e76355f7
commit 32358b2dd6
9 changed files with 132 additions and 68 deletions

View File

@@ -2,12 +2,15 @@ use std::{
collections::HashMap, collections::HashMap,
fmt::Write, fmt::Write,
hash::{Hash as HashTrait, Hasher}, hash::{Hash as HashTrait, Hasher},
rc::Rc,
}; };
use num_bigint::BigInt; use num_bigint::BigInt;
use valuescript_vm::{vs_value::Val, Bytecode, DecoderMaker};
use crate::{ use crate::{
assembler::ValueType, expression_compiler::CompiledExpression, instruction::RegisterVisitMut, assemble, assembler::ValueType, expression_compiler::CompiledExpression,
instruction::RegisterVisitMut, parse_module,
}; };
pub use crate::instruction::{Instruction, InstructionFieldMut}; pub use crate::instruction::{Instruction, InstructionFieldMut};
@@ -329,6 +332,14 @@ pub struct Pointer {
pub name: String, pub name: String,
} }
impl From<&str> for Pointer {
fn from(name: &str) -> Self {
Pointer {
name: name.to_string(),
}
}
}
impl StructuredFormattable for Pointer { impl StructuredFormattable for Pointer {
fn structured_fmt(&self, sf: &mut StructuredFormatter<'_, '_>) -> std::fmt::Result { fn structured_fmt(&self, sf: &mut StructuredFormatter<'_, '_>) -> std::fmt::Result {
sf.write("@")?; sf.write("@")?;
@@ -854,3 +865,9 @@ impl Object {
result result
} }
} }
pub fn inline(source: &str) -> Val {
let bytecode = Rc::new(Bytecode::new(assemble(&parse_module(source))));
bytecode.decoder(0).decode_val(&mut vec![])
}

View File

@@ -27,3 +27,21 @@ where
result result
} }
pub fn compile_str(source: &str) -> CompileResult {
compile(
ResolvedPath {
path: "(str)".into(),
},
|path| {
if path == "(str)" {
Ok(source.into())
} else {
Err(format!(
"Unknown path {} (no filesystem access for compile_str)",
path
))
}
},
)
}

View File

@@ -24,8 +24,8 @@ mod visit_pointers;
pub use assembler::assemble; pub use assembler::assemble;
pub use assembly_parser::parse_module; pub use assembly_parser::parse_module;
pub use compile::compile;
pub use compile::CompileResult; pub use compile::CompileResult;
pub use compile::{compile, compile_str};
pub use diagnostic::Diagnostic; pub use diagnostic::Diagnostic;
pub use diagnostic::DiagnosticLevel; pub use diagnostic::DiagnosticLevel;
pub use gather_modules::gather_modules; pub use gather_modules::gather_modules;

View File

@@ -1,11 +1,9 @@
use std::{process::exit, rc::Rc}; use std::{process::exit, rc::Rc};
use valuescript_vm::{Bytecode, VirtualMachine}; use valuescript_vm::{vs_value::Val, Bytecode, DecoderMaker, VirtualMachine};
pub fn main() { pub fn main() {
let mut vm = VirtualMachine::default(); let bytecode = Rc::new(Bytecode::new(vec![
let result = vm.run(
Rc::new(Bytecode::new(vec![
// //
// This is the compiled bytecode for inputs/passing/projEuler/p28.ts. // This is the compiled bytecode for inputs/passing/projEuler/p28.ts.
// //
@@ -26,29 +24,34 @@ pub fn main() {
// cargo build // cargo build
// ./target/debug/valuescript_program_embed // ./target/debug/valuescript_program_embed
// //
0x0d, 0x05, 0x00, 0x0a, 0x00, 0x0b, 0x08, 0x00, 0x21, 0x0d, 0x9c, 0x00, 0x09, 0x09, 0x06, 0x0d, 0x05, 0x00, 0x0a, 0x00, 0x0b, 0x08, 0x00, 0x21, 0x0d, 0x9c, 0x00, 0x09, 0x09, 0x06, 0x01,
0x01, 0x06, 0x09, 0x06, 0x19, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x7f, 0x40, 0x06, 0x09, 0x06, 0x19, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x7f, 0x40, 0x00, 0x02,
0x00, 0x02, 0x05, 0x0e, 0x02, 0x06, 0x01, 0x03, 0x21, 0x0d, 0x9c, 0x00, 0x09, 0x09, 0x06, 0x05, 0x0e, 0x02, 0x06, 0x01, 0x03, 0x21, 0x0d, 0x9c, 0x00, 0x09, 0x09, 0x06, 0x01, 0x06, 0x03,
0x01, 0x06, 0x03, 0x06, 0x0d, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x7f, 0x40, 0x06, 0x0d, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x7f, 0x40, 0x00, 0x02, 0x05, 0x0e,
0x00, 0x02, 0x05, 0x0e, 0x02, 0x06, 0x01, 0x04, 0x21, 0x0d, 0x9c, 0x00, 0x09, 0x09, 0x06, 0x02, 0x06, 0x01, 0x04, 0x21, 0x0d, 0x9c, 0x00, 0x09, 0x09, 0x06, 0x01, 0x06, 0x05, 0x06, 0x11,
0x01, 0x06, 0x05, 0x06, 0x11, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x7f, 0x40, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x7f, 0x40, 0x00, 0x02, 0x05, 0x0e, 0x02, 0x06,
0x00, 0x02, 0x05, 0x0e, 0x02, 0x06, 0x01, 0x05, 0x21, 0x0d, 0x9c, 0x00, 0x09, 0x09, 0x06, 0x01, 0x05, 0x21, 0x0d, 0x9c, 0x00, 0x09, 0x09, 0x06, 0x01, 0x06, 0x07, 0x06, 0x15, 0x00, 0x07,
0x01, 0x06, 0x07, 0x06, 0x15, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x7f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x7f, 0x40, 0x00, 0x02, 0x05, 0x0e, 0x02, 0x06, 0x01, 0x06,
0x00, 0x02, 0x05, 0x0e, 0x02, 0x06, 0x01, 0x06, 0x26, 0x09, 0x06, 0x01, 0x0e, 0x03, 0x0e, 0x26, 0x09, 0x06, 0x01, 0x0e, 0x03, 0x0e, 0x04, 0x0e, 0x05, 0x0e, 0x06, 0x00, 0x08, 0x06, 0x72,
0x04, 0x0e, 0x05, 0x0e, 0x06, 0x00, 0x08, 0x06, 0x72, 0x65, 0x64, 0x75, 0x63, 0x65, 0x09, 0x65, 0x64, 0x75, 0x63, 0x65, 0x09, 0x0d, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x08, 0x02, 0x26,
0x0d, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x08, 0x02, 0x26, 0x0e, 0x02, 0x08, 0x06, 0x72, 0x0e, 0x02, 0x08, 0x06, 0x72, 0x65, 0x64, 0x75, 0x63, 0x65, 0x09, 0x0d, 0x1e, 0x01, 0x00, 0x04,
0x65, 0x64, 0x75, 0x63, 0x65, 0x09, 0x0d, 0x1e, 0x01, 0x00, 0x04, 0x01, 0x06, 0x03, 0x05, 0x01, 0x06, 0x03, 0x05, 0x11, 0x0e, 0x05, 0x0e, 0x03, 0x06, 0x10, 0x0e, 0x06, 0x06, 0x28, 0x0e,
0x11, 0x0e, 0x05, 0x0e, 0x03, 0x06, 0x10, 0x0e, 0x06, 0x06, 0x28, 0x0e, 0x06, 0xe1, 0x00, 0x06, 0xe1, 0x00, 0x21, 0x0d, 0xe6, 0x00, 0x09, 0x0e, 0x02, 0x00, 0x02, 0x24, 0x0e, 0x02, 0x06,
0x21, 0x0d, 0xe6, 0x00, 0x09, 0x0e, 0x02, 0x00, 0x02, 0x24, 0x0e, 0x02, 0x06, 0x02, 0x06, 0x02, 0x06, 0x04, 0x0e, 0x04, 0x0e, 0x06, 0x04, 0x01, 0x0e, 0x05, 0x06, 0x02, 0x05, 0x27, 0xb4,
0x04, 0x0e, 0x04, 0x0e, 0x06, 0x04, 0x01, 0x0e, 0x05, 0x06, 0x02, 0x05, 0x27, 0xb4, 0x00, 0x00, 0x01, 0x0e, 0x04, 0x00, 0x00, 0x0b, 0x09, 0x01, 0x24, 0x0e, 0x02, 0x06, 0x00, 0x03, 0x24,
0x01, 0x0e, 0x04, 0x00, 0x00, 0x0b, 0x09, 0x01, 0x24, 0x0e, 0x02, 0x06, 0x00, 0x03, 0x24, 0x0e, 0x02, 0x06, 0x01, 0x04, 0x24, 0x0e, 0x02, 0x06, 0x02, 0x05, 0x06, 0x06, 0x03, 0x0e, 0x05,
0x0e, 0x02, 0x06, 0x01, 0x04, 0x24, 0x0e, 0x02, 0x06, 0x02, 0x05, 0x06, 0x06, 0x03, 0x0e, 0x02, 0x06, 0x06, 0x03, 0x0e, 0x04, 0x06, 0x05, 0x0e, 0x02, 0x0e, 0x06, 0x07, 0x04, 0x0e, 0x07,
0x05, 0x02, 0x06, 0x06, 0x03, 0x0e, 0x04, 0x06, 0x05, 0x0e, 0x02, 0x0e, 0x06, 0x07, 0x04, 0x0e, 0x03, 0x06, 0x01, 0x09, 0x0e, 0x04, 0x0e, 0x05, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x0b, 0x05,
0x0e, 0x07, 0x0e, 0x03, 0x06, 0x01, 0x09, 0x0e, 0x04, 0x0e, 0x05, 0x0e, 0x06, 0x00, 0x00, 0x02, 0x04, 0x0e, 0x02, 0x0e, 0x03, 0x00, 0x00,
0x00, 0x0b, 0x05, 0x02, 0x04, 0x0e, 0x02, 0x0e, 0x03, 0x00, 0x00, ]));
])),
let mut vm = VirtualMachine::default();
let result = vm.run(
None, None,
&[], &mut Val::Undefined,
bytecode.decoder(0).decode_val(&mut vec![]),
vec![],
); );
match result { match result {

View File

@@ -29,7 +29,7 @@ mod vs_storage_ptr;
mod vs_symbol; mod vs_symbol;
pub mod vs_value; pub mod vs_value;
pub use bytecode::Bytecode; pub use bytecode::{Bytecode, DecoderMaker};
pub use string_methods::unicode_at; pub use string_methods::unicode_at;
pub use virtual_machine::VirtualMachine; pub use virtual_machine::VirtualMachine;
pub use vs_symbol::VsSymbol; pub use vs_symbol::VsSymbol;

View File

@@ -1,9 +1,11 @@
use std::mem::take;
use std::rc::Rc; use std::rc::Rc;
use crate::builtins::internal_error_builtin::ToInternalError; use crate::builtins::internal_error_builtin::ToInternalError;
use crate::bytecode::Bytecode; use crate::bytecode::Bytecode;
use crate::bytecode::DecoderMaker; use crate::bytecode::DecoderMaker;
use crate::first_stack_frame::FirstStackFrame; use crate::first_stack_frame::FirstStackFrame;
use crate::stack_frame::CallResult;
use crate::stack_frame::FrameStepOk; use crate::stack_frame::FrameStepOk;
use crate::stack_frame::StackFrame; use crate::stack_frame::StackFrame;
use crate::vs_value::{LoadFunctionResult, Val, ValTrait}; use crate::vs_value::{LoadFunctionResult, Val, ValTrait};
@@ -25,27 +27,26 @@ impl Default for VirtualMachine {
impl VirtualMachine { impl VirtualMachine {
pub fn run( pub fn run(
&mut self, &mut self,
bytecode: Rc<Bytecode>,
step_limit: Option<usize>, step_limit: Option<usize>,
params: &[Val], this: &mut Val,
fn_: Val,
args: Vec<Val>,
) -> Result<Val, Val> { ) -> Result<Val, Val> {
let mut bd = bytecode.decoder(0); let mut frame = match fn_.load_function() {
let main_fn = bd.decode_val(&mut Vec::new());
let mut frame = match main_fn.load_function() {
LoadFunctionResult::StackFrame(f) => f, LoadFunctionResult::StackFrame(f) => f,
_ => return Err("bytecode does start with function".to_internal_error()), _ => return Err("bytecode does start with function".to_internal_error()),
}; };
for p in params { frame.write_param(take(this));
frame.write_param(p.clone());
for a in args {
frame.write_param(a);
} }
self.push(frame); self.push(frame);
match step_limit { let res = match step_limit {
Some(step_limit) => { Some(step_limit) => 'b: {
let mut step_count = 0; let mut step_count = 0;
while step_count < step_limit { while step_count < step_limit {
@@ -53,20 +54,29 @@ impl VirtualMachine {
step_count += 1; step_count += 1;
if self.stack.is_empty() { if self.stack.is_empty() {
return Ok(self.frame.get_call_result().return_); break 'b self.frame.get_call_result();
} }
} }
Err("step limit reached".to_internal_error()) return Err("step limit reached".to_internal_error());
} }
None => { None => {
while !self.stack.is_empty() { while !self.stack.is_empty() {
self.step()?; self.step()?;
} }
Ok(self.frame.get_call_result().return_) self.frame.get_call_result()
}
} }
};
let CallResult {
return_,
this: updated_this,
} = res;
*this = updated_this;
Ok(return_)
} }
pub fn step(&mut self) -> Result<(), Val> { pub fn step(&mut self) -> Result<(), Val> {

View File

@@ -8,7 +8,7 @@ use valuescript_compiler::{
}; };
use valuescript_vm::{ use valuescript_vm::{
vs_value::{ToVal, Val}, vs_value::{ToVal, Val},
Bytecode, LoadFunctionResult, ValTrait, VirtualMachine, Bytecode, DecoderMaker, LoadFunctionResult, ValTrait, VirtualMachine,
}; };
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
@@ -130,7 +130,12 @@ fn run_to_result(entry_point: &str, read_file: &js_sys::Function, args: &str) ->
} }
}; };
let vm_result = vm.run(bytecode, None, &val_args); let vm_result = vm.run(
None,
&mut Val::Undefined,
bytecode.decoder(0).decode_val(&mut vec![]),
val_args,
);
RunResult { RunResult {
diagnostics: HashMap::default(), diagnostics: HashMap::default(),

View File

@@ -1,8 +1,8 @@
use std::process::exit; use std::process::exit;
use std::rc::Rc; use std::rc::Rc;
use valuescript_vm::vs_value::Val;
use valuescript_vm::VirtualMachine; use valuescript_vm::VirtualMachine;
use valuescript_vm::{vs_value::Val, DecoderMaker};
use crate::to_bytecode::{format_from_path, to_bytecode, RunFormat}; use crate::to_bytecode::{format_from_path, to_bytecode, RunFormat};
@@ -41,7 +41,12 @@ pub fn run_command(args: &Vec<String>) {
.map(|a| Val::String(Rc::from(a.clone()))) .map(|a| Val::String(Rc::from(a.clone())))
.collect(); .collect();
match vm.run(bytecode, None, &val_args) { match vm.run(
None,
&mut Val::Undefined,
bytecode.decoder(0).decode_val(&mut vec![]),
val_args,
) {
Ok(Val::Undefined) => {} Ok(Val::Undefined) => {}
Ok(result) => { Ok(result) => {
println!("{}", result.pretty()); println!("{}", result.pretty());

View File

@@ -9,8 +9,9 @@ mod tests {
use valuescript_compiler::asm::Structured; use valuescript_compiler::asm::Structured;
use valuescript_compiler::compile; use valuescript_compiler::compile;
use valuescript_compiler::{assemble, parse_module}; use valuescript_compiler::{assemble, parse_module};
use valuescript_vm::VirtualMachine; use valuescript_vm::vs_value::Val;
use valuescript_vm::{Bytecode, ValTrait}; use valuescript_vm::{Bytecode, ValTrait};
use valuescript_vm::{DecoderMaker, VirtualMachine};
use crate::handle_diagnostics_cli::handle_diagnostics_cli; use crate::handle_diagnostics_cli::handle_diagnostics_cli;
use crate::resolve_entry_path::resolve_entry_path; use crate::resolve_entry_path::resolve_entry_path;
@@ -111,7 +112,12 @@ mod tests {
let mut vm = VirtualMachine::default(); let mut vm = VirtualMachine::default();
let result = vm.run(bytecode, Some(2_000_000), &[]); let result = vm.run(
Some(2_000_000),
&mut Val::Undefined,
bytecode.decoder(0).decode_val(&mut vec![]),
vec![],
);
let result_string = match result { let result_string = match result {
Ok(val) => val.codify(), Ok(val) => val.codify(),