Chromium Code Reviews| 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); |
|
ahe
2012/03/26 13:43:45
if (node.arguments.isEmpty() || node.arguments.tai
ngeoffray
2012/03/26 13:55:32
Done.
|
| - 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 handleForeignJsToClosure(Send node) { |
| + Node closure = node.arguments.head; |
| + if (!node.arguments.tail.isEmpty()) { |
|
ahe
2012/03/26 13:43:45
See above. You should probably test for node.argu
ngeoffray
2012/03/26 13:55:32
Done.
|
| + compiler.cancel( |
| + 'Invalid number of arguments in JS_TO_CLOSURE', |
|
ahe
2012/03/26 13:43:45
'exactly one argument required'
ngeoffray
2012/03/26 13:55:32
Done.
|
| + node: node); |
|
ahe
2012/03/26 13:43:45
node: node.arguments
ngeoffray
2012/03/26 13:55:32
Done.
|
| + } |
| + 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'))) { |
|
ahe
2012/03/26 13:43:45
This is weird, I think. Wouldn't this be simpler:
ngeoffray
2012/03/26 13:55:32
Yes, but I thought we agreed on comparing elements
ahe
2012/03/26 14:01:23
In general yes, however, this is going too far in
ngeoffray
2012/03/26 14:13:44
No that's ok (a foreign element can only be create
|
| @@ -1957,6 +1993,9 @@ |
| } else if (element === compiler.findHelper( |
| const SourceString('JS_CALL_IN_ISOLATE'))) { |
| handleForeignJsCallInIsolate(node); |
| + } else if (element === compiler.findHelper( |
| + const SourceString('JS_TO_CLOSURE'))) { |
| + handleForeignJsToClosure(node); |
| } else if (element === currentLibrary.find(const SourceString('native'))) { |
| native.handleSsaNative(this, node); |
| } else { |