OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library dart2js.ir_builder; | 5 library dart2js.ir_builder; |
6 | 6 |
7 import '../closure.dart' as closure; | 7 import '../closure.dart' as closure; |
8 import '../common.dart'; | 8 import '../common.dart'; |
9 import '../common/names.dart' show | 9 import '../common/names.dart' show |
10 Names, | 10 Names, |
11 Selectors; | 11 Selectors; |
12 import '../compile_time_constants.dart' show | 12 import '../compile_time_constants.dart' show |
13 BackendConstantEnvironment; | 13 BackendConstantEnvironment; |
14 import '../constants/constant_system.dart'; | 14 import '../constants/constant_system.dart'; |
15 import '../constants/values.dart' show | 15 import '../constants/values.dart' show |
16 ConstantValue, | 16 ConstantValue, |
17 PrimitiveConstantValue; | 17 PrimitiveConstantValue; |
18 import '../dart_types.dart'; | 18 import '../dart_types.dart'; |
19 import '../elements/elements.dart'; | 19 import '../elements/elements.dart'; |
20 import '../io/source_information.dart'; | 20 import '../io/source_information.dart'; |
21 import '../js/js.dart' as js show | 21 import '../js/js.dart' as js show |
22 js, | 22 js, |
23 objectLiteral, | |
23 LiteralStatement, | 24 LiteralStatement, |
24 Template, | 25 Template, |
26 InterpolatedExpression, | |
25 isIdentityTemplate; | 27 isIdentityTemplate; |
26 import '../native/native.dart' show | 28 import '../native/native.dart' show |
27 NativeBehavior; | 29 NativeBehavior; |
28 import '../tree/tree.dart' as ast; | 30 import '../tree/tree.dart' as ast; |
29 import '../types/types.dart' show | 31 import '../types/types.dart' show |
30 TypeMask; | 32 TypeMask; |
31 import '../universe/call_structure.dart' show | 33 import '../universe/call_structure.dart' show |
32 CallStructure; | 34 CallStructure; |
33 import '../universe/selector.dart' show | 35 import '../universe/selector.dart' show |
34 Selector, | 36 Selector, |
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
684 return primitive; | 686 return primitive; |
685 } | 687 } |
686 | 688 |
687 ir.Primitive buildInvokeStatic(Element element, | 689 ir.Primitive buildInvokeStatic(Element element, |
688 Selector selector, | 690 Selector selector, |
689 List<ir.Primitive> arguments, | 691 List<ir.Primitive> arguments, |
690 SourceInformation sourceInformation) { | 692 SourceInformation sourceInformation) { |
691 assert(!element.isLocal); | 693 assert(!element.isLocal); |
692 assert(!element.isInstanceMember); | 694 assert(!element.isInstanceMember); |
693 assert(isOpen); | 695 assert(isOpen); |
694 return addPrimitive( | 696 if (program.isJsInterop(element)) { |
695 new ir.InvokeStatic(element, selector, arguments, sourceInformation)); | 697 return buildInvokeJsInteropMember(element, arguments); |
698 } else { | |
Jacob
2016/02/11 17:54:33
style not: remove else.
Siggi Cherem (dart-lang)
2016/02/11 21:16:53
Done.
| |
699 return addPrimitive( | |
700 new ir.InvokeStatic(element, selector, arguments, sourceInformation)); | |
701 } | |
696 } | 702 } |
697 | 703 |
698 ir.Primitive _buildInvokeSuper(Element target, | 704 ir.Primitive _buildInvokeSuper(Element target, |
699 Selector selector, | 705 Selector selector, |
700 List<ir.Primitive> arguments, | 706 List<ir.Primitive> arguments, |
701 SourceInformation sourceInformation) { | 707 SourceInformation sourceInformation) { |
702 assert(target.isInstanceMember); | 708 assert(target.isInstanceMember); |
703 assert(isOpen); | 709 assert(isOpen); |
704 return addPrimitive(new ir.InvokeMethodDirectly( | 710 return addPrimitive(new ir.InvokeMethodDirectly( |
705 buildThis(), target, selector, arguments, sourceInformation)); | 711 buildThis(), target, selector, arguments, sourceInformation)); |
(...skipping 1353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2059 // Generate the [ForeignCode] expression and a return statement to return | 2065 // Generate the [ForeignCode] expression and a return statement to return |
2060 // its value. | 2066 // its value. |
2061 ir.Primitive value = buildForeignCode( | 2067 ir.Primitive value = buildForeignCode( |
2062 js.js.uncachedExpressionTemplate(code), | 2068 js.js.uncachedExpressionTemplate(code), |
2063 arguments, | 2069 arguments, |
2064 behavior, | 2070 behavior, |
2065 type: program.getTypeMaskForNativeFunction(function)); | 2071 type: program.getTypeMaskForNativeFunction(function)); |
2066 buildReturn(value: value, sourceInformation: source); | 2072 buildReturn(value: value, sourceInformation: source); |
2067 } | 2073 } |
2068 | 2074 |
2075 static _isNotNull(ir.Primitive value) => | |
2076 value is! ir.Constant || !value.value.isNull; | |
2077 | |
2078 /// Builds a call to a resolved js-interop element. | |
2079 ir.Primitive buildInvokeJsInteropMember(FunctionElement element, | |
Siggi Cherem (dart-lang)
2016/02/11 03:13:30
most of this code logic is line-per-line as it was
Jacob
2016/02/11 17:54:33
Acknowledged.
| |
2080 List<ir.Primitive> arguments) { | |
2081 program.addNativeMethod(element); | |
2082 String target = program.getJsInteropTargetPath(element); | |
2083 // Strip off trailing arguments that were not specified. | |
2084 // TODO(jacobr): assert that the trailing arguments are all null. | |
Jacob
2016/02/11 17:54:33
hey now... shouldn't this be
TODO(sigmund)?
:)
Siggi Cherem (dart-lang)
2016/02/11 21:16:53
The comment was there before, I just made it a TOD
| |
2085 // TODO(jacobr): rewrite named arguments to an object literal matching | |
2086 // the factory constructor case. | |
2087 var inputs = arguments.where(_isNotNull).toList(); | |
2088 | |
2089 var behavior = new NativeBehavior()..sideEffects.setAllSideEffects(); | |
2090 DartType type = element.isConstructor ? | |
2091 element.enclosingClass.thisType : element.type.returnType; | |
2092 // Native behavior effects here are similar to native/behavior.dart. | |
2093 // The return type is dynamic if we don't trust js-interop type | |
2094 // declarations. | |
2095 behavior.typesReturned.add( | |
2096 program.trustJSInteropTypeAnnotations ? type : const DynamicType()); | |
2097 | |
2098 // The allocation effects include the declared type if it is native (which | |
2099 // includes js interop types). | |
2100 if (type.element != null && program.isNative(type.element)) { | |
2101 behavior.typesInstantiated.add(type); | |
2102 } | |
2103 | |
2104 // It also includes any other JS interop type if we don't trust the | |
2105 // annotation or if is declared too broad. | |
2106 if (!program.trustJSInteropTypeAnnotations || type.isObject || | |
2107 type.isDynamic) { | |
2108 behavior.typesInstantiated.add(program.jsJavascriptObjectType); | |
2109 } | |
2110 | |
2111 String code; | |
2112 if (element.isGetter) { | |
2113 code = target; | |
Siggi Cherem (dart-lang)
2016/02/11 03:13:30
difference 1: I use `target` directly here, SSA cr
Jacob
2016/02/11 17:54:33
Acknowledged.
| |
2114 } else if (element.isSetter) { | |
2115 code = "$target = #"; | |
2116 } else { | |
2117 var args = new List.filled(inputs.length, '#').join(','); | |
2118 code = element.isConstructor ? "new $target($args)" : "$target($args)"; | |
2119 } | |
2120 return buildForeignCode(js.js.parseForeignJS(code), inputs, behavior); | |
Siggi Cherem (dart-lang)
2016/02/11 03:13:31
difference 2: I no longer attach the code to the b
| |
2121 // TODO(sigmund): should we record the source-information here? | |
Siggi Cherem (dart-lang)
2016/02/11 03:13:31
difference 3: I have no place to store source-info
Jacob
2016/02/11 17:54:33
Will that result in a good source maps exerience u
Siggi Cherem (dart-lang)
2016/02/11 21:16:53
Yeah, I think that is likely to be an issue here a
| |
2122 } | |
2123 | |
2124 /// Builds an object literal that results from invoking a factory constructor | |
2125 /// of a js-interop anonymous type. | |
2126 ir.Primitive buildJsInteropObjectLiteral(ConstructorElement constructor, | |
2127 List<ir.Primitive> arguments, {SourceInformation source}) { | |
2128 assert(program.isJsInteropAnonymous(constructor)); | |
2129 program.addNativeMethod(constructor); | |
2130 FunctionSignature params = constructor.functionSignature; | |
2131 int i = 0; | |
2132 var filteredArguments = <ir.Primitive>[]; | |
2133 var entries = new Map<String, js.Expression>(); | |
2134 params.orderedForEachParameter((ParameterElement parameter) { | |
2135 // TODO(jacobr): throw if parameter names do not match names of property | |
2136 // names in the class. | |
2137 assert (parameter.isNamed); | |
2138 ir.Primitive argument = arguments[i++]; | |
2139 if (_isNotNull(argument)) { | |
2140 filteredArguments.add(argument); | |
2141 entries[parameter.name] = | |
2142 new js.InterpolatedExpression(filteredArguments.length - 1); | |
2143 } | |
2144 }); | |
2145 var code = new js.Template(null, js.objectLiteral(entries)); | |
2146 var behavior = new NativeBehavior(); | |
2147 if (program.trustJSInteropTypeAnnotations) { | |
2148 behavior.typesReturned.add(constructor.enclosingClass.thisType); | |
2149 } | |
2150 | |
2151 // TODO(sigmund): should we record the source-information here? | |
2152 return buildForeignCode(code, filteredArguments, behavior); | |
2153 } | |
2154 | |
2069 /// Create a blocks of [statements] by applying [build] to all reachable | 2155 /// Create a blocks of [statements] by applying [build] to all reachable |
2070 /// statements. The first statement is assumed to be reachable. | 2156 /// statements. The first statement is assumed to be reachable. |
2071 // TODO(johnniwinther): Type [statements] as `Iterable` when `NodeList` uses | 2157 // TODO(johnniwinther): Type [statements] as `Iterable` when `NodeList` uses |
2072 // `List` instead of `Link`. | 2158 // `List` instead of `Link`. |
2073 void buildBlock(var statements, BuildFunction build) { | 2159 void buildBlock(var statements, BuildFunction build) { |
2074 // Build(Block(stamements), C) = C' | 2160 // Build(Block(stamements), C) = C' |
2075 // where C' = statements.fold(Build, C) | 2161 // where C' = statements.fold(Build, C) |
2076 assert(isOpen); | 2162 assert(isOpen); |
2077 return buildSequence(statements, build); | 2163 return buildSequence(statements, build); |
2078 } | 2164 } |
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2544 ConstructorElement element, | 2630 ConstructorElement element, |
2545 CallStructure callStructure, | 2631 CallStructure callStructure, |
2546 DartType type, | 2632 DartType type, |
2547 List<ir.Primitive> arguments, | 2633 List<ir.Primitive> arguments, |
2548 SourceInformation sourceInformation, | 2634 SourceInformation sourceInformation, |
2549 {TypeMask allocationSiteType}) { | 2635 {TypeMask allocationSiteType}) { |
2550 assert(isOpen); | 2636 assert(isOpen); |
2551 Selector selector = | 2637 Selector selector = |
2552 new Selector(SelectorKind.CALL, element.memberName, callStructure); | 2638 new Selector(SelectorKind.CALL, element.memberName, callStructure); |
2553 ClassElement cls = element.enclosingClass; | 2639 ClassElement cls = element.enclosingClass; |
2640 if (program.isJsInterop(element)) { | |
2641 if (program.isJsInteropAnonymous(element)) { | |
2642 return buildJsInteropObjectLiteral(element, arguments, | |
2643 source: sourceInformation); | |
2644 } else { | |
Jacob
2016/02/11 17:54:33
sme nit about unneeded else
Siggi Cherem (dart-lang)
2016/02/11 21:16:53
Done.
| |
2645 return buildInvokeJsInteropMember(element, arguments); | |
2646 } | |
2647 } | |
2554 if (program.requiresRuntimeTypesFor(cls)) { | 2648 if (program.requiresRuntimeTypesFor(cls)) { |
2555 InterfaceType interface = type; | 2649 InterfaceType interface = type; |
2556 Iterable<ir.Primitive> typeArguments = | 2650 Iterable<ir.Primitive> typeArguments = |
2557 interface.typeArguments.map((DartType argument) { | 2651 interface.typeArguments.map((DartType argument) { |
2558 return type.treatAsRaw | 2652 return type.treatAsRaw |
2559 ? buildNullConstant() | 2653 ? buildNullConstant() |
2560 : buildTypeExpression(argument); | 2654 : buildTypeExpression(argument); |
2561 }); | 2655 }); |
2562 arguments = new List<ir.Primitive>.from(arguments) | 2656 arguments = new List<ir.Primitive>.from(arguments) |
2563 ..addAll(typeArguments); | 2657 ..addAll(typeArguments); |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2843 this.stackTraceVariable, | 2937 this.stackTraceVariable, |
2844 this.buildCatchBlock}); | 2938 this.buildCatchBlock}); |
2845 } | 2939 } |
2846 | 2940 |
2847 class SwitchCaseInfo { | 2941 class SwitchCaseInfo { |
2848 final SubbuildFunction buildCondition; | 2942 final SubbuildFunction buildCondition; |
2849 final SubbuildFunction buildBody; | 2943 final SubbuildFunction buildBody; |
2850 | 2944 |
2851 SwitchCaseInfo(this.buildCondition, this.buildBody); | 2945 SwitchCaseInfo(this.buildCondition, this.buildBody); |
2852 } | 2946 } |
OLD | NEW |