| 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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 void redirectElement(Element from, Element to) { | 139 void redirectElement(Element from, Element to) { |
| 140 assert(redirectionMapping[from] == null); | 140 assert(redirectionMapping[from] == null); |
| 141 redirectionMapping[from] = to; | 141 redirectionMapping[from] = to; |
| 142 assert(isStoredInClosureField(from) || isBoxed(from)); | 142 assert(isStoredInClosureField(from) || isBoxed(from)); |
| 143 } | 143 } |
| 144 | 144 |
| 145 HInstruction createBox() { | 145 HInstruction createBox() { |
| 146 // TODO(floitsch): Clean up this hack. Should we create a box-object by | 146 // TODO(floitsch): Clean up this hack. Should we create a box-object by |
| 147 // just creating an empty object literal? | 147 // just creating an empty object literal? |
| 148 JavaScriptBackend backend = builder.backend; | 148 JavaScriptBackend backend = builder.backend; |
| 149 HInstruction box = new HForeign(js.js.parseForeignJS('{}'), | 149 HInstruction box = new HForeign(new js.ObjectInitializer([]), |
| 150 backend.nonNullType, | 150 backend.nonNullType, |
| 151 <HInstruction>[]); | 151 <HInstruction>[]); |
| 152 builder.add(box); | 152 builder.add(box); |
| 153 return box; | 153 return box; |
| 154 } | 154 } |
| 155 | 155 |
| 156 /** | 156 /** |
| 157 * If the scope (function or loop) [node] has captured variables then this | 157 * If the scope (function or loop) [node] has captured variables then this |
| 158 * method creates a box and sets up the redirections. | 158 * method creates a box and sets up the redirections. |
| 159 */ | 159 */ |
| (...skipping 2891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3051 localsHandler.updateLocal(element, checked); | 3051 localsHandler.updateLocal(element, checked); |
| 3052 } | 3052 } |
| 3053 } | 3053 } |
| 3054 | 3054 |
| 3055 HInstruction invokeInterceptor(HInstruction receiver) { | 3055 HInstruction invokeInterceptor(HInstruction receiver) { |
| 3056 HInterceptor interceptor = new HInterceptor(receiver, backend.nonNullType); | 3056 HInterceptor interceptor = new HInterceptor(receiver, backend.nonNullType); |
| 3057 add(interceptor); | 3057 add(interceptor); |
| 3058 return interceptor; | 3058 return interceptor; |
| 3059 } | 3059 } |
| 3060 | 3060 |
| 3061 HForeign createForeign(js.Template code, | 3061 HForeign createForeign(js.Expression code, |
| 3062 TypeMask type, | 3062 TypeMask type, |
| 3063 List<HInstruction> inputs) { | 3063 List<HInstruction> inputs) { |
| 3064 return new HForeign(code, type, inputs); | 3064 return new HForeign(code, type, inputs); |
| 3065 } | 3065 } |
| 3066 | 3066 |
| 3067 HLiteralList buildLiteralList(List<HInstruction> inputs) { | 3067 HLiteralList buildLiteralList(List<HInstruction> inputs) { |
| 3068 return new HLiteralList(inputs, backend.extendableArrayType); | 3068 return new HLiteralList(inputs, backend.extendableArrayType); |
| 3069 } | 3069 } |
| 3070 | 3070 |
| 3071 // TODO(karlklose): change construction of the representations to be GVN'able | 3071 // TODO(karlklose): change construction of the representations to be GVN'able |
| 3072 // (dartbug.com/7182). | 3072 // (dartbug.com/7182). |
| 3073 HInstruction buildTypeArgumentRepresentations(DartType type) { | 3073 HInstruction buildTypeArgumentRepresentations(DartType type) { |
| 3074 // Compute the representation of the type arguments, including access | 3074 // Compute the representation of the type arguments, including access |
| 3075 // to the runtime type information for type variables as instructions. | 3075 // to the runtime type information for type variables as instructions. |
| 3076 if (type.kind == TypeKind.TYPE_VARIABLE) { | 3076 if (type.kind == TypeKind.TYPE_VARIABLE) { |
| 3077 return buildLiteralList(<HInstruction>[addTypeVariableReference(type)]); | 3077 return buildLiteralList(<HInstruction>[addTypeVariableReference(type)]); |
| 3078 } else { | 3078 } else { |
| 3079 assert(type.element.isClass()); | 3079 assert(type.element.isClass()); |
| 3080 InterfaceType interface = type; | 3080 InterfaceType interface = type; |
| 3081 List<HInstruction> inputs = <HInstruction>[]; | 3081 List<HInstruction> inputs = <HInstruction>[]; |
| 3082 bool first = true; | 3082 bool first = true; |
| 3083 List<String> templates = <String>[]; | 3083 List<String> templates = <String>[]; |
| 3084 for (DartType argument in interface.typeArguments) { | 3084 for (DartType argument in interface.typeArguments) { |
| 3085 templates.add(rti.getTypeRepresentationWithHashes(argument, (variable) { | 3085 templates.add(rti.getTypeRepresentationWithHashes(argument, (variable) { |
| 3086 HInstruction runtimeType = addTypeVariableReference(variable); | 3086 HInstruction runtimeType = addTypeVariableReference(variable); |
| 3087 inputs.add(runtimeType); | 3087 inputs.add(runtimeType); |
| 3088 })); | 3088 })); |
| 3089 } | 3089 } |
| 3090 String template = '[${templates.join(', ')}]'; | 3090 String template = '[${templates.join(', ')}]'; |
| 3091 // TODO(sra): This is a fresh template each time. We can't let the | 3091 js.Expression code = js.js.parseForeignJS(template); |
| 3092 // template manager build them. | |
| 3093 js.Template code = js.js.uncachedExpressionTemplate(template); | |
| 3094 HInstruction representation = | 3092 HInstruction representation = |
| 3095 createForeign(code, backend.readableArrayType, inputs); | 3093 createForeign(code, backend.readableArrayType, inputs); |
| 3096 return representation; | 3094 return representation; |
| 3097 } | 3095 } |
| 3098 } | 3096 } |
| 3099 | 3097 |
| 3100 visitOperatorSend(ast.Send node) { | 3098 visitOperatorSend(ast.Send node) { |
| 3101 ast.Operator op = node.selector; | 3099 ast.Operator op = node.selector; |
| 3102 if ("[]" == op.source) { | 3100 if ("[]" == op.source) { |
| 3103 visitDynamicSend(node); | 3101 visitDynamicSend(node); |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3312 'At least two arguments expected.'); | 3310 'At least two arguments expected.'); |
| 3313 } | 3311 } |
| 3314 native.NativeBehavior nativeBehavior = | 3312 native.NativeBehavior nativeBehavior = |
| 3315 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node); | 3313 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node); |
| 3316 | 3314 |
| 3317 List<HInstruction> inputs = <HInstruction>[]; | 3315 List<HInstruction> inputs = <HInstruction>[]; |
| 3318 addGenericSendArgumentsToList(link.tail.tail, inputs); | 3316 addGenericSendArgumentsToList(link.tail.tail, inputs); |
| 3319 | 3317 |
| 3320 TypeMask ssaType = | 3318 TypeMask ssaType = |
| 3321 TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler); | 3319 TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler); |
| 3322 | 3320 push(new HForeign(nativeBehavior.codeAst, ssaType, inputs, |
| 3323 if (nativeBehavior.codeTemplate.isExpression) { | 3321 effects: nativeBehavior.sideEffects, |
| 3324 push(new HForeign(nativeBehavior.codeTemplate, ssaType, inputs, | 3322 nativeBehavior: nativeBehavior)); |
| 3325 effects: nativeBehavior.sideEffects, | |
| 3326 nativeBehavior: nativeBehavior)); | |
| 3327 } else { | |
| 3328 push(new HForeign(nativeBehavior.codeTemplate, ssaType, inputs, | |
| 3329 isStatement: true, | |
| 3330 effects: nativeBehavior.sideEffects, | |
| 3331 nativeBehavior: nativeBehavior, | |
| 3332 canThrow: true)); | |
| 3333 } | |
| 3334 } | 3323 } |
| 3335 | 3324 |
| 3336 void handleJsStringConcat(ast.Send node) { | 3325 void handleJsStringConcat(ast.Send node) { |
| 3337 List<HInstruction> inputs = <HInstruction>[]; | 3326 List<HInstruction> inputs = <HInstruction>[]; |
| 3338 addGenericSendArgumentsToList(node.arguments, inputs); | 3327 addGenericSendArgumentsToList(node.arguments, inputs); |
| 3339 if (inputs.length != 2) { | 3328 if (inputs.length != 2) { |
| 3340 compiler.internalError(node.argumentsNode, 'Two arguments expected.'); | 3329 compiler.internalError(node.argumentsNode, 'Two arguments expected.'); |
| 3341 } | 3330 } |
| 3342 push(new HStringConcat(inputs[0], inputs[1], node, backend.stringType)); | 3331 push(new HStringConcat(inputs[0], inputs[1], node, backend.stringType)); |
| 3343 } | 3332 } |
| 3344 | 3333 |
| 3345 void handleForeignJsCurrentIsolateContext(ast.Send node) { | 3334 void handleForeignJsCurrentIsolateContext(ast.Send node) { |
| 3346 if (!node.arguments.isEmpty) { | 3335 if (!node.arguments.isEmpty) { |
| 3347 compiler.internalError(node, | 3336 compiler.internalError(node, |
| 3348 'Too many arguments to JS_CURRENT_ISOLATE_CONTEXT.'); | 3337 'Too many arguments to JS_CURRENT_ISOLATE_CONTEXT.'); |
| 3349 } | 3338 } |
| 3350 | 3339 |
| 3351 if (!compiler.hasIsolateSupport()) { | 3340 if (!compiler.hasIsolateSupport()) { |
| 3352 // If the isolate library is not used, we just generate code | 3341 // If the isolate library is not used, we just generate code |
| 3353 // to fetch the current isolate. | 3342 // to fetch the current isolate. |
| 3354 String name = backend.namer.currentIsolate; | 3343 String name = backend.namer.currentIsolate; |
| 3355 push(new HForeign(js.js.parseForeignJS(name), | 3344 push(new HForeign(new js.LiteralString(name), |
| 3356 backend.dynamicType, | 3345 backend.dynamicType, |
| 3357 <HInstruction>[])); | 3346 <HInstruction>[])); |
| 3358 } else { | 3347 } else { |
| 3359 // Call a helper method from the isolate library. The isolate | 3348 // Call a helper method from the isolate library. The isolate |
| 3360 // library uses its own isolate structure, that encapsulates | 3349 // library uses its own isolate structure, that encapsulates |
| 3361 // Leg's isolate. | 3350 // Leg's isolate. |
| 3362 Element element = compiler.isolateHelperLibrary.find('_currentIsolate'); | 3351 Element element = compiler.isolateHelperLibrary.find('_currentIsolate'); |
| 3363 if (element == null) { | 3352 if (element == null) { |
| 3364 compiler.internalError(node, | 3353 compiler.internalError(node, |
| 3365 'Isolate library and compiler mismatch.'); | 3354 'Isolate library and compiler mismatch.'); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3500 // and implementation signatures. Currently it is need because the | 3489 // and implementation signatures. Currently it is need because the |
| 3501 // signatures have different elements for parameters. | 3490 // signatures have different elements for parameters. |
| 3502 FunctionElement implementation = function.implementation; | 3491 FunctionElement implementation = function.implementation; |
| 3503 FunctionSignature params = implementation.functionSignature; | 3492 FunctionSignature params = implementation.functionSignature; |
| 3504 if (params.optionalParameterCount != 0) { | 3493 if (params.optionalParameterCount != 0) { |
| 3505 compiler.internalError(closure, | 3494 compiler.internalError(closure, |
| 3506 '"$name" does not handle closure with optional parameters.'); | 3495 '"$name" does not handle closure with optional parameters.'); |
| 3507 } | 3496 } |
| 3508 | 3497 |
| 3509 compiler.enqueuer.codegen.registerStaticUse(element); | 3498 compiler.enqueuer.codegen.registerStaticUse(element); |
| 3510 push(new HForeign(js.js.expressionTemplateYielding( | 3499 push(new HForeign(backend.namer.elementAccess(element), |
| 3511 backend.namer.elementAccess(element)), | |
| 3512 backend.dynamicType, | 3500 backend.dynamicType, |
| 3513 <HInstruction>[])); | 3501 <HInstruction>[])); |
| 3514 return params; | 3502 return params; |
| 3515 } | 3503 } |
| 3516 | 3504 |
| 3517 void handleForeignDartClosureToJs(ast.Send node, String name) { | 3505 void handleForeignDartClosureToJs(ast.Send node, String name) { |
| 3518 // TODO(ahe): This implements DART_CLOSURE_TO_JS and should probably take | 3506 // TODO(ahe): This implements DART_CLOSURE_TO_JS and should probably take |
| 3519 // care to wrap the closure in another closure that saves the current | 3507 // care to wrap the closure in another closure that saves the current |
| 3520 // isolate. | 3508 // isolate. |
| 3521 handleForeignRawFunctionRef(node, name); | 3509 handleForeignRawFunctionRef(node, name); |
| 3522 } | 3510 } |
| 3523 | 3511 |
| 3524 void handleForeignSetCurrentIsolate(ast.Send node) { | 3512 void handleForeignSetCurrentIsolate(ast.Send node) { |
| 3525 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { | 3513 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { |
| 3526 compiler.internalError(node.argumentsNode, | 3514 compiler.internalError(node.argumentsNode, |
| 3527 'Exactly one argument required.'); | 3515 'Exactly one argument required.'); |
| 3528 } | 3516 } |
| 3529 visit(node.arguments.head); | 3517 visit(node.arguments.head); |
| 3530 String isolateName = backend.namer.currentIsolate; | 3518 String isolateName = backend.namer.currentIsolate; |
| 3531 SideEffects sideEffects = new SideEffects.empty(); | 3519 SideEffects sideEffects = new SideEffects.empty(); |
| 3532 sideEffects.setAllSideEffects(); | 3520 sideEffects.setAllSideEffects(); |
| 3533 push(new HForeign(js.js.parseForeignJS("$isolateName = #"), | 3521 push(new HForeign(js.js("$isolateName = #"), |
| 3534 backend.dynamicType, | 3522 backend.dynamicType, |
| 3535 <HInstruction>[pop()], | 3523 <HInstruction>[pop()], |
| 3536 effects: sideEffects)); | 3524 effects: sideEffects)); |
| 3537 } | 3525 } |
| 3538 | 3526 |
| 3539 void handleForeignCreateIsolate(ast.Send node) { | 3527 void handleForeignCreateIsolate(ast.Send node) { |
| 3540 if (!node.arguments.isEmpty) { | 3528 if (!node.arguments.isEmpty) { |
| 3541 compiler.internalError(node.argumentsNode, 'Too many arguments.'); | 3529 compiler.internalError(node.argumentsNode, 'Too many arguments.'); |
| 3542 } | 3530 } |
| 3543 String constructorName = backend.namer.isolateName; | 3531 String constructorName = backend.namer.isolateName; |
| 3544 push(new HForeign(js.js.parseForeignJS("new $constructorName()"), | 3532 push(new HForeign(js.js("new $constructorName()"), |
| 3545 backend.dynamicType, | 3533 backend.dynamicType, |
| 3546 <HInstruction>[])); | 3534 <HInstruction>[])); |
| 3547 } | 3535 } |
| 3548 | 3536 |
| 3549 void handleForeignDartObjectJsConstructorFunction(ast.Send node) { | 3537 void handleForeignDartObjectJsConstructorFunction(ast.Send node) { |
| 3550 if (!node.arguments.isEmpty) { | 3538 if (!node.arguments.isEmpty) { |
| 3551 compiler.internalError(node.argumentsNode, 'Too many arguments.'); | 3539 compiler.internalError(node.argumentsNode, 'Too many arguments.'); |
| 3552 } | 3540 } |
| 3553 push(new HForeign(js.js.expressionTemplateYielding( | 3541 String jsClassReference = backend.namer.isolateAccess(compiler.objectClass); |
| 3554 backend.namer.elementAccess(compiler.objectClass)), | 3542 push(new HForeign(new js.LiteralString(jsClassReference), |
| 3555 backend.dynamicType, | 3543 backend.dynamicType, |
| 3556 <HInstruction>[])); | 3544 <HInstruction>[])); |
| 3557 } | 3545 } |
| 3558 | 3546 |
| 3559 void handleForeignJsCurrentIsolate(ast.Send node) { | 3547 void handleForeignJsCurrentIsolate(ast.Send node) { |
| 3560 if (!node.arguments.isEmpty) { | 3548 if (!node.arguments.isEmpty) { |
| 3561 compiler.internalError(node.argumentsNode, 'Too many arguments.'); | 3549 compiler.internalError(node.argumentsNode, 'Too many arguments.'); |
| 3562 } | 3550 } |
| 3563 push(new HForeign(js.js.parseForeignJS(backend.namer.currentIsolate), | 3551 push(new HForeign(new js.LiteralString(backend.namer.currentIsolate), |
| 3564 backend.dynamicType, | 3552 backend.dynamicType, |
| 3565 <HInstruction>[])); | 3553 <HInstruction>[])); |
| 3566 } | 3554 } |
| 3567 | 3555 |
| 3568 visitForeignSend(ast.Send node) { | 3556 visitForeignSend(ast.Send node) { |
| 3569 Selector selector = elements.getSelector(node); | 3557 Selector selector = elements.getSelector(node); |
| 3570 String name = selector.name; | 3558 String name = selector.name; |
| 3571 if (name == 'JS') { | 3559 if (name == 'JS') { |
| 3572 handleForeignJs(node); | 3560 handleForeignJs(node); |
| 3573 } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') { | 3561 } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') { |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3859 if (argument.kind == TypeKind.TYPE_VARIABLE) { | 3847 if (argument.kind == TypeKind.TYPE_VARIABLE) { |
| 3860 return addTypeVariableReference(argument); | 3848 return addTypeVariableReference(argument); |
| 3861 } | 3849 } |
| 3862 | 3850 |
| 3863 List<HInstruction> inputs = <HInstruction>[]; | 3851 List<HInstruction> inputs = <HInstruction>[]; |
| 3864 | 3852 |
| 3865 String template = rti.getTypeRepresentationWithHashes(argument, (variable) { | 3853 String template = rti.getTypeRepresentationWithHashes(argument, (variable) { |
| 3866 inputs.add(addTypeVariableReference(variable)); | 3854 inputs.add(addTypeVariableReference(variable)); |
| 3867 }); | 3855 }); |
| 3868 | 3856 |
| 3869 js.Template code = js.js.uncachedExpressionTemplate(template); | 3857 js.Expression code = js.js.parseForeignJS(template); |
| 3870 HInstruction result = createForeign(code, backend.stringType, inputs); | 3858 HInstruction result = createForeign(code, backend.stringType, inputs); |
| 3871 add(result); | 3859 add(result); |
| 3872 return result; | 3860 return result; |
| 3873 } | 3861 } |
| 3874 | 3862 |
| 3875 HInstruction handleListConstructor(InterfaceType type, | 3863 HInstruction handleListConstructor(InterfaceType type, |
| 3876 ast.Node currentNode, | 3864 ast.Node currentNode, |
| 3877 HInstruction newObject) { | 3865 HInstruction newObject) { |
| 3878 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { | 3866 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { |
| 3879 return newObject; | 3867 return newObject; |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4011 | 3999 |
| 4012 TypeMask elementType = computeType(constructor); | 4000 TypeMask elementType = computeType(constructor); |
| 4013 if (isFixedListConstructorCall) { | 4001 if (isFixedListConstructorCall) { |
| 4014 if (!inputs[0].isNumber(compiler)) { | 4002 if (!inputs[0].isNumber(compiler)) { |
| 4015 HTypeConversion conversion = new HTypeConversion( | 4003 HTypeConversion conversion = new HTypeConversion( |
| 4016 null, HTypeConversion.ARGUMENT_TYPE_CHECK, backend.numType, | 4004 null, HTypeConversion.ARGUMENT_TYPE_CHECK, backend.numType, |
| 4017 inputs[0], null); | 4005 inputs[0], null); |
| 4018 add(conversion); | 4006 add(conversion); |
| 4019 inputs[0] = conversion; | 4007 inputs[0] = conversion; |
| 4020 } | 4008 } |
| 4021 js.Template code = js.js.parseForeignJS('Array(#)'); | 4009 js.Expression code = js.js.parseForeignJS('Array(#)'); |
| 4022 var behavior = new native.NativeBehavior(); | 4010 var behavior = new native.NativeBehavior(); |
| 4023 behavior.typesReturned.add(expectedType); | 4011 behavior.typesReturned.add(expectedType); |
| 4024 // The allocation can throw only if the given length is a double | 4012 // The allocation can throw only if the given length is a double |
| 4025 // or negative. | 4013 // or negative. |
| 4026 bool canThrow = true; | 4014 bool canThrow = true; |
| 4027 if (inputs[0].isInteger(compiler) && inputs[0] is HConstant) { | 4015 if (inputs[0].isInteger(compiler) && inputs[0] is HConstant) { |
| 4028 var constant = inputs[0]; | 4016 var constant = inputs[0]; |
| 4029 if (constant.constant.value >= 0) canThrow = false; | 4017 if (constant.constant.value >= 0) canThrow = false; |
| 4030 } | 4018 } |
| 4031 HForeign foreign = new HForeign( | 4019 HForeign foreign = new HForeign( |
| 4032 code, elementType, inputs, nativeBehavior: behavior, | 4020 code, elementType, inputs, nativeBehavior: behavior, |
| 4033 canThrow: canThrow); | 4021 canThrow: canThrow); |
| 4034 push(foreign); | 4022 push(foreign); |
| 4035 TypesInferrer inferrer = compiler.typesTask.typesInferrer; | 4023 TypesInferrer inferrer = compiler.typesTask.typesInferrer; |
| 4036 if (inferrer.isFixedArrayCheckedForGrowable(send)) { | 4024 if (inferrer.isFixedArrayCheckedForGrowable(send)) { |
| 4037 js.Template code = js.js.parseForeignJS(r'#.fixed$length = init'); | 4025 js.Expression code = js.js.parseForeignJS(r'#.fixed$length = init'); |
| 4038 // We set the instruction as [canThrow] to avoid it being dead code. | 4026 // We set the instruction as [canThrow] to avoid it being dead code. |
| 4039 // We need a finer grained side effect. | 4027 // We need a finer grained side effect. |
| 4040 add(new HForeign( | 4028 add(new HForeign( |
| 4041 code, backend.nullType, [stack.last], canThrow: true)); | 4029 code, backend.nullType, [stack.last], canThrow: true)); |
| 4042 } | 4030 } |
| 4043 } else if (isGrowableListConstructorCall) { | 4031 } else if (isGrowableListConstructorCall) { |
| 4044 push(buildLiteralList(<HInstruction>[])); | 4032 push(buildLiteralList(<HInstruction>[])); |
| 4045 stack.last.instructionType = elementType; | 4033 stack.last.instructionType = elementType; |
| 4046 } else { | 4034 } else { |
| 4047 ClassElement cls = constructor.getEnclosingClass(); | 4035 ClassElement cls = constructor.getEnclosingClass(); |
| (...skipping 1276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5324 () {}, | 5312 () {}, |
| 5325 buildSwitch); | 5313 buildSwitch); |
| 5326 } | 5314 } |
| 5327 | 5315 |
| 5328 if (hasDefault) { | 5316 if (hasDefault) { |
| 5329 buildLoop(); | 5317 buildLoop(); |
| 5330 } else { | 5318 } else { |
| 5331 // If the switch statement has no default case, surround the loop with | 5319 // If the switch statement has no default case, surround the loop with |
| 5332 // a test of the target. | 5320 // a test of the target. |
| 5333 void buildCondition() { | 5321 void buildCondition() { |
| 5334 js.Template code = js.js.parseForeignJS('#'); | 5322 js.Expression code = js.js.parseForeignJS('#'); |
| 5335 push(createForeign(code, | 5323 push(createForeign(code, |
| 5336 backend.boolType, | 5324 backend.boolType, |
| 5337 [localsHandler.readLocal(switchTarget)])); | 5325 [localsHandler.readLocal(switchTarget)])); |
| 5338 } | 5326 } |
| 5339 handleIf(node, buildCondition, buildLoop, () => {}); | 5327 handleIf(node, buildCondition, buildLoop, () => {}); |
| 5340 } | 5328 } |
| 5341 } | 5329 } |
| 5342 | 5330 |
| 5343 /** | 5331 /** |
| 5344 * Creates a switch statement. | 5332 * Creates a switch statement. |
| (...skipping 925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6270 DartType unaliased = type.unalias(builder.compiler); | 6258 DartType unaliased = type.unalias(builder.compiler); |
| 6271 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 6259 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
| 6272 unaliased.accept(this, builder); | 6260 unaliased.accept(this, builder); |
| 6273 } | 6261 } |
| 6274 | 6262 |
| 6275 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 6263 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
| 6276 ClassElement cls = builder.compiler.findHelper('DynamicRuntimeType'); | 6264 ClassElement cls = builder.compiler.findHelper('DynamicRuntimeType'); |
| 6277 builder.push(new HDynamicType(type, new TypeMask.exact(cls))); | 6265 builder.push(new HDynamicType(type, new TypeMask.exact(cls))); |
| 6278 } | 6266 } |
| 6279 } | 6267 } |
| OLD | NEW |