Chromium Code Reviews| 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(); |