OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 native; | 5 part of native; |
6 | 6 |
7 /// This class is a temporary work-around until we get a more powerful DartType. | 7 /// This class is a temporary work-around until we get a more powerful DartType. |
8 class SpecialType { | 8 class SpecialType { |
9 final String name; | 9 final String name; |
10 const SpecialType._(this.name); | 10 const SpecialType._(this.name); |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 .visit(behavior.codeTemplate.ast); | 487 .visit(behavior.codeTemplate.ast); |
488 } | 488 } |
489 if (!throwBehaviorFromSpecString) { | 489 if (!throwBehaviorFromSpecString) { |
490 behavior.throwBehavior = | 490 behavior.throwBehavior = |
491 new ThrowBehaviorVisitor().analyze(behavior.codeTemplate.ast); | 491 new ThrowBehaviorVisitor().analyze(behavior.codeTemplate.ast); |
492 } | 492 } |
493 | 493 |
494 return behavior; | 494 return behavior; |
495 } | 495 } |
496 | 496 |
497 static NativeBehavior ofJsEmbeddedGlobalCall(Send jsGlobalCall, | 497 static void _fillNativeBehaviorOfBuiltinOrEmbeddedGlobal( |
498 Compiler compiler, | 498 NativeBehavior behavior, |
499 resolver) { | 499 Send jsBuiltinOrEmbeddedGlobalCall, |
| 500 Compiler compiler, |
| 501 ResolverVisitor resolver, |
| 502 {bool isBuiltin, |
| 503 List<String> validTags}) { |
500 // The first argument of a JS-embedded global call is a string encoding | 504 // The first argument of a JS-embedded global call is a string encoding |
501 // the type of the code. | 505 // the type of the code. |
502 // | 506 // |
503 // 'Type1|Type2'. A union type. | 507 // 'Type1|Type2'. A union type. |
504 // '=Object'. A JavaScript Object, no subtype. | 508 // '=Object'. A JavaScript Object, no subtype. |
505 | 509 |
506 Link<Node> argNodes = jsGlobalCall.arguments; | 510 String builtinOrGlobal = isBuiltin ? "builtin" : "embedded global"; |
| 511 |
| 512 Link<Node> argNodes = jsBuiltinOrEmbeddedGlobalCall.arguments; |
507 if (argNodes.isEmpty) { | 513 if (argNodes.isEmpty) { |
508 compiler.internalError(jsGlobalCall, | 514 compiler.internalError(jsBuiltinOrEmbeddedGlobalCall, |
509 "JS embedded global expression has no type."); | 515 "JS $builtinOrGlobal expression has no type."); |
510 } | 516 } |
511 | 517 |
512 // We don't check the given name. That needs to be done at a later point. | 518 // We don't check the given name. That needs to be done at a later point. |
513 // This is, because we want to allow non-literals as names. | 519 // This is, because we want to allow non-literals (like references to |
| 520 // enums) as names. |
514 if (argNodes.tail.isEmpty) { | 521 if (argNodes.tail.isEmpty) { |
515 compiler.internalError(jsGlobalCall, 'Embedded Global is missing name.'); | 522 compiler.internalError(jsBuiltinOrEmbeddedGlobalCall, |
| 523 'JS $builtinOrGlobal is missing name.'); |
516 } | 524 } |
517 | 525 |
518 if (!argNodes.tail.tail.isEmpty) { | 526 if (!isBuiltin) { |
519 compiler.internalError(argNodes.tail.tail.head, | 527 if (!argNodes.tail.tail.isEmpty) { |
520 'Embedded Global has more than 2 arguments'); | 528 compiler.internalError(argNodes.tail.tail.head, |
| 529 'JS embedded global has more than 2 arguments'); |
| 530 } |
521 } | 531 } |
522 | 532 |
523 LiteralString specLiteral = argNodes.head.asLiteralString(); | 533 LiteralString specLiteral = argNodes.head.asLiteralString(); |
524 if (specLiteral == null) { | 534 if (specLiteral == null) { |
525 // TODO(sra): We could accept a type identifier? e.g. JS(bool, '1<2'). It | 535 // TODO(sra): We could accept a type identifier? e.g. JS(bool, '1<2'). It |
526 // is not very satisfactory because it does not work for void, dynamic. | 536 // is not very satisfactory because it does not work for void, dynamic. |
527 compiler.internalError(argNodes.head, "Unexpected first argument."); | 537 compiler.internalError(argNodes.head, "Unexpected first argument."); |
528 } | 538 } |
529 | 539 |
530 NativeBehavior behavior = new NativeBehavior(); | |
531 | |
532 String specString = specLiteral.dartString.slowToString(); | 540 String specString = specLiteral.dartString.slowToString(); |
533 | 541 |
534 dynamic resolveType(String typeString) { | 542 dynamic resolveType(String typeString) { |
535 return _parseType( | 543 return _parseType( |
536 typeString, | 544 typeString, |
537 compiler, | 545 compiler, |
538 (name) => resolver.resolveTypeFromString(specLiteral, name), | 546 (name) => resolver.resolveTypeFromString(specLiteral, name), |
539 jsGlobalCall); | 547 jsBuiltinOrEmbeddedGlobalCall); |
540 } | 548 } |
541 | 549 |
542 processSpecString(compiler, jsGlobalCall, | 550 void setSideEffects(SideEffects newEffects) { |
| 551 behavior.sideEffects.setTo(newEffects); |
| 552 } |
| 553 |
| 554 processSpecString(compiler, jsBuiltinOrEmbeddedGlobalCall, |
543 specString, | 555 specString, |
544 validTags: const ['returns', 'creates'], | 556 validTags: validTags, |
545 resolveType: resolveType, | 557 resolveType: resolveType, |
| 558 setSideEffects: setSideEffects, |
546 typesReturned: behavior.typesReturned, | 559 typesReturned: behavior.typesReturned, |
547 typesInstantiated: behavior.typesInstantiated, | 560 typesInstantiated: behavior.typesInstantiated, |
548 objectType: compiler.objectClass.computeType(compiler), | 561 objectType: compiler.objectClass.computeType(compiler), |
549 nullType: compiler.nullClass.computeType(compiler)); | 562 nullType: compiler.nullClass.computeType(compiler)); |
| 563 } |
550 | 564 |
551 // Embedded globals are usually pre-computed data structures or JavaScript | 565 static NativeBehavior ofJsBuiltinCall(Send jsBuiltinCall, |
552 // functions that never change. | 566 Compiler compiler, |
553 // TODO(sra): Allow the use site to override these defaults. | 567 ResolverVisitor resolver) { |
554 behavior.sideEffects.clearAllDependencies(); | 568 NativeBehavior behavior = new NativeBehavior(); |
555 behavior.sideEffects.clearAllSideEffects(); | 569 behavior.sideEffects.setTo(new SideEffects()); |
556 behavior.throwBehavior = NativeThrowBehavior.NEVER; | 570 |
| 571 _fillNativeBehaviorOfBuiltinOrEmbeddedGlobal( |
| 572 behavior, jsBuiltinCall, compiler, resolver, isBuiltin: true); |
557 | 573 |
558 return behavior; | 574 return behavior; |
559 } | 575 } |
560 | 576 |
| 577 static NativeBehavior ofJsEmbeddedGlobalCall(Send jsEmbeddedGlobalCall, |
| 578 Compiler compiler, |
| 579 ResolverVisitor resolver) { |
| 580 NativeBehavior behavior = new NativeBehavior(); |
| 581 // TODO(sra): Allow the use site to override these defaults. |
| 582 // Embedded globals are usually pre-computed data structures or JavaScript |
| 583 // functions that never change. |
| 584 behavior.sideEffects.setTo(new SideEffects.empty()); |
| 585 behavior.throwBehavior = NativeThrowBehavior.NEVER; |
| 586 |
| 587 _fillNativeBehaviorOfBuiltinOrEmbeddedGlobal( |
| 588 behavior, jsEmbeddedGlobalCall, compiler, resolver, |
| 589 isBuiltin: false, |
| 590 validTags: const ['returns', 'creates']); |
| 591 |
| 592 return behavior; |
| 593 } |
| 594 |
561 static NativeBehavior ofMethod(FunctionElement method, Compiler compiler) { | 595 static NativeBehavior ofMethod(FunctionElement method, Compiler compiler) { |
562 FunctionType type = method.computeType(compiler); | 596 FunctionType type = method.computeType(compiler); |
563 var behavior = new NativeBehavior(); | 597 var behavior = new NativeBehavior(); |
564 behavior.typesReturned.add(type.returnType); | 598 behavior.typesReturned.add(type.returnType); |
565 if (!type.returnType.isVoid) { | 599 if (!type.returnType.isVoid) { |
566 // Declared types are nullable. | 600 // Declared types are nullable. |
567 behavior.typesReturned.add(compiler.nullClass.computeType(compiler)); | 601 behavior.typesReturned.add(compiler.nullClass.computeType(compiler)); |
568 } | 602 } |
569 behavior._capture(type, compiler); | 603 behavior._capture(type, compiler); |
570 | 604 |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
719 MessageKind.GENERIC, | 753 MessageKind.GENERIC, |
720 {'text': "Type '$typeString' not found."}); | 754 {'text': "Type '$typeString' not found."}); |
721 return const DynamicType(); | 755 return const DynamicType(); |
722 } | 756 } |
723 | 757 |
724 static _errorNode(locationNodeOrElement, compiler) { | 758 static _errorNode(locationNodeOrElement, compiler) { |
725 if (locationNodeOrElement is Node) return locationNodeOrElement; | 759 if (locationNodeOrElement is Node) return locationNodeOrElement; |
726 return locationNodeOrElement.parseNode(compiler); | 760 return locationNodeOrElement.parseNode(compiler); |
727 } | 761 } |
728 } | 762 } |
OLD | NEW |