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