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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart

Issue 1688433006: cpsir: implementation of jsinterop in cps ir (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 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
OLDNEW
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698