| Index: frog/leg/ssa/builder.dart
|
| ===================================================================
|
| --- frog/leg/ssa/builder.dart (revision 5817)
|
| +++ frog/leg/ssa/builder.dart (working copy)
|
| @@ -1854,11 +1854,17 @@
|
| link = link.tail.tail;
|
| List<HInstruction> inputs = <HInstruction>[];
|
| addGenericSendArgumentsToList(link, inputs);
|
| - LiteralString type = node.arguments.head;
|
| - LiteralString literal = node.arguments.tail.head;
|
| - compiler.ensure(literal is LiteralString);
|
| - compiler.ensure(type is LiteralString);
|
| - push(new HForeign(literal.dartString, type.dartString, inputs));
|
| + Node type = node.arguments.head;
|
| + Node literal = node.arguments.tail.head;
|
| + if (literal is !StringNode || literal.dynamic.isInterpolation) {
|
| + compiler.cancel('JS code must be a string literal', node: literal);
|
| + }
|
| + if (type is !LiteralString) {
|
| + compiler.cancel(
|
| + 'The type of a JS expression must be a string literal', node: type);
|
| + }
|
| + push(new HForeign(
|
| + literal.dynamic.dartString, type.dynamic.dartString, inputs));
|
| }
|
|
|
| void handleForeignUnintercepted(Send node) {
|
| @@ -1941,6 +1947,36 @@
|
| }
|
| }
|
|
|
| + void handleForeignDartClosureToJs(Send node) {
|
| + Node closure = node.arguments.head;
|
| + if (!node.arguments.tail.isEmpty()) {
|
| + compiler.cancel(
|
| + 'Invalid number of arguments in JS_TO_CLOSURE',
|
| + node: node);
|
| + }
|
| + Element element = elements[closure];
|
| + if (!Elements.isStaticOrTopLevelFunction(element)) {
|
| + compiler.cancel(
|
| + 'JS_TO_CLOSURE requires a static or top-level method',
|
| + node: closure);
|
| + }
|
| + FunctionElement function = element;
|
| + FunctionParameters parameters = element.computeParameters(compiler);
|
| + if (parameters.optionalParameterCount !== 0) {
|
| + compiler.cancel(
|
| + 'JS_TO_CLOSURE does not handle closure with optional parameters',
|
| + node: closure);
|
| + }
|
| + visit(closure);
|
| + List<HInstruction> inputs = <HInstruction>[pop()];
|
| + String invocationName = compiler.namer.closureInvocationName(
|
| + new Selector(SelectorKind.INVOCATION,
|
| + parameters.requiredParameterCount));
|
| + push(new HForeign(new SourceString('#.$invocationName'),
|
| + const SourceString('var'),
|
| + inputs));
|
| + }
|
| +
|
| handleForeignSend(Send node) {
|
| Element element = elements[node];
|
| if (element === compiler.findHelper(const SourceString('JS'))) {
|
| @@ -1957,6 +1993,9 @@
|
| } else if (element === compiler.findHelper(
|
| const SourceString('JS_CALL_IN_ISOLATE'))) {
|
| handleForeignJsCallInIsolate(node);
|
| + } else if (element === compiler.findHelper(
|
| + const SourceString('DART_CLOSURE_TO_JS'))) {
|
| + handleForeignDartClosureToJs(node);
|
| } else if (element === currentLibrary.find(const SourceString('native'))) {
|
| native.handleSsaNative(this, node);
|
| } else {
|
|
|