Compare commits
	
		
			2 Commits 
		
	
	
		
			8baea40e82
			...
			543cf58b1e
		
	
	| Author | SHA1 | Date | 
|---|---|---|
| 
							
							
								 | 
						543cf58b1e | |
| 
							
							
								 | 
						b88735a61b | 
| 
						 | 
				
			
			@ -12,7 +12,3 @@ lunar_wave_vm = { path = "../lunar_wave_vm" }
 | 
			
		|||
linker = "/usr/bin/clang"
 | 
			
		||||
# Recommended for flamegraph
 | 
			
		||||
rustflags = ["-Clink-arg=-fuse-ld=lld", "-Clink-arg=-Wl,--no-rosegment"]
 | 
			
		||||
 | 
			
		||||
[profile.release]
 | 
			
		||||
# Recommended for profiling, e.g. flamegraph
 | 
			
		||||
debug = true
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -160,6 +160,7 @@ pub fn parse_inst (buf: [u8; 4]) -> Option <Inst>
 | 
			
		|||
		0x4a => Inst::ForPrep (a, bx),
 | 
			
		||||
		0x4e => Inst::SetList (a, b, c, k),
 | 
			
		||||
		0x4f => Inst::Closure (a, bx),
 | 
			
		||||
		0x50 => unimplemented! ("OP_VARARG"),
 | 
			
		||||
		0x51 => Inst::VarArgPrep (a.into ()),
 | 
			
		||||
		0x52 => Inst::ExtraArg (ax),
 | 
			
		||||
		_ => return None,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,7 +82,6 @@ fn lw_print (l: &mut State, num_args: usize) -> usize {
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
	println! ("");
 | 
			
		||||
	*l.reg_mut (0) = Value::from (1993);
 | 
			
		||||
	1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -107,9 +106,39 @@ fn lw_string_format (l: &mut State, num_args: usize) -> usize {
 | 
			
		|||
	1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn lw_tonumber (l: &mut State, num_args: usize) -> usize {
 | 
			
		||||
	assert_eq! (num_args, 1, "tonumber only implemented for 1 argument");
 | 
			
		||||
	let output = match l.reg (0) {
 | 
			
		||||
fn lw_table_concat (l: &mut State, num_args: usize) -> usize {
 | 
			
		||||
	assert_eq! (num_args, 2);
 | 
			
		||||
	
 | 
			
		||||
	let s = {
 | 
			
		||||
		let t = l.reg (0).as_table ().unwrap ().borrow ();
 | 
			
		||||
		let joiner = l.reg (1).as_str ().unwrap ();
 | 
			
		||||
		
 | 
			
		||||
		let mut s = String::new ();
 | 
			
		||||
		
 | 
			
		||||
		for i in 0..t.length () {
 | 
			
		||||
			if i > 0 {
 | 
			
		||||
				s.push_str (joiner);
 | 
			
		||||
			}
 | 
			
		||||
			let x = t.get_int (i + 1);
 | 
			
		||||
			s.push_str (&format! ("{}", x));
 | 
			
		||||
		}
 | 
			
		||||
		s
 | 
			
		||||
	};
 | 
			
		||||
	*l.reg_mut (0) = Value::from (s);
 | 
			
		||||
	1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn lw_table_pack (l: &mut State, num_args: usize) -> usize {
 | 
			
		||||
	let mut v = vec! [];
 | 
			
		||||
	for i in 0..num_args {
 | 
			
		||||
		v.push (l.reg (u8::try_from (i).unwrap ()).clone ());
 | 
			
		||||
	}
 | 
			
		||||
	*l.reg_mut (0) = Value::from_iter (v.into_iter ());
 | 
			
		||||
	1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn tonumber (value: &Value) -> Value {
 | 
			
		||||
	match value {
 | 
			
		||||
		Value::Float (x) => Value::Float (*x),
 | 
			
		||||
		Value::Integer (x) => Value::Integer (*x),
 | 
			
		||||
		Value::String (x) => {
 | 
			
		||||
| 
						 | 
				
			
			@ -124,7 +153,12 @@ fn lw_tonumber (l: &mut State, num_args: usize) -> usize {
 | 
			
		|||
			}
 | 
			
		||||
		},
 | 
			
		||||
		_ => Value::Nil,
 | 
			
		||||
	};
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn lw_tonumber (l: &mut State, num_args: usize) -> usize {
 | 
			
		||||
	assert_eq! (num_args, 1, "tonumber only implemented for 1 argument");
 | 
			
		||||
	let output = tonumber (l.reg (0));
 | 
			
		||||
	*l.reg_mut (0) = output;
 | 
			
		||||
	1
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -182,12 +216,18 @@ impl State {
 | 
			
		|||
			("format", Value::RsFunc (lw_string_format)),
 | 
			
		||||
		].into_iter ().map (|(k, v)| (k.to_string (), v));
 | 
			
		||||
		
 | 
			
		||||
		let table = [
 | 
			
		||||
			("concat", Value::RsFunc (lw_table_concat)),
 | 
			
		||||
			("pack", Value::RsFunc (lw_table_pack)),
 | 
			
		||||
		].into_iter ().map (|(k, v)| (k.to_string (), v));
 | 
			
		||||
		
 | 
			
		||||
		let env = [
 | 
			
		||||
			("arg", arg),
 | 
			
		||||
			("io", Value::from_iter (io.into_iter ())),
 | 
			
		||||
			("math", Value::from_iter (math.into_iter ())),
 | 
			
		||||
			("print", Value::RsFunc (lw_print)),
 | 
			
		||||
			("string", Value::from_iter (string.into_iter ())),
 | 
			
		||||
			("table", Value::from_iter (table.into_iter ())),
 | 
			
		||||
			("tonumber", Value::RsFunc (lw_tonumber)),
 | 
			
		||||
		].into_iter ().map (|(k, v)| (k.to_string (), v));
 | 
			
		||||
		
 | 
			
		||||
| 
						 | 
				
			
			@ -336,7 +376,7 @@ impl State {
 | 
			
		|||
						});
 | 
			
		||||
						
 | 
			
		||||
						let num_args = if b == 0 {
 | 
			
		||||
							self.top - a as usize
 | 
			
		||||
							self.top - new_offset
 | 
			
		||||
						}
 | 
			
		||||
						else {
 | 
			
		||||
							b - 1
 | 
			
		||||
| 
						 | 
				
			
			@ -385,7 +425,7 @@ impl State {
 | 
			
		|||
					upvalues: new_upvalues,
 | 
			
		||||
				});
 | 
			
		||||
			},
 | 
			
		||||
			Instruction::Concat (a, b) => {
 | 
			
		||||
			Instruction::Concat (_a, _b) => {
 | 
			
		||||
				unimplemented! ("OP_CONCAT")
 | 
			
		||||
			},
 | 
			
		||||
			Instruction::Div (a, b, c) => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -208,9 +208,30 @@ fn function_calls () {
 | 
			
		|||
	
 | 
			
		||||
	vm.eval ("print (x ())").ok ();
 | 
			
		||||
	vm.eval ("x = function () return 5 end").ok ();
 | 
			
		||||
	
 | 
			
		||||
	// Currently failing because I don't have a way to jump into a Lua
 | 
			
		||||
	// function that's no longer in the currently-executing chunk
 | 
			
		||||
	vm.eval ("print (x ())").ok ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn function_returns () {
 | 
			
		||||
	let upvalues = crate::State::upvalues_from_args (vec! ["_exe_name".to_string ()].into_iter ());
 | 
			
		||||
	
 | 
			
		||||
	let mut vm = crate::State::new (crate::Chunk::default (), upvalues);
 | 
			
		||||
	
 | 
			
		||||
	assert_eq! (
 | 
			
		||||
		vm.eval ("return ((function () return 5 end)())").unwrap (), 
 | 
			
		||||
		vec! [Value::from (5)]
 | 
			
		||||
	);	
 | 
			
		||||
	assert_eq! (
 | 
			
		||||
		vm.eval ("return (math.sqrt (25))").unwrap (), 
 | 
			
		||||
		vec! [Value::from (5.0)]
 | 
			
		||||
	);
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn heap () {
 | 
			
		||||
	use std::{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue