Capture this in arrow functions

This commit is contained in:
Andrew Morris
2023-07-21 16:38:30 +10:00
parent fd116d06a2
commit 9536a5fc6e
18 changed files with 99 additions and 40 deletions

View File

@@ -6,6 +6,7 @@ use swc_common::Spanned;
use crate::asm::{Array, Instruction, Label, Number, Object, Register, Value};
use crate::diagnostic::{Diagnostic, DiagnosticLevel};
use crate::function_compiler::{FunctionCompiler, Functionish, QueuedFunction};
use crate::ident::Ident as CrateIdent;
use crate::scope::{NameId, OwnerId};
use crate::scope_analysis::{fn_to_owner_id, NameType};
use crate::target_accessor::TargetAccessor;
@@ -86,7 +87,7 @@ impl<'a> ExpressionCompiler<'a> {
use swc_ecma_ast::Expr::*;
match expr {
This(_) => Value::Register(Register::this()).to_ce(),
This(this) => self.ident(&CrateIdent::this(this.span), target_register),
Array(array_exp) => self.array_expression(array_exp, target_register),
Object(object_exp) => self.object_expression(object_exp, target_register),
Fn(fn_) => self.fn_expression(fn_, target_register),
@@ -123,7 +124,7 @@ impl<'a> ExpressionCompiler<'a> {
self.compile(seq_exp.exprs.last().unwrap(), target_register)
}
Ident(ident) => self.identifier(ident, target_register),
Ident(ident) => self.ident(&CrateIdent::from_swc_ident(ident), target_register),
Lit(lit) => self.compile_literal(lit).to_ce(),
Tpl(tpl) => self.template_literal(tpl, target_register),
TaggedTpl(tagged_tpl) => {
@@ -292,7 +293,7 @@ impl<'a> ExpressionCompiler<'a> {
CompiledExpression::new(Value::Register(target), nested_registers)
}
pub fn get_register_for_ident_mutation(&mut self, ident: &swc_ecma_ast::Ident) -> Register {
pub fn get_register_for_ident_mutation(&mut self, ident: &CrateIdent) -> Register {
let (reg, err_msg) = match self.fnc.lookup_value(ident) {
Some(Value::Register(reg)) => (Some(reg), None),
lookup_result => (
@@ -343,7 +344,9 @@ impl<'a> ExpressionCompiler<'a> {
) -> CompiledExpression {
let mut at = match &assign_expr.left {
swc_ecma_ast::PatOrExpr::Pat(pat) => match &**pat {
swc_ecma_ast::Pat::Ident(ident) => TargetAccessor::compile_ident(self, &ident.id),
swc_ecma_ast::Pat::Ident(ident) => {
TargetAccessor::compile_ident(self, &CrateIdent::from_swc_ident(&ident.id))
}
swc_ecma_ast::Pat::Expr(expr) => TargetAccessor::compile(self, expr, true),
_ => return self.assign_pat_eq(pat, &assign_expr.right, target_register),
},
@@ -410,9 +413,9 @@ impl<'a> ExpressionCompiler<'a> {
let mut target = match &assign_expr.left {
PatOrExpr::Expr(expr) => TargetAccessor::compile(self, expr, true),
PatOrExpr::Pat(pat) => match &**pat {
Pat::Ident(ident) => {
TargetAccessor::Register(self.get_register_for_ident_mutation(&ident.id))
}
Pat::Ident(ident) => TargetAccessor::Register(
self.get_register_for_ident_mutation(&CrateIdent::from_swc_ident(&ident.id)),
),
_ => {
self.fnc.diagnostics.push(Diagnostic {
level: DiagnosticLevel::Error,
@@ -496,7 +499,7 @@ impl<'a> ExpressionCompiler<'a> {
Prop::Shorthand(ident) => {
let prop_key = Value::String(ident.sym.to_string());
let mut compiled_value = self.identifier(ident, None);
let mut compiled_value = self.ident(&CrateIdent::from_swc_ident(ident), None);
sub_nested_registers.append(&mut compiled_value.nested_registers);
compiled_value.release_checker.has_unreleased_registers = false;
let prop_value = compiled_value.value;
@@ -1224,9 +1227,9 @@ impl<'a> ExpressionCompiler<'a> {
CompiledExpression::new(Value::Register(dst), nested_registers)
}
pub fn identifier(
pub fn ident(
&mut self,
ident: &swc_ecma_ast::Ident,
ident: &CrateIdent,
target_register: Option<Register>,
) -> CompiledExpression {
let fn_as_owner_id = match self.fnc.scope_analysis.lookup(ident) {
@@ -1251,6 +1254,8 @@ impl<'a> ExpressionCompiler<'a> {
}
};
let value = self.fnc.lookup_value(ident).unwrap_or_default();
let name = match self.fnc.lookup(ident) {
Some(v) => v,
None => {
@@ -1258,8 +1263,6 @@ impl<'a> ExpressionCompiler<'a> {
}
};
let value = name.value.clone();
match fn_as_owner_id {
Some(owner_id) => {
let capture_params = self.fnc.scope_analysis.get_register_captures(&owner_id);
@@ -1376,7 +1379,9 @@ impl<'a> ExpressionCompiler<'a> {
}
ObjectPatProp::Assign(assign) => {
let key = assign.key.sym.to_string();
let reg = self.fnc.get_variable_register(&assign.key);
let reg = self
.fnc
.get_variable_register(&CrateIdent::from_swc_ident(&assign.key));
self.fnc.push(Instruction::Sub(
Value::Register(register.clone()),

View File

@@ -14,6 +14,7 @@ use crate::compile_enum_value::compile_enum_value;
use crate::diagnostic::{Diagnostic, DiagnosticLevel};
use crate::expression_compiler::CompiledExpression;
use crate::expression_compiler::ExpressionCompiler;
use crate::ident::Ident;
use crate::name_allocator::{NameAllocator, RegAllocator};
use crate::scope::{NameId, OwnerId};
use crate::scope_analysis::{fn_to_owner_id, Name, ScopeAnalysis};
@@ -132,7 +133,7 @@ impl FunctionCompiler {
self.current.body.push(FnLine::Comment(message));
}
pub fn lookup(&mut self, ident: &swc_ecma_ast::Ident) -> Option<&Name> {
pub fn lookup(&mut self, ident: &Ident) -> Option<&Name> {
let name = self.scope_analysis.lookup(ident);
if name.is_none() {
@@ -146,7 +147,7 @@ impl FunctionCompiler {
name
}
pub fn lookup_value(&self, ident: &swc_ecma_ast::Ident) -> Option<Value> {
pub fn lookup_value(&self, ident: &Ident) -> Option<Value> {
self.scope_analysis.lookup_value(&self.owner_id, ident)
}
@@ -404,7 +405,7 @@ impl FunctionCompiler {
swc_ecma_ast::TsParamPropParam::Ident(ident) => {
match ident.id.sym.to_string().as_str() {
"this" => None,
_ => Some(self.get_variable_register(&ident.id)),
_ => Some(self.get_variable_register(&Ident::from_swc_ident(&ident.id))),
}
}
swc_ecma_ast::TsParamPropParam::Assign(assign) => {
@@ -431,7 +432,7 @@ impl FunctionCompiler {
Some(match param_pat {
Pat::Ident(ident) => match ident.id.sym.to_string().as_str() {
"this" => return None,
_ => self.get_variable_register(&ident.id),
_ => self.get_variable_register(&Ident::from_swc_ident(&ident.id)),
},
Pat::Assign(assign) => return self.get_pattern_register_opt(&assign.left),
Pat::Array(_) => self.allocate_numbered_reg("_array_pat"),
@@ -452,7 +453,7 @@ impl FunctionCompiler {
}
}
pub fn get_variable_register(&mut self, ident: &swc_ecma_ast::Ident) -> Register {
pub fn get_variable_register(&mut self, ident: &Ident) -> Register {
match self.scope_analysis.lookup_value(&self.owner_id, ident) {
Some(Value::Register(reg)) => reg,
lookup_result => {
@@ -462,7 +463,7 @@ impl FunctionCompiler {
"Register should have been allocated for variable {}, instead: {:?}",
ident.sym, lookup_result,
),
span: ident.span(),
span: ident.span,
});
self.allocate_numbered_reg("_error_variable_without_register")
@@ -1220,7 +1221,7 @@ impl FunctionCompiler {
self
.queue
.add(QueuedFunction {
definition_pointer: match self.lookup_value(&fn_decl.ident) {
definition_pointer: match self.lookup_value(&Ident::from_swc_ident(&fn_decl.ident)) {
Some(Value::Pointer(p)) => p,
_ => {
self.diagnostics.push(Diagnostic {
@@ -1228,7 +1229,7 @@ impl FunctionCompiler {
message: format!(
"Lookup of function {} was not a pointer, lookup_result: {:?}",
fn_decl.ident.sym,
self.lookup_value(&fn_decl.ident)
self.lookup_value(&Ident::from_swc_ident(&fn_decl.ident))
),
span: fn_decl.ident.span,
});
@@ -1247,7 +1248,7 @@ impl FunctionCompiler {
TsEnum(ts_enum) => {
let pointer = match self
.scope_analysis
.lookup_value(&OwnerId::Module, &ts_enum.id)
.lookup_value(&OwnerId::Module, &Ident::from_swc_ident(&ts_enum.id))
{
Some(Value::Pointer(p)) => p,
_ => {

View File

@@ -1,3 +1,4 @@
#[derive(Debug)]
pub struct Ident {
pub sym: swc_atoms::JsWord,
pub span: swc_common::Span,

View File

@@ -16,6 +16,7 @@ use crate::compile_enum_value::compile_enum_value;
use crate::diagnostic::{Diagnostic, DiagnosticLevel};
use crate::expression_compiler::{CompiledExpression, ExpressionCompiler};
use crate::function_compiler::{FunctionCompiler, Functionish};
use crate::ident::Ident;
use crate::name_allocator::{ident_from_str, NameAllocator};
use crate::scope::OwnerId;
use crate::scope_analysis::ScopeAnalysis;
@@ -205,7 +206,7 @@ impl ModuleCompiler {
let value = match &*ede.expr {
swc_ecma_ast::Expr::Ident(ident) => self
.scope_analysis
.lookup(ident)
.lookup(&Ident::from_swc_ident(ident))
.map(|name| name.value.clone()),
expr => static_eval_expr(&self.scope_analysis, &self.constants_map.borrow(), expr),
};
@@ -315,7 +316,7 @@ impl ModuleCompiler {
}
};
let pointer = match self.scope_analysis.lookup(ident) {
let pointer = match self.scope_analysis.lookup(&Ident::from_swc_ident(ident)) {
Some(name) => match &name.value {
Value::Pointer(p) => p.clone(),
_ => {
@@ -363,7 +364,7 @@ impl ModuleCompiler {
let pointer = match self
.scope_analysis
.lookup_value(&OwnerId::Module, &fn_.ident)
.lookup_value(&OwnerId::Module, &Ident::from_swc_ident(&fn_.ident))
{
Some(Value::Pointer(p)) => p,
_ => {
@@ -396,7 +397,7 @@ impl ModuleCompiler {
fn compile_enum_decl(&mut self, export: bool, ts_enum: &swc_ecma_ast::TsEnumDecl) {
let pointer = match self
.scope_analysis
.lookup_value(&OwnerId::Module, &ts_enum.id)
.lookup_value(&OwnerId::Module, &Ident::from_swc_ident(&ts_enum.id))
{
Some(Value::Pointer(p)) => p,
_ => {
@@ -443,7 +444,10 @@ impl ModuleCompiler {
Some(ident) => {
let fn_name = ident.sym.to_string();
let defn = match self.scope_analysis.lookup_value(&OwnerId::Module, ident) {
let defn = match self
.scope_analysis
.lookup_value(&OwnerId::Module, &Ident::from_swc_ident(ident))
{
Some(Value::Pointer(p)) => p,
_ => {
self.diagnostics.push(Diagnostic {
@@ -569,7 +573,7 @@ impl ModuleCompiler {
}
None => match self
.scope_analysis
.lookup_value(&OwnerId::Module, orig_name)
.lookup_value(&OwnerId::Module, &Ident::from_swc_ident(orig_name))
{
Some(Value::Pointer(p)) => Some(p),
lookup_result => {
@@ -694,7 +698,7 @@ impl ModuleCompiler {
let pointer = match self
.scope_analysis
.lookup_value(&OwnerId::Module, &named.local)
.lookup_value(&OwnerId::Module, &Ident::from_swc_ident(&named.local))
{
Some(Value::Pointer(p)) => p,
_ => {
@@ -730,7 +734,7 @@ impl ModuleCompiler {
let pointer = match self
.scope_analysis
.lookup_value(&OwnerId::Module, &default.local)
.lookup_value(&OwnerId::Module, &Ident::from_swc_ident(&default.local))
{
Some(Value::Pointer(p)) => p,
_ => {
@@ -759,7 +763,7 @@ impl ModuleCompiler {
let pointer = match self
.scope_analysis
.lookup_value(&OwnerId::Module, &namespace.local)
.lookup_value(&OwnerId::Module, &Ident::from_swc_ident(&namespace.local))
{
Some(Value::Pointer(p)) => p,
_ => {
@@ -819,7 +823,10 @@ impl ModuleCompiler {
let mut dependent_definitions: Vec<Definition>;
let defn_name = match ident {
Some(ident) => match self.scope_analysis.lookup_value(&OwnerId::Module, ident) {
Some(ident) => match self
.scope_analysis
.lookup_value(&OwnerId::Module, &Ident::from_swc_ident(ident))
{
Some(Value::Pointer(p)) => p,
_ => {
self.diagnostics.push(Diagnostic {

View File

@@ -136,12 +136,12 @@ impl ScopeAnalysis {
sa
}
pub fn lookup(&self, ident: &swc_ecma_ast::Ident) -> Option<&Name> {
pub fn lookup(&self, ident: &Ident) -> Option<&Name> {
let name_id = &self.refs.get(&ident.span)?.name_id;
self.names.get(name_id)
}
pub fn lookup_value(&self, scope: &OwnerId, ident: &swc_ecma_ast::Ident) -> Option<Value> {
pub fn lookup_value(&self, scope: &OwnerId, ident: &Ident) -> Option<Value> {
let name_id = &self.refs.get(&ident.span)?.name_id;
self.lookup_by_name_id(scope, name_id)
}

View File

@@ -5,6 +5,7 @@ use valuescript_vm::operations::to_i32;
use crate::{
asm::{Array, Builtin, Number, Object, Pointer, Value},
expression_compiler::value_from_literal,
ident::Ident,
scope_analysis::ScopeAnalysis,
};
@@ -84,7 +85,10 @@ pub fn static_eval_expr(
swc_ecma_ast::Expr::SuperProp(_) => None,
swc_ecma_ast::Expr::Call(_) => None,
swc_ecma_ast::Expr::New(_) => None,
swc_ecma_ast::Expr::Ident(ident) => match sa.lookup(ident).map(|name| name.value.clone()) {
swc_ecma_ast::Expr::Ident(ident) => match sa
.lookup(&Ident::from_swc_ident(ident))
.map(|name| name.value.clone())
{
Some(Value::Pointer(p)) => cm.get(&p).cloned(),
Some(value) => Some(value),
None => None,

View File

@@ -3,6 +3,7 @@ use std::mem::take;
use crate::{
asm::{Instruction, Register, Value},
expression_compiler::{CompiledExpression, ExpressionCompiler},
ident::Ident as CrateIdent,
Diagnostic, DiagnosticLevel,
};
use swc_common::Spanned;
@@ -23,7 +24,7 @@ impl TargetAccessor {
use swc_ecma_ast::Expr::*;
return match expr {
Ident(ident) => match ec.fnc.lookup(ident) {
Ident(ident) => match ec.fnc.lookup(&crate::ident::Ident::from_swc_ident(ident)) {
Some(name) => !name.effectively_const,
_ => false, // TODO: InternalError?
},
@@ -56,8 +57,8 @@ impl TargetAccessor {
use swc_ecma_ast::Expr::*;
return match expr {
Ident(ident) => TargetAccessor::compile_ident(ec, ident),
This(_) => TargetAccessor::Register(Register::this()),
Ident(ident) => TargetAccessor::compile_ident(ec, &CrateIdent::from_swc_ident(ident)),
This(this) => TargetAccessor::compile_ident(ec, &CrateIdent::this(this.span)),
Member(member) => {
let obj = TargetAccessor::compile(ec, &member.obj, false);
let subscript = ec.member_prop(&member.prop, None);
@@ -100,7 +101,7 @@ impl TargetAccessor {
};
}
pub fn compile_ident(ec: &mut ExpressionCompiler, ident: &swc_ecma_ast::Ident) -> TargetAccessor {
pub fn compile_ident(ec: &mut ExpressionCompiler, ident: &CrateIdent) -> TargetAccessor {
TargetAccessor::Register(ec.get_register_for_ident_mutation(ident))
}