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

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

Issue 763883004: Fix for issue 21579 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: remove dead method Created 6 years 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 | « no previous file | tests/compiler/dart2js_extra/21579_test.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 SsaCodeGeneratorTask extends CompilerTask { 7 class SsaCodeGeneratorTask extends CompilerTask {
8 8
9 final JavaScriptBackend backend; 9 final JavaScriptBackend backend;
10 10
(...skipping 2234 matching lines...) Expand 10 before | Expand all | Expand 10 after
2245 void checkNull(HInstruction input) { 2245 void checkNull(HInstruction input) {
2246 use(input); 2246 use(input);
2247 push(new js.Binary('==', pop(), new js.LiteralNull())); 2247 push(new js.Binary('==', pop(), new js.LiteralNull()));
2248 } 2248 }
2249 2249
2250 void checkNonNull(HInstruction input) { 2250 void checkNonNull(HInstruction input) {
2251 use(input); 2251 use(input);
2252 push(new js.Binary('!=', pop(), new js.LiteralNull())); 2252 push(new js.Binary('!=', pop(), new js.LiteralNull()));
2253 } 2253 }
2254 2254
2255 bool checkIndexingBehavior(HInstruction input, {bool negative: false}) {
2256 if (!compiler.resolverWorld.isInstantiated(
2257 backend.jsIndexingBehaviorInterface)) {
2258 return false;
2259 }
2260
2261 use(input);
2262 js.Expression object1 = pop();
2263 use(input);
2264 js.Expression object2 = pop();
2265 push(backend.generateIsJsIndexableCall(object1, object2));
2266 if (negative) push(new js.Prefix('!', pop()));
2267 return true;
2268 }
2269
2270 void checkType(HInstruction input, HInstruction interceptor, 2255 void checkType(HInstruction input, HInstruction interceptor,
2271 DartType type, {bool negative: false}) { 2256 DartType type, {bool negative: false}) {
2272 Element element = type.element; 2257 Element element = type.element;
2273 if (element == backend.jsArrayClass) { 2258 if (element == backend.jsArrayClass) {
2274 checkArray(input, negative ? '!==': '==='); 2259 checkArray(input, negative ? '!==': '===');
2275 return; 2260 return;
2276 } else if (element == backend.jsMutableArrayClass) { 2261 } else if (element == backend.jsMutableArrayClass) {
2277 if (negative) { 2262 if (negative) {
2278 checkImmutableArray(input); 2263 checkImmutableArray(input);
2279 } else { 2264 } else {
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
2460 attachLocationToLast(node); 2445 attachLocationToLast(node);
2461 } 2446 }
2462 } 2447 }
2463 } 2448 }
2464 2449
2465 void emitIsViaInterceptor(HIsViaInterceptor node, bool negative) { 2450 void emitIsViaInterceptor(HIsViaInterceptor node, bool negative) {
2466 checkTypeViaProperty(node.interceptor, node.typeExpression, negative); 2451 checkTypeViaProperty(node.interceptor, node.typeExpression, negative);
2467 attachLocationToLast(node); 2452 attachLocationToLast(node);
2468 } 2453 }
2469 2454
2470 js.Expression generateTest(HInstruction input, TypeMask checkedType) { 2455 js.Expression generateReceiverOrArgumentTypeTest(
2456 HInstruction input, TypeMask checkedType) {
2471 ClassWorld classWorld = compiler.world; 2457 ClassWorld classWorld = compiler.world;
2472 TypeMask receiver = input.instructionType; 2458 TypeMask inputType = input.instructionType;
2473 // Figure out if it is beneficial to turn this into a null check. 2459 // Figure out if it is beneficial to turn this into a null check.
2474 // V8 generally prefers 'typeof' checks, but for integers and 2460 // V8 generally prefers 'typeof' checks, but for integers and
2475 // indexable primitives we cannot compile this test into a single 2461 // indexable primitives we cannot compile this test into a single
2476 // typeof check so the null check is cheaper. 2462 // typeof check so the null check is cheaper.
2477 bool turnIntoNumCheck = input.isIntegerOrNull(compiler) 2463 bool isIntCheck = checkedType.containsOnlyInt(classWorld);
2478 && checkedType.containsOnlyInt(classWorld); 2464 bool turnIntoNumCheck = isIntCheck && input.isIntegerOrNull(compiler);
2479 bool turnIntoNullCheck = !turnIntoNumCheck 2465 bool turnIntoNullCheck = !turnIntoNumCheck
2480 && (checkedType.nullable() == receiver) 2466 && (checkedType.nullable() == inputType)
2481 && (checkedType.containsOnlyInt(classWorld) 2467 && (isIntCheck
2482 || checkedType.satisfies(backend.jsIndexableClass, classWorld)); 2468 || checkedType.satisfies(backend.jsIndexableClass, classWorld));
2483 js.Expression test; 2469
2484 if (turnIntoNullCheck) { 2470 if (turnIntoNullCheck) {
2485 use(input); 2471 use(input);
2486 test = new js.Binary("==", pop(), new js.LiteralNull()); 2472 return new js.Binary("==", pop(), new js.LiteralNull());
2487 } else if (checkedType.containsOnlyInt(classWorld) && !turnIntoNumCheck) { 2473 } else if (isIntCheck && !turnIntoNumCheck) {
2488 // input is !int 2474 // input is !int
2489 checkInt(input, '!=='); 2475 checkBigInt(input, '!==');
2490 test = pop(); 2476 return pop();
2491 } else if (checkedType.containsOnlyNum(classWorld) || turnIntoNumCheck) { 2477 } else if (turnIntoNumCheck || checkedType.containsOnlyNum(classWorld)) {
2492 // input is !num 2478 // input is !num
2493 checkNum(input, '!=='); 2479 checkNum(input, '!==');
2494 test = pop(); 2480 return pop();
2495 } else if (checkedType.containsOnlyBool(classWorld)) { 2481 } else if (checkedType.containsOnlyBool(classWorld)) {
2496 // input is !bool 2482 // input is !bool
2497 checkBool(input, '!=='); 2483 checkBool(input, '!==');
2498 test = pop(); 2484 return pop();
2499 } else if (checkedType.containsOnlyString(classWorld)) { 2485 } else if (checkedType.containsOnlyString(classWorld)) {
2500 // input is !string 2486 // input is !string
2501 checkString(input, '!=='); 2487 checkString(input, '!==');
2502 test = pop(); 2488 return pop();
2503 } else if (checkedType.satisfies(backend.jsExtendableArrayClass,
2504 classWorld)) {
2505 // input is !Object || input is !Array || input.isFixed
2506 checkObject(input, '!==');
2507 js.Expression objectTest = pop();
2508 checkArray(input, '!==');
2509 js.Expression arrayTest = pop();
2510 checkFixedArray(input);
2511 test = new js.Binary('||', objectTest, arrayTest);
2512 test = new js.Binary('||', test, pop());
2513 } else if (checkedType.satisfies(backend.jsMutableArrayClass, classWorld)) {
2514 // input is !Object
2515 // || ((input is !Array || input.isImmutable)
2516 // && input is !JsIndexingBehavior)
2517 checkObject(input, '!==');
2518 js.Expression objectTest = pop();
2519 checkArray(input, '!==');
2520 js.Expression arrayTest = pop();
2521 checkImmutableArray(input);
2522 js.Binary notArrayOrImmutable = new js.Binary('||', arrayTest, pop());
2523
2524 js.Binary notIndexing = checkIndexingBehavior(input, negative: true)
2525 ? new js.Binary('&&', notArrayOrImmutable, pop())
2526 : notArrayOrImmutable;
2527 test = new js.Binary('||', objectTest, notIndexing);
2528 } else if (checkedType.satisfies(backend.jsArrayClass, classWorld)) {
2529 // input is !Object
2530 // || (input is !Array && input is !JsIndexingBehavior)
2531 checkObject(input, '!==');
2532 js.Expression objectTest = pop();
2533 checkArray(input, '!==');
2534 js.Expression arrayTest = pop();
2535
2536 js.Expression notIndexing = checkIndexingBehavior(input, negative: true)
2537 ? new js.Binary('&&', arrayTest, pop())
2538 : arrayTest;
2539 test = new js.Binary('||', objectTest, notIndexing);
2540 } else if (checkedType.satisfies(backend.jsIndexableClass, classWorld)) {
2541 // input is !String
2542 // && (input is !Object
2543 // || (input is !Array && input is !JsIndexingBehavior))
2544 checkString(input, '!==');
2545 js.Expression stringTest = pop();
2546 checkObject(input, '!==');
2547 js.Expression objectTest = pop();
2548 checkArray(input, '!==');
2549 js.Expression arrayTest = pop();
2550
2551 js.Binary notIndexingTest = checkIndexingBehavior(input, negative: true)
2552 ? new js.Binary('&&', arrayTest, pop())
2553 : arrayTest;
2554 js.Binary notObjectOrIndexingTest =
2555 new js.Binary('||', objectTest, notIndexingTest);
2556 test = new js.Binary('&&', stringTest, notObjectOrIndexingTest);
2557 } else {
2558 compiler.internalError(input, 'Unexpected check.');
2559 } 2489 }
2560 return test; 2490 compiler.internalError(input, 'Unexpected check.');
2491 return null;
2561 } 2492 }
2562 2493
2563 void visitTypeConversion(HTypeConversion node) { 2494 void visitTypeConversion(HTypeConversion node) {
2564 if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) { 2495 if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) {
2565 ClassWorld classWorld = compiler.world; 2496 ClassWorld classWorld = compiler.world;
2566 // An int check if the input is not int or null, is not 2497 // An int check if the input is not int or null, is not
2567 // sufficient for doing an argument or receiver check. 2498 // sufficient for doing an argument or receiver check.
2568 assert(compiler.trustTypeAnnotations || 2499 assert(compiler.trustTypeAnnotations ||
2569 !node.checkedType.containsOnlyInt(classWorld) || 2500 !node.checkedType.containsOnlyInt(classWorld) ||
2570 node.checkedInput.isIntegerOrNull(compiler)); 2501 node.checkedInput.isIntegerOrNull(compiler));
2571 js.Expression test = generateTest(node.checkedInput, node.checkedType); 2502 js.Expression test = generateReceiverOrArgumentTypeTest(
2503 node.checkedInput, node.checkedType);
2572 js.Block oldContainer = currentContainer; 2504 js.Block oldContainer = currentContainer;
2573 js.Statement body = new js.Block.empty(); 2505 js.Statement body = new js.Block.empty();
2574 currentContainer = body; 2506 currentContainer = body;
2575 if (node.isArgumentTypeCheck) { 2507 if (node.isArgumentTypeCheck) {
2576 generateThrowWithHelper('iae', node.checkedInput); 2508 generateThrowWithHelper('iae', node.checkedInput);
2577 } else if (node.isReceiverTypeCheck) { 2509 } else if (node.isReceiverTypeCheck) {
2578 use(node.checkedInput); 2510 use(node.checkedInput);
2579 String methodName = 2511 String methodName =
2580 backend.namer.invocationName(node.receiverTypeCheckSelector); 2512 backend.namer.invocationName(node.receiverTypeCheckSelector);
2581 js.Expression call = js.propertyCall(pop(), methodName, []); 2513 js.Expression call = js.propertyCall(pop(), methodName, []);
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
2715 js.PropertyAccess accessHelper(String name) { 2647 js.PropertyAccess accessHelper(String name) {
2716 Element helper = backend.findHelper(name); 2648 Element helper = backend.findHelper(name);
2717 if (helper == null) { 2649 if (helper == null) {
2718 // For mocked-up tests. 2650 // For mocked-up tests.
2719 return js.js('(void 0).$name'); 2651 return js.js('(void 0).$name');
2720 } 2652 }
2721 registry.registerStaticUse(helper); 2653 registry.registerStaticUse(helper);
2722 return backend.namer.elementAccess(helper); 2654 return backend.namer.elementAccess(helper);
2723 } 2655 }
2724 } 2656 }
OLDNEW
« no previous file with comments | « no previous file | tests/compiler/dart2js_extra/21579_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698