| 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 implement [TypedElement.type] because our | 9 * methods. We need to implement [TypedElement.type] because our |
| 10 * optimizers may look at its declared type. | 10 * optimizers may look at its declared type. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 kind == ElementKind.SETTER) { | 47 kind == ElementKind.SETTER) { |
| 48 graph = builder.buildMethod(element); | 48 graph = builder.buildMethod(element); |
| 49 } else if (kind == ElementKind.FIELD) { | 49 } else if (kind == ElementKind.FIELD) { |
| 50 if (element.isInstanceMember()) { | 50 if (element.isInstanceMember()) { |
| 51 assert(compiler.enableTypeAssertions); | 51 assert(compiler.enableTypeAssertions); |
| 52 graph = builder.buildCheckedSetter(element); | 52 graph = builder.buildCheckedSetter(element); |
| 53 } else { | 53 } else { |
| 54 graph = builder.buildLazyInitializer(element); | 54 graph = builder.buildLazyInitializer(element); |
| 55 } | 55 } |
| 56 } else { | 56 } else { |
| 57 compiler.internalErrorOnElement(element, | 57 compiler.internalError(element, 'Unexpected element kind $kind.'); |
| 58 'unexpected element kind $kind'); | |
| 59 } | 58 } |
| 60 assert(graph.isValid()); | 59 assert(graph.isValid()); |
| 61 if (!identical(kind, ElementKind.FIELD)) { | 60 if (!identical(kind, ElementKind.FIELD)) { |
| 62 FunctionElement function = element; | 61 FunctionElement function = element; |
| 63 FunctionSignature signature = function.functionSignature; | 62 FunctionSignature signature = function.functionSignature; |
| 64 signature.forEachOptionalParameter((Element parameter) { | 63 signature.forEachOptionalParameter((Element parameter) { |
| 65 // This ensures the default value will be computed. | 64 // This ensures the default value will be computed. |
| 66 Constant constant = | 65 Constant constant = |
| 67 compiler.constantHandler.getConstantForVariable(parameter); | 66 compiler.constantHandler.getConstantForVariable(parameter); |
| 68 backend.registerCompileTimeConstant(constant, work.resolutionTree); | 67 backend.registerCompileTimeConstant(constant, work.resolutionTree); |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 | 348 |
| 350 /** | 349 /** |
| 351 * Returns an [HInstruction] for the given element. If the element is | 350 * Returns an [HInstruction] for the given element. If the element is |
| 352 * boxed or stored in a closure then the method generates code to retrieve | 351 * boxed or stored in a closure then the method generates code to retrieve |
| 353 * the value. | 352 * the value. |
| 354 */ | 353 */ |
| 355 HInstruction readLocal(Element element) { | 354 HInstruction readLocal(Element element) { |
| 356 if (isAccessedDirectly(element)) { | 355 if (isAccessedDirectly(element)) { |
| 357 if (directLocals[element] == null) { | 356 if (directLocals[element] == null) { |
| 358 if (element.isTypeVariable()) { | 357 if (element.isTypeVariable()) { |
| 359 builder.compiler.internalError( | 358 builder.compiler.internalError(builder.compiler.currentElement, |
| 360 "Runtime type information not available for $element", | 359 "Runtime type information not available for $element."); |
| 361 element: builder.compiler.currentElement); | |
| 362 } else { | 360 } else { |
| 363 builder.compiler.internalError( | 361 builder.compiler.internalError(element, |
| 364 "Cannot find value $element", | 362 "Cannot find value $element."); |
| 365 element: element); | |
| 366 } | 363 } |
| 367 } | 364 } |
| 368 return directLocals[element]; | 365 return directLocals[element]; |
| 369 } else if (isStoredInClosureField(element)) { | 366 } else if (isStoredInClosureField(element)) { |
| 370 Element redirect = redirectionMapping[element]; | 367 Element redirect = redirectionMapping[element]; |
| 371 HInstruction receiver = readLocal(closureData.closureElement); | 368 HInstruction receiver = readLocal(closureData.closureElement); |
| 372 TypeMask type = (element.kind == ElementKind.VARIABLE_LIST) | 369 TypeMask type = (element.kind == ElementKind.VARIABLE_LIST) |
| 373 ? builder.backend.nonNullType | 370 ? builder.backend.nonNullType |
| 374 : builder.getTypeOfCapturedVariable(redirect); | 371 : builder.getTypeOfCapturedVariable(redirect); |
| 375 assert(element.kind != ElementKind.VARIABLE_LIST | 372 assert(element.kind != ElementKind.VARIABLE_LIST |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 | 686 |
| 690 // Insert break handler used to avoid null checks when a target isn't | 687 // Insert break handler used to avoid null checks when a target isn't |
| 691 // used as the target of a break, and therefore doesn't need a break | 688 // used as the target of a break, and therefore doesn't need a break |
| 692 // handler associated with it. | 689 // handler associated with it. |
| 693 class NullJumpHandler implements JumpHandler { | 690 class NullJumpHandler implements JumpHandler { |
| 694 final Compiler compiler; | 691 final Compiler compiler; |
| 695 | 692 |
| 696 NullJumpHandler(this.compiler); | 693 NullJumpHandler(this.compiler); |
| 697 | 694 |
| 698 void generateBreak([LabelElement label]) { | 695 void generateBreak([LabelElement label]) { |
| 699 compiler.internalError('generateBreak should not be called'); | 696 compiler.internalError(CURRENT_ELEMENT_SPANNABLE, |
| 697 'NullJumpHandler.generateBreak should not be called.'); |
| 700 } | 698 } |
| 701 | 699 |
| 702 void generateContinue([LabelElement label]) { | 700 void generateContinue([LabelElement label]) { |
| 703 compiler.internalError('generateContinue should not be called'); | 701 compiler.internalError(CURRENT_ELEMENT_SPANNABLE, |
| 702 'NullJumpHandler.generateContinue should not be called.'); |
| 704 } | 703 } |
| 705 | 704 |
| 706 void forEachBreak(Function ignored) { } | 705 void forEachBreak(Function ignored) { } |
| 707 void forEachContinue(Function ignored) { } | 706 void forEachContinue(Function ignored) { } |
| 708 void close() { } | 707 void close() { } |
| 709 bool hasAnyContinue() => false; | 708 bool hasAnyContinue() => false; |
| 710 bool hasAnyBreak() => false; | 709 bool hasAnyBreak() => false; |
| 711 | 710 |
| 712 List<LabelElement> labels() => const <LabelElement>[]; | 711 List<LabelElement> labels() => const <LabelElement>[]; |
| 713 TargetElement get target => null; | 712 TargetElement get target => null; |
| (...skipping 1075 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1789 ClassElement enclosingClass = constructor.getEnclosingClass(); | 1788 ClassElement enclosingClass = constructor.getEnclosingClass(); |
| 1790 ClassElement superClass = enclosingClass.superclass; | 1789 ClassElement superClass = enclosingClass.superclass; |
| 1791 if (!enclosingClass.isObject(compiler)) { | 1790 if (!enclosingClass.isObject(compiler)) { |
| 1792 assert(superClass != null); | 1791 assert(superClass != null); |
| 1793 assert(superClass.resolutionState == STATE_DONE); | 1792 assert(superClass.resolutionState == STATE_DONE); |
| 1794 Selector selector = | 1793 Selector selector = |
| 1795 new Selector.callDefaultConstructor(enclosingClass.getLibrary()); | 1794 new Selector.callDefaultConstructor(enclosingClass.getLibrary()); |
| 1796 // TODO(johnniwinther): Should we find injected constructors as well? | 1795 // TODO(johnniwinther): Should we find injected constructors as well? |
| 1797 FunctionElement target = superClass.lookupConstructor(selector); | 1796 FunctionElement target = superClass.lookupConstructor(selector); |
| 1798 if (target == null) { | 1797 if (target == null) { |
| 1799 compiler.internalError("no default constructor available"); | 1798 compiler.internalError(superClass, |
| 1799 "No default constructor available."); |
| 1800 } | 1800 } |
| 1801 List<HInstruction> arguments = <HInstruction>[]; | 1801 List<HInstruction> arguments = <HInstruction>[]; |
| 1802 selector.addArgumentsToList(const Link<ast.Node>(), | 1802 selector.addArgumentsToList(const Link<ast.Node>(), |
| 1803 arguments, | 1803 arguments, |
| 1804 target.implementation, | 1804 target.implementation, |
| 1805 null, | 1805 null, |
| 1806 handleConstantForOptionalParameter, | 1806 handleConstantForOptionalParameter, |
| 1807 compiler); | 1807 compiler); |
| 1808 inlineSuperOrRedirect(target, | 1808 inlineSuperOrRedirect(target, |
| 1809 arguments, | 1809 arguments, |
| (...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2274 | 2274 |
| 2275 visitBlock(ast.Block node) { | 2275 visitBlock(ast.Block node) { |
| 2276 assert(!isAborted()); | 2276 assert(!isAborted()); |
| 2277 if (!isReachable) return; // This can only happen when inlining. | 2277 if (!isReachable) return; // This can only happen when inlining. |
| 2278 for (Link<ast.Node> link = node.statements.nodes; | 2278 for (Link<ast.Node> link = node.statements.nodes; |
| 2279 !link.isEmpty; | 2279 !link.isEmpty; |
| 2280 link = link.tail) { | 2280 link = link.tail) { |
| 2281 visit(link.head); | 2281 visit(link.head); |
| 2282 if (!isReachable) { | 2282 if (!isReachable) { |
| 2283 // The block has been aborted by a return or a throw. | 2283 // The block has been aborted by a return or a throw. |
| 2284 if (!stack.isEmpty) compiler.cancel('non-empty instruction stack'); | 2284 if (!stack.isEmpty) { |
| 2285 compiler.internalError(node, 'Non-empty instruction stack.'); |
| 2286 } |
| 2285 return; | 2287 return; |
| 2286 } | 2288 } |
| 2287 } | 2289 } |
| 2288 assert(!current.isClosed()); | 2290 assert(!current.isClosed()); |
| 2289 if (!stack.isEmpty) compiler.cancel('non-empty instruction stack'); | 2291 if (!stack.isEmpty) { |
| 2292 compiler.internalError(node, 'Non-empty instruction stack.'); |
| 2293 } |
| 2290 } | 2294 } |
| 2291 | 2295 |
| 2292 visitClassNode(ast.ClassNode node) { | 2296 visitClassNode(ast.ClassNode node) { |
| 2293 compiler.internalError('visitClassNode should not be called', node: node); | 2297 compiler.internalError(node, |
| 2298 'SsaBuilder.visitClassNode should not be called.'); |
| 2294 } | 2299 } |
| 2295 | 2300 |
| 2296 visitThrowExpression(ast.Expression expression) { | 2301 visitThrowExpression(ast.Expression expression) { |
| 2297 bool old = inThrowExpression; | 2302 bool old = inThrowExpression; |
| 2298 try { | 2303 try { |
| 2299 inThrowExpression = true; | 2304 inThrowExpression = true; |
| 2300 visit(expression); | 2305 visit(expression); |
| 2301 } finally { | 2306 } finally { |
| 2302 inThrowExpression = old; | 2307 inThrowExpression = old; |
| 2303 } | 2308 } |
| (...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2810 visitFunctionDeclaration(ast.FunctionDeclaration node) { | 2815 visitFunctionDeclaration(ast.FunctionDeclaration node) { |
| 2811 assert(isReachable); | 2816 assert(isReachable); |
| 2812 visit(node.function); | 2817 visit(node.function); |
| 2813 localsHandler.updateLocal(elements[node], pop()); | 2818 localsHandler.updateLocal(elements[node], pop()); |
| 2814 } | 2819 } |
| 2815 | 2820 |
| 2816 visitIdentifier(ast.Identifier node) { | 2821 visitIdentifier(ast.Identifier node) { |
| 2817 if (node.isThis()) { | 2822 if (node.isThis()) { |
| 2818 stack.add(localsHandler.readThis()); | 2823 stack.add(localsHandler.readThis()); |
| 2819 } else { | 2824 } else { |
| 2820 compiler.internalError("SsaFromAstMixin.visitIdentifier on non-this", | 2825 compiler.internalError(node, |
| 2821 node: node); | 2826 "SsaFromAstMixin.visitIdentifier on non-this."); |
| 2822 } | 2827 } |
| 2823 } | 2828 } |
| 2824 | 2829 |
| 2825 visitIf(ast.If node) { | 2830 visitIf(ast.If node) { |
| 2826 assert(isReachable); | 2831 assert(isReachable); |
| 2827 handleIf(node, | 2832 handleIf(node, |
| 2828 () => visit(node.condition), | 2833 () => visit(node.condition), |
| 2829 () => visit(node.thenPart), | 2834 () => visit(node.thenPart), |
| 2830 node.elsePart != null ? () => visit(node.elsePart) : null); | 2835 node.elsePart != null ? () => visit(node.elsePart) : null); |
| 2831 } | 2836 } |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3291 new HInvokeClosure(closureSelector, inputs, backend.dynamicType), | 3296 new HInvokeClosure(closureSelector, inputs, backend.dynamicType), |
| 3292 node); | 3297 node); |
| 3293 } | 3298 } |
| 3294 | 3299 |
| 3295 void handleForeignJs(ast.Send node) { | 3300 void handleForeignJs(ast.Send node) { |
| 3296 Link<ast.Node> link = node.arguments; | 3301 Link<ast.Node> link = node.arguments; |
| 3297 // If the invoke is on foreign code, don't visit the first | 3302 // If the invoke is on foreign code, don't visit the first |
| 3298 // argument, which is the type, and the second argument, | 3303 // argument, which is the type, and the second argument, |
| 3299 // which is the foreign code. | 3304 // which is the foreign code. |
| 3300 if (link.isEmpty || link.tail.isEmpty) { | 3305 if (link.isEmpty || link.tail.isEmpty) { |
| 3301 compiler.cancel('At least two arguments expected', | 3306 compiler.internalError(node.argumentsNode, |
| 3302 node: node.argumentsNode); | 3307 'At least two arguments expected.'); |
| 3303 } | 3308 } |
| 3304 native.NativeBehavior nativeBehavior = | 3309 native.NativeBehavior nativeBehavior = |
| 3305 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node); | 3310 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node); |
| 3306 | 3311 |
| 3307 List<HInstruction> inputs = <HInstruction>[]; | 3312 List<HInstruction> inputs = <HInstruction>[]; |
| 3308 addGenericSendArgumentsToList(link.tail.tail, inputs); | 3313 addGenericSendArgumentsToList(link.tail.tail, inputs); |
| 3309 | 3314 |
| 3310 TypeMask ssaType = | 3315 TypeMask ssaType = |
| 3311 TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler); | 3316 TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler); |
| 3312 push(new HForeign(nativeBehavior.codeAst, ssaType, inputs, | 3317 push(new HForeign(nativeBehavior.codeAst, ssaType, inputs, |
| 3313 effects: nativeBehavior.sideEffects, | 3318 effects: nativeBehavior.sideEffects, |
| 3314 nativeBehavior: nativeBehavior)); | 3319 nativeBehavior: nativeBehavior)); |
| 3315 return; | 3320 return; |
| 3316 } | 3321 } |
| 3317 | 3322 |
| 3318 void handleForeignJsCurrentIsolateContext(ast.Send node) { | 3323 void handleForeignJsCurrentIsolateContext(ast.Send node) { |
| 3319 if (!node.arguments.isEmpty) { | 3324 if (!node.arguments.isEmpty) { |
| 3320 compiler.cancel( | 3325 compiler.internalError(node, |
| 3321 'Too many arguments to JS_CURRENT_ISOLATE_CONTEXT', node: node); | 3326 'Too many arguments to JS_CURRENT_ISOLATE_CONTEXT.'); |
| 3322 } | 3327 } |
| 3323 | 3328 |
| 3324 if (!compiler.hasIsolateSupport()) { | 3329 if (!compiler.hasIsolateSupport()) { |
| 3325 // If the isolate library is not used, we just generate code | 3330 // If the isolate library is not used, we just generate code |
| 3326 // to fetch the current isolate. | 3331 // to fetch the current isolate. |
| 3327 String name = backend.namer.currentIsolate; | 3332 String name = backend.namer.currentIsolate; |
| 3328 push(new HForeign(new js.LiteralString(name), | 3333 push(new HForeign(new js.LiteralString(name), |
| 3329 backend.dynamicType, | 3334 backend.dynamicType, |
| 3330 <HInstruction>[])); | 3335 <HInstruction>[])); |
| 3331 } else { | 3336 } else { |
| 3332 // Call a helper method from the isolate library. The isolate | 3337 // Call a helper method from the isolate library. The isolate |
| 3333 // library uses its own isolate structure, that encapsulates | 3338 // library uses its own isolate structure, that encapsulates |
| 3334 // Leg's isolate. | 3339 // Leg's isolate. |
| 3335 Element element = compiler.isolateHelperLibrary.find('_currentIsolate'); | 3340 Element element = compiler.isolateHelperLibrary.find('_currentIsolate'); |
| 3336 if (element == null) { | 3341 if (element == null) { |
| 3337 compiler.cancel( | 3342 compiler.internalError(node, |
| 3338 'Isolate library and compiler mismatch', node: node); | 3343 'Isolate library and compiler mismatch.'); |
| 3339 } | 3344 } |
| 3340 pushInvokeStatic(null, element, [], backend.dynamicType); | 3345 pushInvokeStatic(null, element, [], backend.dynamicType); |
| 3341 } | 3346 } |
| 3342 } | 3347 } |
| 3343 | 3348 |
| 3344 void handleForeignJsGetName(ast.Send node) { | 3349 void handleForeignJsGetName(ast.Send node) { |
| 3345 List<ast.Node> arguments = node.arguments.toList(); | 3350 List<ast.Node> arguments = node.arguments.toList(); |
| 3346 ast.Node argument; | 3351 ast.Node argument; |
| 3347 switch (arguments.length) { | 3352 switch (arguments.length) { |
| 3348 case 0: | 3353 case 0: |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3403 // closure. | 3408 // closure. |
| 3404 visit(link.tail.head); | 3409 visit(link.tail.head); |
| 3405 Selector selector = new Selector.callClosure(0); | 3410 Selector selector = new Selector.callClosure(0); |
| 3406 push(new HInvokeClosure(selector, | 3411 push(new HInvokeClosure(selector, |
| 3407 <HInstruction>[pop()], | 3412 <HInstruction>[pop()], |
| 3408 backend.dynamicType)); | 3413 backend.dynamicType)); |
| 3409 } else { | 3414 } else { |
| 3410 // Call a helper method from the isolate library. | 3415 // Call a helper method from the isolate library. |
| 3411 Element element = compiler.isolateHelperLibrary.find('_callInIsolate'); | 3416 Element element = compiler.isolateHelperLibrary.find('_callInIsolate'); |
| 3412 if (element == null) { | 3417 if (element == null) { |
| 3413 compiler.cancel( | 3418 compiler.internalError(node, |
| 3414 'Isolate library and compiler mismatch', node: node); | 3419 'Isolate library and compiler mismatch.'); |
| 3415 } | 3420 } |
| 3416 List<HInstruction> inputs = <HInstruction>[]; | 3421 List<HInstruction> inputs = <HInstruction>[]; |
| 3417 addGenericSendArgumentsToList(link, inputs); | 3422 addGenericSendArgumentsToList(link, inputs); |
| 3418 pushInvokeStatic(node, element, inputs, backend.dynamicType); | 3423 pushInvokeStatic(node, element, inputs, backend.dynamicType); |
| 3419 } | 3424 } |
| 3420 } | 3425 } |
| 3421 | 3426 |
| 3422 FunctionSignature handleForeignRawFunctionRef(ast.Send node, String name) { | 3427 FunctionSignature handleForeignRawFunctionRef(ast.Send node, String name) { |
| 3423 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { | 3428 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { |
| 3424 compiler.cancel('"$name" requires exactly one argument', | 3429 compiler.internalError(node.argumentsNode, |
| 3425 node: node.argumentsNode); | 3430 '"$name" requires exactly one argument.'); |
| 3426 } | 3431 } |
| 3427 ast.Node closure = node.arguments.head; | 3432 ast.Node closure = node.arguments.head; |
| 3428 Element element = elements[closure]; | 3433 Element element = elements[closure]; |
| 3429 if (!Elements.isStaticOrTopLevelFunction(element)) { | 3434 if (!Elements.isStaticOrTopLevelFunction(element)) { |
| 3430 compiler.cancel( | 3435 compiler.internalError(closure, |
| 3431 '"$name" requires a static or top-level method', | 3436 '"$name" requires a static or top-level method.'); |
| 3432 node: closure); | |
| 3433 } | 3437 } |
| 3434 FunctionElement function = element; | 3438 FunctionElement function = element; |
| 3435 // TODO(johnniwinther): Try to eliminate the need to distinguish declaration | 3439 // TODO(johnniwinther): Try to eliminate the need to distinguish declaration |
| 3436 // and implementation signatures. Currently it is need because the | 3440 // and implementation signatures. Currently it is need because the |
| 3437 // signatures have different elements for parameters. | 3441 // signatures have different elements for parameters. |
| 3438 FunctionElement implementation = function.implementation; | 3442 FunctionElement implementation = function.implementation; |
| 3439 FunctionSignature params = implementation.functionSignature; | 3443 FunctionSignature params = implementation.functionSignature; |
| 3440 if (params.optionalParameterCount != 0) { | 3444 if (params.optionalParameterCount != 0) { |
| 3441 compiler.cancel( | 3445 compiler.internalError(closure, |
| 3442 '"$name" does not handle closure with optional parameters', | 3446 '"$name" does not handle closure with optional parameters.'); |
| 3443 node: closure); | |
| 3444 } | 3447 } |
| 3445 | 3448 |
| 3446 compiler.enqueuer.codegen.registerStaticUse(element); | 3449 compiler.enqueuer.codegen.registerStaticUse(element); |
| 3447 push(new HForeign(backend.namer.elementAccess(element), | 3450 push(new HForeign(backend.namer.elementAccess(element), |
| 3448 backend.dynamicType, | 3451 backend.dynamicType, |
| 3449 <HInstruction>[])); | 3452 <HInstruction>[])); |
| 3450 return params; | 3453 return params; |
| 3451 } | 3454 } |
| 3452 | 3455 |
| 3453 void handleForeignDartClosureToJs(ast.Send node, String name) { | 3456 void handleForeignDartClosureToJs(ast.Send node, String name) { |
| 3454 // TODO(ahe): This implements DART_CLOSURE_TO_JS and should probably take | 3457 // TODO(ahe): This implements DART_CLOSURE_TO_JS and should probably take |
| 3455 // care to wrap the closure in another closure that saves the current | 3458 // care to wrap the closure in another closure that saves the current |
| 3456 // isolate. | 3459 // isolate. |
| 3457 handleForeignRawFunctionRef(node, name); | 3460 handleForeignRawFunctionRef(node, name); |
| 3458 } | 3461 } |
| 3459 | 3462 |
| 3460 void handleForeignSetCurrentIsolate(ast.Send node) { | 3463 void handleForeignSetCurrentIsolate(ast.Send node) { |
| 3461 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { | 3464 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { |
| 3462 compiler.cancel('Exactly one argument required', | 3465 compiler.internalError(node.argumentsNode, |
| 3463 node: node.argumentsNode); | 3466 'Exactly one argument required.'); |
| 3464 } | 3467 } |
| 3465 visit(node.arguments.head); | 3468 visit(node.arguments.head); |
| 3466 String isolateName = backend.namer.currentIsolate; | 3469 String isolateName = backend.namer.currentIsolate; |
| 3467 SideEffects sideEffects = new SideEffects.empty(); | 3470 SideEffects sideEffects = new SideEffects.empty(); |
| 3468 sideEffects.setAllSideEffects(); | 3471 sideEffects.setAllSideEffects(); |
| 3469 push(new HForeign(js.js("$isolateName = #"), | 3472 push(new HForeign(js.js("$isolateName = #"), |
| 3470 backend.dynamicType, | 3473 backend.dynamicType, |
| 3471 <HInstruction>[pop()], | 3474 <HInstruction>[pop()], |
| 3472 effects: sideEffects)); | 3475 effects: sideEffects)); |
| 3473 } | 3476 } |
| 3474 | 3477 |
| 3475 void handleForeignCreateIsolate(ast.Send node) { | 3478 void handleForeignCreateIsolate(ast.Send node) { |
| 3476 if (!node.arguments.isEmpty) { | 3479 if (!node.arguments.isEmpty) { |
| 3477 compiler.cancel('Too many arguments', | 3480 compiler.internalError(node.argumentsNode, 'Too many arguments.'); |
| 3478 node: node.argumentsNode); | |
| 3479 } | 3481 } |
| 3480 String constructorName = backend.namer.isolateName; | 3482 String constructorName = backend.namer.isolateName; |
| 3481 push(new HForeign(js.js("new $constructorName()"), | 3483 push(new HForeign(js.js("new $constructorName()"), |
| 3482 backend.dynamicType, | 3484 backend.dynamicType, |
| 3483 <HInstruction>[])); | 3485 <HInstruction>[])); |
| 3484 } | 3486 } |
| 3485 | 3487 |
| 3486 void handleForeignDartObjectJsConstructorFunction(ast.Send node) { | 3488 void handleForeignDartObjectJsConstructorFunction(ast.Send node) { |
| 3487 if (!node.arguments.isEmpty) { | 3489 if (!node.arguments.isEmpty) { |
| 3488 compiler.cancel('Too many arguments', node: node.argumentsNode); | 3490 compiler.internalError(node.argumentsNode, 'Too many arguments.'); |
| 3489 } | 3491 } |
| 3490 String jsClassReference = backend.namer.isolateAccess(compiler.objectClass); | 3492 String jsClassReference = backend.namer.isolateAccess(compiler.objectClass); |
| 3491 push(new HForeign(new js.LiteralString(jsClassReference), | 3493 push(new HForeign(new js.LiteralString(jsClassReference), |
| 3492 backend.dynamicType, | 3494 backend.dynamicType, |
| 3493 <HInstruction>[])); | 3495 <HInstruction>[])); |
| 3494 } | 3496 } |
| 3495 | 3497 |
| 3496 void handleForeignJsCurrentIsolate(ast.Send node) { | 3498 void handleForeignJsCurrentIsolate(ast.Send node) { |
| 3497 if (!node.arguments.isEmpty) { | 3499 if (!node.arguments.isEmpty) { |
| 3498 compiler.cancel('Too many arguments', node: node.argumentsNode); | 3500 compiler.internalError(node.argumentsNode, 'Too many arguments.'); |
| 3499 } | 3501 } |
| 3500 push(new HForeign(new js.LiteralString(backend.namer.currentIsolate), | 3502 push(new HForeign(new js.LiteralString(backend.namer.currentIsolate), |
| 3501 backend.dynamicType, | 3503 backend.dynamicType, |
| 3502 <HInstruction>[])); | 3504 <HInstruction>[])); |
| 3503 } | 3505 } |
| 3504 | 3506 |
| 3505 visitForeignSend(ast.Send node) { | 3507 visitForeignSend(ast.Send node) { |
| 3506 Selector selector = elements.getSelector(node); | 3508 Selector selector = elements.getSelector(node); |
| 3507 String name = selector.name; | 3509 String name = selector.name; |
| 3508 if (name == 'JS') { | 3510 if (name == 'JS') { |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3755 (member.isField() && !isBuildingFor(member))) { | 3757 (member.isField() && !isBuildingFor(member))) { |
| 3756 // The type variable is stored in a parameter of the method. | 3758 // The type variable is stored in a parameter of the method. |
| 3757 return localsHandler.readLocal(type.element); | 3759 return localsHandler.readLocal(type.element); |
| 3758 } else if (member.isInstanceMember()) { | 3760 } else if (member.isInstanceMember()) { |
| 3759 // The type variable is stored on the object. | 3761 // The type variable is stored on the object. |
| 3760 return readTypeVariable(member.getEnclosingClass(), | 3762 return readTypeVariable(member.getEnclosingClass(), |
| 3761 type.element); | 3763 type.element); |
| 3762 } else { | 3764 } else { |
| 3763 // TODO(ngeoffray): Match the VM behavior and throw an | 3765 // TODO(ngeoffray): Match the VM behavior and throw an |
| 3764 // exception at runtime. | 3766 // exception at runtime. |
| 3765 compiler.cancel('Unimplemented unresolved type variable', | 3767 compiler.internalError(type.element, |
| 3766 element: type.element); | 3768 'Unimplemented unresolved type variable.'); |
| 3767 return null; | 3769 return null; |
| 3768 } | 3770 } |
| 3769 } | 3771 } |
| 3770 | 3772 |
| 3771 HInstruction analyzeTypeArgument(DartType argument) { | 3773 HInstruction analyzeTypeArgument(DartType argument) { |
| 3772 if (argument.treatAsDynamic) { | 3774 if (argument.treatAsDynamic) { |
| 3773 // Represent [dynamic] as [null]. | 3775 // Represent [dynamic] as [null]. |
| 3774 return graph.addConstantNull(compiler); | 3776 return graph.addConstantNull(compiler); |
| 3775 } | 3777 } |
| 3776 | 3778 |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4163 push(new HInvokeClosure(closureSelector, inputs, backend.dynamicType)); | 4165 push(new HInvokeClosure(closureSelector, inputs, backend.dynamicType)); |
| 4164 } | 4166 } |
| 4165 } | 4167 } |
| 4166 | 4168 |
| 4167 visitGetterSend(ast.Send node) { | 4169 visitGetterSend(ast.Send node) { |
| 4168 generateGetter(node, elements[node]); | 4170 generateGetter(node, elements[node]); |
| 4169 } | 4171 } |
| 4170 | 4172 |
| 4171 // TODO(antonm): migrate rest of SsaFromAstMixin to internalError. | 4173 // TODO(antonm): migrate rest of SsaFromAstMixin to internalError. |
| 4172 internalError(String reason, {ast.Node node}) { | 4174 internalError(String reason, {ast.Node node}) { |
| 4173 compiler.internalError(reason, node: node); | 4175 compiler.internalError(node, reason); |
| 4174 } | 4176 } |
| 4175 | 4177 |
| 4176 void generateError(ast.Node node, String message, Element helper) { | 4178 void generateError(ast.Node node, String message, Element helper) { |
| 4177 HInstruction errorMessage = addConstantString(message); | 4179 HInstruction errorMessage = addConstantString(message); |
| 4178 pushInvokeStatic(node, helper, [errorMessage]); | 4180 pushInvokeStatic(node, helper, [errorMessage]); |
| 4179 } | 4181 } |
| 4180 | 4182 |
| 4181 void generateRuntimeError(ast.Node node, String message) { | 4183 void generateRuntimeError(ast.Node node, String message) { |
| 4182 generateError(node, message, backend.getThrowRuntimeError()); | 4184 generateError(node, message, backend.getThrowRuntimeError()); |
| 4183 } | 4185 } |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4533 assert(!link.isEmpty && link.tail.isEmpty); | 4535 assert(!link.isEmpty && link.tail.isEmpty); |
| 4534 if (Elements.isInstanceSend(node, elements)) { | 4536 if (Elements.isInstanceSend(node, elements)) { |
| 4535 HInstruction receiver = generateInstanceSendReceiver(node); | 4537 HInstruction receiver = generateInstanceSendReceiver(node); |
| 4536 visit(link.head); | 4538 visit(link.head); |
| 4537 generateInstanceSetterWithCompiledReceiver(node, receiver, pop()); | 4539 generateInstanceSetterWithCompiledReceiver(node, receiver, pop()); |
| 4538 } else { | 4540 } else { |
| 4539 visit(link.head); | 4541 visit(link.head); |
| 4540 generateNonInstanceSetter(node, element, pop()); | 4542 generateNonInstanceSetter(node, element, pop()); |
| 4541 } | 4543 } |
| 4542 } else if (identical(op.source, "is")) { | 4544 } else if (identical(op.source, "is")) { |
| 4543 compiler.internalError("is-operator as SendSet", node: op); | 4545 compiler.internalError(op, "is-operator as SendSet."); |
| 4544 } else { | 4546 } else { |
| 4545 assert("++" == op.source || "--" == op.source || | 4547 assert("++" == op.source || "--" == op.source || |
| 4546 node.assignmentOperator.source.endsWith("=")); | 4548 node.assignmentOperator.source.endsWith("=")); |
| 4547 | 4549 |
| 4548 // [receiver] is only used if the node is an instance send. | 4550 // [receiver] is only used if the node is an instance send. |
| 4549 HInstruction receiver = null; | 4551 HInstruction receiver = null; |
| 4550 Element getter = elements[node.selector]; | 4552 Element getter = elements[node.selector]; |
| 4551 | 4553 |
| 4552 if (!Elements.isUnresolved(getter) && getter.impliesType()) { | 4554 if (!Elements.isUnresolved(getter) && getter.impliesType()) { |
| 4553 ast.Identifier selector = node.selector; | 4555 ast.Identifier selector = node.selector; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4626 } | 4628 } |
| 4627 } | 4629 } |
| 4628 } | 4630 } |
| 4629 | 4631 |
| 4630 void visitParenthesizedExpression(ast.ParenthesizedExpression node) { | 4632 void visitParenthesizedExpression(ast.ParenthesizedExpression node) { |
| 4631 visit(node.expression); | 4633 visit(node.expression); |
| 4632 } | 4634 } |
| 4633 | 4635 |
| 4634 visitOperator(ast.Operator node) { | 4636 visitOperator(ast.Operator node) { |
| 4635 // Operators are intercepted in their surrounding Send nodes. | 4637 // Operators are intercepted in their surrounding Send nodes. |
| 4636 compiler.internalError('visitOperator should not be called', node: node); | 4638 compiler.internalError(node, |
| 4639 'SsaBuilder.visitOperator should not be called.'); |
| 4637 } | 4640 } |
| 4638 | 4641 |
| 4639 visitCascade(ast.Cascade node) { | 4642 visitCascade(ast.Cascade node) { |
| 4640 visit(node.expression); | 4643 visit(node.expression); |
| 4641 // Remove the result and reveal the duplicated receiver on the stack. | 4644 // Remove the result and reveal the duplicated receiver on the stack. |
| 4642 pop(); | 4645 pop(); |
| 4643 } | 4646 } |
| 4644 | 4647 |
| 4645 visitCascadeReceiver(ast.CascadeReceiver node) { | 4648 visitCascadeReceiver(ast.CascadeReceiver node) { |
| 4646 visit(node.expression); | 4649 visit(node.expression); |
| 4647 dup(); | 4650 dup(); |
| 4648 } | 4651 } |
| 4649 | 4652 |
| 4650 void handleInTryStatement() { | 4653 void handleInTryStatement() { |
| 4651 if (!inTryStatement) return; | 4654 if (!inTryStatement) return; |
| 4652 HBasicBlock block = close(new HExitTry()); | 4655 HBasicBlock block = close(new HExitTry()); |
| 4653 HBasicBlock newBlock = graph.addNewBlock(); | 4656 HBasicBlock newBlock = graph.addNewBlock(); |
| 4654 block.addSuccessor(newBlock); | 4657 block.addSuccessor(newBlock); |
| 4655 open(newBlock); | 4658 open(newBlock); |
| 4656 } | 4659 } |
| 4657 | 4660 |
| 4658 visitRethrow(ast.Rethrow node) { | 4661 visitRethrow(ast.Rethrow node) { |
| 4659 HInstruction exception = rethrowableException; | 4662 HInstruction exception = rethrowableException; |
| 4660 if (exception == null) { | 4663 if (exception == null) { |
| 4661 exception = graph.addConstantNull(compiler); | 4664 exception = graph.addConstantNull(compiler); |
| 4662 compiler.internalError( | 4665 compiler.internalError(node, |
| 4663 'rethrowableException should not be null', node: node); | 4666 'rethrowableException should not be null.'); |
| 4664 } | 4667 } |
| 4665 handleInTryStatement(); | 4668 handleInTryStatement(); |
| 4666 closeAndGotoExit(new HThrow(exception, isRethrow: true)); | 4669 closeAndGotoExit(new HThrow(exception, isRethrow: true)); |
| 4667 } | 4670 } |
| 4668 | 4671 |
| 4669 visitReturn(ast.Return node) { | 4672 visitReturn(ast.Return node) { |
| 4670 if (identical(node.getBeginToken().stringValue, 'native')) { | 4673 if (identical(node.getBeginToken().stringValue, 'native')) { |
| 4671 native.handleSsaNative(this, node.expression); | 4674 native.handleSsaNative(this, node.expression); |
| 4672 return; | 4675 return; |
| 4673 } | 4676 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4720 visitThrow(ast.Throw node) { | 4723 visitThrow(ast.Throw node) { |
| 4721 visitThrowExpression(node.expression); | 4724 visitThrowExpression(node.expression); |
| 4722 if (isReachable) { | 4725 if (isReachable) { |
| 4723 handleInTryStatement(); | 4726 handleInTryStatement(); |
| 4724 push(new HThrowExpression(pop())); | 4727 push(new HThrowExpression(pop())); |
| 4725 isReachable = false; | 4728 isReachable = false; |
| 4726 } | 4729 } |
| 4727 } | 4730 } |
| 4728 | 4731 |
| 4729 visitTypeAnnotation(ast.TypeAnnotation node) { | 4732 visitTypeAnnotation(ast.TypeAnnotation node) { |
| 4730 compiler.internalError('visiting type annotation in SSA builder', | 4733 compiler.internalError(node, |
| 4731 node: node); | 4734 'Visiting type annotation in SSA builder.'); |
| 4732 } | 4735 } |
| 4733 | 4736 |
| 4734 visitVariableDefinitions(ast.VariableDefinitions node) { | 4737 visitVariableDefinitions(ast.VariableDefinitions node) { |
| 4735 assert(isReachable); | 4738 assert(isReachable); |
| 4736 for (Link<ast.Node> link = node.definitions.nodes; | 4739 for (Link<ast.Node> link = node.definitions.nodes; |
| 4737 !link.isEmpty; | 4740 !link.isEmpty; |
| 4738 link = link.tail) { | 4741 link = link.tail) { |
| 4739 ast.Node definition = link.head; | 4742 ast.Node definition = link.head; |
| 4740 if (definition is ast.Identifier) { | 4743 if (definition is ast.Identifier) { |
| 4741 HInstruction initialValue = graph.addConstantNull(compiler); | 4744 HInstruction initialValue = graph.addConstantNull(compiler); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4794 } | 4797 } |
| 4795 | 4798 |
| 4796 visitStringInterpolation(ast.StringInterpolation node) { | 4799 visitStringInterpolation(ast.StringInterpolation node) { |
| 4797 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); | 4800 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); |
| 4798 stringBuilder.visit(node); | 4801 stringBuilder.visit(node); |
| 4799 stack.add(stringBuilder.result); | 4802 stack.add(stringBuilder.result); |
| 4800 } | 4803 } |
| 4801 | 4804 |
| 4802 visitStringInterpolationPart(ast.StringInterpolationPart node) { | 4805 visitStringInterpolationPart(ast.StringInterpolationPart node) { |
| 4803 // The parts are iterated in visitStringInterpolation. | 4806 // The parts are iterated in visitStringInterpolation. |
| 4804 compiler.internalError('visitStringInterpolation should not be called', | 4807 compiler.internalError(node, |
| 4805 node: node); | 4808 'SsaBuilder.visitStringInterpolation should not be called.'); |
| 4806 } | 4809 } |
| 4807 | 4810 |
| 4808 visitEmptyStatement(ast.EmptyStatement node) { | 4811 visitEmptyStatement(ast.EmptyStatement node) { |
| 4809 // Do nothing, empty statement. | 4812 // Do nothing, empty statement. |
| 4810 } | 4813 } |
| 4811 | 4814 |
| 4812 visitModifiers(ast.Modifiers node) { | 4815 visitModifiers(ast.Modifiers node) { |
| 4813 compiler.unimplemented('SsaFromAstMixin.visitModifiers', node: node); | 4816 compiler.unimplemented(node, 'SsaFromAstMixin.visitModifiers.'); |
| 4814 } | 4817 } |
| 4815 | 4818 |
| 4816 visitBreakStatement(ast.BreakStatement node) { | 4819 visitBreakStatement(ast.BreakStatement node) { |
| 4817 assert(!isAborted()); | 4820 assert(!isAborted()); |
| 4818 handleInTryStatement(); | 4821 handleInTryStatement(); |
| 4819 TargetElement target = elements[node]; | 4822 TargetElement target = elements[node]; |
| 4820 assert(target != null); | 4823 assert(target != null); |
| 4821 JumpHandler handler = jumpTargets[target]; | 4824 JumpHandler handler = jumpTargets[target]; |
| 4822 assert(handler != null); | 4825 assert(handler != null); |
| 4823 if (node.target == null) { | 4826 if (node.target == null) { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4911 generateNonInstanceSetter(null, variable, value, location: identifier); | 4914 generateNonInstanceSetter(null, variable, value, location: identifier); |
| 4912 } | 4915 } |
| 4913 pop(); // Pop the value pushed by the setter call. | 4916 pop(); // Pop the value pushed by the setter call. |
| 4914 | 4917 |
| 4915 visit(node.body); | 4918 visit(node.body); |
| 4916 } | 4919 } |
| 4917 handleLoop(node, buildInitializer, buildCondition, () {}, buildBody); | 4920 handleLoop(node, buildInitializer, buildCondition, () {}, buildBody); |
| 4918 } | 4921 } |
| 4919 | 4922 |
| 4920 visitLabel(ast.Label node) { | 4923 visitLabel(ast.Label node) { |
| 4921 compiler.internalError('SsaFromAstMixin.visitLabel', node: node); | 4924 compiler.internalError(node, 'SsaFromAstMixin.visitLabel.'); |
| 4922 } | 4925 } |
| 4923 | 4926 |
| 4924 visitLabeledStatement(ast.LabeledStatement node) { | 4927 visitLabeledStatement(ast.LabeledStatement node) { |
| 4925 ast.Statement body = node.statement; | 4928 ast.Statement body = node.statement; |
| 4926 if (body is ast.Loop | 4929 if (body is ast.Loop |
| 4927 || body is ast.SwitchStatement | 4930 || body is ast.SwitchStatement |
| 4928 || Elements.isUnusedLabel(node, elements)) { | 4931 || Elements.isUnusedLabel(node, elements)) { |
| 4929 // Loops and switches handle their own labels. | 4932 // Loops and switches handle their own labels. |
| 4930 visit(body); | 4933 visit(body); |
| 4931 return; | 4934 return; |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5341 new HSwitchBlockInformation(expressionInfo, | 5344 new HSwitchBlockInformation(expressionInfo, |
| 5342 statements, | 5345 statements, |
| 5343 jumpHandler.target, | 5346 jumpHandler.target, |
| 5344 jumpHandler.labels()), | 5347 jumpHandler.labels()), |
| 5345 joinBlock); | 5348 joinBlock); |
| 5346 | 5349 |
| 5347 jumpHandler.close(); | 5350 jumpHandler.close(); |
| 5348 } | 5351 } |
| 5349 | 5352 |
| 5350 visitSwitchCase(ast.SwitchCase node) { | 5353 visitSwitchCase(ast.SwitchCase node) { |
| 5351 compiler.internalError('SsaFromAstMixin.visitSwitchCase'); | 5354 compiler.internalError(node, 'SsaFromAstMixin.visitSwitchCase.'); |
| 5352 } | 5355 } |
| 5353 | 5356 |
| 5354 visitCaseMatch(ast.CaseMatch node) { | 5357 visitCaseMatch(ast.CaseMatch node) { |
| 5355 compiler.internalError('SsaFromAstMixin.visitCaseMatch'); | 5358 compiler.internalError(node, 'SsaFromAstMixin.visitCaseMatch.'); |
| 5356 } | 5359 } |
| 5357 | 5360 |
| 5358 visitTryStatement(ast.TryStatement node) { | 5361 visitTryStatement(ast.TryStatement node) { |
| 5359 // Save the current locals. The catch block and the finally block | 5362 // Save the current locals. The catch block and the finally block |
| 5360 // must not reuse the existing locals handler. None of the variables | 5363 // must not reuse the existing locals handler. None of the variables |
| 5361 // that have been defined in the body-block will be used, but for | 5364 // that have been defined in the body-block will be used, but for |
| 5362 // loops we will add (unnecessary) phis that will reference the body | 5365 // loops we will add (unnecessary) phis that will reference the body |
| 5363 // variables. This makes it look as if the variables were used | 5366 // variables. This makes it look as if the variables were used |
| 5364 // in a non-dominated block. | 5367 // in a non-dominated block. |
| 5365 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); | 5368 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5402 | 5405 |
| 5403 pushInvokeStatic(node, backend.getExceptionUnwrapper(), [exception]); | 5406 pushInvokeStatic(node, backend.getExceptionUnwrapper(), [exception]); |
| 5404 HInvokeStatic unwrappedException = pop(); | 5407 HInvokeStatic unwrappedException = pop(); |
| 5405 tryInstruction.exception = exception; | 5408 tryInstruction.exception = exception; |
| 5406 Link<ast.Node> link = node.catchBlocks.nodes; | 5409 Link<ast.Node> link = node.catchBlocks.nodes; |
| 5407 | 5410 |
| 5408 void pushCondition(ast.CatchBlock catchBlock) { | 5411 void pushCondition(ast.CatchBlock catchBlock) { |
| 5409 if (catchBlock.onKeyword != null) { | 5412 if (catchBlock.onKeyword != null) { |
| 5410 DartType type = elements.getType(catchBlock.type); | 5413 DartType type = elements.getType(catchBlock.type); |
| 5411 if (type == null) { | 5414 if (type == null) { |
| 5412 compiler.internalError('On with no type', node: catchBlock.type); | 5415 compiler.internalError(catchBlock.type, 'On with no type.'); |
| 5413 } | 5416 } |
| 5414 HInstruction condition = | 5417 HInstruction condition = |
| 5415 buildIsNode(catchBlock.type, type, unwrappedException); | 5418 buildIsNode(catchBlock.type, type, unwrappedException); |
| 5416 push(condition); | 5419 push(condition); |
| 5417 } else { | 5420 } else { |
| 5418 ast.VariableDefinitions declaration = catchBlock.formals.nodes.head; | 5421 ast.VariableDefinitions declaration = catchBlock.formals.nodes.head; |
| 5419 HInstruction condition = null; | 5422 HInstruction condition = null; |
| 5420 if (declaration.type == null) { | 5423 if (declaration.type == null) { |
| 5421 condition = graph.addConstantBool(true, compiler); | 5424 condition = graph.addConstantBool(true, compiler); |
| 5422 stack.add(condition); | 5425 stack.add(condition); |
| 5423 } else { | 5426 } else { |
| 5424 // TODO(aprelev@gmail.com): Once old catch syntax is removed | 5427 // TODO(aprelev@gmail.com): Once old catch syntax is removed |
| 5425 // "if" condition above and this "else" branch should be deleted as | 5428 // "if" condition above and this "else" branch should be deleted as |
| 5426 // type of declared variable won't matter for the catch | 5429 // type of declared variable won't matter for the catch |
| 5427 // condition. | 5430 // condition. |
| 5428 DartType type = elements.getType(declaration.type); | 5431 DartType type = elements.getType(declaration.type); |
| 5429 if (type == null) { | 5432 if (type == null) { |
| 5430 compiler.cancel('Catch with unresolved type', node: catchBlock); | 5433 compiler.internalError(catchBlock, 'Catch with unresolved type.'); |
| 5431 } | 5434 } |
| 5432 condition = buildIsNode(declaration.type, type, unwrappedException); | 5435 condition = buildIsNode(declaration.type, type, unwrappedException); |
| 5433 push(condition); | 5436 push(condition); |
| 5434 } | 5437 } |
| 5435 } | 5438 } |
| 5436 } | 5439 } |
| 5437 | 5440 |
| 5438 void visitThen() { | 5441 void visitThen() { |
| 5439 ast.CatchBlock catchBlock = link.head; | 5442 ast.CatchBlock catchBlock = link.head; |
| 5440 link = link.tail; | 5443 link = link.tail; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5545 wrapStatementGraph(finallyGraph)), | 5548 wrapStatementGraph(finallyGraph)), |
| 5546 exitBlock); | 5549 exitBlock); |
| 5547 inTryStatement = oldInTryStatement; | 5550 inTryStatement = oldInTryStatement; |
| 5548 } | 5551 } |
| 5549 | 5552 |
| 5550 visitCatchBlock(ast.CatchBlock node) { | 5553 visitCatchBlock(ast.CatchBlock node) { |
| 5551 visit(node.block); | 5554 visit(node.block); |
| 5552 } | 5555 } |
| 5553 | 5556 |
| 5554 visitTypedef(ast.Typedef node) { | 5557 visitTypedef(ast.Typedef node) { |
| 5555 compiler.unimplemented('SsaFromAstMixin.visitTypedef', node: node); | 5558 compiler.unimplemented(node, 'SsaFromAstMixin.visitTypedef.'); |
| 5556 } | 5559 } |
| 5557 | 5560 |
| 5558 visitTypeVariable(ast.TypeVariable node) { | 5561 visitTypeVariable(ast.TypeVariable node) { |
| 5559 compiler.internalError('SsaFromAstMixin.visitTypeVariable'); | 5562 compiler.internalError(node, 'SsaFromAstMixin.visitTypeVariable.'); |
| 5560 } | 5563 } |
| 5561 | 5564 |
| 5562 /** | 5565 /** |
| 5563 * This method is invoked before inlining the body of [function] into this | 5566 * This method is invoked before inlining the body of [function] into this |
| 5564 * [SsaBuilder]. | 5567 * [SsaBuilder]. |
| 5565 */ | 5568 */ |
| 5566 void enterInlinedMethod(FunctionElement function, | 5569 void enterInlinedMethod(FunctionElement function, |
| 5567 ast.Node _, | 5570 ast.Node _, |
| 5568 List<HInstruction> compiledArguments) { | 5571 List<HInstruction> compiledArguments) { |
| 5569 AstInliningState state = new AstInliningState( | 5572 AstInliningState state = new AstInliningState( |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5613 */ | 5616 */ |
| 5614 HInstruction result = null; | 5617 HInstruction result = null; |
| 5615 | 5618 |
| 5616 StringBuilderVisitor(this.builder, this.diagnosticNode); | 5619 StringBuilderVisitor(this.builder, this.diagnosticNode); |
| 5617 | 5620 |
| 5618 void visit(ast.Node node) { | 5621 void visit(ast.Node node) { |
| 5619 node.accept(this); | 5622 node.accept(this); |
| 5620 } | 5623 } |
| 5621 | 5624 |
| 5622 visitNode(ast.Node node) { | 5625 visitNode(ast.Node node) { |
| 5623 builder.compiler.internalError('unexpected node', node: node); | 5626 builder.compiler.internalError(node, 'Unexpected node.'); |
| 5624 } | 5627 } |
| 5625 | 5628 |
| 5626 void visitExpression(ast.Node node) { | 5629 void visitExpression(ast.Node node) { |
| 5627 node.accept(builder); | 5630 node.accept(builder); |
| 5628 HInstruction expression = builder.pop(); | 5631 HInstruction expression = builder.pop(); |
| 5629 if (!expression.isConstantString()) { | 5632 if (!expression.isConstantString()) { |
| 5630 expression = new HStringify(expression, node, builder.backend.stringType); | 5633 expression = new HStringify(expression, node, builder.backend.stringType); |
| 5631 builder.add(expression); | 5634 builder.add(expression); |
| 5632 } | 5635 } |
| 5633 result = (result == null) ? expression : concat(result, expression); | 5636 result = (result == null) ? expression : concat(result, expression); |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5803 class SsaBranchBuilder { | 5806 class SsaBranchBuilder { |
| 5804 final SsaBuilder builder; | 5807 final SsaBuilder builder; |
| 5805 final ast.Node diagnosticNode; | 5808 final ast.Node diagnosticNode; |
| 5806 | 5809 |
| 5807 SsaBranchBuilder(this.builder, [this.diagnosticNode]); | 5810 SsaBranchBuilder(this.builder, [this.diagnosticNode]); |
| 5808 | 5811 |
| 5809 Compiler get compiler => builder.compiler; | 5812 Compiler get compiler => builder.compiler; |
| 5810 | 5813 |
| 5811 void checkNotAborted() { | 5814 void checkNotAborted() { |
| 5812 if (builder.isAborted()) { | 5815 if (builder.isAborted()) { |
| 5813 compiler.unimplemented("aborted control flow", node: diagnosticNode); | 5816 compiler.unimplemented(diagnosticNode, "aborted control flow"); |
| 5814 } | 5817 } |
| 5815 } | 5818 } |
| 5816 | 5819 |
| 5817 void buildCondition(void visitCondition(), | 5820 void buildCondition(void visitCondition(), |
| 5818 SsaBranch conditionBranch, | 5821 SsaBranch conditionBranch, |
| 5819 SsaBranch thenBranch, | 5822 SsaBranch thenBranch, |
| 5820 SsaBranch elseBranch) { | 5823 SsaBranch elseBranch) { |
| 5821 startBranch(conditionBranch); | 5824 startBranch(conditionBranch); |
| 5822 visitCondition(); | 5825 visitCondition(); |
| 5823 checkNotAborted(); | 5826 checkNotAborted(); |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6114 DartType unaliased = type.unalias(builder.compiler); | 6117 DartType unaliased = type.unalias(builder.compiler); |
| 6115 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 6118 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
| 6116 unaliased.accept(this, builder); | 6119 unaliased.accept(this, builder); |
| 6117 } | 6120 } |
| 6118 | 6121 |
| 6119 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 6122 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
| 6120 ClassElement cls = builder.compiler.findHelper('DynamicRuntimeType'); | 6123 ClassElement cls = builder.compiler.findHelper('DynamicRuntimeType'); |
| 6121 builder.push(new HDynamicType(type, new TypeMask.exact(cls))); | 6124 builder.push(new HDynamicType(type, new TypeMask.exact(cls))); |
| 6122 } | 6125 } |
| 6123 } | 6126 } |
| OLD | NEW |