Skip to content

Commit

Permalink
VM: Implement LetDeclList and the let keyword
Browse files Browse the repository at this point in the history
  • Loading branch information
AnnikaCodes committed Jan 2, 2021
1 parent 1052ccd commit 67f92ef
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 19 deletions.
2 changes: 1 addition & 1 deletion boa/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,7 @@ impl Context {
};

let mut compiler = Compiler::default();
statement_list.compile(&mut compiler);
statement_list.compile(&mut compiler, self);
dbg!(&compiler);

let mut vm = VM::new(compiler, self);
Expand Down
14 changes: 7 additions & 7 deletions boa/src/syntax/ast/node/operator/bin_op/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,12 @@ impl Executable for BinOp {

#[cfg(feature = "vm")]
impl CodeGen for BinOp {
fn compile(&self, compiler: &mut Compiler) {
fn compile(&self, compiler: &mut Compiler, context: &mut Context) {
let _timer = BoaProfiler::global().start_event("binOp", "codeGen");
match self.op() {
op::BinOp::Num(op) => {
self.lhs().compile(compiler);
self.rhs().compile(compiler);
self.lhs().compile(compiler, context);
self.rhs().compile(compiler, context);
match op {
NumOp::Add => compiler.add_instruction(Instruction::Add),
NumOp::Sub => compiler.add_instruction(Instruction::Sub),
Expand All @@ -254,8 +254,8 @@ impl CodeGen for BinOp {
}
}
op::BinOp::Bit(op) => {
self.lhs().compile(compiler);
self.rhs().compile(compiler);
self.lhs().compile(compiler, context);
self.rhs().compile(compiler, context);
match op {
BitOp::And => compiler.add_instruction(Instruction::BitAnd),
BitOp::Or => compiler.add_instruction(Instruction::BitOr),
Expand All @@ -266,8 +266,8 @@ impl CodeGen for BinOp {
}
}
op::BinOp::Comp(op) => {
self.lhs().compile(compiler);
self.rhs().compile(compiler);
self.lhs().compile(compiler, context);
self.rhs().compile(compiler, context);
match op {
CompOp::Equal => compiler.add_instruction(Instruction::Eq),
CompOp::NotEqual => compiler.add_instruction(Instruction::NotEq),
Expand Down
4 changes: 2 additions & 2 deletions boa/src/syntax/ast/node/operator/unary_op/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,9 @@ impl From<UnaryOp> for Node {

#[cfg(feature = "vm")]
impl CodeGen for UnaryOp {
fn compile(&self, compiler: &mut Compiler) {
fn compile(&self, compiler: &mut Compiler, context: &mut Context) {
let _timer = BoaProfiler::global().start_event("UnaryOp", "codeGen");
self.target().compile(compiler);
self.target().compile(compiler, context);
match self.op {
op::UnaryOp::Void => compiler.add_instruction(Instruction::Void),
op::UnaryOp::Plus => compiler.add_instruction(Instruction::Pos),
Expand Down
4 changes: 2 additions & 2 deletions boa/src/syntax/ast/node/statement_list/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,11 @@ impl Executable for StatementList {

#[cfg(feature = "vm")]
impl CodeGen for StatementList {
fn compile(&self, compiler: &mut Compiler) {
fn compile(&self, compiler: &mut Compiler, context: &mut Context) {
let _timer = BoaProfiler::global().start_event("StatementList - Code Gen", "codeGen");

for item in self.items().iter() {
item.compile(compiler);
item.compile(compiler, context);
}
}
}
Expand Down
31 changes: 26 additions & 5 deletions boa/src/vm/compilation.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::*;
use crate::{syntax::ast::Const, syntax::ast::Node, value::RcBigInt, value::RcString};
use crate::{syntax::ast::Const, syntax::ast::Node, value::RcBigInt, value::RcString, exec::Executable};

#[derive(Debug, Default)]
pub struct Compiler {
Expand Down Expand Up @@ -30,14 +30,25 @@ impl Compiler {
self.add_instruction(Instruction::BigInt(index));
self.pool.push(bigint.into().into());
}

pub fn add_defvar_instruction<N, V>(&mut self, name: N, value: V)
where
N: Into<RcString>,
V: Into<Value>,
{
let index = self.pool.len();
self.add_instruction(Instruction::DefVar(index, index + 1));
self.pool.push(name.into().into());
self.pool.push(value.into().into());
}
}

pub(crate) trait CodeGen {
fn compile(&self, compiler: &mut Compiler);
fn compile(&self, compiler: &mut Compiler, context: &mut Context);
}

impl CodeGen for Node {
fn compile(&self, compiler: &mut Compiler) {
fn compile(&self, compiler: &mut Compiler, context: &mut Context) {
let _timer = BoaProfiler::global().start_event(&format!("Node ({})", &self), "codeGen");
match *self {
Node::Const(Const::Undefined) => compiler.add_instruction(Instruction::Undefined),
Expand All @@ -56,8 +67,18 @@ impl CodeGen for Node {
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),
Node::BinOp(ref op) => op.compile(compiler, context),
Node::UnaryOp(ref op) => op.compile(compiler, context),
Node::LetDeclList(ref list) => {
for let_decl in list.as_ref() {
let value = match let_decl.init() {
Some(v) => v.run(context).unwrap_or_else(|_| Value::undefined()),
None => Value::undefined(),
};

compiler.add_defvar_instruction(let_decl.name(), value);
}
}
_ => unimplemented!(),
}
}
Expand Down
3 changes: 3 additions & 0 deletions boa/src/vm/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ pub enum Instruction {
Neg,
BitNot,
Not,

DefVar(usize, usize),
}

impl std::fmt::Display for Instruction {
Expand Down Expand Up @@ -100,6 +102,7 @@ impl std::fmt::Display for Instruction {
Self::Neg => write!(f, "Neg"),
Self::BitNot => write!(f, "BitNot"),
Self::Not => write!(f, "Not"),
Self::DefVar(name, value) => write!(f, "DefVar({}, {})", name, value),
}
}
}
24 changes: 22 additions & 2 deletions boa/src/vm/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use crate::{Context, Result, Value};
use crate::{
Context, Result, Value, BoaProfiler,
environment::lexical_environment::VariableScope,
};

pub(crate) mod compilation;
pub(crate) mod instructions;

use crate::BoaProfiler;
pub use compilation::Compiler;
pub use instructions::Instruction;

Expand Down Expand Up @@ -268,6 +270,24 @@ impl<'a> VM<'a> {
};
self.push(value.into());
}
Instruction::DefVar(name_index, value_index) => {
let name = self.pool[name_index].to_string(self.ctx)?;
let value = self.pool[value_index].clone();

self.ctx
.realm_mut()
.environment
.create_mutable_binding(name.to_string(), false, VariableScope::Block)
.map_err(|e| e.to_error(self.ctx))?;

self.ctx
.realm_mut()
.environment
.initialize_binding(&name, value)
.map_err(|e| e.to_error(self.ctx))?;

self.push(Value::undefined());
}
}

idx += 1;
Expand Down

0 comments on commit 67f92ef

Please sign in to comment.