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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
index 470a96d14c1e53abe1a1d0d67cc890a556e4206b..04e5256d08bb1553dcbeef0f79642b7bf24df807 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
@@ -20,8 +20,10 @@ import '../elements/elements.dart';
import '../io/source_information.dart';
import '../js/js.dart' as js show
js,
+ objectLiteral,
LiteralStatement,
Template,
+ InterpolatedExpression,
isIdentityTemplate;
import '../native/native.dart' show
NativeBehavior;
@@ -691,6 +693,9 @@ class IrBuilder {
assert(!element.isLocal);
assert(!element.isInstanceMember);
assert(isOpen);
+ if (program.isJsInterop(element)) {
+ return buildInvokeJsInteropMember(element, arguments);
+ }
return addPrimitive(
new ir.InvokeStatic(element, selector, arguments, sourceInformation));
}
@@ -2066,6 +2071,86 @@ class IrBuilder {
buildReturn(value: value, sourceInformation: source);
}
+ static _isNotNull(ir.Primitive value) =>
+ value is! ir.Constant || !value.value.isNull;
+
+ /// Builds a call to a resolved js-interop element.
+ ir.Primitive buildInvokeJsInteropMember(FunctionElement element,
+ List<ir.Primitive> arguments) {
+ program.addNativeMethod(element);
+ String target = program.getJsInteropTargetPath(element);
+ // Strip off trailing arguments that were not specified.
+ // TODO(jacobr,sigmund): assert that the trailing arguments are all null.
+ // TODO(jacobr): rewrite named arguments to an object literal matching
+ // the factory constructor case.
+ var inputs = arguments.where(_isNotNull).toList();
+
+ var behavior = new NativeBehavior()..sideEffects.setAllSideEffects();
+ DartType type = element.isConstructor ?
+ element.enclosingClass.thisType : element.type.returnType;
+ // Native behavior effects here are similar to native/behavior.dart.
+ // The return type is dynamic if we don't trust js-interop type
+ // declarations.
+ behavior.typesReturned.add(
+ program.trustJSInteropTypeAnnotations ? type : const DynamicType());
+
+ // The allocation effects include the declared type if it is native (which
+ // includes js interop types).
+ if (type.element != null && program.isNative(type.element)) {
+ behavior.typesInstantiated.add(type);
+ }
+
+ // It also includes any other JS interop type if we don't trust the
+ // annotation or if is declared too broad.
+ if (!program.trustJSInteropTypeAnnotations || type.isObject ||
+ type.isDynamic) {
+ behavior.typesInstantiated.add(program.jsJavascriptObjectType);
+ }
+
+ String code;
+ if (element.isGetter) {
+ code = target;
+ } else if (element.isSetter) {
+ code = "$target = #";
+ } else {
+ var args = new List.filled(inputs.length, '#').join(',');
+ code = element.isConstructor ? "new $target($args)" : "$target($args)";
+ }
+ return buildForeignCode(js.js.parseForeignJS(code), inputs, behavior);
+ // TODO(sigmund): should we record the source-information here?
+ }
+
+ /// Builds an object literal that results from invoking a factory constructor
+ /// of a js-interop anonymous type.
+ ir.Primitive buildJsInteropObjectLiteral(ConstructorElement constructor,
+ List<ir.Primitive> arguments, {SourceInformation source}) {
+ assert(program.isJsInteropAnonymous(constructor));
+ program.addNativeMethod(constructor);
+ FunctionSignature params = constructor.functionSignature;
+ int i = 0;
+ var filteredArguments = <ir.Primitive>[];
+ var entries = new Map<String, js.Expression>();
+ params.orderedForEachParameter((ParameterElement parameter) {
+ // TODO(jacobr): throw if parameter names do not match names of property
+ // names in the class.
+ assert (parameter.isNamed);
+ ir.Primitive argument = arguments[i++];
+ if (_isNotNull(argument)) {
+ filteredArguments.add(argument);
+ entries[parameter.name] =
+ new js.InterpolatedExpression(filteredArguments.length - 1);
+ }
+ });
+ var code = new js.Template(null, js.objectLiteral(entries));
+ var behavior = new NativeBehavior();
+ if (program.trustJSInteropTypeAnnotations) {
+ behavior.typesReturned.add(constructor.enclosingClass.thisType);
+ }
+
+ // TODO(sigmund): should we record the source-information here?
+ return buildForeignCode(code, filteredArguments, behavior);
+ }
+
/// Create a blocks of [statements] by applying [build] to all reachable
/// statements. The first statement is assumed to be reachable.
// TODO(johnniwinther): Type [statements] as `Iterable` when `NodeList` uses
@@ -2551,6 +2636,13 @@ class IrBuilder {
Selector selector =
new Selector(SelectorKind.CALL, element.memberName, callStructure);
ClassElement cls = element.enclosingClass;
+ if (program.isJsInterop(element)) {
+ if (program.isJsInteropAnonymous(element)) {
+ return buildJsInteropObjectLiteral(element, arguments,
+ source: sourceInformation);
+ }
+ return buildInvokeJsInteropMember(element, arguments);
+ }
if (program.requiresRuntimeTypesFor(cls)) {
InterfaceType interface = type;
Iterable<ir.Primitive> typeArguments =
« no previous file with comments | « no previous file | pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698