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

Unified Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart

Issue 1288013002: dart2js cps: Handle native functions, getters, and setters. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Address comments. Created 5 years, 4 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 77806c00c334282149e35f446964ba6b83a99a65..c9886775cb8ac9f8777a31b4380c3246b5df65fc 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
@@ -20,7 +20,7 @@ import 'cps_ir_builder_task.dart' show DartCapturedVariables,
GlobalProgramInformation;
import '../common.dart' as types show TypeMask;
-import '../js/js.dart' as js show Template;
+import '../js/js.dart' as js show Template, js, LiteralStatement;
import '../native/native.dart' show NativeBehavior;
/// A mapping from variable elements to their compile-time values.
@@ -2025,6 +2025,80 @@ class IrBuilder {
}
}
+ /// Build a call to the closure conversion helper for the [Function] typed
+ /// value in [value].
+ ir.Primitive _convertDartClosure(ir.Primitive value, FunctionType type) {
+ ir.Constant arity = buildIntegerConstant(type.computeArity());
+ return buildStaticFunctionInvocation(
+ program.closureConverter,
+ CallStructure.TWO_ARGS,
+ <ir.Primitive>[value, arity]);
+ }
+
+ /// Generate the body for a native function [function] that is annotated with
+ /// an implementation in JavaScript (provided as string in [javaScriptCode]).
+ void buildNativeFunctionBody(FunctionElement function,
+ String javaScriptCode) {
+ NativeBehavior behavior = new NativeBehavior();
+ behavior.sideEffects.setAllSideEffects();
+ // Generate a [ForeignCode] statement from the given native code.
+ buildForeignCode(
+ js.js.statementTemplateYielding(
+ new js.LiteralStatement(javaScriptCode)),
+ <ir.Primitive>[],
+ behavior);
+ }
+
+ /// Generate the body for a native function that redirects to a native
+ /// JavaScript function, getter, or setter.
+ ///
+ /// Generates a call to the real target, which is given by [functions]'s
+ /// `fixedBackendName`, passing all parameters as arguments. The target can
+ /// be the JavaScript implementation of a function, getter, or setter.
+ void buildRedirectingNativeFunctionBody(FunctionElement function,
+ SourceInformation source) {
+ String name = function.fixedBackendName;
+ List<ir.Primitive> arguments = <ir.Primitive>[];
+ NativeBehavior behavior = new NativeBehavior();
+ behavior.sideEffects.setAllSideEffects();
+ program.addNativeMethod(function);
+ // Construct the access of the target element.
+ String code = function.isInstanceMember ? '#.$name' : name;
+ if (function.isInstanceMember) {
+ arguments.add(state.thisParameter);
+ }
+ // Collect all parameters of the function and templates for them to be
+ // inserted into the JavaScript code.
+ List<String> argumentTemplates = <String>[];
+ function.functionSignature.forEachParameter((ParameterElement parameter) {
+ ir.Primitive input = environment.lookup(parameter);
+ DartType type = program.unaliasType(parameter.type);
+ if (type is FunctionType) {
+ // The parameter type is a function type either directly or through
+ // typedef(s).
+ input = _convertDartClosure(input, type);
+ }
+ arguments.add(input);
+ argumentTemplates.add('#');
+ });
+ // Construct the application of parameters for functions and setters.
+ if (function.kind == ElementKind.FUNCTION) {
+ code = "$code(${argumentTemplates.join(', ')})";
+ } else if (function.kind == ElementKind.SETTER) {
+ code = "$code = ${argumentTemplates.single}";
+ } else {
+ assert(argumentTemplates.isEmpty);
+ assert(function.kind == ElementKind.GETTER);
+ }
+ // Generate the [ForeignCode] expression and a return statement to return
+ // its value.
+ ir.Primitive value = buildForeignCode(
+ js.js.uncachedExpressionTemplate(code),
+ arguments,
+ behavior);
+ buildReturn(value: value, sourceInformation: source);
+ }
+
/// 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
@@ -2599,6 +2673,7 @@ class IrBuilder {
List<ir.Primitive> arguments,
NativeBehavior behavior,
{Element dependency}) {
+ assert(behavior != null);
types.TypeMask type = program.getTypeMaskForForeign(behavior);
ir.Primitive result = _continueWithExpression((k) => new ir.ForeignCode(
codeTemplate,
@@ -2608,7 +2683,7 @@ class IrBuilder {
k,
dependency: dependency));
if (!codeTemplate.isExpression) {
- // Close the term if this is a "throw" expression.
+ // Close the term if this is a "throw" expression or native body.
add(new ir.Unreachable());
_current = null;
}
« 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