Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/ssa/codegen.dart |
| =================================================================== |
| --- sdk/lib/_internal/compiler/implementation/ssa/codegen.dart (revision 17466) |
| +++ sdk/lib/_internal/compiler/implementation/ssa/codegen.dart (working copy) |
| @@ -1499,12 +1499,13 @@ |
| } |
| void visitInterceptor(HInterceptor node) { |
| - String name = |
| - backend.registerSpecializedGetInterceptor(node.interceptedClasses); |
| - js.VariableUse interceptor = new js.VariableUse(name); |
| + backend.registerSpecializedGetInterceptor(node.interceptedClasses); |
| + String name = backend.namer.getInterceptorName( |
| + backend.getInterceptorMethod, node.interceptedClasses); |
| + var isolate = new js.VariableUse(backend.namer.CURRENT_ISOLATE); |
| use(node.receiver); |
| List<js.Expression> arguments = <js.Expression>[pop()]; |
| - push(new js.Call(interceptor, arguments), node); |
| + push(jsPropertyCall(isolate, name, arguments), node); |
| } |
| visitInvokeDynamicMethod(HInvokeDynamicMethod node) { |
| @@ -1537,39 +1538,28 @@ |
| if (methodName == null) { |
| methodName = backend.namer.invocationName(node.selector); |
| - bool inLoop = node.block.enclosingLoopHeader != null; |
| - |
| - Selector selector = getOptimizedSelectorFor(node, node.selector); |
| - if (node.isInterceptorCall) { |
| - backend.addInterceptedSelector(selector); |
| - } |
| - // Register this invocation to collect the types used at all call sites. |
| - backend.registerDynamicInvocation(node, selector, types); |
| - |
| - // If we don't know what we're calling or if we are calling a getter, |
| - // we need to register that fact that we may be calling a closure |
| - // with the same arguments. |
| - if (target == null || target.isGetter()) { |
| - // TODO(kasperl): If we have a typed selector for the call, we |
| - // may know something about the types of closures that need |
| - // the specific closure call method. |
| - Selector call = new Selector.callClosureFrom(selector); |
| - world.registerDynamicInvocation(call.name, call); |
| - } |
| - |
| - if (target != null) { |
| - // If we know we're calling a specific method, register that |
| - // method only. |
| - if (inLoop) backend.builder.functionsCalledInLoop.add(target); |
| - world.registerDynamicInvocationOf(target); |
| - } else { |
| - if (inLoop) backend.builder.selectorsCalledInLoop[name] = selector; |
| - world.registerDynamicInvocation(name, selector); |
| - } |
| + registerMethodInvoke(node); |
| } |
| push(jsPropertyCall(object, methodName, arguments), node); |
| } |
| + void visitOneShotInterceptor(HOneShotInterceptor node) { |
| + List<js.Expression> arguments = visitArguments(node.inputs); |
| + var isolate = new js.VariableUse(backend.namer.CURRENT_ISOLATE); |
| + Selector selector = node.selector; |
| + String methodName = backend.namer.oneShotInterceptorName(selector); |
| + push(jsPropertyCall(isolate, methodName, arguments), node); |
| + backend.registerSpecializedGetInterceptor(node.interceptedClasses); |
| + backend.addOneShotInterceptor(selector); |
| + if (selector.isGetter()) { |
| + registerGetter(node); |
| + } else if (selector.isSetter()) { |
| + registerSetter(node); |
| + } else { |
| + registerMethodInvoke(node); |
| + } |
| + } |
| + |
| Selector getOptimizedSelectorFor(HInvokeDynamic node, |
| Selector defaultSelector) { |
| // TODO(4434): For private members we need to use the untyped selector. |
| @@ -1592,34 +1582,86 @@ |
| } |
| } |
| - visitInvokeDynamicSetter(HInvokeDynamicSetter node) { |
| - use(node.receiver); |
| - Selector setter = node.selector; |
| - String name = backend.namer.invocationName(setter); |
| - push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node); |
| - Selector selector = getOptimizedSelectorFor(node, setter); |
| - world.registerDynamicSetter(setter.name, selector); |
| + void registerInvoke(HInvokeDynamic node) { |
| + bool inLoop = node.block.enclosingLoopHeader != null; |
| + SourceString name = node.selector.name; |
| + if (inLoop) { |
| + Element target = node.element; |
| + if (target != null) { |
| + backend.builder.functionsCalledInLoop.add(target); |
| + } else { |
| + backend.builder.selectorsCalledInLoop[name] = node.selector; |
| + } |
| + } |
| + |
| + if (node.isInterceptorCall) { |
| + backend.addInterceptedSelector(node.selector); |
| + } |
| + } |
| + |
| + void registerMethodInvoke(HInvokeDynamic node) { |
| + Selector selector = getOptimizedSelectorFor(node, node.selector); |
| + // Register this invocation to collect the types used at all call sites. |
| + backend.registerDynamicInvocation(node, selector, types); |
| + |
| + // If we don't know what we're calling or if we are calling a getter, |
| + // we need to register that fact that we may be calling a closure |
| + // with the same arguments. |
| + Element target = node.element; |
| + if (target == null || target.isGetter()) { |
| + // TODO(kasperl): If we have a typed selector for the call, we |
| + // may know something about the types of closures that need |
| + // the specific closure call method. |
| + Selector call = new Selector.callClosureFrom(selector); |
| + world.registerDynamicInvocation(call.name, call); |
| + } |
| + |
| + if (target != null) { |
| + // If we know we're calling a specific method, register that |
| + // method only. |
| + world.registerDynamicInvocationOf(target); |
| + } else { |
| + SourceString name = node.selector.name; |
| + world.registerDynamicInvocation(name, selector); |
| + } |
| + registerInvoke(node); |
| + } |
| + |
| + void registerSetter(HInvokeDynamic node) { |
| + Selector selector = getOptimizedSelectorFor(node, node.selector); |
| + world.registerDynamicSetter(selector.name, selector); |
| HType valueType; |
| if (node.isInterceptorCall) { |
|
kasperl
2013/01/24 09:03:51
Use ?: to avoid having an uninitialized valueType
ngeoffray
2013/01/24 10:41:30
Done.
|
| valueType = types[node.inputs[2]]; |
| - backend.addInterceptedSelector(setter); |
| } else { |
| valueType = types[node.inputs[1]]; |
| } |
| backend.addedDynamicSetter(selector, valueType); |
| + registerInvoke(node); |
| } |
| + void registerGetter(HInvokeDynamic node) { |
| + Selector getter = node.selector; |
| + world.registerDynamicGetter( |
| + getter.name, getOptimizedSelectorFor(node, getter)); |
| + world.registerInstantiatedClass(compiler.functionClass); |
| + registerInvoke(node); |
| + } |
| + |
| + visitInvokeDynamicSetter(HInvokeDynamicSetter node) { |
| + use(node.receiver); |
| + Selector setter = node.selector; |
| + String name = backend.namer.invocationName(setter); |
| + push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node); |
| + registerSetter(node); |
| + } |
| + |
| visitInvokeDynamicGetter(HInvokeDynamicGetter node) { |
| use(node.receiver); |
| Selector getter = node.selector; |
| String name = backend.namer.invocationName(getter); |
| push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node); |
| - world.registerDynamicGetter( |
| - getter.name, getOptimizedSelectorFor(node, getter)); |
| - if (node.isInterceptorCall) { |
| - backend.addInterceptedSelector(getter); |
| - } |
| - world.registerInstantiatedClass(compiler.functionClass); |
| + registerGetter(node); |
| } |
| visitInvokeClosure(HInvokeClosure node) { |