fn hacks things oh god no

This commit is contained in:
nora 2022-01-08 15:54:16 +01:00
parent 23728f26dd
commit 5bce4cc21c
3 changed files with 40 additions and 20 deletions

View file

@ -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 │

View file

@ -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();

View file

@ -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()
}
}