mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-01-10 14:08:09 -05:00
Replace VsPointer with cached decoding
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
rc::Rc,
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
@@ -13,7 +12,7 @@ use crate::asm::{
|
||||
Label, LabelRef, Lazy, Module, Object, Pointer, Register, Value,
|
||||
};
|
||||
|
||||
pub fn assemble(module: &Module) -> Rc<Vec<u8>> {
|
||||
pub fn assemble(module: &Module) -> Vec<u8> {
|
||||
let mut assembler = Assembler {
|
||||
output: Vec::new(),
|
||||
fn_data: Default::default(),
|
||||
@@ -25,8 +24,7 @@ pub fn assemble(module: &Module) -> Rc<Vec<u8>> {
|
||||
|
||||
assembler.module(module);
|
||||
|
||||
// TODO: Don't use Rc
|
||||
return Rc::new(assembler.output);
|
||||
assembler.output
|
||||
}
|
||||
|
||||
struct Assembler {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use std::{process::exit, rc::Rc};
|
||||
|
||||
use valuescript_vm::VirtualMachine;
|
||||
use valuescript_vm::{Bytecode, VirtualMachine};
|
||||
|
||||
pub fn main() {
|
||||
let mut vm = VirtualMachine::new();
|
||||
let result = vm.run(
|
||||
&Rc::new(vec![
|
||||
Rc::new(Bytecode::new(vec![
|
||||
//
|
||||
// This is the compiled bytecode for inputs/passing/projEuler/p28.ts.
|
||||
//
|
||||
@@ -46,7 +46,7 @@ pub fn main() {
|
||||
0x05, 0x02, 0x06, 0x06, 0x03, 0x0e, 0x04, 0x06, 0x05, 0x0e, 0x02, 0x0e, 0x06, 0x07, 0x04,
|
||||
0x0e, 0x07, 0x0e, 0x03, 0x06, 0x01, 0x09, 0x0e, 0x04, 0x0e, 0x05, 0x0e, 0x06, 0x00, 0x00,
|
||||
0x00, 0x0b, 0x05, 0x02, 0x04, 0x0e, 0x02, 0x0e, 0x03, 0x00, 0x00,
|
||||
]),
|
||||
])),
|
||||
None,
|
||||
&[],
|
||||
);
|
||||
|
||||
44
valuescript_vm/src/bytecode.rs
Normal file
44
valuescript_vm/src/bytecode.rs
Normal file
@@ -0,0 +1,44 @@
|
||||
use std::{cell::RefCell, collections::HashMap, fmt, ops::Index, rc::Rc, slice::SliceIndex};
|
||||
|
||||
use crate::{bytecode_decoder::BytecodeDecoder, vs_value::Val};
|
||||
|
||||
pub struct Bytecode {
|
||||
pub code: Vec<u8>,
|
||||
pub cache: RefCell<HashMap<usize, Val>>,
|
||||
}
|
||||
|
||||
impl<I: SliceIndex<[u8]>> Index<I> for Bytecode {
|
||||
type Output = I::Output;
|
||||
|
||||
fn index(&self, index: I) -> &Self::Output {
|
||||
&self.code[index]
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Bytecode {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "Bytecode {{ code: {:?} }}", self.code)
|
||||
}
|
||||
}
|
||||
|
||||
impl Bytecode {
|
||||
pub fn new(code: Vec<u8>) -> Bytecode {
|
||||
Bytecode {
|
||||
code,
|
||||
cache: RefCell::new(HashMap::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait DecoderMaker {
|
||||
fn decoder(&self, pos: usize) -> BytecodeDecoder;
|
||||
}
|
||||
|
||||
impl DecoderMaker for Rc<Bytecode> {
|
||||
fn decoder(&self, pos: usize) -> BytecodeDecoder {
|
||||
BytecodeDecoder {
|
||||
bytecode: self.clone(),
|
||||
pos,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,17 +6,17 @@ use num_bigint::Sign;
|
||||
use valuescript_common::InstructionByte;
|
||||
|
||||
use crate::builtins::BUILTIN_VALS;
|
||||
use crate::bytecode::Bytecode;
|
||||
use crate::vs_class::VsClass;
|
||||
use crate::vs_function::VsFunction;
|
||||
use crate::vs_object::VsObject;
|
||||
use crate::vs_pointer::VsPointer;
|
||||
use crate::vs_symbol::VsSymbol;
|
||||
use crate::vs_value::ToVal;
|
||||
use crate::vs_value::Val;
|
||||
|
||||
pub struct BytecodeDecoder {
|
||||
// TODO: Enable borrow usage to avoid the rc overhead
|
||||
pub data: Rc<Vec<u8>>,
|
||||
pub bytecode: Rc<Bytecode>,
|
||||
pub pos: usize,
|
||||
}
|
||||
|
||||
@@ -74,13 +74,13 @@ impl BytecodeType {
|
||||
|
||||
impl BytecodeDecoder {
|
||||
pub fn decode_byte(&mut self) -> u8 {
|
||||
let byte = self.data[self.pos];
|
||||
let byte = self.bytecode[self.pos];
|
||||
self.pos += 1;
|
||||
return byte;
|
||||
}
|
||||
|
||||
pub fn peek_byte(&self) -> u8 {
|
||||
return self.data[self.pos];
|
||||
return self.bytecode[self.pos];
|
||||
}
|
||||
|
||||
pub fn decode_type(&mut self) -> BytecodeType {
|
||||
@@ -138,7 +138,7 @@ impl BytecodeDecoder {
|
||||
.to_val()
|
||||
}
|
||||
BytecodeType::Function => self.decode_function_header(),
|
||||
BytecodeType::Pointer => self.decode_pointer(),
|
||||
BytecodeType::Pointer => self.decode_pointer(registers),
|
||||
BytecodeType::Register => match registers[self.decode_register_index().unwrap()].clone() {
|
||||
Val::Void => Val::Undefined,
|
||||
val => val,
|
||||
@@ -155,7 +155,7 @@ impl BytecodeDecoder {
|
||||
}
|
||||
|
||||
pub fn decode_signed_byte(&mut self) -> i8 {
|
||||
let res = self.data[self.pos] as i8;
|
||||
let res = self.bytecode[self.pos] as i8;
|
||||
self.pos += 1;
|
||||
return res;
|
||||
}
|
||||
@@ -163,7 +163,7 @@ impl BytecodeDecoder {
|
||||
pub fn decode_number(&mut self) -> f64 {
|
||||
let mut buf = [0u8; 8];
|
||||
let next_pos = self.pos + 8;
|
||||
buf.clone_from_slice(&self.data[self.pos..next_pos]);
|
||||
buf.clone_from_slice(&self.bytecode[self.pos..next_pos]);
|
||||
self.pos = next_pos;
|
||||
return f64::from_le_bytes(buf);
|
||||
}
|
||||
@@ -178,7 +178,7 @@ impl BytecodeDecoder {
|
||||
};
|
||||
|
||||
let len = self.decode_varsize_uint();
|
||||
let bytes = &self.data[self.pos..self.pos + len];
|
||||
let bytes = &self.bytecode[self.pos..self.pos + len];
|
||||
self.pos += len;
|
||||
|
||||
return BigInt::from_bytes_le(sign, bytes);
|
||||
@@ -188,7 +188,7 @@ impl BytecodeDecoder {
|
||||
let len = self.decode_varsize_uint();
|
||||
let start = self.pos; // Start after decoding varsize
|
||||
let end = self.pos + len;
|
||||
let res = String::from_utf8_lossy(&self.data[start..end]).into_owned();
|
||||
let res = String::from_utf8_lossy(&self.bytecode[start..end]).into_owned();
|
||||
self.pos = end;
|
||||
|
||||
return res;
|
||||
@@ -229,12 +229,12 @@ impl BytecodeDecoder {
|
||||
|
||||
pub fn clone_at(&self, pos: usize) -> BytecodeDecoder {
|
||||
return BytecodeDecoder {
|
||||
data: self.data.clone(),
|
||||
pos: pos,
|
||||
bytecode: self.bytecode.clone(),
|
||||
pos,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn decode_pointer(&mut self) -> Val {
|
||||
pub fn decode_pointer(&mut self, registers: &Vec<Val>) -> Val {
|
||||
let from_pos = self.pos;
|
||||
let pos = self.decode_pos();
|
||||
|
||||
@@ -250,7 +250,22 @@ impl BytecodeDecoder {
|
||||
}
|
||||
}
|
||||
|
||||
VsPointer::new(&self.data, pos).to_val()
|
||||
let cached_val = self
|
||||
.bytecode
|
||||
.cache
|
||||
.borrow()
|
||||
.get(&pos)
|
||||
.map(|val| val.clone());
|
||||
|
||||
match cached_val {
|
||||
Some(val) => val,
|
||||
None => {
|
||||
let val = self.clone_at(pos).decode_val(registers);
|
||||
self.bytecode.cache.borrow_mut().insert(pos, val.clone());
|
||||
|
||||
val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decode_function_header(&mut self) -> Val {
|
||||
@@ -259,7 +274,7 @@ impl BytecodeDecoder {
|
||||
let parameter_count = self.decode_byte() as usize;
|
||||
|
||||
return VsFunction {
|
||||
bytecode: self.data.clone(),
|
||||
bytecode: self.bytecode.clone(),
|
||||
register_count,
|
||||
parameter_count,
|
||||
start: self.pos,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
mod array_higher_functions;
|
||||
mod bigint_methods;
|
||||
mod builtins;
|
||||
mod bytecode;
|
||||
mod bytecode_decoder;
|
||||
mod bytecode_stack_frame;
|
||||
mod first_stack_frame;
|
||||
@@ -17,9 +18,9 @@ pub mod vs_array;
|
||||
mod vs_class;
|
||||
mod vs_function;
|
||||
pub mod vs_object;
|
||||
mod vs_pointer;
|
||||
mod vs_symbol;
|
||||
pub mod vs_value;
|
||||
|
||||
pub use bytecode::Bytecode;
|
||||
pub use virtual_machine::VirtualMachine;
|
||||
pub use vs_value::{LoadFunctionResult, ValTrait};
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::builtins::error_builtin::ToError;
|
||||
use crate::bytecode_decoder::BytecodeDecoder;
|
||||
use crate::bytecode::Bytecode;
|
||||
use crate::bytecode::DecoderMaker;
|
||||
use crate::first_stack_frame::FirstStackFrame;
|
||||
use crate::stack_frame::FrameStepOk;
|
||||
use crate::stack_frame::StackFrame;
|
||||
@@ -15,14 +16,11 @@ pub struct VirtualMachine {
|
||||
impl VirtualMachine {
|
||||
pub fn run(
|
||||
&mut self,
|
||||
bytecode: &Rc<Vec<u8>>,
|
||||
bytecode: Rc<Bytecode>,
|
||||
step_limit: Option<usize>,
|
||||
params: &[Val],
|
||||
) -> Result<Val, Val> {
|
||||
let mut bd = BytecodeDecoder {
|
||||
data: bytecode.clone(),
|
||||
pos: 0,
|
||||
};
|
||||
let mut bd = bytecode.decoder(0);
|
||||
|
||||
let main_fn = bd.decode_val(&Vec::new());
|
||||
|
||||
@@ -122,12 +120,7 @@ impl VirtualMachine {
|
||||
Err(exception)
|
||||
}
|
||||
|
||||
pub fn read_default_export(bytecode: &Rc<Vec<u8>>) -> Val {
|
||||
let mut bd = BytecodeDecoder {
|
||||
data: bytecode.clone(),
|
||||
pos: 0,
|
||||
};
|
||||
|
||||
bd.decode_val(&Vec::new())
|
||||
pub fn read_default_export(bytecode: Rc<Bytecode>) -> Val {
|
||||
bytecode.decoder(0).decode_val(&Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::bytecode::Bytecode;
|
||||
use crate::vs_value::ToVal;
|
||||
|
||||
use super::bytecode_decoder::BytecodeDecoder;
|
||||
@@ -9,7 +10,7 @@ use super::vs_value::Val;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VsFunction {
|
||||
pub bytecode: Rc<Vec<u8>>,
|
||||
pub bytecode: Rc<Bytecode>,
|
||||
pub register_count: usize,
|
||||
pub parameter_count: usize,
|
||||
pub start: usize,
|
||||
@@ -49,7 +50,7 @@ impl VsFunction {
|
||||
|
||||
return Box::new(BytecodeStackFrame {
|
||||
decoder: BytecodeDecoder {
|
||||
data: self.bytecode.clone(),
|
||||
bytecode: self.bytecode.clone(),
|
||||
pos: self.start,
|
||||
},
|
||||
registers,
|
||||
|
||||
@@ -1,169 +0,0 @@
|
||||
use std::cell::RefCell;
|
||||
use std::fmt;
|
||||
use std::rc::Rc;
|
||||
|
||||
use num_bigint::BigInt;
|
||||
|
||||
use crate::builtins::error_builtin::ToError;
|
||||
use crate::vs_value::ToVal;
|
||||
|
||||
use super::bytecode_decoder::{BytecodeDecoder, BytecodeType};
|
||||
use super::vs_array::VsArray;
|
||||
use super::vs_class::VsClass;
|
||||
use super::vs_object::VsObject;
|
||||
use super::vs_value::{LoadFunctionResult, Val, ValTrait, VsType};
|
||||
|
||||
pub struct VsPointer {
|
||||
bytecode: Rc<Vec<u8>>,
|
||||
pos: usize,
|
||||
resolved: RefCell<Option<Val>>,
|
||||
}
|
||||
|
||||
impl VsPointer {
|
||||
pub fn new(bytecode: &Rc<Vec<u8>>, pos: usize) -> VsPointer {
|
||||
VsPointer {
|
||||
bytecode: bytecode.clone(),
|
||||
pos,
|
||||
resolved: RefCell::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve(&self) -> Val {
|
||||
let mut resolved = self.resolved.borrow_mut();
|
||||
|
||||
if resolved.is_some() {
|
||||
return resolved.clone().unwrap();
|
||||
}
|
||||
|
||||
let mut bd = BytecodeDecoder {
|
||||
data: self.bytecode.clone(),
|
||||
pos: self.pos,
|
||||
};
|
||||
|
||||
let val = bd.decode_val(&Vec::new());
|
||||
|
||||
// TODO: Check that this actually inserts into the cell and not just a copy
|
||||
// somehow
|
||||
*resolved = Some(val.clone());
|
||||
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
impl ValTrait for VsPointer {
|
||||
fn typeof_(&self) -> VsType {
|
||||
let mut bd = BytecodeDecoder {
|
||||
data: self.bytecode.clone(),
|
||||
pos: self.pos,
|
||||
};
|
||||
|
||||
return match bd.decode_type() {
|
||||
BytecodeType::End => panic!("Invalid: pointer to end"),
|
||||
BytecodeType::Void => panic!("Invalid: pointer to void"),
|
||||
BytecodeType::Undefined => VsType::Undefined,
|
||||
BytecodeType::Null => VsType::Null,
|
||||
BytecodeType::False => VsType::Bool,
|
||||
BytecodeType::True => VsType::Bool,
|
||||
BytecodeType::SignedByte => VsType::Number,
|
||||
BytecodeType::Number => VsType::Number,
|
||||
BytecodeType::String => VsType::String,
|
||||
BytecodeType::Array => VsType::Array,
|
||||
BytecodeType::Object => VsType::Object,
|
||||
BytecodeType::Function => VsType::Function,
|
||||
BytecodeType::Pointer => panic!("Invalid: pointer to pointer"),
|
||||
BytecodeType::Register => panic!("Invalid: pointer to register"),
|
||||
BytecodeType::Builtin => panic!("Invalid: pointer to builtin"),
|
||||
BytecodeType::Class => VsType::Class,
|
||||
BytecodeType::BigInt => VsType::BigInt,
|
||||
BytecodeType::Unrecognized => panic!("Unrecognized bytecode type at {}", self.pos - 1),
|
||||
};
|
||||
}
|
||||
|
||||
fn to_number(&self) -> f64 {
|
||||
return self.resolve().to_number();
|
||||
}
|
||||
|
||||
fn to_index(&self) -> Option<usize> {
|
||||
return self.resolve().to_index();
|
||||
}
|
||||
|
||||
fn is_primitive(&self) -> bool {
|
||||
return match self.typeof_() {
|
||||
VsType::Undefined => true,
|
||||
VsType::Null => true,
|
||||
VsType::Bool => true,
|
||||
VsType::Number => true,
|
||||
VsType::BigInt => true,
|
||||
VsType::Symbol => true,
|
||||
VsType::String => true,
|
||||
VsType::Array => false,
|
||||
VsType::Object => false,
|
||||
VsType::Function => false,
|
||||
VsType::Class => false,
|
||||
};
|
||||
}
|
||||
|
||||
fn bind(&self, params: Vec<Val>) -> Option<Val> {
|
||||
return self.resolve().bind(params);
|
||||
}
|
||||
|
||||
fn is_truthy(&self) -> bool {
|
||||
return self.resolve().is_truthy();
|
||||
}
|
||||
|
||||
fn is_nullish(&self) -> bool {
|
||||
return self.resolve().is_nullish();
|
||||
}
|
||||
|
||||
fn as_bigint_data(&self) -> Option<BigInt> {
|
||||
return self.resolve().as_bigint_data();
|
||||
}
|
||||
|
||||
fn as_array_data(&self) -> Option<Rc<VsArray>> {
|
||||
return self.resolve().as_array_data();
|
||||
}
|
||||
|
||||
fn as_object_data(&self) -> Option<Rc<VsObject>> {
|
||||
return self.resolve().as_object_data();
|
||||
}
|
||||
|
||||
fn as_class_data(&self) -> Option<Rc<VsClass>> {
|
||||
return self.resolve().as_class_data();
|
||||
}
|
||||
|
||||
fn load_function(&self) -> LoadFunctionResult {
|
||||
return self.resolve().load_function();
|
||||
}
|
||||
|
||||
fn sub(&self, subscript: Val) -> Result<Val, Val> {
|
||||
self.resolve().sub(subscript)
|
||||
}
|
||||
|
||||
fn submov(&mut self, _subscript: Val, _value: Val) -> Result<(), Val> {
|
||||
Err("TODO: Probably an exception, but might be possible".to_error())
|
||||
}
|
||||
|
||||
fn next(&mut self) -> LoadFunctionResult {
|
||||
self.resolve().next()
|
||||
}
|
||||
|
||||
fn pretty_fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.resolve().pretty_fmt(f)
|
||||
}
|
||||
|
||||
fn codify(&self) -> String {
|
||||
self.resolve().codify()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for VsPointer {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.resolve().fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToVal for VsPointer {
|
||||
fn to_val(self) -> Val {
|
||||
Val::Custom(Rc::new(self))
|
||||
}
|
||||
}
|
||||
@@ -244,6 +244,7 @@ impl ValTrait for Val {
|
||||
|
||||
return match self {
|
||||
Function(f) => Some(f.bind(params).to_val()),
|
||||
Static(val) => val.bind(params),
|
||||
Custom(val) => val.bind(params),
|
||||
|
||||
_ => None,
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::{
|
||||
collections::{BTreeMap, HashMap},
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
@@ -9,7 +12,7 @@ use valuescript_compiler::{
|
||||
use valuescript_vm::{
|
||||
vs_object::VsObject,
|
||||
vs_value::{ToVal, Val},
|
||||
LoadFunctionResult, ValTrait, VirtualMachine,
|
||||
Bytecode, LoadFunctionResult, ValTrait, VirtualMachine,
|
||||
};
|
||||
|
||||
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
|
||||
@@ -108,9 +111,9 @@ fn run_to_result(entry_point: &str, read_file: &js_sys::Function, args: &str) ->
|
||||
}
|
||||
};
|
||||
|
||||
let bytecode = assemble(&module);
|
||||
let bytecode = Rc::new(Bytecode::new(assemble(&module)));
|
||||
|
||||
match VirtualMachine::read_default_export(&bytecode).load_function() {
|
||||
match VirtualMachine::read_default_export(bytecode.clone()).load_function() {
|
||||
LoadFunctionResult::NotAFunction => {
|
||||
return RunResult {
|
||||
diagnostics: HashMap::default(),
|
||||
@@ -132,7 +135,7 @@ 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(bytecode, None, &val_args);
|
||||
|
||||
RunResult {
|
||||
diagnostics: HashMap::default(),
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use std::fs;
|
||||
use std::rc::Rc;
|
||||
use std::{ffi::OsStr, path::Path, process::exit};
|
||||
|
||||
use valuescript_compiler::{assemble, compile, parse_module};
|
||||
use valuescript_vm::vs_value::Val;
|
||||
use valuescript_vm::VirtualMachine;
|
||||
use valuescript_vm::{Bytecode, VirtualMachine};
|
||||
|
||||
use crate::resolve_entry_path::resolve_entry_path;
|
||||
|
||||
@@ -35,7 +36,7 @@ pub fn run_command(args: &Vec<String>) {
|
||||
let file_path = &args[argpos];
|
||||
argpos += 1;
|
||||
|
||||
let bytecode = to_bytecode(format, file_path);
|
||||
let bytecode = Rc::new(to_bytecode(format, file_path));
|
||||
|
||||
let mut vm = VirtualMachine::new();
|
||||
|
||||
@@ -44,7 +45,7 @@ pub fn run_command(args: &Vec<String>) {
|
||||
.map(|a| Val::String(Rc::new(a.into())))
|
||||
.collect();
|
||||
|
||||
match vm.run(&bytecode, None, &val_args) {
|
||||
match vm.run(bytecode, None, &val_args) {
|
||||
Ok(result) => {
|
||||
println!("{}", result.pretty());
|
||||
}
|
||||
@@ -87,8 +88,8 @@ fn format_from_path(file_path: &String) -> RunFormat {
|
||||
};
|
||||
}
|
||||
|
||||
fn to_bytecode(format: RunFormat, file_path: &String) -> Rc<Vec<u8>> {
|
||||
match format {
|
||||
fn to_bytecode(format: RunFormat, file_path: &String) -> Bytecode {
|
||||
Bytecode::new(match format {
|
||||
RunFormat::TypeScript => {
|
||||
let resolved_entry_path = resolve_entry_path(file_path);
|
||||
|
||||
@@ -115,10 +116,10 @@ fn to_bytecode(format: RunFormat, file_path: &String) -> Rc<Vec<u8>> {
|
||||
assemble(&module)
|
||||
}
|
||||
|
||||
RunFormat::Bytecode => Rc::new(
|
||||
std::fs::read(file_path).unwrap_or_else(|_| panic!("Failed to read file {}", file_path)),
|
||||
),
|
||||
}
|
||||
RunFormat::Bytecode => {
|
||||
fs::read(file_path).unwrap_or_else(|_| panic!("Failed to read file {}", file_path))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn show_help() {
|
||||
|
||||
@@ -3,11 +3,12 @@ mod tests {
|
||||
use std::collections::HashSet;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::rc::Rc;
|
||||
|
||||
use valuescript_compiler::compile;
|
||||
use valuescript_compiler::{assemble, parse_module};
|
||||
use valuescript_vm::ValTrait;
|
||||
use valuescript_vm::VirtualMachine;
|
||||
use valuescript_vm::{Bytecode, ValTrait};
|
||||
|
||||
use crate::handle_diagnostics_cli::handle_diagnostics_cli;
|
||||
use crate::resolve_entry_path::resolve_entry_path;
|
||||
@@ -70,20 +71,20 @@ mod tests {
|
||||
.module
|
||||
.expect("Should have exited if module is None");
|
||||
|
||||
let bytecode = assemble(&module);
|
||||
let bytecode = Rc::new(Bytecode::new(assemble(&module)));
|
||||
|
||||
let assembly = module.to_string();
|
||||
let parsed_assembly = parse_module(&assembly);
|
||||
let bytecode_via_assembly = assemble(&parsed_assembly);
|
||||
|
||||
if bytecode != bytecode_via_assembly {
|
||||
if bytecode.code != bytecode_via_assembly {
|
||||
println!(" Bytecode mismatch between original and parsed assembly");
|
||||
failed_paths.insert(file_path.clone());
|
||||
}
|
||||
|
||||
let mut vm = VirtualMachine::new();
|
||||
|
||||
let result = vm.run(&bytecode, Some(2_000_000), &[]);
|
||||
let result = vm.run(bytecode, Some(2_000_000), &[]);
|
||||
|
||||
let result_str = match result {
|
||||
Ok(val) => val.codify(),
|
||||
|
||||
Reference in New Issue
Block a user