| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A special element for the extra parameter taken by intercepted | 8 * A special element for the extra parameter taken by intercepted |
| 9 * methods. We need to override [Element.computeType] because our | 9 * methods. We need to override [Element.computeType] because our |
| 10 * optimizers may look at its declared type. | 10 * optimizers may look at its declared type. |
| (...skipping 2225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2236 stack.add(graph.addConstant(folded)); | 2236 stack.add(graph.addConstant(folded)); |
| 2237 return; | 2237 return; |
| 2238 } | 2238 } |
| 2239 } | 2239 } |
| 2240 | 2240 |
| 2241 HInvokeDynamicMethod result = | 2241 HInvokeDynamicMethod result = |
| 2242 buildInvokeDynamic(node, elements.getSelector(node), operand, []); | 2242 buildInvokeDynamic(node, elements.getSelector(node), operand, []); |
| 2243 pushWithPosition(result, node); | 2243 pushWithPosition(result, node); |
| 2244 } | 2244 } |
| 2245 | 2245 |
| 2246 void visitBinary( | 2246 void visitBinary(HInstruction left, |
| 2247 HInstruction left, Operator op, HInstruction right, Send send) { | 2247 Operator op, |
| 2248 Selector selector = null; | 2248 HInstruction right, |
| 2249 // TODO(ngeoffray): The resolver creates these selectors already | 2249 Selector selector, |
| 2250 // but does not put them on the [send] instruction. | 2250 Send send) { |
| 2251 switch (op.source.stringValue) { | 2251 switch (op.source.stringValue) { |
| 2252 case "+": | |
| 2253 case "+=": | |
| 2254 case "++": | |
| 2255 selector = new Selector.binaryOperator(const SourceString('+')); | |
| 2256 break; | |
| 2257 case "-": | |
| 2258 case "-=": | |
| 2259 case "--": | |
| 2260 selector = new Selector.binaryOperator(const SourceString('-')); | |
| 2261 break; | |
| 2262 case "*": | |
| 2263 case "*=": | |
| 2264 selector = new Selector.binaryOperator(const SourceString('*')); | |
| 2265 break; | |
| 2266 case "/": | |
| 2267 case "/=": | |
| 2268 selector = new Selector.binaryOperator(const SourceString('/')); | |
| 2269 break; | |
| 2270 case "~/": | |
| 2271 case "~/=": | |
| 2272 selector = new Selector.binaryOperator(const SourceString('~/')); | |
| 2273 break; | |
| 2274 case "%": | |
| 2275 case "%=": | |
| 2276 selector = new Selector.binaryOperator(const SourceString('%')); | |
| 2277 break; | |
| 2278 case "<<": | |
| 2279 case "<<=": | |
| 2280 selector = new Selector.binaryOperator(const SourceString('<<')); | |
| 2281 break; | |
| 2282 case ">>": | |
| 2283 case ">>=": | |
| 2284 selector = new Selector.binaryOperator(const SourceString('>>')); | |
| 2285 break; | |
| 2286 case "|": | |
| 2287 case "|=": | |
| 2288 selector = new Selector.binaryOperator(const SourceString('|')); | |
| 2289 break; | |
| 2290 case "&": | |
| 2291 case "&=": | |
| 2292 selector = new Selector.binaryOperator(const SourceString('&')); | |
| 2293 break; | |
| 2294 case "^": | |
| 2295 case "^=": | |
| 2296 selector = new Selector.binaryOperator(const SourceString('^')); | |
| 2297 break; | |
| 2298 case "==": | |
| 2299 case "!=": | |
| 2300 selector = new Selector.binaryOperator(const SourceString('==')); | |
| 2301 break; | |
| 2302 case "<": | |
| 2303 selector = new Selector.binaryOperator(const SourceString('<')); | |
| 2304 break; | |
| 2305 case "<=": | |
| 2306 selector = new Selector.binaryOperator(const SourceString('<=')); | |
| 2307 break; | |
| 2308 case ">": | |
| 2309 selector = new Selector.binaryOperator(const SourceString('>')); | |
| 2310 break; | |
| 2311 case ">=": | |
| 2312 selector = new Selector.binaryOperator(const SourceString('>=')); | |
| 2313 break; | |
| 2314 case "===": | 2252 case "===": |
| 2315 pushWithPosition(new HIdentity(left, right), op); | 2253 pushWithPosition(new HIdentity(left, right), op); |
| 2316 return; | 2254 return; |
| 2317 case "!==": | 2255 case "!==": |
| 2318 HIdentity eq = new HIdentity(left, right); | 2256 HIdentity eq = new HIdentity(left, right); |
| 2319 add(eq); | 2257 add(eq); |
| 2320 pushWithPosition(new HNot(eq), op); | 2258 pushWithPosition(new HNot(eq), op); |
| 2321 return; | 2259 return; |
| 2322 default: | |
| 2323 compiler.internalError("Unexpected operator $op", node: op); | |
| 2324 break; | |
| 2325 } | 2260 } |
| 2326 | 2261 |
| 2327 pushWithPosition( | 2262 pushWithPosition( |
| 2328 buildInvokeDynamic(send, selector, left, [right]), | 2263 buildInvokeDynamic(send, selector, left, [right]), |
| 2329 op); | 2264 op); |
| 2330 if (op.source.stringValue == '!=') { | 2265 if (op.source.stringValue == '!=') { |
| 2331 pushWithPosition(new HNot(popBoolified()), op); | 2266 pushWithPosition(new HNot(popBoolified()), op); |
| 2332 } | 2267 } |
| 2333 } | 2268 } |
| 2334 | 2269 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2351 | 2286 |
| 2352 /** | 2287 /** |
| 2353 * Returns a set of interceptor classes that contain a member whose | 2288 * Returns a set of interceptor classes that contain a member whose |
| 2354 * signature matches the given [selector]. | 2289 * signature matches the given [selector]. |
| 2355 */ | 2290 */ |
| 2356 Set<ClassElement> getInterceptedClassesOn(Selector selector) { | 2291 Set<ClassElement> getInterceptedClassesOn(Selector selector) { |
| 2357 return backend.getInterceptedClassesOn(selector); | 2292 return backend.getInterceptedClassesOn(selector); |
| 2358 } | 2293 } |
| 2359 | 2294 |
| 2360 void generateInstanceGetterWithCompiledReceiver(Send send, | 2295 void generateInstanceGetterWithCompiledReceiver(Send send, |
| 2296 Selector selector, |
| 2361 HInstruction receiver) { | 2297 HInstruction receiver) { |
| 2362 assert(Elements.isInstanceSend(send, elements)); | 2298 assert(Elements.isInstanceSend(send, elements)); |
| 2363 // TODO(kasperl): This is a convoluted way of checking if we're | |
| 2364 // generating code for a compound assignment. If we are, we need | |
| 2365 // to get the selector from the mapping for the AST selector node. | |
| 2366 Selector selector = (send.asSendSet() == null) | |
| 2367 ? elements.getSelector(send) | |
| 2368 : elements.getSelector(send.selector); | |
| 2369 assert(selector.isGetter()); | 2299 assert(selector.isGetter()); |
| 2370 SourceString getterName = selector.name; | 2300 SourceString getterName = selector.name; |
| 2371 Set<ClassElement> interceptedClasses = getInterceptedClassesOn(selector); | 2301 Set<ClassElement> interceptedClasses = getInterceptedClassesOn(selector); |
| 2372 | 2302 |
| 2373 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); | 2303 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); |
| 2374 HInstruction instruction; | 2304 HInstruction instruction; |
| 2375 if (interceptedClasses != null) { | 2305 if (interceptedClasses != null) { |
| 2376 // If we're using an interceptor class, emit a call to the | 2306 // If we're using an interceptor class, emit a call to the |
| 2377 // interceptor method and then the actual dynamic call on the | 2307 // interceptor method and then the actual dynamic call on the |
| 2378 // interceptor object. | 2308 // interceptor object. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2411 } | 2341 } |
| 2412 // TODO(5346): Try to avoid the need for calling [declaration] before | 2342 // TODO(5346): Try to avoid the need for calling [declaration] before |
| 2413 // creating an [HStatic]. | 2343 // creating an [HStatic]. |
| 2414 push(new HStatic(element.declaration)); | 2344 push(new HStatic(element.declaration)); |
| 2415 if (element.isGetter()) { | 2345 if (element.isGetter()) { |
| 2416 push(new HInvokeStatic(<HInstruction>[pop()], HType.UNKNOWN)); | 2346 push(new HInvokeStatic(<HInstruction>[pop()], HType.UNKNOWN)); |
| 2417 } | 2347 } |
| 2418 } | 2348 } |
| 2419 } else if (Elements.isInstanceSend(send, elements)) { | 2349 } else if (Elements.isInstanceSend(send, elements)) { |
| 2420 HInstruction receiver = generateInstanceSendReceiver(send); | 2350 HInstruction receiver = generateInstanceSendReceiver(send); |
| 2421 generateInstanceGetterWithCompiledReceiver(send, receiver); | 2351 generateInstanceGetterWithCompiledReceiver( |
| 2352 send, elements.getSelector(send), receiver); |
| 2422 } else if (Elements.isStaticOrTopLevelFunction(element)) { | 2353 } else if (Elements.isStaticOrTopLevelFunction(element)) { |
| 2423 // TODO(5346): Try to avoid the need for calling [declaration] before | 2354 // TODO(5346): Try to avoid the need for calling [declaration] before |
| 2424 // creating an [HStatic]. | 2355 // creating an [HStatic]. |
| 2425 push(new HStatic(element.declaration)); | 2356 push(new HStatic(element.declaration)); |
| 2426 // TODO(ahe): This should be registered in codegen. | 2357 // TODO(ahe): This should be registered in codegen. |
| 2427 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); | 2358 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); |
| 2428 } else if (Elements.isErroneousElement(element)) { | 2359 } else if (Elements.isErroneousElement(element)) { |
| 2429 // An erroneous element indicates an unresolved static getter. | 2360 // An erroneous element indicates an unresolved static getter. |
| 2430 generateThrowNoSuchMethod(send, | 2361 generateThrowNoSuchMethod(send, |
| 2431 getTargetName(element, 'get'), | 2362 getTargetName(element, 'get'), |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2704 DartType type = elements.getType(typeAnnotation); | 2635 DartType type = elements.getType(typeAnnotation); |
| 2705 HInstruction converted = expression.convertType( | 2636 HInstruction converted = expression.convertType( |
| 2706 compiler, type, HTypeConversion.CAST_TYPE_CHECK); | 2637 compiler, type, HTypeConversion.CAST_TYPE_CHECK); |
| 2707 if (converted != expression) add(converted); | 2638 if (converted != expression) add(converted); |
| 2708 stack.add(converted); | 2639 stack.add(converted); |
| 2709 } else { | 2640 } else { |
| 2710 visit(node.receiver); | 2641 visit(node.receiver); |
| 2711 visit(node.argumentsNode); | 2642 visit(node.argumentsNode); |
| 2712 var right = pop(); | 2643 var right = pop(); |
| 2713 var left = pop(); | 2644 var left = pop(); |
| 2714 visitBinary(left, op, right, node); | 2645 visitBinary(left, op, right, elements.getSelector(node), node); |
| 2715 } | 2646 } |
| 2716 } | 2647 } |
| 2717 | 2648 |
| 2718 void addDynamicSendArgumentsToList(Send node, List<HInstruction> list) { | 2649 void addDynamicSendArgumentsToList(Send node, List<HInstruction> list) { |
| 2719 Selector selector = elements.getSelector(node); | 2650 Selector selector = elements.getSelector(node); |
| 2720 if (selector.namedArgumentCount == 0) { | 2651 if (selector.namedArgumentCount == 0) { |
| 2721 addGenericSendArgumentsToList(node.arguments, list); | 2652 addGenericSendArgumentsToList(node.arguments, list); |
| 2722 } else { | 2653 } else { |
| 2723 // Visit positional arguments and add them to the list. | 2654 // Visit positional arguments and add them to the list. |
| 2724 Link<Node> arguments = node.arguments; | 2655 Link<Node> arguments = node.arguments; |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3111 Element element = elements[node]; | 3042 Element element = elements[node]; |
| 3112 if (element != null && identical(element, currentElement)) { | 3043 if (element != null && identical(element, currentElement)) { |
| 3113 graph.isRecursiveMethod = true; | 3044 graph.isRecursiveMethod = true; |
| 3114 } | 3045 } |
| 3115 super.visitSend(node); | 3046 super.visitSend(node); |
| 3116 } | 3047 } |
| 3117 | 3048 |
| 3118 visitSuperSend(Send node) { | 3049 visitSuperSend(Send node) { |
| 3119 Selector selector = elements.getSelector(node); | 3050 Selector selector = elements.getSelector(node); |
| 3120 Element element = elements[node]; | 3051 Element element = elements[node]; |
| 3121 if (element == null) return generateSuperNoSuchMethodSend(node); | 3052 if (Elements.isUnresolved(element)) { |
| 3053 return generateSuperNoSuchMethodSend(node); |
| 3054 } |
| 3122 // TODO(5346): Try to avoid the need for calling [declaration] before | 3055 // TODO(5346): Try to avoid the need for calling [declaration] before |
| 3123 // creating an [HStatic]. | 3056 // creating an [HStatic]. |
| 3124 HInstruction target = new HStatic(element.declaration); | 3057 HInstruction target = new HStatic(element.declaration); |
| 3125 HInstruction context = localsHandler.readThis(); | 3058 HInstruction context = localsHandler.readThis(); |
| 3126 add(target); | 3059 add(target); |
| 3127 var inputs = <HInstruction>[target, context]; | 3060 var inputs = <HInstruction>[target, context]; |
| 3128 if (node.isPropertyAccess) { | 3061 if (node.isPropertyAccess) { |
| 3129 push(new HInvokeSuper(inputs)); | 3062 push(new HInvokeSuper(inputs)); |
| 3130 } else if (element.isFunction() || element.isGenerativeConstructor()) { | 3063 } else if (element.isFunction() || element.isGenerativeConstructor()) { |
| 3131 // TODO(5347): Try to avoid the need for calling [implementation] before | 3064 // TODO(5347): Try to avoid the need for calling [implementation] before |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3618 bool isPrefix = !node.isPostfix; | 3551 bool isPrefix = !node.isPostfix; |
| 3619 if (isCompoundAssignment) { | 3552 if (isCompoundAssignment) { |
| 3620 value = pop(); | 3553 value = pop(); |
| 3621 index = pop(); | 3554 index = pop(); |
| 3622 } else { | 3555 } else { |
| 3623 index = pop(); | 3556 index = pop(); |
| 3624 value = graph.addConstantInt(1, constantSystem); | 3557 value = graph.addConstantInt(1, constantSystem); |
| 3625 } | 3558 } |
| 3626 | 3559 |
| 3627 HInvokeDynamicMethod left = buildInvokeDynamic( | 3560 HInvokeDynamicMethod left = buildInvokeDynamic( |
| 3628 node, new Selector.index(), receiver, [index]); | 3561 node, |
| 3562 elements.getGetterSelectorInComplexSendSet(node), |
| 3563 receiver, |
| 3564 <HInstruction>[index]); |
| 3629 add(left); | 3565 add(left); |
| 3630 visitBinary(left, op, value, node); | 3566 visitBinary(left, op, value, |
| 3567 elements.getOperatorSelectorInComplexSendSet(node), node); |
| 3631 value = pop(); | 3568 value = pop(); |
| 3632 HInvokeDynamicMethod assign = buildInvokeDynamic( | 3569 HInvokeDynamicMethod assign = buildInvokeDynamic( |
| 3633 node, new Selector.indexSet(), receiver, [index, value]); | 3570 node, elements.getSelector(node), receiver, [index, value]); |
| 3634 add(assign); | 3571 add(assign); |
| 3635 if (isPrefix) { | 3572 if (isPrefix) { |
| 3636 stack.add(value); | 3573 stack.add(value); |
| 3637 } else { | 3574 } else { |
| 3638 stack.add(left); | 3575 stack.add(left); |
| 3639 } | 3576 } |
| 3640 } | 3577 } |
| 3641 } else if (const SourceString("=") == op.source) { | 3578 } else if (const SourceString("=") == op.source) { |
| 3642 Link<Node> link = node.arguments; | 3579 Link<Node> link = node.arguments; |
| 3643 assert(!link.isEmpty && link.tail.isEmpty); | 3580 assert(!link.isEmpty && link.tail.isEmpty); |
| 3644 visit(link.head); | 3581 visit(link.head); |
| 3645 HInstruction value = pop(); | 3582 HInstruction value = pop(); |
| 3646 generateSetter(node, element, value); | 3583 generateSetter(node, element, value); |
| 3647 } else if (identical(op.source.stringValue, "is")) { | 3584 } else if (identical(op.source.stringValue, "is")) { |
| 3648 compiler.internalError("is-operator as SendSet", node: op); | 3585 compiler.internalError("is-operator as SendSet", node: op); |
| 3649 } else { | 3586 } else { |
| 3650 assert(const SourceString("++") == op.source || | 3587 assert(const SourceString("++") == op.source || |
| 3651 const SourceString("--") == op.source || | 3588 const SourceString("--") == op.source || |
| 3652 node.assignmentOperator.source.stringValue.endsWith("=")); | 3589 node.assignmentOperator.source.stringValue.endsWith("=")); |
| 3653 bool isCompoundAssignment = !node.arguments.isEmpty; | 3590 bool isCompoundAssignment = !node.arguments.isEmpty; |
| 3654 bool isPrefix = !node.isPostfix; // Compound assignments are prefix. | 3591 bool isPrefix = !node.isPostfix; // Compound assignments are prefix. |
| 3655 | 3592 |
| 3656 // [receiver] is only used if the node is an instance send. | 3593 // [receiver] is only used if the node is an instance send. |
| 3657 HInstruction receiver = null; | 3594 HInstruction receiver = null; |
| 3658 if (Elements.isInstanceSend(node, elements)) { | 3595 if (Elements.isInstanceSend(node, elements)) { |
| 3659 receiver = generateInstanceSendReceiver(node); | 3596 receiver = generateInstanceSendReceiver(node); |
| 3660 generateInstanceGetterWithCompiledReceiver(node, receiver); | 3597 generateInstanceGetterWithCompiledReceiver( |
| 3598 node, elements.getGetterSelectorInComplexSendSet(node), receiver); |
| 3661 } else { | 3599 } else { |
| 3662 generateGetter(node, elements[node.selector]); | 3600 generateGetter(node, elements[node.selector]); |
| 3663 } | 3601 } |
| 3664 HInstruction left = pop(); | 3602 HInstruction left = pop(); |
| 3665 HInstruction right; | 3603 HInstruction right; |
| 3666 if (isCompoundAssignment) { | 3604 if (isCompoundAssignment) { |
| 3667 visit(node.argumentsNode); | 3605 visit(node.argumentsNode); |
| 3668 right = pop(); | 3606 right = pop(); |
| 3669 } else { | 3607 } else { |
| 3670 right = graph.addConstantInt(1, constantSystem); | 3608 right = graph.addConstantInt(1, constantSystem); |
| 3671 } | 3609 } |
| 3672 visitBinary(left, op, right, node); | 3610 visitBinary(left, op, right, |
| 3611 elements.getOperatorSelectorInComplexSendSet(node), node); |
| 3673 HInstruction operation = pop(); | 3612 HInstruction operation = pop(); |
| 3674 assert(operation != null); | 3613 assert(operation != null); |
| 3675 if (Elements.isInstanceSend(node, elements)) { | 3614 if (Elements.isInstanceSend(node, elements)) { |
| 3676 assert(receiver != null); | 3615 assert(receiver != null); |
| 3677 generateInstanceSetterWithCompiledReceiver(node, receiver, operation); | 3616 generateInstanceSetterWithCompiledReceiver(node, receiver, operation); |
| 3678 } else { | 3617 } else { |
| 3679 assert(receiver == null); | 3618 assert(receiver == null); |
| 3680 generateSetter(node, element, operation); | 3619 generateSetter(node, element, operation); |
| 3681 } | 3620 } |
| 3682 if (!isPrefix) { | 3621 if (!isPrefix) { |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3908 // Generate a structure equivalent to: | 3847 // Generate a structure equivalent to: |
| 3909 // Iterator<E> $iter = <iterable>.iterator; | 3848 // Iterator<E> $iter = <iterable>.iterator; |
| 3910 // while ($iter.moveNext()) { | 3849 // while ($iter.moveNext()) { |
| 3911 // E <declaredIdentifier> = $iter.current; | 3850 // E <declaredIdentifier> = $iter.current; |
| 3912 // <body> | 3851 // <body> |
| 3913 // } | 3852 // } |
| 3914 | 3853 |
| 3915 // The iterator is shared between initializer, condition and body. | 3854 // The iterator is shared between initializer, condition and body. |
| 3916 HInstruction iterator; | 3855 HInstruction iterator; |
| 3917 void buildInitializer() { | 3856 void buildInitializer() { |
| 3918 SourceString iteratorName = const SourceString("iterator"); | 3857 Selector selector = elements.getIteratorSelector(node); |
| 3919 Selector selector = | |
| 3920 new Selector.getter(iteratorName, currentElement.getLibrary()); | |
| 3921 Set<ClassElement> interceptedClasses = getInterceptedClassesOn(selector); | 3858 Set<ClassElement> interceptedClasses = getInterceptedClassesOn(selector); |
| 3922 visit(node.expression); | 3859 visit(node.expression); |
| 3923 HInstruction receiver = pop(); | 3860 HInstruction receiver = pop(); |
| 3924 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); | 3861 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); |
| 3925 if (interceptedClasses == null) { | 3862 if (interceptedClasses == null) { |
| 3926 iterator = | 3863 iterator = |
| 3927 new HInvokeDynamicGetter(selector, null, receiver, !hasGetter); | 3864 new HInvokeDynamicGetter(selector, null, receiver, !hasGetter); |
| 3928 } else { | 3865 } else { |
| 3929 HInterceptor interceptor = | 3866 HInterceptor interceptor = |
| 3930 invokeInterceptor(interceptedClasses, receiver, null); | 3867 invokeInterceptor(interceptedClasses, receiver, null); |
| 3931 iterator = | 3868 iterator = |
| 3932 new HInvokeDynamicGetter(selector, null, interceptor, !hasGetter); | 3869 new HInvokeDynamicGetter(selector, null, interceptor, !hasGetter); |
| 3933 // Add the receiver as an argument to the getter call on the | 3870 // Add the receiver as an argument to the getter call on the |
| 3934 // interceptor. | 3871 // interceptor. |
| 3935 iterator.inputs.add(receiver); | 3872 iterator.inputs.add(receiver); |
| 3936 } | 3873 } |
| 3937 add(iterator); | 3874 add(iterator); |
| 3938 } | 3875 } |
| 3939 HInstruction buildCondition() { | 3876 HInstruction buildCondition() { |
| 3940 SourceString name = const SourceString('moveNext'); | 3877 Selector selector = elements.getMoveNextSelector(node); |
| 3941 Selector selector = new Selector.call( | |
| 3942 name, currentElement.getLibrary(), 0); | |
| 3943 push(new HInvokeDynamicMethod(selector, <HInstruction>[iterator])); | 3878 push(new HInvokeDynamicMethod(selector, <HInstruction>[iterator])); |
| 3944 return popBoolified(); | 3879 return popBoolified(); |
| 3945 } | 3880 } |
| 3946 void buildBody() { | 3881 void buildBody() { |
| 3947 SourceString name = const SourceString('current'); | 3882 Selector call = elements.getCurrentSelector(node); |
| 3948 Selector call = new Selector.getter(name, currentElement.getLibrary()); | |
| 3949 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(call); | 3883 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(call); |
| 3950 push(new HInvokeDynamicGetter(call, null, iterator, !hasGetter)); | 3884 push(new HInvokeDynamicGetter(call, null, iterator, !hasGetter)); |
| 3951 | 3885 |
| 3952 Element variable; | 3886 Element variable; |
| 3953 if (node.declaredIdentifier.asSend() != null) { | 3887 if (node.declaredIdentifier.asSend() != null) { |
| 3954 variable = elements[node.declaredIdentifier]; | 3888 variable = elements[node.declaredIdentifier]; |
| 3955 } else { | 3889 } else { |
| 3956 assert(node.declaredIdentifier.asVariableDefinitions() != null); | 3890 assert(node.declaredIdentifier.asVariableDefinitions() != null); |
| 3957 VariableDefinitions variableDefinitions = node.declaredIdentifier; | 3891 VariableDefinitions variableDefinitions = node.declaredIdentifier; |
| 3958 variable = elements[variableDefinitions.definitions.nodes.head]; | 3892 variable = elements[variableDefinitions.definitions.nodes.head]; |
| (...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5030 new HSubGraphBlockInformation(elseBranch.graph)); | 4964 new HSubGraphBlockInformation(elseBranch.graph)); |
| 5031 | 4965 |
| 5032 HBasicBlock conditionStartBlock = conditionBranch.block; | 4966 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 5033 conditionStartBlock.setBlockFlow(info, joinBlock); | 4967 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 5034 SubGraph conditionGraph = conditionBranch.graph; | 4968 SubGraph conditionGraph = conditionBranch.graph; |
| 5035 HIf branch = conditionGraph.end.last; | 4969 HIf branch = conditionGraph.end.last; |
| 5036 assert(branch is HIf); | 4970 assert(branch is HIf); |
| 5037 branch.blockInformation = conditionStartBlock.blockFlow; | 4971 branch.blockInformation = conditionStartBlock.blockFlow; |
| 5038 } | 4972 } |
| 5039 } | 4973 } |
| OLD | NEW |