mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-04-18 03:00:27 -04:00
Limit register copying to only variables that are mutated
This commit is contained in:
@@ -1333,23 +1333,15 @@ impl<'a> ExpressionCompiler<'a> {
|
||||
}
|
||||
};
|
||||
|
||||
let value = match self.fnc.lookup_value(ident) {
|
||||
Some(v) => v, // TODO: Capturing functions
|
||||
let name = match self.fnc.lookup(ident) {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
self.fnc.diagnostics.push(Diagnostic {
|
||||
level: DiagnosticLevel::InternalError,
|
||||
message: format!(
|
||||
"Failed to lookup identifier `{}`, ref: {:?}",
|
||||
ident.sym,
|
||||
self.fnc.scope_analysis.refs.get(&ident.span)
|
||||
),
|
||||
span: ident.span,
|
||||
});
|
||||
|
||||
Value::Register(self.fnc.allocate_numbered_reg("_todo_identifier"))
|
||||
return self.inline(Value::Undefined, target_register);
|
||||
}
|
||||
};
|
||||
|
||||
let value = name.value.clone();
|
||||
|
||||
match fn_as_owner_id {
|
||||
Some(owner_id) => {
|
||||
let capture_params = self.fnc.scope_analysis.captures.get(&owner_id).cloned();
|
||||
@@ -1367,7 +1359,15 @@ impl<'a> ExpressionCompiler<'a> {
|
||||
}
|
||||
None => match value {
|
||||
Value::Register(reg) => {
|
||||
if name.mutations.is_empty() {
|
||||
// Just use the register for the variable if it's not mutated
|
||||
return self.inline(Value::Register(reg), target_register);
|
||||
}
|
||||
|
||||
// Otherwise, we need to capture the current value for the result of the expression
|
||||
// TODO: This case can be limited further by checking *where* the mutations are
|
||||
let new_reg = self.fnc.allocate_tmp();
|
||||
|
||||
self.fnc.push(Instruction::Mov(
|
||||
Value::Register(reg.clone()),
|
||||
new_reg.clone(),
|
||||
|
||||
@@ -14,7 +14,7 @@ use crate::expression_compiler::CompiledExpression;
|
||||
use crate::expression_compiler::ExpressionCompiler;
|
||||
use crate::name_allocator::{NameAllocator, RegAllocator};
|
||||
use crate::scope::{NameId, OwnerId};
|
||||
use crate::scope_analysis::{fn_to_owner_id, ScopeAnalysis};
|
||||
use crate::scope_analysis::{fn_to_owner_id, Name, ScopeAnalysis};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Functionish {
|
||||
@@ -121,6 +121,20 @@ impl FunctionCompiler {
|
||||
self.current.body.push(InstructionOrLabel::Label(label));
|
||||
}
|
||||
|
||||
pub fn lookup(&mut self, ident: &swc_ecma_ast::Ident) -> Option<&Name> {
|
||||
let name = self.scope_analysis.lookup(ident);
|
||||
|
||||
if name.is_none() {
|
||||
self.diagnostics.push(Diagnostic {
|
||||
level: DiagnosticLevel::InternalError,
|
||||
message: format!("Could not find name for ident {:?}", ident),
|
||||
span: ident.span,
|
||||
});
|
||||
}
|
||||
|
||||
name
|
||||
}
|
||||
|
||||
pub fn lookup_value(&self, ident: &swc_ecma_ast::Ident) -> Option<Value> {
|
||||
self.scope_analysis.lookup_value(&self.owner_id, ident)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user