-
-
Notifications
You must be signed in to change notification settings - Fork 407
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bytecode Interpreter (new branch) (#860)
Nodes implement CodeGen which generates instructions onto a stack held in Context. The VM will interpret the instructions from Context. There are some issues: - Only basic instructions are added, but I'm working off https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals/Bytecode for now it should be easy to add more in. - The Stack is a Vec, this isn't ideal (we may be able to live with it for now) but the stack should really be a fixed sized array. This isn't possible because Value can't be copied in there as it holds Rc and Gc values. Can we have fixed-sized Values that hold a pointer? Something like the "stackvec" crate should help - put all VM related code behind "vm" feature flag Co-authored-by: Jason Williams <jwilliams720@bloomberg.net> Co-authored-by: Halid Odat <halidodat@gmail.com>
- Loading branch information
1 parent
14ef50c
commit 1052ccd
Showing
12 changed files
with
626 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
use super::*; | ||
use crate::{syntax::ast::Const, syntax::ast::Node, value::RcBigInt, value::RcString}; | ||
|
||
#[derive(Debug, Default)] | ||
pub struct Compiler { | ||
pub(super) instructions: Vec<Instruction>, | ||
pub(super) pool: Vec<Value>, | ||
} | ||
|
||
impl Compiler { | ||
// Add a new instruction. | ||
pub fn add_instruction(&mut self, instr: Instruction) { | ||
self.instructions.push(instr); | ||
} | ||
|
||
pub fn add_string_instruction<S>(&mut self, string: S) | ||
where | ||
S: Into<RcString>, | ||
{ | ||
let index = self.pool.len(); | ||
self.add_instruction(Instruction::String(index)); | ||
self.pool.push(string.into().into()); | ||
} | ||
|
||
pub fn add_bigint_instruction<B>(&mut self, bigint: B) | ||
where | ||
B: Into<RcBigInt>, | ||
{ | ||
let index = self.pool.len(); | ||
self.add_instruction(Instruction::BigInt(index)); | ||
self.pool.push(bigint.into().into()); | ||
} | ||
} | ||
|
||
pub(crate) trait CodeGen { | ||
fn compile(&self, compiler: &mut Compiler); | ||
} | ||
|
||
impl CodeGen for Node { | ||
fn compile(&self, compiler: &mut Compiler) { | ||
let _timer = BoaProfiler::global().start_event(&format!("Node ({})", &self), "codeGen"); | ||
match *self { | ||
Node::Const(Const::Undefined) => compiler.add_instruction(Instruction::Undefined), | ||
Node::Const(Const::Null) => compiler.add_instruction(Instruction::Null), | ||
Node::Const(Const::Bool(true)) => compiler.add_instruction(Instruction::True), | ||
Node::Const(Const::Bool(false)) => compiler.add_instruction(Instruction::False), | ||
Node::Const(Const::Num(num)) => compiler.add_instruction(Instruction::Rational(num)), | ||
Node::Const(Const::Int(num)) => match num { | ||
0 => compiler.add_instruction(Instruction::Zero), | ||
1 => compiler.add_instruction(Instruction::One), | ||
_ => compiler.add_instruction(Instruction::Int32(num)), | ||
}, | ||
Node::Const(Const::String(ref string)) => { | ||
compiler.add_string_instruction(string.clone()) | ||
} | ||
Node::Const(Const::BigInt(ref bigint)) => { | ||
compiler.add_bigint_instruction(bigint.clone()) | ||
} | ||
Node::BinOp(ref op) => op.compile(compiler), | ||
Node::UnaryOp(ref op) => op.compile(compiler), | ||
_ => unimplemented!(), | ||
} | ||
} | ||
} |
Oops, something went wrong.