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

Side by Side Diff: pkg/compiler/lib/src/ssa/builder.dart

Issue 1074043003: Compute default throws behavior from JavaScript. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 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
« no previous file with comments | « pkg/compiler/lib/src/native/js.dart ('k') | pkg/compiler/lib/src/ssa/nodes.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 class SsaFunctionCompiler implements FunctionCompiler { 7 class SsaFunctionCompiler implements FunctionCompiler {
8 SsaCodeGeneratorTask generator; 8 SsaCodeGeneratorTask generator;
9 SsaBuilderTask builder; 9 SsaBuilderTask builder;
10 SsaOptimizerTask optimizer; 10 SsaOptimizerTask optimizer;
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 void redirectElement(Local from, CapturedVariable to) { 235 void redirectElement(Local from, CapturedVariable to) {
236 assert(redirectionMapping[from] == null); 236 assert(redirectionMapping[from] == null);
237 redirectionMapping[from] = to; 237 redirectionMapping[from] = to;
238 assert(isStoredInClosureField(from) || isBoxed(from)); 238 assert(isStoredInClosureField(from) || isBoxed(from));
239 } 239 }
240 240
241 HInstruction createBox() { 241 HInstruction createBox() {
242 // TODO(floitsch): Clean up this hack. Should we create a box-object by 242 // TODO(floitsch): Clean up this hack. Should we create a box-object by
243 // just creating an empty object literal? 243 // just creating an empty object literal?
244 JavaScriptBackend backend = builder.backend; 244 JavaScriptBackend backend = builder.backend;
245 HInstruction box = new HForeignCode(js.js.parseForeignJS('{}'), 245 HInstruction box = new HForeignCode(
246 backend.nonNullType, 246 js.js.parseForeignJS('{}'),
247 <HInstruction>[]); 247 backend.nonNullType,
248 <HInstruction>[],
249 nativeBehavior: native.NativeBehavior.PURE_ALLOCATION);
248 builder.add(box); 250 builder.add(box);
249 return box; 251 return box;
250 } 252 }
251 253
252 /** 254 /**
253 * If the scope (function or loop) [node] has captured variables then this 255 * If the scope (function or loop) [node] has captured variables then this
254 * method creates a box and sets up the redirections. 256 * method creates a box and sets up the redirections.
255 */ 257 */
256 void enterScope(ast.Node node, Element element) { 258 void enterScope(ast.Node node, Element element) {
257 // See if any variable in the top-scope of the function is captured. If yes 259 // See if any variable in the top-scope of the function is captured. If yes
(...skipping 3141 matching lines...) Expand 10 before | Expand all | Expand 10 after
3399 localsHandler.updateLocal(local, checkedOrTrusted); 3401 localsHandler.updateLocal(local, checkedOrTrusted);
3400 } 3402 }
3401 } 3403 }
3402 3404
3403 HInstruction invokeInterceptor(HInstruction receiver) { 3405 HInstruction invokeInterceptor(HInstruction receiver) {
3404 HInterceptor interceptor = new HInterceptor(receiver, backend.nonNullType); 3406 HInterceptor interceptor = new HInterceptor(receiver, backend.nonNullType);
3405 add(interceptor); 3407 add(interceptor);
3406 return interceptor; 3408 return interceptor;
3407 } 3409 }
3408 3410
3409 HForeignCode createForeign(js.Template code,
3410 TypeMask type,
3411 List<HInstruction> inputs) {
3412 return new HForeignCode(code, type, inputs);
3413 }
3414
3415 HLiteralList buildLiteralList(List<HInstruction> inputs) { 3411 HLiteralList buildLiteralList(List<HInstruction> inputs) {
3416 return new HLiteralList(inputs, backend.extendableArrayType); 3412 return new HLiteralList(inputs, backend.extendableArrayType);
3417 } 3413 }
3418 3414
3419 // TODO(karlklose): change construction of the representations to be GVN'able 3415 // TODO(karlklose): change construction of the representations to be GVN'able
3420 // (dartbug.com/7182). 3416 // (dartbug.com/7182).
3421 HInstruction buildTypeArgumentRepresentations(DartType type) { 3417 HInstruction buildTypeArgumentRepresentations(DartType type) {
3422 // Compute the representation of the type arguments, including access 3418 // Compute the representation of the type arguments, including access
3423 // to the runtime type information for type variables as instructions. 3419 // to the runtime type information for type variables as instructions.
3424 if (type.isTypeVariable) { 3420 if (type.isTypeVariable) {
3425 return buildLiteralList(<HInstruction>[addTypeVariableReference(type)]); 3421 return buildLiteralList(<HInstruction>[addTypeVariableReference(type)]);
3426 } else { 3422 } else {
3427 assert(type.element.isClass); 3423 assert(type.element.isClass);
3428 InterfaceType interface = type; 3424 InterfaceType interface = type;
3429 List<HInstruction> inputs = <HInstruction>[]; 3425 List<HInstruction> inputs = <HInstruction>[];
3430 bool first = true; 3426 bool first = true;
3431 List<String> templates = <String>[]; 3427 List<String> templates = <String>[];
3432 for (DartType argument in interface.typeArguments) { 3428 for (DartType argument in interface.typeArguments) {
3433 templates.add(rti.getTypeRepresentationWithHashes(argument, (variable) { 3429 templates.add(rti.getTypeRepresentationWithHashes(argument, (variable) {
3434 HInstruction runtimeType = addTypeVariableReference(variable); 3430 HInstruction runtimeType = addTypeVariableReference(variable);
3435 inputs.add(runtimeType); 3431 inputs.add(runtimeType);
3436 })); 3432 }));
3437 } 3433 }
3438 String template = '[${templates.join(', ')}]'; 3434 String template = '[${templates.join(', ')}]';
3439 // TODO(sra): This is a fresh template each time. We can't let the 3435 // TODO(sra): This is a fresh template each time. We can't let the
3440 // template manager build them. 3436 // template manager build them.
3441 js.Template code = js.js.uncachedExpressionTemplate(template); 3437 js.Template code = js.js.uncachedExpressionTemplate(template);
3442 HInstruction representation = 3438 HInstruction representation =
3443 createForeign(code, backend.readableArrayType, inputs); 3439 new HForeignCode(code, backend.readableArrayType, inputs,
3440 nativeBehavior: native.NativeBehavior.PURE_ALLOCATION);
3444 return representation; 3441 return representation;
3445 } 3442 }
3446 } 3443 }
3447 3444
3448 visitOperatorSend(ast.Send node) { 3445 visitOperatorSend(ast.Send node) {
3449 ast.Operator op = node.selector; 3446 ast.Operator op = node.selector;
3450 if ("[]" == op.source) { 3447 if ("[]" == op.source) {
3451 visitDynamicSend(node); 3448 visitDynamicSend(node);
3452 } else if ("&&" == op.source || 3449 } else if ("&&" == op.source ||
3453 "||" == op.source) { 3450 "||" == op.source) {
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
3647 inputs.add(closureTarget); 3644 inputs.add(closureTarget);
3648 addDynamicSendArgumentsToList(node, inputs); 3645 addDynamicSendArgumentsToList(node, inputs);
3649 Selector closureSelector = new Selector.callClosureFrom(selector); 3646 Selector closureSelector = new Selector.callClosureFrom(selector);
3650 pushWithPosition( 3647 pushWithPosition(
3651 new HInvokeClosure(closureSelector, inputs, backend.dynamicType), 3648 new HInvokeClosure(closureSelector, inputs, backend.dynamicType),
3652 node); 3649 node);
3653 } 3650 }
3654 3651
3655 void handleForeignJs(ast.Send node) { 3652 void handleForeignJs(ast.Send node) {
3656 Link<ast.Node> link = node.arguments; 3653 Link<ast.Node> link = node.arguments;
3657 // If the invoke is on foreign code, don't visit the first 3654 // Don't visit the first argument, which is the type, and the second
3658 // argument, which is the type, and the second argument, 3655 // argument, which is the foreign code.
3659 // which is the foreign code.
3660 if (link.isEmpty || link.tail.isEmpty) { 3656 if (link.isEmpty || link.tail.isEmpty) {
3661 compiler.internalError(node.argumentsNode, 3657 compiler.internalError(node.argumentsNode,
3662 'At least two arguments expected.'); 3658 'At least two arguments expected.');
3663 } 3659 }
3664 native.NativeBehavior nativeBehavior = 3660 native.NativeBehavior nativeBehavior =
3665 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node); 3661 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
3666 3662
3667 List<HInstruction> inputs = <HInstruction>[]; 3663 List<HInstruction> inputs = <HInstruction>[];
3668 addGenericSendArgumentsToList(link.tail.tail, inputs); 3664 addGenericSendArgumentsToList(link.tail.tail, inputs);
3669 3665
3670 TypeMask ssaType = 3666 TypeMask ssaType =
3671 TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler); 3667 TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler);
3672 3668
3673 if (nativeBehavior.codeTemplate.isExpression) { 3669 if (nativeBehavior.codeTemplate.isExpression) {
3674 push(new HForeignCode(nativeBehavior.codeTemplate, ssaType, inputs, 3670 push(new HForeignCode(
3675 effects: nativeBehavior.sideEffects, 3671 nativeBehavior.codeTemplate, ssaType, inputs,
3676 nativeBehavior: nativeBehavior)); 3672 effects: nativeBehavior.sideEffects,
3673 nativeBehavior: nativeBehavior));
3677 } else { 3674 } else {
3678 push(new HForeignCode(nativeBehavior.codeTemplate, ssaType, inputs, 3675 push(new HForeignCode(
3679 isStatement: true, 3676 nativeBehavior.codeTemplate, ssaType, inputs,
3680 effects: nativeBehavior.sideEffects, 3677 isStatement: true,
3681 nativeBehavior: nativeBehavior, 3678 effects: nativeBehavior.sideEffects,
3682 canThrow: true)); 3679 nativeBehavior: nativeBehavior));
3683 } 3680 }
3684 } 3681 }
3685 3682
3686 void handleJsStringConcat(ast.Send node) { 3683 void handleJsStringConcat(ast.Send node) {
3687 List<HInstruction> inputs = <HInstruction>[]; 3684 List<HInstruction> inputs = <HInstruction>[];
3688 addGenericSendArgumentsToList(node.arguments, inputs); 3685 addGenericSendArgumentsToList(node.arguments, inputs);
3689 if (inputs.length != 2) { 3686 if (inputs.length != 2) {
3690 compiler.internalError(node.argumentsNode, 'Two arguments expected.'); 3687 compiler.internalError(node.argumentsNode, 'Two arguments expected.');
3691 } 3688 }
3692 push(new HStringConcat(inputs[0], inputs[1], node, backend.stringType)); 3689 push(new HStringConcat(inputs[0], inputs[1], node, backend.stringType));
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
3831 } 3828 }
3832 HConstant hConstant = globalNameHNode; 3829 HConstant hConstant = globalNameHNode;
3833 StringConstantValue constant = hConstant.constant; 3830 StringConstantValue constant = hConstant.constant;
3834 String globalName = constant.primitiveValue.slowToString(); 3831 String globalName = constant.primitiveValue.slowToString();
3835 js.Template expr = js.js.expressionTemplateYielding( 3832 js.Template expr = js.js.expressionTemplateYielding(
3836 backend.emitter.generateEmbeddedGlobalAccess(globalName)); 3833 backend.emitter.generateEmbeddedGlobalAccess(globalName));
3837 native.NativeBehavior nativeBehavior = 3834 native.NativeBehavior nativeBehavior =
3838 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node); 3835 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
3839 TypeMask ssaType = 3836 TypeMask ssaType =
3840 TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler); 3837 TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler);
3841 push(new HForeignCode(expr, ssaType, const [])); 3838 push(new HForeignCode(expr, ssaType, const [],
3839 nativeBehavior: nativeBehavior));
3842 } 3840 }
3843 3841
3844 void handleJsInterceptorConstant(ast.Send node) { 3842 void handleJsInterceptorConstant(ast.Send node) {
3845 // Single argument must be a TypeConstant which is converted into a 3843 // Single argument must be a TypeConstant which is converted into a
3846 // InterceptorConstant. 3844 // InterceptorConstant.
3847 if (!node.arguments.isEmpty && node.arguments.tail.isEmpty) { 3845 if (!node.arguments.isEmpty && node.arguments.tail.isEmpty) {
3848 ast.Node argument = node.arguments.head; 3846 ast.Node argument = node.arguments.head;
3849 visit(argument); 3847 visit(argument);
3850 HInstruction argumentInstruction = pop(); 3848 HInstruction argumentInstruction = pop();
3851 if (argumentInstruction is HConstant) { 3849 if (argumentInstruction is HConstant) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
3903 // and implementation signatures. Currently it is need because the 3901 // and implementation signatures. Currently it is need because the
3904 // signatures have different elements for parameters. 3902 // signatures have different elements for parameters.
3905 FunctionElement implementation = function.implementation; 3903 FunctionElement implementation = function.implementation;
3906 FunctionSignature params = implementation.functionSignature; 3904 FunctionSignature params = implementation.functionSignature;
3907 if (params.optionalParameterCount != 0) { 3905 if (params.optionalParameterCount != 0) {
3908 compiler.internalError(closure, 3906 compiler.internalError(closure,
3909 '"$name" does not handle closure with optional parameters.'); 3907 '"$name" does not handle closure with optional parameters.');
3910 } 3908 }
3911 3909
3912 registry.registerStaticUse(element); 3910 registry.registerStaticUse(element);
3913 push(new HForeignCode(js.js.expressionTemplateYielding( 3911 push(new HForeignCode(
3914 backend.emitter.staticFunctionAccess(element)), 3912 js.js.expressionTemplateYielding(
3915 backend.dynamicType, 3913 backend.emitter.staticFunctionAccess(element)),
3916 <HInstruction>[])); 3914 backend.dynamicType,
3915 <HInstruction>[],
3916 nativeBehavior: native.NativeBehavior.PURE));
3917 return params; 3917 return params;
3918 } 3918 }
3919 3919
3920 void handleForeignDartClosureToJs(ast.Send node, String name) { 3920 void handleForeignDartClosureToJs(ast.Send node, String name) {
3921 // TODO(ahe): This implements DART_CLOSURE_TO_JS and should probably take 3921 // TODO(ahe): This implements DART_CLOSURE_TO_JS and should probably take
3922 // care to wrap the closure in another closure that saves the current 3922 // care to wrap the closure in another closure that saves the current
3923 // isolate. 3923 // isolate.
3924 handleForeignRawFunctionRef(node, name); 3924 handleForeignRawFunctionRef(node, name);
3925 } 3925 }
3926 3926
3927 void handleForeignSetCurrentIsolate(ast.Send node) { 3927 void handleForeignSetCurrentIsolate(ast.Send node) {
3928 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { 3928 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) {
3929 compiler.internalError(node.argumentsNode, 3929 compiler.internalError(node.argumentsNode,
3930 'Exactly one argument required.'); 3930 'Exactly one argument required.');
3931 } 3931 }
3932 visit(node.arguments.head); 3932 visit(node.arguments.head);
3933 String isolateName = backend.namer.currentIsolate; 3933 String isolateName = backend.namer.currentIsolate;
3934 SideEffects sideEffects = new SideEffects.empty(); 3934 SideEffects sideEffects = new SideEffects.empty();
3935 sideEffects.setAllSideEffects(); 3935 sideEffects.setAllSideEffects();
3936 push(new HForeignCode(js.js.parseForeignJS("$isolateName = #"), 3936 push(new HForeignCode(
3937 backend.dynamicType, 3937 js.js.parseForeignJS("$isolateName = #"),
3938 <HInstruction>[pop()], 3938 backend.dynamicType,
3939 effects: sideEffects)); 3939 <HInstruction>[pop()],
3940 nativeBehavior: native.NativeBehavior.PURE,
3941 effects: sideEffects));
3940 } 3942 }
3941 3943
3942 void handleForeignDartObjectJsConstructorFunction(ast.Send node) { 3944 void handleForeignDartObjectJsConstructorFunction(ast.Send node) {
3943 if (!node.arguments.isEmpty) { 3945 if (!node.arguments.isEmpty) {
3944 compiler.internalError(node.argumentsNode, 'Too many arguments.'); 3946 compiler.internalError(node.argumentsNode, 'Too many arguments.');
3945 } 3947 }
3946 push(new HForeignCode(js.js.expressionTemplateYielding( 3948 push(new HForeignCode(
3947 backend.emitter.typeAccess(compiler.objectClass)), 3949 js.js.expressionTemplateYielding(
3948 backend.dynamicType, 3950 backend.emitter.typeAccess(compiler.objectClass)),
3949 <HInstruction>[])); 3951 backend.dynamicType,
3952 <HInstruction>[]));
3950 } 3953 }
3951 3954
3952 void handleForeignJsCurrentIsolate(ast.Send node) { 3955 void handleForeignJsCurrentIsolate(ast.Send node) {
3953 if (!node.arguments.isEmpty) { 3956 if (!node.arguments.isEmpty) {
3954 compiler.internalError(node.argumentsNode, 'Too many arguments.'); 3957 compiler.internalError(node.argumentsNode, 'Too many arguments.');
3955 } 3958 }
3956 push(new HForeignCode(js.js.parseForeignJS(backend.namer.currentIsolate), 3959 push(new HForeignCode(js.js.parseForeignJS(backend.namer.currentIsolate),
3957 backend.dynamicType, 3960 backend.dynamicType,
3958 <HInstruction>[])); 3961 <HInstruction>[]));
3959 } 3962 }
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
4271 return addTypeVariableReference(argument); 4274 return addTypeVariableReference(argument);
4272 } 4275 }
4273 4276
4274 List<HInstruction> inputs = <HInstruction>[]; 4277 List<HInstruction> inputs = <HInstruction>[];
4275 4278
4276 String template = rti.getTypeRepresentationWithHashes(argument, (variable) { 4279 String template = rti.getTypeRepresentationWithHashes(argument, (variable) {
4277 inputs.add(addTypeVariableReference(variable)); 4280 inputs.add(addTypeVariableReference(variable));
4278 }); 4281 });
4279 4282
4280 js.Template code = js.js.uncachedExpressionTemplate(template); 4283 js.Template code = js.js.uncachedExpressionTemplate(template);
4281 HInstruction result = createForeign(code, backend.stringType, inputs); 4284 HInstruction result = new HForeignCode(code, backend.stringType, inputs,
4285 nativeBehavior: native.NativeBehavior.PURE);
4282 add(result); 4286 add(result);
4283 return result; 4287 return result;
4284 } 4288 }
4285 4289
4286 HInstruction handleListConstructor(InterfaceType type, 4290 HInstruction handleListConstructor(InterfaceType type,
4287 ast.Node currentNode, 4291 ast.Node currentNode,
4288 HInstruction newObject) { 4292 HInstruction newObject) {
4289 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { 4293 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) {
4290 return newObject; 4294 return newObject;
4291 } 4295 }
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
4438 js.Template code = js.js.parseForeignJS('Array(#)'); 4442 js.Template code = js.js.parseForeignJS('Array(#)');
4439 var behavior = new native.NativeBehavior(); 4443 var behavior = new native.NativeBehavior();
4440 behavior.typesReturned.add(expectedType); 4444 behavior.typesReturned.add(expectedType);
4441 // The allocation can throw only if the given length is a double 4445 // The allocation can throw only if the given length is a double
4442 // or negative. 4446 // or negative.
4443 bool canThrow = true; 4447 bool canThrow = true;
4444 if (inputs[0].isInteger(compiler) && inputs[0] is HConstant) { 4448 if (inputs[0].isInteger(compiler) && inputs[0] is HConstant) {
4445 var constant = inputs[0]; 4449 var constant = inputs[0];
4446 if (constant.constant.primitiveValue >= 0) canThrow = false; 4450 if (constant.constant.primitiveValue >= 0) canThrow = false;
4447 } 4451 }
4448 HForeignCode foreign = new HForeignCode( 4452 HForeignCode foreign = new HForeignCode(code, elementType, inputs,
4449 code, elementType, inputs, nativeBehavior: behavior, 4453 nativeBehavior: behavior,
4450 canThrow: canThrow); 4454 throwBehavior: canThrow
4455 ? native.NativeThrowBehavior.MAY
4456 : native.NativeThrowBehavior.NEVER);
4451 push(foreign); 4457 push(foreign);
4452 TypesInferrer inferrer = compiler.typesTask.typesInferrer; 4458 TypesInferrer inferrer = compiler.typesTask.typesInferrer;
4453 if (inferrer.isFixedArrayCheckedForGrowable(send)) { 4459 if (inferrer.isFixedArrayCheckedForGrowable(send)) {
4454 js.Template code = js.js.parseForeignJS(r'#.fixed$length = Array'); 4460 js.Template code = js.js.parseForeignJS(r'#.fixed$length = Array');
4455 // We set the instruction as [canThrow] to avoid it being dead code. 4461 // We set the instruction as [canThrow] to avoid it being dead code.
4456 // We need a finer grained side effect. 4462 // We need a finer grained side effect.
4457 add(new HForeignCode( 4463 add(new HForeignCode(code, backend.nullType, [stack.last],
4458 code, backend.nullType, [stack.last], canThrow: true)); 4464 throwBehavior: native.NativeThrowBehavior.MAY));
4459 } 4465 }
4460 } else if (isGrowableListConstructorCall) { 4466 } else if (isGrowableListConstructorCall) {
4461 push(buildLiteralList(<HInstruction>[])); 4467 push(buildLiteralList(<HInstruction>[]));
4462 stack.last.instructionType = elementType; 4468 stack.last.instructionType = elementType;
4463 } else { 4469 } else {
4464 ClassElement cls = constructor.enclosingClass; 4470 ClassElement cls = constructor.enclosingClass;
4465 if (cls.isAbstract && constructor.isGenerativeConstructor) { 4471 if (cls.isAbstract && constructor.isGenerativeConstructor) {
4466 generateAbstractClassInstantiationError(send, cls.name); 4472 generateAbstractClassInstantiationError(send, cls.name);
4467 return; 4473 return;
4468 } 4474 }
(...skipping 1423 matching lines...) Expand 10 before | Expand all | Expand 10 after
5892 buildSwitch); 5898 buildSwitch);
5893 } 5899 }
5894 5900
5895 if (hasDefault) { 5901 if (hasDefault) {
5896 buildLoop(); 5902 buildLoop();
5897 } else { 5903 } else {
5898 // If the switch statement has no default case, surround the loop with 5904 // If the switch statement has no default case, surround the loop with
5899 // a test of the target. 5905 // a test of the target.
5900 void buildCondition() { 5906 void buildCondition() {
5901 js.Template code = js.js.parseForeignJS('#'); 5907 js.Template code = js.js.parseForeignJS('#');
5902 push(createForeign(code, 5908 push(new HForeignCode(
5903 backend.boolType, 5909 code,
5904 [localsHandler.readLocal(switchTarget)])); 5910 backend.boolType,
5911 [localsHandler.readLocal(switchTarget)],
5912 nativeBehavior: native.NativeBehavior.PURE));
5905 } 5913 }
5906 handleIf(node, buildCondition, buildLoop, () => {}); 5914 handleIf(node, buildCondition, buildLoop, () => {});
5907 } 5915 }
5908 } 5916 }
5909 5917
5910 /** 5918 /**
5911 * Creates a switch statement. 5919 * Creates a switch statement.
5912 * 5920 *
5913 * [jumpHandler] is the [JumpHandler] for the created switch statement. 5921 * [jumpHandler] is the [JumpHandler] for the created switch statement.
5914 * [buildExpression] creates the switch expression. 5922 * [buildExpression] creates the switch expression.
(...skipping 1058 matching lines...) Expand 10 before | Expand all | Expand 10 after
6973 if (unaliased is TypedefType) throw 'unable to unalias $type'; 6981 if (unaliased is TypedefType) throw 'unable to unalias $type';
6974 unaliased.accept(this, builder); 6982 unaliased.accept(this, builder);
6975 } 6983 }
6976 6984
6977 void visitDynamicType(DynamicType type, SsaBuilder builder) { 6985 void visitDynamicType(DynamicType type, SsaBuilder builder) {
6978 JavaScriptBackend backend = builder.compiler.backend; 6986 JavaScriptBackend backend = builder.compiler.backend;
6979 ClassElement cls = backend.findHelper('DynamicRuntimeType'); 6987 ClassElement cls = backend.findHelper('DynamicRuntimeType');
6980 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); 6988 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld)));
6981 } 6989 }
6982 } 6990 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/native/js.dart ('k') | pkg/compiler/lib/src/ssa/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698