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 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
|
||||
//! 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
|
||||
//! 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
|
||||
//! the element before it is stored as the new offset.
|
||||
|
|
@ -37,14 +41,14 @@
|
|||
//! returned value.
|
||||
//!
|
||||
//! ```text
|
||||
//! old stack offset ╮ ╭ Parameters ╮ ╭ local
|
||||
//! v v v v
|
||||
//! ───────┬────────────┬───────────┬──────────┬─────────╮
|
||||
//! Num(6) │ Native(20) │ Num(5) │ Num(6) │ Num(5) │
|
||||
//! ───────┴────────────┴───────────┴──────────┴─────────╯
|
||||
//! ╰────────────────────────────────────────────────── current stack frame
|
||||
//! ^ ^
|
||||
//! ╰─ old local ╰╮
|
||||
//! old stack offset ╮ old *mut FnBlock ╮ ╭ Parameters ╮ ╭ local
|
||||
//! v v v v v
|
||||
//! ───────┬─────────────┬────────────┬──────────┬─────────┬──────────┬─────────╮
|
||||
//! Num(6) │ NativeU(20) │ NativeU(4) │ Ptr │ Num(5) │ Num(6) │ Num(5) │
|
||||
//! ───────┴─────────────┴────────────┴──────────┴─────────┴──────────┴─────────╯
|
||||
//! ^ ╰──────────────────────────────────────────────────────────────────── current stack frame
|
||||
//! │ ^ ^
|
||||
//! ╰─ old local ╰╮ ╰─ old PC
|
||||
//! │
|
||||
//! │
|
||||
//! Vm │
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ impl<'bc, 'gc> Compiler<'bc, 'gc> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn compile_fn_decl(&mut self, _: &FnDecl) -> CResult {
|
||||
fn compile_fn_decl(&mut self, decl: &FnDecl) -> CResult {
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
|
@ -415,13 +415,13 @@ impl<'bc, 'gc> Compiler<'bc, 'gc> {
|
|||
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];
|
||||
block.code[index] = instr;
|
||||
}
|
||||
|
||||
/// 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 stack_top = block.stack_sizes.last().copied().unwrap_or(0);
|
||||
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 std::fmt::{Debug, Display, Formatter};
|
||||
use std::io::{Read, Write};
|
||||
use std::ptr::NonNull;
|
||||
|
||||
type VmError = &'static str;
|
||||
type VmResult = Result<(), VmError>;
|
||||
|
|
@ -13,7 +14,6 @@ pub fn execute<'bc>(
|
|||
cfg: &mut Config,
|
||||
) -> Result<(), VmError> {
|
||||
let mut vm = Vm {
|
||||
_blocks: bytecode,
|
||||
current: bytecode.first().ok_or("no bytecode found")?,
|
||||
pc: 0,
|
||||
stack: Vec::with_capacity(1024 << 5),
|
||||
|
|
@ -40,10 +40,15 @@ pub enum Value {
|
|||
Array,
|
||||
/// A map from string to value
|
||||
Object(Object),
|
||||
/// A value that is stored by the vm for bookkeeping and should never be accessed for anythign else
|
||||
Native(usize),
|
||||
/// A value that is stored by the vm for bookkeeping and should never be accessed for anything else
|
||||
NativeU(usize),
|
||||
/// A function
|
||||
Fn(Ptr),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Ptr(NonNull<()>);
|
||||
|
||||
const _: () = _check_val_size();
|
||||
const fn _check_val_size() {
|
||||
if std::mem::size_of::<Value>() != 24 {
|
||||
|
|
@ -55,14 +60,16 @@ const TRUE: Value = Value::Bool(true);
|
|||
const FALSE: Value = Value::Bool(false);
|
||||
|
||||
struct Vm<'bc, 'io> {
|
||||
_blocks: &'bc [FnBlock<'bc>],
|
||||
current: &'bc FnBlock<'bc>,
|
||||
// -- global
|
||||
_alloc: RtAlloc,
|
||||
/// Index of the instruction currently being executed
|
||||
pc: usize,
|
||||
stack: Vec<Value>,
|
||||
stdout: &'io mut dyn Write,
|
||||
step: bool,
|
||||
|
||||
// -- local to the current function
|
||||
current: &'bc FnBlock<'bc>,
|
||||
/// Index of the instruction currently being executed
|
||||
pc: usize,
|
||||
}
|
||||
|
||||
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::Call(_) => todo!(),
|
||||
Instr::Return => todo!(),
|
||||
Instr::ShrinkStack(size) => {
|
||||
assert!(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::Array => 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