Skip to content

Commit

Permalink
rework constants with SoA
Browse files Browse the repository at this point in the history
  • Loading branch information
y21 committed Oct 7, 2024
1 parent 270638e commit 281a7bd
Show file tree
Hide file tree
Showing 22 changed files with 524 additions and 415 deletions.
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/dash_compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ from_string = ["dash_parser", "dash_lexer"]
decompile = []

[dependencies]
dash_regex = { path = "../dash_regex" }
dash_middle = { path = "../dash_middle" }
strum = "0.24.0"
strum_macros = "0.24.0"
Expand Down
96 changes: 73 additions & 23 deletions crates/dash_compiler/src/instruction.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use dash_middle::compiler::constant::{Constant, LimitExceededError};
use std::rc::Rc;

use dash_middle::compiler::constant::{
BooleanConstant, Function, FunctionConstant, LimitExceededError, NumberConstant, RegexConstant, SymbolConstant,
};
use dash_middle::compiler::instruction::{AssignKind, Instruction, IntrinsicOperation};
use dash_middle::compiler::{
ExportPropertyKind, FunctionCallMetadata, ObjectMemberKind as CompilerObjectMemberKind, StaticImportKind,
Expand Down Expand Up @@ -81,12 +85,6 @@ impl<'cx, 'interner> InstructionBuilder<'cx, 'interner> {
self.writew(tc_depth);
}

pub fn build_constant(&mut self, constant: Constant) -> Result<(), LimitExceededError> {
let id = self.current_function_mut().cp.add(constant)?;
self.write_wide_instr(Instruction::Constant, Instruction::ConstantW, id);
Ok(())
}

pub fn write_bool(&mut self, b: bool) {
self.write(b.into());
}
Expand All @@ -112,15 +110,67 @@ impl<'cx, 'interner> InstructionBuilder<'cx, 'interner> {
compile_local_load_into(&mut self.current_function_mut().buf, index, is_extern);
}

pub fn build_string_constant(&mut self, sym: Symbol) -> Result<(), LimitExceededError> {
let SymbolConstant(id) = self.current_function_mut().cp.add_symbol(sym)?;
self.write_instr(Instruction::String);
self.writew(id);
Ok(())
}

pub fn build_boolean_constant(&mut self, b: bool) -> Result<(), LimitExceededError> {
let BooleanConstant(id) = self.current_function_mut().cp.add_boolean(b)?;
self.write_instr(Instruction::Boolean);
self.writew(id);
Ok(())
}

pub fn build_number_constant(&mut self, n: f64) -> Result<(), LimitExceededError> {
let NumberConstant(id) = self.current_function_mut().cp.add_number(n)?;
self.write_instr(Instruction::Number);
self.writew(id);
Ok(())
}

pub fn build_regex_constant(
&mut self,
regex: dash_regex::ParsedRegex,
flags: dash_regex::Flags,
sym: Symbol,
) -> Result<(), LimitExceededError> {
let RegexConstant(id) = self.current_function_mut().cp.add_regex((regex, flags, sym))?;
self.write_instr(Instruction::Regex);
self.writew(id);
Ok(())
}

pub fn build_null_constant(&mut self) -> Result<(), LimitExceededError> {
self.write_instr(Instruction::Null);
Ok(())
}

pub fn build_undefined_constant(&mut self) -> Result<(), LimitExceededError> {
self.write_instr(Instruction::Undefined);
Ok(())
}

pub fn build_function_constant(&mut self, fun: Function) -> Result<(), LimitExceededError> {
let FunctionConstant(id) = self.current_function_mut().cp.add_function(Rc::new(fun))?;
self.write_instr(Instruction::Function);
self.writew(id);
Ok(())
}

// pub fn build_boolean_constant(&mut self, b: bool) -> Result<

pub fn build_global_load(&mut self, ident: Symbol) -> Result<(), LimitExceededError> {
let id = self.current_function_mut().cp.add(Constant::Identifier(ident))?;
let SymbolConstant(id) = self.current_function_mut().cp.add_symbol(ident)?;
self.write_instr(Instruction::LdGlobal);
self.writew(id);
Ok(())
}

pub fn build_global_store(&mut self, kind: AssignKind, ident: Symbol) -> Result<(), LimitExceededError> {
let id = self.current_function_mut().cp.add(Constant::Identifier(ident))?;
let SymbolConstant(id) = self.current_function_mut().cp.add_symbol(ident)?;
self.write_wide_instr(Instruction::StoreGlobal, Instruction::StoreGlobalW, id);
self.write(kind as u8);
Ok(())
Expand Down Expand Up @@ -196,7 +246,7 @@ impl<'cx, 'interner> InstructionBuilder<'cx, 'interner> {
}

pub fn build_static_prop_access(&mut self, ident: Symbol, preserve_this: bool) -> Result<(), LimitExceededError> {
let id = self.current_function_mut().cp.add(Constant::Identifier(ident))?;
let SymbolConstant(id) = self.current_function_mut().cp.add_symbol(ident)?;
self.write_instr(Instruction::StaticPropAccess);
self.writew(id);
self.write(preserve_this.into());
Expand All @@ -210,7 +260,7 @@ impl<'cx, 'interner> InstructionBuilder<'cx, 'interner> {
}

pub fn build_static_prop_assign(&mut self, kind: AssignKind, ident: Symbol) -> Result<(), LimitExceededError> {
let id = self.current_function_mut().cp.add(Constant::Identifier(ident))?;
let SymbolConstant(id) = self.current_function_mut().cp.add_symbol(ident)?;
self.write_instr(Instruction::StaticPropAssign);
self.write(kind as u8);
self.writew(id);
Expand Down Expand Up @@ -255,10 +305,10 @@ impl<'cx, 'interner> InstructionBuilder<'cx, 'interner> {
name: Symbol,
kind_id: u8,
) -> Result<(), Error> {
let id = ib
let SymbolConstant(id) = ib
.current_function_mut()
.cp
.add(Constant::Identifier(name))
.add_symbol(name)
.map_err(|_| Error::ConstantPoolLimitExceeded(span))?;

ib.write(kind_id);
Expand All @@ -284,20 +334,20 @@ impl<'cx, 'interner> InstructionBuilder<'cx, 'interner> {
Ok(())
}

pub fn build_static_import(&mut self, import: StaticImportKind, local_id: u16, path_id: u16) {
pub fn build_static_import(&mut self, import: StaticImportKind, local_id: u16, path_id: SymbolConstant) {
self.write_instr(Instruction::ImportStatic);
self.write(import as u8);
self.writew(local_id);
self.writew(path_id);
self.writew(path_id.0);
}

pub fn build_dynamic_import(&mut self) {
self.write_instr(Instruction::ImportDyn);
}

pub fn build_static_delete(&mut self, id: u16) {
pub fn build_static_delete(&mut self, id: SymbolConstant) {
self.write_instr(Instruction::DeletePropertyStatic);
self.writew(id);
self.writew(id.0);
}

pub fn build_named_export(&mut self, span: Span, it: &[NamedExportKind]) -> Result<(), Error> {
Expand All @@ -315,11 +365,11 @@ impl<'cx, 'interner> InstructionBuilder<'cx, 'interner> {
NamedExportKind::Local { loc_id, ident_id } => {
self.write(ExportPropertyKind::Local as u8);
self.writew(loc_id);
self.writew(ident_id);
self.writew(ident_id.0);
}
NamedExportKind::Global { ident_id } => {
self.write(ExportPropertyKind::Global as u8);
self.writew(ident_id);
self.writew(ident_id.0);
}
}
}
Expand Down Expand Up @@ -546,10 +596,10 @@ impl<'cx, 'interner> InstructionBuilder<'cx, 'interner> {
}

pub fn build_typeof_global_ident(&mut self, at: Span, ident: Symbol) -> Result<(), Error> {
let id = self
let SymbolConstant(id) = self
.current_function_mut()
.cp
.add(Constant::Identifier(ident))
.add_symbol(ident)
.map_err(|_| Error::ConstantPoolLimitExceeded(at))?;
self.write_instr(Instruction::TypeOfGlobalIdent);
self.writew(id);
Expand All @@ -559,8 +609,8 @@ impl<'cx, 'interner> InstructionBuilder<'cx, 'interner> {

#[derive(Copy, Clone)]
pub enum NamedExportKind {
Local { loc_id: u16, ident_id: u16 },
Global { ident_id: u16 },
Local { loc_id: u16, ident_id: SymbolConstant },
Global { ident_id: SymbolConstant },
}

pub fn compile_local_load_into(out: &mut Vec<u8>, index: u16, is_extern: bool) {
Expand Down
50 changes: 27 additions & 23 deletions crates/dash_compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::mem;
use std::rc::Rc;

use dash_log::{debug, span, Level};
use dash_middle::compiler::constant::{Buffer, Constant, ConstantPool, Function};
use dash_middle::compiler::constant::{Buffer, ConstantPool, Function, NumberConstant, SymbolConstant};
use dash_middle::compiler::external::External;
use dash_middle::compiler::instruction::{AssignKind, Instruction, IntrinsicOperation};
use dash_middle::compiler::scope::{CompileValueType, LimitExceededError, Local, ScopeGraph};
Expand Down Expand Up @@ -64,9 +64,7 @@ enum Breakable {
struct FunctionLocalState {
/// Instruction buffer
buf: Vec<u8>,
/// A list of constants used throughout this function.
///
/// Bytecode can refer to constants using the [Instruction::Constant] instruction, followed by a u8 index.
/// A list of constants used throughout this function
cp: ConstantPool,
/// Current `try` depth (note that this does NOT include `catch`es)
try_depth: u16,
Expand Down Expand Up @@ -107,7 +105,7 @@ impl FunctionLocalState {
pub fn new(ty: FunctionKind, id: ScopeId) -> Self {
Self {
buf: Vec::new(),
cp: ConstantPool::new(),
cp: ConstantPool::default(),
try_depth: 0,
finally_labels: Vec::new(),
finally_counter: Counter::new(),
Expand Down Expand Up @@ -717,11 +715,17 @@ impl<'interner> Visitor<Result<(), Error>> for FunctionCompiler<'interner> {
}

fn visit_literal_expression(&mut self, span: Span, expr: LiteralExpr) -> Result<(), Error> {
let constant = Constant::from_literal(&expr);
InstructionBuilder::new(self)
.build_constant(constant)
.map_err(|_| Error::ConstantPoolLimitExceeded(span))?;
Ok(())
let mut ib = InstructionBuilder::new(self);
let res = match expr {
LiteralExpr::Boolean(b) => ib.build_boolean_constant(b),
LiteralExpr::Number(n) => ib.build_number_constant(n),
LiteralExpr::String(s) => ib.build_string_constant(s),
LiteralExpr::Identifier(_) => unreachable!("identifiers are handled in visit_identifier_expression"),
LiteralExpr::Regex(regex, flags, sym) => ib.build_regex_constant(regex, flags, sym),
LiteralExpr::Null => ib.build_null_constant(),
LiteralExpr::Undefined => ib.build_undefined_constant(),
};
res.map_err(|_| Error::ConstantPoolLimitExceeded(span))
}

fn visit_identifier_expression(&mut self, span: Span, ident: Symbol) -> Result<(), Error> {
Expand Down Expand Up @@ -782,7 +786,7 @@ impl<'interner> Visitor<Result<(), Error>> for FunctionCompiler<'interner> {
let id = ib
.current_function_mut()
.cp
.add(Constant::Identifier(ident))
.add_symbol(ident)
.map_err(|_| Error::ConstantPoolLimitExceeded(span))?;
ib.build_static_delete(id);
}
Expand All @@ -797,12 +801,12 @@ impl<'interner> Visitor<Result<(), Error>> for FunctionCompiler<'interner> {
let id = ib
.current_function_mut()
.cp
.add(Constant::Identifier(ident))
.add_symbol(ident)
.map_err(|_| Error::ConstantPoolLimitExceeded(span))?;
ib.build_static_delete(id);
}
_ => {
ib.build_constant(Constant::Boolean(true))
ib.build_boolean_constant(true)
.map_err(|_| Error::ConstantPoolLimitExceeded(span))?;
}
}
Expand Down Expand Up @@ -876,15 +880,15 @@ impl<'interner> Visitor<Result<(), Error>> for FunctionCompiler<'interner> {
let name = alias.unwrap_or(name);
let id = ib.find_local_from_binding(Binding { id: local, ident: name });

let var_id = ib
let NumberConstant(var_id) = ib
.current_function_mut()
.cp
.add(Constant::Number(id as f64))
.add_number(id as f64)
.map_err(|_| Error::ConstantPoolLimitExceeded(span))?;
let ident_id = ib
let SymbolConstant(ident_id) = ib
.current_function_mut()
.cp
.add(Constant::Identifier(name))
.add_symbol(name)
.map_err(|_| Error::ConstantPoolLimitExceeded(span))?;
ib.writew(var_id);
ib.writew(ident_id);
Expand All @@ -910,10 +914,10 @@ impl<'interner> Visitor<Result<(), Error>> for FunctionCompiler<'interner> {
if let Some(name) = name {
let id = ib.find_local_from_binding(name);

let id = ib
let NumberConstant(id) = ib
.current_function_mut()
.cp
.add(Constant::Number(id as f64))
.add_number(id as f64)
.map_err(|_| Error::ConstantPoolLimitExceeded(span))?;

ib.writew(id);
Expand Down Expand Up @@ -1765,7 +1769,7 @@ impl<'interner> Visitor<Result<(), Error>> for FunctionCompiler<'interner> {

let function = Function {
buffer: Buffer(Cell::new(cmp.buf.into())),
constants: cmp.cp.into_vec().into(),
constants: cmp.cp,
locals,
name: name.map(|binding| binding.ident),
ty,
Expand All @@ -1780,7 +1784,7 @@ impl<'interner> Visitor<Result<(), Error>> for FunctionCompiler<'interner> {
source: Rc::clone(&ib.source),
references_arguments: cmp.references_arguments.is_some(),
};
ib.build_constant(Constant::Function(Rc::new(function)))
ib.build_function_constant(function)
.map_err(|_| Error::ConstantPoolLimitExceeded(span))?;

Ok(())
Expand Down Expand Up @@ -1988,7 +1992,7 @@ impl<'interner> Visitor<Result<(), Error>> for FunctionCompiler<'interner> {
let path_id = ib
.current_function_mut()
.cp
.add(Constant::String(path))
.add_symbol(path)
.map_err(|_| Error::ConstantPoolLimitExceeded(span))?;

ib.build_static_import(
Expand Down Expand Up @@ -2021,7 +2025,7 @@ impl<'interner> Visitor<Result<(), Error>> for FunctionCompiler<'interner> {
let ident_id = ib
.current_function_mut()
.cp
.add(Constant::Identifier(name))
.add_symbol(name)
.map_err(|_| Error::ConstantPoolLimitExceeded(span))?;

match ib.find_local(name) {
Expand Down
Loading

0 comments on commit 281a7bd

Please sign in to comment.