This commit is contained in:
Andrew Morris
2023-03-24 09:24:17 +11:00
parent 64e79cf13b
commit ec14f657e9
5 changed files with 74 additions and 185 deletions

View File

@@ -1024,7 +1024,8 @@ impl<'a> ExpressionCompiler<'a> {
.fnc
.scope_analysis
.captures
.get(&OwnerId::Span(fn_.function.span));
.get(&OwnerId::Span(fn_.function.span))
.cloned();
self
.fnc
@@ -1040,9 +1041,8 @@ impl<'a> ExpressionCompiler<'a> {
None => self.inline(Value::Pointer(definition_pointer), target_register),
Some(capture_params) => self.capturing_fn_ref(
fn_name,
fn_.ident.span(),
&definition_pointer,
capture_params,
&capture_params,
target_register,
),
}
@@ -1059,7 +1059,8 @@ impl<'a> ExpressionCompiler<'a> {
.fnc
.scope_analysis
.captures
.get(&OwnerId::Span(arrow_expr.span));
.get(&OwnerId::Span(arrow_expr.span))
.cloned();
self
.fnc
@@ -1073,26 +1074,20 @@ impl<'a> ExpressionCompiler<'a> {
match capture_params {
None => self.inline(Value::Pointer(definition_pointer), target_register),
Some(capture_params) => self.capturing_fn_ref(
None,
arrow_expr.span(),
&definition_pointer,
capture_params,
target_register,
),
Some(capture_params) => {
self.capturing_fn_ref(None, &definition_pointer, &capture_params, target_register)
}
}
}
pub fn capturing_fn_ref(
&mut self,
fn_name: Option<String>,
span: swc_common::Span,
definition_pointer: &Pointer,
captures: &HashSet<NameId>,
target_register: Option<Register>,
) -> CompiledExpression {
let mut nested_registers = Vec::<Register>::new();
let mut sub_nested_registers = Vec::<Register>::new();
let reg = match target_register {
None => {
@@ -1120,10 +1115,6 @@ impl<'a> ExpressionCompiler<'a> {
reg.clone(),
));
for reg in sub_nested_registers {
self.fnc.release_reg(&reg);
}
return CompiledExpression::new(Value::Register(reg), nested_registers);
}

View File

@@ -208,7 +208,7 @@ impl FunctionCompiler {
pub fn process_queue(&mut self) {
loop {
match self.queue.remove() {
Ok(qfn) => self.compile_functionish(qfn.definition_pointer, qfn.fn_name, &qfn.functionish),
Ok(qfn) => self.compile_functionish(qfn.definition_pointer, &qfn.functionish),
Err(_) => {
break;
}
@@ -216,12 +216,7 @@ impl FunctionCompiler {
}
}
fn compile_functionish(
&mut self,
definition_pointer: Pointer,
fn_name: Option<String>,
functionish: &Functionish,
) {
fn compile_functionish(&mut self, definition_pointer: Pointer, functionish: &Functionish) {
// TODO: Use a new FunctionCompiler per function instead of this hack
self.reg_allocator = self
.scope_analysis

View File

@@ -12,7 +12,6 @@ mod link_module;
mod module_compiler;
mod name_allocator;
mod resolve_path;
mod scope;
mod scope_analysis;
pub use assembler::assemble;

View File

@@ -11,14 +11,12 @@ use crate::asm::{
Class, Definition, DefinitionContent, Function, Instruction, InstructionOrLabel, Lazy, Module,
Object, Pointer, Register, Value,
};
use crate::diagnostic::{Diagnostic, DiagnosticLevel};
use crate::expression_compiler::{CompiledExpression, ExpressionCompiler};
use crate::function_compiler::{FunctionCompiler, Functionish};
use crate::name_allocator::NameAllocator;
use crate::scope_analysis::OwnerId;
use super::diagnostic::{Diagnostic, DiagnosticLevel};
use super::expression_compiler::{CompiledExpression, ExpressionCompiler};
use super::function_compiler::{FunctionCompiler, Functionish};
use super::name_allocator::NameAllocator;
use super::scope::{init_std_scope, MappedName, Scope};
use super::scope_analysis::ScopeAnalysis;
use crate::scope_analysis::ScopeAnalysis;
struct DiagnosticCollector {
diagnostics: Arc<Mutex<Vec<Diagnostic>>>,
@@ -174,7 +172,6 @@ impl ModuleCompiler {
fn compile_module(&mut self, module: &swc_ecma_ast::Module) {
let mut scope_analysis = ScopeAnalysis::run(module);
self.diagnostics.append(&mut scope_analysis.diagnostics);
let scope = init_std_scope();
for module_item in &module.body {
self.compile_module_item(module_item);
@@ -239,7 +236,7 @@ impl ModuleCompiler {
match decl {
Class(class) => {
self.compile_class(None, Some(class.ident.sym.to_string()), &class.class);
self.compile_class(None, Some(&class.ident), &class.class);
}
Fn(fn_) => self.compile_fn_decl(false, fn_),
Var(var_decl) => {
@@ -291,12 +288,7 @@ impl ModuleCompiler {
match &edd.decl {
DefaultDecl::Class(class) => {
let class_name = match &class.ident {
Some(ident) => Some(ident.sym.to_string()),
None => None,
};
let pointer = self.compile_class(None, class_name, &class.class);
let pointer = self.compile_class(None, class.ident.as_ref(), &class.class);
self.module.export_default = Value::Pointer(pointer);
}
DefaultDecl::Fn(fn_) => {
@@ -340,7 +332,7 @@ impl ModuleCompiler {
match &ed.decl {
Decl::Class(class) => {
let class_name = class.ident.sym.to_string();
self.compile_class(Some(class_name.clone()), Some(class_name), &class.class);
self.compile_class(Some(class_name.clone()), Some(&class.ident), &class.class);
}
Decl::Fn(fn_) => self.compile_fn_decl(true, fn_),
Decl::Var(var_decl) => {
@@ -366,7 +358,7 @@ impl ModuleCompiler {
match specifier {
Named(named) => {
let orig_name = match &named.orig {
ModuleExportName::Ident(ident) => ident.sym.to_string(),
ModuleExportName::Ident(ident) => ident,
ModuleExportName::Str(_) => {
self.diagnostics.push(Diagnostic {
level: DiagnosticLevel::InternalError,
@@ -374,7 +366,7 @@ impl ModuleCompiler {
span: named.span,
});
"_todo_export_non_ident".to_string()
continue;
}
};
@@ -384,7 +376,7 @@ impl ModuleCompiler {
self.todo(str_.span, "exporting a non-identifier");
"_todo_export_non_ident".to_string()
}
None => orig_name.clone(),
None => orig_name.sym.to_string(),
};
let defn = match &en.src {
@@ -394,7 +386,7 @@ impl ModuleCompiler {
self.module.definitions.push(Definition {
pointer: defn.clone(),
content: DefinitionContent::Lazy(Lazy {
body: match orig_name == "default" {
body: match orig_name.sym.to_string() == "default" {
true => vec![InstructionOrLabel::Instruction(Instruction::Import(
Value::String(src.value.to_string()),
Register::Return,
@@ -406,7 +398,7 @@ impl ModuleCompiler {
)),
InstructionOrLabel::Instruction(Instruction::Sub(
Value::Register(Register::Return),
Value::String(orig_name.clone()),
Value::String(orig_name.sym.to_string()),
Register::Return,
)),
],
@@ -416,9 +408,9 @@ impl ModuleCompiler {
Some(defn)
}
None => match scope.get_defn(&orig_name) {
Some(found_defn) => Some(found_defn),
None => {
None => match self.scope_analysis.lookup(&OwnerId::Module, &orig_name) {
Value::Pointer(p) => Some(p),
_ => {
self.diagnostics.push(Diagnostic {
level: DiagnosticLevel::InternalError,
message: format!("Definition for {} should have been in scope", orig_name),
@@ -525,9 +517,18 @@ impl ModuleCompiler {
None => local_name.clone(),
};
let pointer = scope
.get_defn(&local_name)
.expect("imported name should have been in scope");
let pointer = match self.scope_analysis.lookup(&OwnerId::Module, &named.local) {
Value::Pointer(pointer) => pointer,
_ => {
self.diagnostics.push(Diagnostic {
level: DiagnosticLevel::InternalError,
message: format!("Imported name {} should have been a pointer", local_name),
span: named.span,
});
self.allocate_defn(local_name.as_str())
}
};
self.module.definitions.push(Definition {
pointer,
@@ -549,9 +550,18 @@ impl ModuleCompiler {
Default(default) => {
let local_name = default.local.sym.to_string();
let pointer = scope
.get_defn(&local_name)
.expect("imported name should have been in scope");
let pointer = match self.scope_analysis.lookup(&OwnerId::Module, &default.local) {
Value::Pointer(pointer) => pointer,
_ => {
self.diagnostics.push(Diagnostic {
level: DiagnosticLevel::InternalError,
message: format!("Imported name {} should have been a pointer", local_name),
span: default.span,
});
self.allocate_defn(local_name.as_str())
}
};
self.module.definitions.push(Definition {
pointer,
@@ -566,9 +576,21 @@ impl ModuleCompiler {
Namespace(namespace) => {
let local_name = namespace.local.sym.to_string();
let pointer = scope
.get_defn(&local_name)
.expect("imported name should have been in scope");
let pointer = match self
.scope_analysis
.lookup(&OwnerId::Module, &namespace.local)
{
Value::Pointer(pointer) => pointer,
_ => {
self.diagnostics.push(Diagnostic {
level: DiagnosticLevel::InternalError,
message: format!("Imported name {} should have been a pointer", local_name),
span: namespace.span,
});
self.allocate_defn(local_name.as_str())
}
};
self.module.definitions.push(Definition {
pointer,
@@ -606,31 +628,27 @@ impl ModuleCompiler {
fn compile_class(
&mut self,
export_name: Option<String>,
class_name: Option<String>,
ident: Option<&swc_ecma_ast::Ident>,
class: &swc_ecma_ast::Class,
) -> Pointer {
let mut constructor: Value = Value::Void;
let mut methods: Object = Object::default();
let mut dependent_definitions: Vec<Definition>;
let defn_name = 'block: {
let class_name = match class_name {
Some(class_name) => class_name,
None => break 'block self.allocate_defn_numbered("_anon"),
};
match parent_scope.get(&class_name) {
Some(MappedName::Definition(d)) => d,
let defn_name = match ident {
Some(ident) => match self.scope_analysis.lookup(&OwnerId::Module, ident) {
Value::Pointer(p) => p,
_ => {
self.diagnostics.push(Diagnostic {
level: DiagnosticLevel::InternalError,
message: format!("Definition for {} should have been in scope", class_name),
message: format!("Definition for {} should have been in scope", ident.sym),
span: class.span, // FIXME: make class_name ident and use that span
});
return self.allocate_defn_numbered("_scope_error");
self.allocate_defn_numbered("_scope_error")
}
}
},
None => self.allocate_defn_numbered("_anon"),
};
if let Some(export_name) = export_name {
@@ -656,7 +674,6 @@ impl ModuleCompiler {
}
let mut ec = ExpressionCompiler {
scope: parent_scope,
fnc: &mut member_initializers_fnc,
};
@@ -684,7 +701,7 @@ impl ModuleCompiler {
member_initializers_assembly.append(&mut member_initializers_fnc.current.body);
// Include any other definitions that were created by the member initializers
member_initializers_fnc.process_queue(parent_scope);
member_initializers_fnc.process_queue();
dependent_definitions = std::mem::take(&mut member_initializers_fnc.definitions);
let mut has_constructor = false;
@@ -704,7 +721,6 @@ impl ModuleCompiler {
class.span,
ctor.clone(),
),
parent_scope,
));
constructor = Value::Pointer(ctor_defn_name);
@@ -746,7 +762,6 @@ impl ModuleCompiler {
method_defn_name.clone(),
None,
Functionish::Fn(method.function.clone()),
parent_scope,
));
methods

View File

@@ -1,111 +0,0 @@
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use valuescript_common::BUILTIN_NAMES;
use crate::{
asm::{Builtin, Pointer, Register, Value},
constants::CONSTANTS,
};
use super::function_compiler::QueuedFunction;
#[derive(Clone, Debug)]
pub enum MappedName {
Register(Register),
Definition(Pointer),
QueuedFunction(QueuedFunction),
Builtin(Builtin),
Constant(Value),
}
pub fn scope_reg(name: String) -> MappedName {
if name == "return" || name == "this" || name == "ignore" {
std::panic!("Invalid register name (use Register enum)");
}
MappedName::Register(Register::Named(name))
}
pub struct ScopeData {
pub name_map: HashMap<String, MappedName>,
pub parent: Option<Scope>,
}
#[derive(Clone)]
pub struct Scope {
pub rc: Rc<RefCell<ScopeData>>,
}
impl Scope {
pub fn get(&self, name: &String) -> Option<MappedName> {
match self.rc.borrow().name_map.get(name) {
Some(mapped_name) => Some(mapped_name.clone()),
None => match &self.rc.borrow().parent {
Some(parent) => parent.get(name),
None => None,
},
}
}
pub fn get_defn(&self, name: &String) -> Option<Pointer> {
let get_result = self.get(name);
return match get_result {
Some(MappedName::Definition(d)) => Some(d.clone()),
_ => None,
};
}
pub fn set(&self, name: String, mapped_name: MappedName) {
let old_mapping = self.rc.borrow_mut().name_map.insert(name, mapped_name);
if old_mapping.is_some() {
std::panic!("Scope overwrite occurred (not implemented: being permissive about this)");
}
}
pub fn nest(&self) -> Scope {
return Scope {
rc: Rc::new(RefCell::new(ScopeData {
name_map: Default::default(),
parent: Some(self.clone()),
})),
};
}
}
pub fn _init_scope() -> Scope {
return Scope {
rc: Rc::new(RefCell::new(ScopeData {
name_map: Default::default(),
parent: None,
})),
};
}
pub fn init_std_scope() -> Scope {
let mut name_map: HashMap<String, MappedName> = Default::default();
for name in BUILTIN_NAMES {
name_map.insert(
name.to_string(),
MappedName::Builtin(Builtin {
name: name.to_string(),
}),
);
}
for (name, value) in CONSTANTS {
name_map.insert(name.to_string(), MappedName::Constant(value.clone()));
}
Scope {
rc: Rc::new(RefCell::new(ScopeData {
name_map,
parent: None,
})),
}
.nest()
}