mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-04-18 03:00:27 -04:00
Use compile-time borrowing of module compiler to simplify fnc, ec
This commit is contained in:
@@ -61,11 +61,11 @@ impl Drop for ReleaseChecker {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ExpressionCompiler<'a> {
|
||||
pub fnc: &'a mut FunctionCompiler,
|
||||
pub struct ExpressionCompiler<'a, 'fnc> {
|
||||
pub fnc: &'a mut FunctionCompiler<'fnc>,
|
||||
}
|
||||
|
||||
impl<'a> ExpressionCompiler<'a> {
|
||||
impl<'a, 'fnc> ExpressionCompiler<'a, 'fnc> {
|
||||
pub fn compile_top_level(
|
||||
&mut self,
|
||||
expr: &swc_ecma_ast::Expr,
|
||||
@@ -952,6 +952,7 @@ impl<'a> ExpressionCompiler<'a> {
|
||||
|
||||
let capture_params = self
|
||||
.fnc
|
||||
.mc
|
||||
.scope_analysis
|
||||
.get_register_captures(&fn_to_owner_id(&fn_.ident, &fn_.function));
|
||||
|
||||
@@ -989,6 +990,7 @@ impl<'a> ExpressionCompiler<'a> {
|
||||
|
||||
let capture_params = self
|
||||
.fnc
|
||||
.mc
|
||||
.scope_analysis
|
||||
.get_register_captures(&OwnerId::Span(arrow_expr.span));
|
||||
|
||||
@@ -1075,6 +1077,7 @@ impl<'a> ExpressionCompiler<'a> {
|
||||
if !is_param {
|
||||
let cap_name = self
|
||||
.fnc
|
||||
.mc
|
||||
.scope_analysis
|
||||
.names
|
||||
.get(cap)
|
||||
@@ -1232,7 +1235,7 @@ impl<'a> ExpressionCompiler<'a> {
|
||||
ident: &CrateIdent,
|
||||
target_register: Option<Register>,
|
||||
) -> CompiledExpression {
|
||||
let fn_as_owner_id = match self.fnc.scope_analysis.lookup(ident) {
|
||||
let fn_as_owner_id = match self.fnc.mc.scope_analysis.lookup(ident) {
|
||||
Some(name) => match name.type_ == NameType::Function {
|
||||
true => match name.id {
|
||||
// TODO: This is a bit of a hack, it might break...
|
||||
@@ -1265,7 +1268,7 @@ impl<'a> ExpressionCompiler<'a> {
|
||||
|
||||
match fn_as_owner_id {
|
||||
Some(owner_id) => {
|
||||
let capture_params = self.fnc.scope_analysis.get_register_captures(&owner_id);
|
||||
let capture_params = self.fnc.mc.scope_analysis.get_register_captures(&owner_id);
|
||||
|
||||
match capture_params.len() {
|
||||
0 => value.to_ce(),
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
use queues::*;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::{BTreeSet, HashMap};
|
||||
use std::collections::BTreeSet;
|
||||
use std::mem::take;
|
||||
use std::rc::Rc;
|
||||
|
||||
use swc_common::Spanned;
|
||||
|
||||
@@ -15,9 +13,10 @@ use crate::diagnostic::{Diagnostic, DiagnosticLevel};
|
||||
use crate::expression_compiler::CompiledExpression;
|
||||
use crate::expression_compiler::ExpressionCompiler;
|
||||
use crate::ident::Ident;
|
||||
use crate::module_compiler::ModuleCompiler;
|
||||
use crate::name_allocator::{NameAllocator, RegAllocator};
|
||||
use crate::scope::{NameId, OwnerId};
|
||||
use crate::scope_analysis::{fn_to_owner_id, Name, ScopeAnalysis};
|
||||
use crate::scope_analysis::{fn_to_owner_id, Name};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Functionish {
|
||||
@@ -62,13 +61,11 @@ pub struct CatchSetting {
|
||||
pub reg: Register,
|
||||
}
|
||||
|
||||
pub struct FunctionCompiler {
|
||||
pub struct FunctionCompiler<'a> {
|
||||
pub mc: &'a mut ModuleCompiler,
|
||||
pub current: Function,
|
||||
pub definitions: Vec<Definition>,
|
||||
pub owner_id: OwnerId,
|
||||
pub scope_analysis: Rc<ScopeAnalysis>,
|
||||
pub constants_map: Rc<RefCell<HashMap<Pointer, Value>>>,
|
||||
pub definition_allocator: Rc<RefCell<NameAllocator>>,
|
||||
pub reg_allocator: RegAllocator,
|
||||
pub label_allocator: NameAllocator,
|
||||
pub queue: Queue<QueuedFunction>,
|
||||
@@ -81,25 +78,18 @@ pub struct FunctionCompiler {
|
||||
pub diagnostics: Vec<Diagnostic>,
|
||||
}
|
||||
|
||||
impl FunctionCompiler {
|
||||
pub fn new(
|
||||
scope_analysis: &Rc<ScopeAnalysis>,
|
||||
constants_map: &Rc<RefCell<HashMap<Pointer, Value>>>,
|
||||
owner_id: OwnerId,
|
||||
definition_allocator: Rc<RefCell<NameAllocator>>,
|
||||
) -> FunctionCompiler {
|
||||
let reg_allocator = match scope_analysis.reg_allocators.get(&owner_id) {
|
||||
impl<'a> FunctionCompiler<'a> {
|
||||
pub fn new(mc: &'a mut ModuleCompiler, owner_id: OwnerId) -> Self {
|
||||
let reg_allocator = match mc.scope_analysis.reg_allocators.get(&owner_id) {
|
||||
Some(reg_allocator) => reg_allocator.clone(),
|
||||
None => RegAllocator::default(),
|
||||
};
|
||||
|
||||
FunctionCompiler {
|
||||
mc,
|
||||
current: Function::default(),
|
||||
definitions: vec![],
|
||||
owner_id,
|
||||
scope_analysis: scope_analysis.clone(),
|
||||
constants_map: constants_map.clone(),
|
||||
definition_allocator,
|
||||
reg_allocator,
|
||||
label_allocator: NameAllocator::default(),
|
||||
queue: Queue::new(),
|
||||
@@ -134,7 +124,7 @@ impl FunctionCompiler {
|
||||
}
|
||||
|
||||
pub fn lookup(&mut self, ident: &Ident) -> Option<&Name> {
|
||||
let name = self.scope_analysis.lookup(ident);
|
||||
let name = self.mc.scope_analysis.lookup(ident);
|
||||
|
||||
if name.is_none() {
|
||||
self.diagnostics.push(Diagnostic {
|
||||
@@ -148,11 +138,12 @@ impl FunctionCompiler {
|
||||
}
|
||||
|
||||
pub fn lookup_value(&self, ident: &Ident) -> Option<Value> {
|
||||
self.scope_analysis.lookup_value(&self.owner_id, ident)
|
||||
self.mc.scope_analysis.lookup_value(&self.owner_id, ident)
|
||||
}
|
||||
|
||||
pub fn lookup_by_name_id(&self, name_id: &NameId) -> Option<Value> {
|
||||
self
|
||||
.mc
|
||||
.scope_analysis
|
||||
.lookup_by_name_id(&self.owner_id, name_id)
|
||||
}
|
||||
@@ -182,10 +173,7 @@ impl FunctionCompiler {
|
||||
}
|
||||
|
||||
pub fn allocate_defn(&mut self, name: &str) -> Pointer {
|
||||
let allocated_name = self
|
||||
.definition_allocator
|
||||
.borrow_mut()
|
||||
.allocate(&name.to_string());
|
||||
let allocated_name = self.mc.definition_allocator.allocate(&name.to_string());
|
||||
|
||||
Pointer {
|
||||
name: allocated_name,
|
||||
@@ -193,10 +181,7 @@ impl FunctionCompiler {
|
||||
}
|
||||
|
||||
pub fn allocate_defn_numbered(&mut self, name: &str) -> Pointer {
|
||||
let allocated_name = self
|
||||
.definition_allocator
|
||||
.borrow_mut()
|
||||
.allocate_numbered(name);
|
||||
let allocated_name = self.mc.definition_allocator.allocate_numbered(name);
|
||||
|
||||
Pointer {
|
||||
name: allocated_name,
|
||||
@@ -240,19 +225,12 @@ impl FunctionCompiler {
|
||||
}
|
||||
|
||||
pub fn compile(
|
||||
mc: &'a mut ModuleCompiler,
|
||||
definition_pointer: Pointer,
|
||||
fn_name: Option<String>,
|
||||
functionish: Functionish,
|
||||
scope_analysis: &Rc<ScopeAnalysis>,
|
||||
constants_map: &Rc<RefCell<HashMap<Pointer, Value>>>,
|
||||
definition_allocator: Rc<RefCell<NameAllocator>>,
|
||||
) -> (Vec<Definition>, Vec<Diagnostic>) {
|
||||
let mut self_ = FunctionCompiler::new(
|
||||
scope_analysis,
|
||||
constants_map,
|
||||
functionish.owner_id(),
|
||||
definition_allocator,
|
||||
);
|
||||
let mut self_ = FunctionCompiler::new(mc, functionish.owner_id());
|
||||
|
||||
self_
|
||||
.queue
|
||||
@@ -287,6 +265,7 @@ impl FunctionCompiler {
|
||||
|
||||
// TODO: Use a new FunctionCompiler per function instead of this hack
|
||||
self.reg_allocator = match self
|
||||
.mc
|
||||
.scope_analysis
|
||||
.reg_allocators
|
||||
.get(&functionish.owner_id())
|
||||
@@ -298,11 +277,13 @@ impl FunctionCompiler {
|
||||
self.owner_id = functionish.owner_id();
|
||||
|
||||
let capture_params = self
|
||||
.mc
|
||||
.scope_analysis
|
||||
.get_register_captures(&functionish.owner_id());
|
||||
|
||||
for cap_param in capture_params {
|
||||
let reg = match self
|
||||
.mc
|
||||
.scope_analysis
|
||||
.lookup_capture(&self.owner_id, &cap_param)
|
||||
{
|
||||
@@ -454,7 +435,7 @@ impl FunctionCompiler {
|
||||
}
|
||||
|
||||
pub fn get_variable_register(&mut self, ident: &Ident) -> Register {
|
||||
match self.scope_analysis.lookup_value(&self.owner_id, ident) {
|
||||
match self.mc.scope_analysis.lookup_value(&self.owner_id, ident) {
|
||||
Some(Value::Register(reg)) => reg,
|
||||
lookup_result => {
|
||||
self.diagnostics.push(Diagnostic {
|
||||
@@ -1243,6 +1224,7 @@ impl FunctionCompiler {
|
||||
TsTypeAlias(_) => {}
|
||||
TsEnum(ts_enum) => {
|
||||
let pointer = match self
|
||||
.mc
|
||||
.scope_analysis
|
||||
.lookup_value(&OwnerId::Module, &Ident::from_swc_ident(&ts_enum.id))
|
||||
{
|
||||
@@ -1259,8 +1241,8 @@ impl FunctionCompiler {
|
||||
};
|
||||
|
||||
let enum_value = compile_enum_value(
|
||||
&self.scope_analysis,
|
||||
&self.constants_map.borrow(),
|
||||
&self.mc.scope_analysis,
|
||||
&self.mc.constants_map,
|
||||
ts_enum,
|
||||
&mut self.diagnostics,
|
||||
);
|
||||
@@ -1333,7 +1315,7 @@ impl FunctionCompiler {
|
||||
|
||||
let mut mutated_registers = BTreeSet::<Register>::new();
|
||||
|
||||
for (_span, mutated_name_id) in self.scope_analysis.mutations.range(start..end) {
|
||||
for (_span, mutated_name_id) in self.mc.scope_analysis.mutations.range(start..end) {
|
||||
if let Some(Value::Register(reg)) = self.lookup_by_name_id(mutated_name_id) {
|
||||
mutated_registers.insert(reg);
|
||||
}
|
||||
@@ -1342,7 +1324,7 @@ impl FunctionCompiler {
|
||||
// TODO: Avoid doing this. This is a workaround to include mutations of variables that are
|
||||
// supposed to be const, because we don't yet protect these variables from mutation that occurs
|
||||
// via method calls. Once that is implemented, this shouldn't be needed.
|
||||
for (_span, mutated_name_id) in self.scope_analysis.optional_mutations.range(start..end) {
|
||||
for (_span, mutated_name_id) in self.mc.scope_analysis.optional_mutations.range(start..end) {
|
||||
if let Some(Value::Register(reg)) = self.lookup_by_name_id(mutated_name_id) {
|
||||
mutated_registers.insert(reg);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use swc_common::errors::{DiagnosticBuilder, Emitter};
|
||||
@@ -96,12 +94,12 @@ pub fn compile_module(source: &str) -> CompilerOutput {
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct ModuleCompiler {
|
||||
diagnostics: Vec<Diagnostic>,
|
||||
definition_allocator: Rc<RefCell<NameAllocator>>,
|
||||
scope_analysis: Rc<ScopeAnalysis>,
|
||||
constants_map: Rc<RefCell<HashMap<Pointer, Value>>>,
|
||||
module: Module,
|
||||
pub struct ModuleCompiler {
|
||||
pub diagnostics: Vec<Diagnostic>,
|
||||
pub definition_allocator: NameAllocator,
|
||||
pub scope_analysis: ScopeAnalysis,
|
||||
pub constants_map: HashMap<Pointer, Value>,
|
||||
pub module: Module,
|
||||
}
|
||||
|
||||
impl ModuleCompiler {
|
||||
@@ -122,10 +120,7 @@ impl ModuleCompiler {
|
||||
}
|
||||
|
||||
fn allocate_defn(&mut self, name: &str) -> Pointer {
|
||||
let allocated_name = self
|
||||
.definition_allocator
|
||||
.borrow_mut()
|
||||
.allocate(&name.to_string());
|
||||
let allocated_name = self.definition_allocator.allocate(&name.to_string());
|
||||
|
||||
Pointer {
|
||||
name: allocated_name,
|
||||
@@ -133,10 +128,7 @@ impl ModuleCompiler {
|
||||
}
|
||||
|
||||
fn allocate_defn_numbered(&mut self, name: &str) -> Pointer {
|
||||
let allocated_name = self
|
||||
.definition_allocator
|
||||
.borrow_mut()
|
||||
.allocate_numbered(name);
|
||||
let allocated_name = self.definition_allocator.allocate_numbered(name);
|
||||
|
||||
Pointer {
|
||||
name: allocated_name,
|
||||
@@ -169,7 +161,7 @@ impl ModuleCompiler {
|
||||
);
|
||||
|
||||
let mut self_ = Self {
|
||||
scope_analysis: Rc::new(scope_analysis),
|
||||
scope_analysis,
|
||||
diagnostics: scope_analysis_diagnostics,
|
||||
..Default::default()
|
||||
};
|
||||
@@ -208,7 +200,7 @@ impl ModuleCompiler {
|
||||
.scope_analysis
|
||||
.lookup(&Ident::from_swc_ident(ident))
|
||||
.map(|name| name.value.clone()),
|
||||
expr => static_eval_expr(&self.scope_analysis, &self.constants_map.borrow(), expr),
|
||||
expr => static_eval_expr(&self.scope_analysis, &self.constants_map, expr),
|
||||
};
|
||||
|
||||
match value {
|
||||
@@ -311,7 +303,7 @@ impl ModuleCompiler {
|
||||
};
|
||||
|
||||
if let (Some(ident), Some(init)) = (ident, init) {
|
||||
let value_opt = static_eval_expr(&self.scope_analysis, &self.constants_map.borrow(), init);
|
||||
let value_opt = static_eval_expr(&self.scope_analysis, &self.constants_map, init);
|
||||
|
||||
let value = match value_opt {
|
||||
Some(value) => value,
|
||||
@@ -349,10 +341,7 @@ impl ModuleCompiler {
|
||||
}
|
||||
};
|
||||
|
||||
self
|
||||
.constants_map
|
||||
.borrow_mut()
|
||||
.insert(pointer.clone(), value.clone());
|
||||
self.constants_map.insert(pointer.clone(), value.clone());
|
||||
|
||||
self.module.definitions.push(Definition {
|
||||
pointer: pointer.clone(),
|
||||
@@ -430,7 +419,7 @@ impl ModuleCompiler {
|
||||
|
||||
let enum_value = compile_enum_value(
|
||||
&self.scope_analysis,
|
||||
&self.constants_map.borrow(),
|
||||
&self.constants_map,
|
||||
ts_enum,
|
||||
&mut self.diagnostics,
|
||||
);
|
||||
@@ -797,14 +786,8 @@ impl ModuleCompiler {
|
||||
fn_name: Option<String>,
|
||||
functionish: Functionish,
|
||||
) -> Vec<Definition> {
|
||||
let (defn, mut diagnostics) = FunctionCompiler::compile(
|
||||
defn_pointer,
|
||||
fn_name,
|
||||
functionish,
|
||||
&self.scope_analysis,
|
||||
&self.constants_map,
|
||||
self.definition_allocator.clone(),
|
||||
);
|
||||
let (defn, mut diagnostics) =
|
||||
FunctionCompiler::compile(self, defn_pointer, fn_name, functionish);
|
||||
|
||||
self.diagnostics.append(&mut diagnostics);
|
||||
|
||||
@@ -848,18 +831,13 @@ impl ModuleCompiler {
|
||||
));
|
||||
}
|
||||
|
||||
let mut member_initializers_fnc = FunctionCompiler::new(
|
||||
&self.scope_analysis,
|
||||
&self.constants_map,
|
||||
OwnerId::Span(class.span),
|
||||
self.definition_allocator.clone(),
|
||||
);
|
||||
let mut member_initializers_fnc = FunctionCompiler::new(self, OwnerId::Span(class.span));
|
||||
|
||||
for class_member in &class.body {
|
||||
match class_member {
|
||||
swc_ecma_ast::ClassMember::ClassProp(class_prop) => {
|
||||
if class_prop.is_static {
|
||||
self.todo(class_prop.span, "static props");
|
||||
member_initializers_fnc.todo(class_prop.span, "static props");
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -885,7 +863,7 @@ impl ModuleCompiler {
|
||||
ec.fnc.release_ce(compiled_value);
|
||||
}
|
||||
swc_ecma_ast::ClassMember::PrivateProp(private_prop) => {
|
||||
self.todo(private_prop.span, "private props")
|
||||
member_initializers_fnc.todo(private_prop.span, "private props")
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@@ -943,11 +921,8 @@ impl ModuleCompiler {
|
||||
let name = match &method.key {
|
||||
swc_ecma_ast::PropName::Ident(ident) => Value::String(ident.sym.to_string()),
|
||||
swc_ecma_ast::PropName::Computed(computed) => {
|
||||
let value_opt = static_eval_expr(
|
||||
&self.scope_analysis,
|
||||
&self.constants_map.borrow(),
|
||||
&computed.expr,
|
||||
);
|
||||
let value_opt =
|
||||
static_eval_expr(&self.scope_analysis, &self.constants_map, &computed.expr);
|
||||
|
||||
match value_opt {
|
||||
None => {
|
||||
|
||||
Reference in New Issue
Block a user