Compare commits

..

No commits in common. "71c11e87e5793fdac8d64e66ed7ffcf262592b03" and "21300b71cf00db6a4a23e7c8f592e6972fd1578c" have entirely different histories.

View File

@ -566,60 +566,28 @@ impl ClosureRunner {
.unwrap_or(Value::Nil); .unwrap_or(Value::Nil);
} }
Instruction::SetTable(tablereg, indexreg, valuereg) => { Instruction::SetTable(tablereg, indexreg, valuereg) => {
let table_value = self.stack.get(tablereg); let table = self.stack.get(tablereg);
match table_value { match table {
Some(value) => { Some(value) => {
let mut table = value.borrow_mut(); let mut table = value.borrow_mut();
if let Value::Table { if let Value::Table { contents, .. } = &mut *table {
contents,
metatable,
} = &mut *table
{
let index_value = self let index_value = self
.stack .stack
.get(indexreg) .get(indexreg)
.map(|v| v.borrow().clone()) .map(|v| v.borrow().clone())
.unwrap_or(Value::Nil); .unwrap_or(Value::Nil)
.as_indexable()?;
let value = self let value = self
.stack .stack
.get(valuereg) .get(valuereg)
.map(|v| v.borrow().clone()) .map(|v| v.borrow().clone())
.unwrap_or(Value::Nil); .unwrap_or(Value::Nil);
if contents
.borrow()
.contains_key(&index_value.clone().as_indexable()?)
{
match value { match value {
Value::Nil => { Value::Nil => {
contents contents.borrow_mut().remove(&index_value);
.borrow_mut()
.remove(&index_value.as_indexable()?);
} }
_ => { _ => {
contents contents.borrow_mut().insert(index_value, value);
.borrow_mut()
.insert(index_value.as_indexable()?, value);
}
}
} else {
match self.call_metamethod(
metatable,
"__newindex",
vec![table_value.unwrap().borrow().clone()],
) {
Ok(_) => {}
Err(_) => match value {
Value::Nil => {
contents
.borrow_mut()
.remove(&index_value.as_indexable()?);
}
_ => {
contents
.borrow_mut()
.insert(index_value.as_indexable()?, value);
}
},
} }
} }
} else { } else {
@ -631,34 +599,20 @@ impl ClosureRunner {
} }
Instruction::GetTable(res, tablereg, indexreg) => { Instruction::GetTable(res, tablereg, indexreg) => {
let value = match self.stack.get(tablereg).cloned() { let value = match self.stack.get(tablereg).cloned() {
Some(table_value) => { Some(value) => {
let table = table_value.borrow(); let table = value.borrow();
if let Value::Table { if let Value::Table { contents, .. } = &*table {
contents,
metatable,
} = &*table
{
let table = contents.borrow(); let table = contents.borrow();
let index_value = self let index_value = self
.stack .stack
.get(indexreg) .get(indexreg)
.map(|v| v.borrow().clone()) .map(|v| v.borrow().clone())
.unwrap_or(Value::Nil); .unwrap_or(Value::Nil)
let value = table.get(&index_value.clone().as_indexable()?); .as_indexable()?;
let value = table.get(&index_value);
match value { match value {
Some(value) => StackValue::Value(value.clone()), Some(value) => StackValue::Value(value.clone()),
None => { None => StackValue::Value(Value::Nil),
match self.call_metamethod(
metatable,
"__index",
vec![value.unwrap().clone(), index_value.clone()],
) {
Ok(value) => {
StackValue::Value(value.first().unwrap().clone())
}
Err(_) => StackValue::Value(Value::Nil),
}
}
} }
} else { } else {
return Err(RuntimeError::NotTable(table.clone())); return Err(RuntimeError::NotTable(table.clone()));
@ -775,7 +729,7 @@ impl ClosureRunner {
.get(func_reg) .get(func_reg)
.map(|v| v.borrow().clone()) .map(|v| v.borrow().clone())
.unwrap_or(Value::Nil); .unwrap_or(Value::Nil);
match &value { match value {
Value::RustFunction(func) => { Value::RustFunction(func) => {
let ret_values = func.borrow_mut().execute(params)?; let ret_values = func.borrow_mut().execute(params)?;
if *ret_len != 0 { if *ret_len != 0 {
@ -809,34 +763,6 @@ impl ClosureRunner {
} }
self.inner = Some(Box::new(closure.run(params))); self.inner = Some(Box::new(closure.run(params)));
} }
Value::Table { metatable, .. } => {
let mut metamethod_params = vec![value.clone()];
metamethod_params.extend(params);
let ret_values =
self.call_metamethod(&metatable, "__call", metamethod_params)?;
if *ret_len != 0 {
for i in 0..=(*ret_len - 2) {
self.set_stack(
*func_reg + i,
StackValue::Value(
ret_values
.get(i as usize)
.cloned()
.unwrap_or(Value::Nil),
),
);
}
} else {
for (i, value) in ret_values.iter().enumerate() {
self.set_stack(
*func_reg + i as u16 + 1,
StackValue::Value(value.clone()),
);
}
self.top = *func_reg + ret_values.len() as u16;
}
}
_ => return Err(RuntimeError::TriedCallingNonFunction(value.clone())), _ => return Err(RuntimeError::TriedCallingNonFunction(value.clone())),
} }
} }
@ -1049,8 +975,6 @@ impl ClosureRunner {
"__eq", "__eq",
vec![lhs.clone(), rhs.clone()], vec![lhs.clone(), rhs.clone()],
)? )?
.first()
.unwrap()
.is_truthy(), .is_truthy(),
))), ))),
); );
@ -1125,10 +1049,7 @@ impl ClosureRunner {
Value::Table { metatable, .. } => { Value::Table { metatable, .. } => {
match self.call_metamethod(&metatable, "__len", vec![value.clone()]) { match self.call_metamethod(&metatable, "__len", vec![value.clone()]) {
Ok(result) => { Ok(result) => {
self.set_stack( self.set_stack(*res, StackValue::Value(result));
*res,
StackValue::Value(result.first().unwrap().clone()),
);
} }
Err(_) => { Err(_) => {
self.set_stack(*res, StackValue::Value(value.len()?)); self.set_stack(*res, StackValue::Value(value.len()?));
@ -1222,11 +1143,7 @@ impl ClosureRunner {
.borrow() .borrow()
.contains_key(&IndexableValue::String(metamethod.to_owned())) .contains_key(&IndexableValue::String(metamethod.to_owned()))
{ {
Ok(self self.call_metamethod(metatable, metamethod, vec![param.clone()])
.call_metamethod(metatable, metamethod, vec![param.clone()])?
.into_iter()
.next()
.unwrap())
} else { } else {
Err(RuntimeError::InvalidUnop( Err(RuntimeError::InvalidUnop(
metamethod.to_owned(), metamethod.to_owned(),
@ -1257,26 +1174,14 @@ impl ClosureRunner {
.borrow() .borrow()
.contains_key(&IndexableValue::String(metamethod.to_owned())) .contains_key(&IndexableValue::String(metamethod.to_owned()))
{ {
Ok(self self.call_metamethod(&metatable, metamethod, vec![lhs.clone(), rhs])
.call_metamethod(&metatable, metamethod, vec![lhs.clone(), rhs])?
.into_iter()
.next()
.unwrap())
} else { } else {
if let Value::Table { metatable, .. } = &rhs { if let Value::Table { metatable, .. } = &rhs {
if metatable if metatable
.borrow() .borrow()
.contains_key(&IndexableValue::String(metamethod.to_owned())) .contains_key(&IndexableValue::String(metamethod.to_owned()))
{ {
Ok(self self.call_metamethod(&metatable, metamethod, vec![lhs, rhs.clone()])
.call_metamethod(
&metatable,
metamethod,
vec![lhs, rhs.clone()],
)?
.into_iter()
.next()
.unwrap())
} else { } else {
Err(RuntimeError::InvalidBinop( Err(RuntimeError::InvalidBinop(
metamethod.to_owned(), metamethod.to_owned(),
@ -1297,11 +1202,7 @@ impl ClosureRunner {
.borrow() .borrow()
.contains_key(&IndexableValue::String(metamethod.to_owned())) .contains_key(&IndexableValue::String(metamethod.to_owned()))
{ {
Ok(self self.call_metamethod(&metatable, metamethod, vec![lhs, rhs.clone()])
.call_metamethod(&metatable, metamethod, vec![lhs, rhs.clone()])?
.into_iter()
.next()
.unwrap())
} else { } else {
Err(RuntimeError::InvalidBinop( Err(RuntimeError::InvalidBinop(
metamethod.to_owned(), metamethod.to_owned(),
@ -1325,7 +1226,7 @@ impl ClosureRunner {
metatable: &Table, metatable: &Table,
metamethod: &str, metamethod: &str,
params: Vec<Value>, params: Vec<Value>,
) -> Result<Vec<Value>, RuntimeError> { ) -> Result<Value, RuntimeError> {
if let Some(value) = metatable if let Some(value) = metatable
.borrow() .borrow()
.get(&IndexableValue::String(metamethod.to_owned())) .get(&IndexableValue::String(metamethod.to_owned()))
@ -1333,7 +1234,7 @@ impl ClosureRunner {
match value { match value {
Value::RustFunction(function) => { Value::RustFunction(function) => {
let result = function.borrow_mut().execute(params)?; let result = function.borrow_mut().execute(params)?;
Ok(result) Ok(result.into_iter().next().unwrap())
} }
Value::Function(closure) => { Value::Function(closure) => {
let mut runnable = closure.run(params); let mut runnable = closure.run(params);
@ -1343,7 +1244,7 @@ impl ClosureRunner {
return_value = runnable.next()?; return_value = runnable.next()?;
return_value.is_none() return_value.is_none()
} {} } {}
Ok(return_value.unwrap()) Ok(return_value.unwrap().into_iter().next().unwrap())
} }
_ => Err(RuntimeError::MetafunctionNotCallable(value.clone())), _ => Err(RuntimeError::MetafunctionNotCallable(value.clone())),
} }