Index: sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart |
=================================================================== |
--- sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart (revision 14840) |
+++ sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart (working copy) |
@@ -441,13 +441,17 @@ |
*/ |
class VariableNamer { |
final VariableNames names; |
+ final Compiler compiler; |
final Set<String> usedNames; |
final Map<Element, String> parameterNames; |
final List<String> freeTemporaryNames; |
int temporaryIndex = 0; |
static final RegExp regexp = new RegExp('t[0-9]+'); |
- VariableNamer(LiveEnvironment environment, this.names, this.parameterNames) |
+ VariableNamer(LiveEnvironment environment, |
+ this.names, |
+ this.parameterNames, |
+ this.compiler) |
: usedNames = new Set<String>(), |
freeTemporaryNames = new List<String>() { |
// [VariableNames.swapTemp] is used when there is a cycle in a copy handler. |
@@ -512,11 +516,23 @@ |
if (name != null) return addAllocatedName(instruction, name); |
} |
- // The dom/html libraries have inline JS code that reference |
- // parameter names directly. Long-term such code will be rejected. |
- // Now, just don't mangle the parameter name. |
- if (instruction is HParameterValue |
+ if (instruction is HThis) { |
+ name = "this"; |
+ if (instruction.sourceElement != null) { |
+ Element cls = instruction.sourceElement.getEnclosingClass(); |
+ // Change the name of [:this:] in a method of a foreign class |
+ // to use the first parameter of the method, which is the |
+ // actual receiver. |
+ JavaScriptBackend backend = compiler.backend; |
+ if (backend.isInterceptorClass(cls)) { |
+ name = "primitive"; |
+ } |
+ } |
+ } else if (instruction is HParameterValue |
&& instruction.sourceElement.enclosingElement.isNative()) { |
+ // The dom/html libraries have inline JS code that reference |
+ // parameter names directly. Long-term such code will be rejected. |
+ // Now, just don't mangle the parameter name. |
name = instruction.sourceElement.name.slowToString(); |
} else if (instruction.sourceElement != null) { |
name = allocateWithHint(instruction.sourceElement.name.slowToString()); |
@@ -531,12 +547,11 @@ |
name = allocateTemporary(); |
} |
} |
- |
return addAllocatedName(instruction, name); |
} |
String addAllocatedName(HInstruction instruction, String name) { |
- if (instruction is HParameterValue) { |
+ if (instruction is HParameterValue && name != 'this') { |
parameterNames[instruction.sourceElement] = name; |
} |
usedNames.add(name); |
@@ -599,7 +614,7 @@ |
void visitBasicBlock(HBasicBlock block) { |
VariableNamer namer = new VariableNamer( |
- liveInstructions[block], names, parameterNames); |
+ liveInstructions[block], names, parameterNames, compiler); |
block.forEachPhi((HPhi phi) { |
handlePhi(phi, namer); |
@@ -618,7 +633,7 @@ |
// TODO(ngeoffray): locals/parameters are being generated at use site, |
// but we need a name for them. We should probably not make |
// them generate at use site to make things simpler. |
- if (instruction is HLocalValue && instruction is !HThis) return true; |
+ if (instruction is HLocalValue) return true; |
if (instruction.usedBy.isEmpty) return false; |
if (generateAtUseSite.contains(instruction)) return false; |
// A [HCheck] instruction that has control flow needs a name only if its |