Fix function calling bug
This commit is contained in:
parent
2b677c7ec8
commit
9d370aea2a
@ -1,7 +1,7 @@
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||||
use dust_lang::{run, DustString};
|
use dust_lang::run;
|
||||||
|
|
||||||
const SOURCE: &str = r"
|
const SOURCE: &str = r"
|
||||||
let mut i = 0
|
let mut i = 0
|
||||||
@ -12,7 +12,7 @@ const SOURCE: &str = r"
|
|||||||
";
|
";
|
||||||
|
|
||||||
fn addictive_addition(source: &str) {
|
fn addictive_addition(source: &str) {
|
||||||
run(Some(DustString::from("addictive_addition")), source).unwrap();
|
run(source).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn criterion_benchmark(c: &mut Criterion) {
|
fn criterion_benchmark(c: &mut Criterion) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||||
use dust_lang::{run, DustString};
|
use dust_lang::run;
|
||||||
|
|
||||||
const SOURCE: &str = r"
|
const SOURCE: &str = r"
|
||||||
fn fib (n: int) -> int {
|
fn fib (n: int) -> int {
|
||||||
@ -15,7 +15,7 @@ const SOURCE: &str = r"
|
|||||||
";
|
";
|
||||||
|
|
||||||
fn addictive_addition(source: &str) {
|
fn addictive_addition(source: &str) {
|
||||||
run(Some(DustString::from("fibonacci")), source).unwrap();
|
run(source).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn criterion_benchmark(c: &mut Criterion) {
|
fn criterion_benchmark(c: &mut Criterion) {
|
||||||
|
@ -49,10 +49,10 @@ use crate::{
|
|||||||
///
|
///
|
||||||
/// assert_eq!(chunk.instructions().len(), 3);
|
/// assert_eq!(chunk.instructions().len(), 3);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn compile(program_name: Option<DustString>, source: &str) -> Result<Chunk, DustError> {
|
pub fn compile(source: &str) -> Result<Chunk, DustError> {
|
||||||
let lexer = Lexer::new(source);
|
let lexer = Lexer::new(source);
|
||||||
let mut compiler = Compiler::new(lexer, program_name, true)
|
let mut compiler =
|
||||||
.map_err(|error| DustError::compile(error, source))?;
|
Compiler::new(lexer, None, true).map_err(|error| DustError::compile(error, source))?;
|
||||||
|
|
||||||
compiler
|
compiler
|
||||||
.compile()
|
.compile()
|
||||||
|
@ -768,7 +768,7 @@ impl Debug for Instruction {
|
|||||||
|
|
||||||
impl Display for Instruction {
|
impl Display for Instruction {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
write!(f, "{} {}", self.operation(), self.disassembly_info())
|
write!(f, "{} | {}", self.operation(), self.disassembly_info())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,10 +18,10 @@ pub use thread::{Thread, ThreadData};
|
|||||||
|
|
||||||
use tracing::{span, Level};
|
use tracing::{span, Level};
|
||||||
|
|
||||||
use crate::{compile, Chunk, DustError, DustString, Value};
|
use crate::{compile, Chunk, DustError, Value};
|
||||||
|
|
||||||
pub fn run(program_name: Option<DustString>, source: &str) -> Result<Option<Value>, DustError> {
|
pub fn run(source: &str) -> Result<Option<Value>, DustError> {
|
||||||
let chunk = compile(program_name, source)?;
|
let chunk = compile(source)?;
|
||||||
let vm = Vm::new(chunk);
|
let vm = Vm::new(chunk);
|
||||||
|
|
||||||
Ok(vm.run())
|
Ok(vm.run())
|
||||||
@ -92,8 +92,8 @@ pub enum Pointer {
|
|||||||
impl Display for Pointer {
|
impl Display for Pointer {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Self::Stack(index) => write!(f, "R{}", index),
|
Self::Stack(index) => write!(f, "PR{}", index),
|
||||||
Self::Constant(index) => write!(f, "C{}", index),
|
Self::Constant(index) => write!(f, "PC{}", index),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -544,11 +544,17 @@ pub fn call(instruction: Instruction, data: &mut ThreadData) -> bool {
|
|||||||
ip: current_call.ip,
|
ip: current_call.ip,
|
||||||
record: Record::new(prototype),
|
record: Record::new(prototype),
|
||||||
};
|
};
|
||||||
|
let mut argument_index = 0;
|
||||||
|
|
||||||
for (argument_index, register_index) in (first_argument_register..return_register).enumerate() {
|
for register_index in first_argument_register..return_register {
|
||||||
let argument = current_call
|
let value_option = current_call
|
||||||
.record
|
.record
|
||||||
.clone_register_value_or_constant_unchecked(register_index);
|
.open_register_allow_empty_unchecked(register_index);
|
||||||
|
let argument = if let Some(value) = value_option {
|
||||||
|
value.clone()
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
trace!(
|
trace!(
|
||||||
"Passing argument \"{argument}\" to {}",
|
"Passing argument \"{argument}\" to {}",
|
||||||
@ -560,7 +566,9 @@ pub fn call(instruction: Instruction, data: &mut ThreadData) -> bool {
|
|||||||
|
|
||||||
next_call
|
next_call
|
||||||
.record
|
.record
|
||||||
.set_register(argument_index as u8, Register::Value(argument));
|
.set_register(argument_index, Register::Value(argument));
|
||||||
|
|
||||||
|
argument_index += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.next_action = get_next_action(&mut next_call.record);
|
data.next_action = get_next_action(&mut next_call.record);
|
||||||
@ -601,12 +609,12 @@ pub fn r#return(instruction: Instruction, data: &mut ThreadData) -> bool {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let outer_call = data.call_stack.last_mut_unchecked();
|
let outer_call = data.call_stack.last_mut_unchecked();
|
||||||
let destination = current_call.return_register;
|
|
||||||
|
|
||||||
if should_return_value {
|
if should_return_value {
|
||||||
let return_value = current_call
|
let return_value = current_call
|
||||||
.record
|
.record
|
||||||
.empty_register_or_clone_constant_unchecked(return_register);
|
.empty_register_or_clone_constant_unchecked(return_register);
|
||||||
|
let destination = current_call.return_register;
|
||||||
|
|
||||||
outer_call
|
outer_call
|
||||||
.record
|
.record
|
||||||
|
Loading…
x
Reference in New Issue
Block a user