| Index: pkg/compiler/lib/src/ssa/builder_kernel.dart
|
| diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
|
| index 75547da496dc779ee7908395b4493269eeebee09..4a52308b1f9f52b8433af9a7ea311a7a18fca754 100644
|
| --- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
|
| +++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
|
| @@ -719,15 +719,70 @@ class KernelSsaGraphBuilder extends ir.Visitor
|
|
|
| /// Builds a SSA graph for FunctionNodes of external methods.
|
| void buildExternalFunctionNode(ir.FunctionNode functionNode) {
|
| + assert(functionNode.body == null);
|
| openFunction(functionNode);
|
| ir.TreeNode parent = functionNode.parent;
|
| if (parent is ir.Procedure && parent.kind == ir.ProcedureKind.Factory) {
|
| _addClassTypeVariablesIfNeeded(parent);
|
| }
|
| - // TODO(sra): Generate conversion of Function typed arguments to JavaScript
|
| - // functions.
|
| - // TODO(sra): Invoke native method.
|
| - assert(functionNode.body == null);
|
| +
|
| + if (closedWorld.nativeData.isNativeMember(targetElement)) {
|
| + String nativeName;
|
| + if (closedWorld.nativeData.hasFixedBackendName(targetElement)) {
|
| + nativeName = closedWorld.nativeData.getFixedBackendName(targetElement);
|
| + } else {
|
| + nativeName = targetElement.name;
|
| + }
|
| +
|
| + String templateReceiver = '';
|
| + List<String> templateArguments = <String>[];
|
| + List<HInstruction> inputs = <HInstruction>[];
|
| + if (targetElement.isInstanceMember) {
|
| + templateReceiver = '#.';
|
| + inputs.add(localsHandler.readThis());
|
| + }
|
| +
|
| + for (ir.VariableDeclaration param in functionNode.positionalParameters) {
|
| + templateArguments.add('#');
|
| + Local local = localsMap.getLocalVariable(param);
|
| + // Convert Dart function to JavaScript function.
|
| + HInstruction argument = localsHandler.readLocal(local);
|
| + ir.DartType type = param.type;
|
| + if (type is ir.FunctionType) {
|
| + int arity = type.positionalParameters.length;
|
| + _pushStaticInvocation(
|
| + _commonElements.closureConverter,
|
| + [argument, graph.addConstantInt(arity, closedWorld)],
|
| + commonMasks.dynamicType);
|
| + argument = pop();
|
| + }
|
| + inputs.add(argument);
|
| + }
|
| +
|
| + String arguments = templateArguments.join(',');
|
| +
|
| + // TODO(sra): Use declared type or NativeBehavior type.
|
| + TypeMask typeMask = commonMasks.dynamicType;
|
| + String template;
|
| + if (targetElement.isGetter) {
|
| + template = '${templateReceiver}$nativeName';
|
| + } else if (targetElement.isSetter) {
|
| + template = '${templateReceiver}$nativeName = ${arguments}';
|
| + } else {
|
| + template = '${templateReceiver}$nativeName(${arguments})';
|
| + }
|
| +
|
| + push(new HForeignCode(
|
| + js.js.uncachedExpressionTemplate(template), typeMask, inputs,
|
| + effects: new SideEffects()));
|
| + // TODO(johnniwinther): Provide source information.
|
| + HInstruction value = pop();
|
| + if (targetElement.isSetter) {
|
| + value = graph.addConstantNull(closedWorld);
|
| + }
|
| + close(new HReturn(value, null)).addSuccessor(graph.exit);
|
| + }
|
| + // TODO(sra): Handle JS-interop methods.
|
| closeFunction();
|
| }
|
|
|
|
|