⭐ loading upvalue metadata
							parent
							
								
									b639d02027
								
							
						
					
					
						commit
						05b1d6e1f7
					
				|  | @ -251,19 +251,25 @@ pub fn parse_block <R: Read> (rdr: &mut R, blocks: &mut Vec <Block>) | |||
| 	} | ||||
| 	
 | ||||
| 	let upvalue_count = parse_int (rdr).unwrap () as usize; | ||||
| 	
 | ||||
| 	let mut upvalues = Vec::with_capacity (upvalue_count); | ||||
| 	for _ in 0..upvalue_count { | ||||
| 		// Just ignore these
 | ||||
| 		let in_stack = parse_byte (rdr).unwrap () == 1; | ||||
| 		let idx = parse_byte (rdr).unwrap (); | ||||
| 		let kind = parse_byte (rdr).unwrap (); | ||||
| 		
 | ||||
| 		for _ in 0..3 { | ||||
| 			parse_byte (rdr).unwrap (); | ||||
| 		} | ||||
| 		let upvalue = crate::state::Upvalue { | ||||
| 			in_stack, | ||||
| 			idx, | ||||
| 			kind, | ||||
| 		}; | ||||
| 		
 | ||||
| 		upvalues.push (upvalue); | ||||
| 	} | ||||
| 	
 | ||||
| 	blocks.push (Block { | ||||
| 		constants, | ||||
| 		instructions, | ||||
| 		upvalue_count, | ||||
| 		upvalues, | ||||
| 	}); | ||||
| 	
 | ||||
| 	// Recursion
 | ||||
|  |  | |||
							
								
								
									
										20
									
								
								src/state.rs
								
								
								
								
							
							
						
						
									
										20
									
								
								src/state.rs
								
								
								
								
							|  | @ -8,11 +8,18 @@ use crate::{ | |||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| #[derive (Debug)] | ||||
| pub struct Upvalue { | ||||
| 	pub in_stack: bool, | ||||
| 	pub idx: u8, | ||||
| 	pub kind: u8, | ||||
| } | ||||
| 
 | ||||
| #[derive (Debug)] | ||||
| pub struct Block { | ||||
| 	pub instructions: Vec <Instruction>, | ||||
| 	pub constants: Vec <Value>, | ||||
| 	pub upvalue_count: usize, | ||||
| 	pub upvalues: Vec <Upvalue>, | ||||
| } | ||||
| 
 | ||||
| #[derive (Debug)] | ||||
|  | @ -345,7 +352,14 @@ impl State { | |||
| 					
 | ||||
| 					let b  = usize::try_from  (*b).unwrap (); | ||||
| 					
 | ||||
| 					*self.reg_mut (*a) = upvalues [b].clone (); | ||||
| 					let upvalue = match upvalues.get (b) { | ||||
| 						Some (x) => x.clone (), | ||||
| 						None => { | ||||
| 							dbg! (chunk, &self); | ||||
| 							panic! ("Missing upvalue"); | ||||
| 						} | ||||
| 					}; | ||||
| 					*self.reg_mut (*a) = upvalue; | ||||
| 				}, | ||||
| 				Instruction::Jmp (s_j) => next_pc += s_j, | ||||
| 				Instruction::Len (a, b) => { | ||||
|  | @ -420,7 +434,7 @@ impl State { | |||
| 							_ => panic! ("Impossible"), | ||||
| 						}; | ||||
| 						
 | ||||
| 						let upvalue_count = chunk.blocks [closure_idx].upvalue_count; | ||||
| 						let upvalue_count = chunk.blocks [closure_idx].upvalues.len (); | ||||
| 						
 | ||||
| 						let start_reg = a + popped_frame.register_offset - upvalue_count; | ||||
| 						
 | ||||
|  |  | |||
							
								
								
									
										14
									
								
								src/tests.rs
								
								
								
								
							
							
						
						
									
										14
									
								
								src/tests.rs
								
								
								
								
							|  | @ -93,7 +93,7 @@ fn bools () { | |||
| 					"arg".into (), | ||||
| 					"print".into (), | ||||
| 				], | ||||
| 				upvalue_count: 1, | ||||
| 				upvalues: vec! [], | ||||
| 			}, | ||||
| 			Block { | ||||
| 				instructions: vec! [ | ||||
|  | @ -107,7 +107,7 @@ fn bools () { | |||
| 					Inst::Return0, | ||||
| 				], | ||||
| 				constants: vec! [], | ||||
| 				upvalue_count: 0, | ||||
| 				upvalues: vec! [], | ||||
| 			}, | ||||
| 		], | ||||
| 	}; | ||||
|  | @ -164,7 +164,7 @@ fn floats () { | |||
| 			0.5.into (), | ||||
| 			"print".into (), | ||||
| 		], | ||||
| 		upvalue_count: 1, | ||||
| 		upvalues: vec! [], | ||||
| 	}; | ||||
| 	let chunk = Chunk { | ||||
| 		blocks: vec! [block], | ||||
|  | @ -187,8 +187,10 @@ fn floats () { | |||
| fn fma () { | ||||
| 	let bytecode = include_bytes! ("../test_vectors/fma.luac"); | ||||
| 	let mut rdr = std::io::Cursor::new (bytecode); | ||||
| 	let file = crate::loader::parse_chunk (&mut rdr).unwrap (); | ||||
| 	assert_eq! (file.blocks.len (), 4); | ||||
| 	let chunk = crate::loader::parse_chunk (&mut rdr).unwrap (); | ||||
| 	assert_eq! (chunk.blocks.len (), 4); | ||||
| 	
 | ||||
| 	assert_eq! (chunk.blocks [3].upvalues.len (), 2); | ||||
| 	
 | ||||
| 	for (arg, expected) in [ | ||||
| 		(vec! ["_exe_name"], vec! [122.into ()]), | ||||
|  | @ -197,7 +199,7 @@ fn fma () { | |||
| 		let expected: Vec <Value> = expected; | ||||
| 		let mut vm = State::default (); | ||||
| 		let upvalues = State::upvalues_from_args (arg.into_iter ().map (|s| s.to_string ())); | ||||
| 		let actual = vm.execute_chunk (&file, &upvalues); | ||||
| 		let actual = vm.execute_chunk (&chunk, &upvalues); | ||||
| 		
 | ||||
| 		assert_eq! (actual, expected); | ||||
| 	} | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| -- This one fails :( I haven't implemented closures properly yet. | ||||
| 
 | ||||
| local ii = "bogus" | ||||
| 
 | ||||
| local function add (aa, bb) | ||||
| 	return aa + bb | ||||
| end | ||||
|  | @ -12,6 +14,12 @@ local function fma (ee, ff, gg) | |||
| 	return add (mul (ee, ff), gg) | ||||
| end | ||||
| 
 | ||||
| local hh = fma (10, 11, 12) | ||||
| print (hh) | ||||
| local function run () | ||||
| 	local hh = fma (10, 11, 12) | ||||
| 	print (hh) | ||||
| end | ||||
| 
 | ||||
| run () | ||||
| print (ii) | ||||
| 
 | ||||
| return hh | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 _
						_