mirror of
https://github.com/Noratrieb/dilaria.git
synced 2026-01-14 17:35:03 +01:00
fn hacks things oh god no
This commit is contained in:
parent
23728f26dd
commit
5bce4cc21c
3 changed files with 40 additions and 20 deletions
|
|
@ -20,10 +20,14 @@
|
||||||
//! to the length before the call. This means the interpreter has to do some bookkeeping, but it has
|
//! to the length before the call. This means the interpreter has to do some bookkeeping, but it has
|
||||||
//! to do that anyways.
|
//! to do that anyways.
|
||||||
//!
|
//!
|
||||||
|
//! It is the compilers job to generate the correct loading of the arguments and assure that the aritiy
|
||||||
|
//! is correct before the `Call` instruction.
|
||||||
|
//!
|
||||||
|
//!
|
||||||
//! # ABI
|
//! # ABI
|
||||||
//! Function arguments are passed on the stack and can be loaded just like local variables. They belong
|
//! Function arguments are passed on the stack and can be loaded just like local variables. They belong
|
||||||
//! to the stack frame of the new function and are cleaned up after returning, leaving the return value where
|
//! to the stack frame of the new function and are cleaned up after returning, leaving the return value where
|
||||||
//! the stack frame was.
|
//! the stack frame was
|
||||||
//!
|
//!
|
||||||
//! When a call happens, the current stack offset is pushed onto the stack as a `Value::Native` and
|
//! When a call happens, the current stack offset is pushed onto the stack as a `Value::Native` and
|
||||||
//! the element before it is stored as the new offset.
|
//! the element before it is stored as the new offset.
|
||||||
|
|
@ -37,14 +41,14 @@
|
||||||
//! returned value.
|
//! returned value.
|
||||||
//!
|
//!
|
||||||
//! ```text
|
//! ```text
|
||||||
//! old stack offset ╮ ╭ Parameters ╮ ╭ local
|
//! old stack offset ╮ old *mut FnBlock ╮ ╭ Parameters ╮ ╭ local
|
||||||
//! v v v v
|
//! v v v v v
|
||||||
//! ───────┬────────────┬───────────┬──────────┬─────────╮
|
//! ───────┬─────────────┬────────────┬──────────┬─────────┬──────────┬─────────╮
|
||||||
//! Num(6) │ Native(20) │ Num(5) │ Num(6) │ Num(5) │
|
//! Num(6) │ NativeU(20) │ NativeU(4) │ Ptr │ Num(5) │ Num(6) │ Num(5) │
|
||||||
//! ───────┴────────────┴───────────┴──────────┴─────────╯
|
//! ───────┴─────────────┴────────────┴──────────┴─────────┴──────────┴─────────╯
|
||||||
//! ╰────────────────────────────────────────────────── current stack frame
|
//! ^ ╰──────────────────────────────────────────────────────────────────── current stack frame
|
||||||
//! ^ ^
|
//! │ ^ ^
|
||||||
//! ╰─ old local ╰╮
|
//! ╰─ old local ╰╮ ╰─ old PC
|
||||||
//! │
|
//! │
|
||||||
//! │
|
//! │
|
||||||
//! Vm │
|
//! Vm │
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ impl<'bc, 'gc> Compiler<'bc, 'gc> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_fn_decl(&mut self, _: &FnDecl) -> CResult {
|
fn compile_fn_decl(&mut self, decl: &FnDecl) -> CResult {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -415,13 +415,13 @@ impl<'bc, 'gc> Compiler<'bc, 'gc> {
|
||||||
block.stack_sizes.last().copied().unwrap_or(0)
|
block.stack_sizes.last().copied().unwrap_or(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_instr(&mut self, index: usize, instr: Instr) {
|
fn change_instr(&mut self, index: usize, instr: Instr<'bc>) {
|
||||||
let block = &mut self.blocks[self.current_block];
|
let block = &mut self.blocks[self.current_block];
|
||||||
block.code[index] = instr;
|
block.code[index] = instr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pushes an instruction and returns the index of the new instruction
|
/// Pushes an instruction and returns the index of the new instruction
|
||||||
fn push_instr(&mut self, instr: Instr, stack_change: StackChange, span: Span) -> usize {
|
fn push_instr(&mut self, instr: Instr<'bc>, stack_change: StackChange, span: Span) -> usize {
|
||||||
let block = &mut self.blocks[self.current_block];
|
let block = &mut self.blocks[self.current_block];
|
||||||
let stack_top = block.stack_sizes.last().copied().unwrap_or(0);
|
let stack_top = block.stack_sizes.last().copied().unwrap_or(0);
|
||||||
let new_stack_top = stack_top as isize + stack_change.as_isize();
|
let new_stack_top = stack_top as isize + stack_change.as_isize();
|
||||||
|
|
|
||||||
32
src/vm.rs
32
src/vm.rs
|
|
@ -3,6 +3,7 @@ use crate::gc::{Object, RtAlloc, Symbol};
|
||||||
use crate::Config;
|
use crate::Config;
|
||||||
use std::fmt::{Debug, Display, Formatter};
|
use std::fmt::{Debug, Display, Formatter};
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
type VmError = &'static str;
|
type VmError = &'static str;
|
||||||
type VmResult = Result<(), VmError>;
|
type VmResult = Result<(), VmError>;
|
||||||
|
|
@ -13,7 +14,6 @@ pub fn execute<'bc>(
|
||||||
cfg: &mut Config,
|
cfg: &mut Config,
|
||||||
) -> Result<(), VmError> {
|
) -> Result<(), VmError> {
|
||||||
let mut vm = Vm {
|
let mut vm = Vm {
|
||||||
_blocks: bytecode,
|
|
||||||
current: bytecode.first().ok_or("no bytecode found")?,
|
current: bytecode.first().ok_or("no bytecode found")?,
|
||||||
pc: 0,
|
pc: 0,
|
||||||
stack: Vec::with_capacity(1024 << 5),
|
stack: Vec::with_capacity(1024 << 5),
|
||||||
|
|
@ -40,10 +40,15 @@ pub enum Value {
|
||||||
Array,
|
Array,
|
||||||
/// A map from string to value
|
/// A map from string to value
|
||||||
Object(Object),
|
Object(Object),
|
||||||
/// A value that is stored by the vm for bookkeeping and should never be accessed for anythign else
|
/// A value that is stored by the vm for bookkeeping and should never be accessed for anything else
|
||||||
Native(usize),
|
NativeU(usize),
|
||||||
|
/// A function
|
||||||
|
Fn(Ptr),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct Ptr(NonNull<()>);
|
||||||
|
|
||||||
const _: () = _check_val_size();
|
const _: () = _check_val_size();
|
||||||
const fn _check_val_size() {
|
const fn _check_val_size() {
|
||||||
if std::mem::size_of::<Value>() != 24 {
|
if std::mem::size_of::<Value>() != 24 {
|
||||||
|
|
@ -55,14 +60,16 @@ const TRUE: Value = Value::Bool(true);
|
||||||
const FALSE: Value = Value::Bool(false);
|
const FALSE: Value = Value::Bool(false);
|
||||||
|
|
||||||
struct Vm<'bc, 'io> {
|
struct Vm<'bc, 'io> {
|
||||||
_blocks: &'bc [FnBlock<'bc>],
|
// -- global
|
||||||
current: &'bc FnBlock<'bc>,
|
|
||||||
_alloc: RtAlloc,
|
_alloc: RtAlloc,
|
||||||
/// Index of the instruction currently being executed
|
|
||||||
pc: usize,
|
|
||||||
stack: Vec<Value>,
|
stack: Vec<Value>,
|
||||||
stdout: &'io mut dyn Write,
|
stdout: &'io mut dyn Write,
|
||||||
step: bool,
|
step: bool,
|
||||||
|
|
||||||
|
// -- local to the current function
|
||||||
|
current: &'bc FnBlock<'bc>,
|
||||||
|
/// Index of the instruction currently being executed
|
||||||
|
pc: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'bc> Vm<'bc, '_> {
|
impl<'bc> Vm<'bc, '_> {
|
||||||
|
|
@ -179,6 +186,7 @@ impl<'bc> Vm<'bc, '_> {
|
||||||
}
|
}
|
||||||
Instr::Jmp(pos) => self.pc = (self.pc as isize + pos) as usize,
|
Instr::Jmp(pos) => self.pc = (self.pc as isize + pos) as usize,
|
||||||
Instr::Call(_) => todo!(),
|
Instr::Call(_) => todo!(),
|
||||||
|
Instr::Return => todo!(),
|
||||||
Instr::ShrinkStack(size) => {
|
Instr::ShrinkStack(size) => {
|
||||||
assert!(self.stack.len() >= size);
|
assert!(self.stack.len() >= size);
|
||||||
let new_len = self.stack.len() - size;
|
let new_len = self.stack.len() - size;
|
||||||
|
|
@ -232,7 +240,15 @@ impl Display for Value {
|
||||||
Value::String(str) => f.write_str(str.as_str()),
|
Value::String(str) => f.write_str(str.as_str()),
|
||||||
Value::Array => todo!(),
|
Value::Array => todo!(),
|
||||||
Value::Object(_) => todo!(),
|
Value::Object(_) => todo!(),
|
||||||
Value::Native(_) => panic!("Called display on native value!"),
|
Value::NativeU(_) => panic!("Called display on native value!"),
|
||||||
|
Value::Fn(_) => f.write_str("[function]"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "pretty")]
|
||||||
|
impl debug2::Debug for Ptr {
|
||||||
|
fn fmt(&self, f: &mut debug2::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Ptr").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue