Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 237583014: JS templates (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: cleanup Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698