Index: sdk/lib/_internal/compiler/implementation/ssa/codegen.dart |
=================================================================== |
--- sdk/lib/_internal/compiler/implementation/ssa/codegen.dart (revision 15190) |
+++ sdk/lib/_internal/compiler/implementation/ssa/codegen.dart (working copy) |
@@ -1529,16 +1529,6 @@ |
arguments); |
} |
- // TODO(ngeoffray): Once we remove the old interceptors, we can |
- // start using HInvokeInterceptor to represent interceptor calls on |
- // an Interceptor class. Currently we recognize if a call is a call |
- // on an interceptor by checking if the arguments in the inputs list |
- // is one more than the arguments in the selector. The extra |
- // argument in an interceptor call is the actual receiver. |
- bool isInterceptorCall(HInvokeDynamic node) { |
- return node.inputs.length - 1 != node.selector.argumentCount; |
- } |
- |
visitInvokeDynamicMethod(HInvokeDynamicMethod node) { |
use(node.receiver); |
js.Expression object = pop(); |
@@ -1565,7 +1555,7 @@ |
// receiver (the first is the interceptor), the backend gets |
// confused. We should pass a list of types instead of a node to |
// [registerDynamicInvocation]. |
- if (!isInterceptorCall(node)) { |
+ if (!node.isInterceptorCall) { |
backend.registerDynamicInvocation(node, selector, types); |
} else { |
backend.addInterceptedSelector(selector); |
@@ -1600,7 +1590,7 @@ |
// TODO(4434): For private members we need to use the untyped selector. |
if (defaultSelector.name.isPrivate()) return defaultSelector; |
// TODO(ngeoffray): Type intercepted calls. |
- if (isInterceptorCall(node)) return defaultSelector; |
+ if (node.isInterceptorCall) return defaultSelector; |
// If [JSInvocationMirror.invokeOn] has been called, we must not create a |
// typed selector based on the receiver type. |
if (node.element == null && // Invocation is not exact. |
@@ -1623,7 +1613,14 @@ |
push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node); |
Selector selector = getOptimizedSelectorFor(node, setter); |
world.registerDynamicSetter(setter.name, selector); |
- backend.addedDynamicSetter(selector, types[node.inputs[1]]); |
+ HType valueType; |
+ if (node.isInterceptorCall) { |
+ valueType = types[node.inputs[2]]; |
+ backend.addInterceptedSelector(setter); |
+ } else { |
+ valueType = types[node.inputs[1]]; |
+ } |
+ backend.addedDynamicSetter(selector, valueType); |
} |
visitInvokeDynamicGetter(HInvokeDynamicGetter node) { |
@@ -1633,7 +1630,7 @@ |
push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node); |
world.registerDynamicGetter( |
getter.name, getOptimizedSelectorFor(node, getter)); |
- if (isInterceptorCall(node)) { |
+ if (node.isInterceptorCall) { |
backend.addInterceptedSelector(getter); |
} |
} |
@@ -1715,14 +1712,19 @@ |
} |
visitFieldGet(HFieldGet node) { |
ahe
2012/11/23 06:51:23
What is a HFieldGet? Is that when we know that we
ngeoffray
2012/11/23 12:01:17
Yes.
|
- String name = backend.namer.getName(node.element); |
use(node.receiver); |
- push(new js.PropertyAccess.field(pop(), name), node); |
- HType receiverHType = types[node.receiver]; |
- DartType type = receiverHType.computeType(compiler); |
- if (type != null) { |
- world.registerFieldGetter( |
- node.element.name, node.element.getLibrary(), type); |
+ if (node.element == backend.jsArrayLength |
+ || node.element == backend.jsStringLength) { |
+ push(new js.PropertyAccess.field(pop(), 'length'), node); |
ahe
2012/11/23 06:51:23
Please add a comment explaining why this name shou
ngeoffray
2012/11/23 12:01:17
Done.
|
+ } else { |
+ String name = backend.namer.getName(node.element); |
+ push(new js.PropertyAccess.field(pop(), name), node); |
+ HType receiverHType = types[node.receiver]; |
+ DartType type = receiverHType.computeType(compiler); |
+ if (type != null) { |
+ world.registerFieldGetter( |
+ node.element.name, node.element.getLibrary(), type); |
+ } |
} |
} |
@@ -2198,64 +2200,6 @@ |
} |
} |
- String builtinJsName(HInvokeInterceptor interceptor) { |
- // Don't count the target method or the receiver in the arity. |
- int arity = interceptor.inputs.length - 2; |
- HInstruction receiver = interceptor.inputs[1]; |
- bool isCall = interceptor.selector.isCall(); |
- SourceString name = interceptor.selector.name; |
- |
- if (interceptor.isLengthGetterOnStringOrArray(types)) { |
- return 'length'; |
- } else if (interceptor.isPopCall(types)) { |
- return 'pop'; |
- } else if (receiver.isExtendableArray(types) && isCall) { |
- if (name == const SourceString('add') && arity == 1) { |
- return 'push'; |
- } |
- } else if (receiver.isString(types) && isCall) { |
- if (name == const SourceString('concat') && |
- arity == 1 && |
- interceptor.inputs[2].isString(types)) { |
- return '+'; |
- } |
- if (name == const SourceString('split') && |
- arity == 1 && |
- interceptor.inputs[2].isString(types)) { |
- return 'split'; |
- } |
- } |
- |
- return null; |
- } |
- |
- void visitInvokeInterceptor(HInvokeInterceptor node) { |
- String builtin = builtinJsName(node); |
- if (builtin != null) { |
- if (builtin == '+') { |
- use(node.inputs[1]); |
- js.Expression left = pop(); |
- use(node.inputs[2]); |
- push(new js.Binary("+", left, pop()), node); |
- } else { |
- use(node.inputs[1]); |
- js.PropertyAccess access = new js.PropertyAccess.field(pop(), builtin); |
- if (node.selector.isGetter()) { |
- push(access, node); |
- return; |
- } |
- List<js.Expression> arguments = <js.Expression>[]; |
- for (int i = 2; i < node.inputs.length; i++) { |
- use(node.inputs[i]); |
- arguments.add(pop()); |
- } |
- push(new js.Call(access, arguments), node); |
- } |
- } else { |
- return visitInvokeStatic(node); |
- } |
- } |
- |
void checkInt(HInstruction input, String cmp) { |
use(input); |
js.Expression left = pop(); |