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

Unified Diff: frog/leg/ssa/builder.dart

Issue 9750003: Write our JS blobs for handling native classes in Dart. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 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
Index: frog/leg/ssa/builder.dart
===================================================================
--- frog/leg/ssa/builder.dart (revision 5866)
+++ frog/leg/ssa/builder.dart (working copy)
@@ -1851,14 +1851,23 @@
// If the invoke is on foreign code, don't visit the first
// argument, which is the type, and the second argument,
// which is the foreign code.
+ if (link.isEmpty() || link.isEmpty()) {
+ compiler.cancel('At least two arguments expected', node: node.arguments);
+ }
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,23 +1950,49 @@
}
}
+ void handleForeignDartClosureToJs(Send node) {
+ if (node.arguments.isEmpty() || !node.arguments.tail.isEmpty()) {
+ compiler.cancel('Exactly one argument required', node: node.arguments);
+ }
+ Node closure = node.arguments.head;
+ 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'))) {
+ if (element.name == const SourceString('JS')) {
handleForeignJs(node);
- } else if (element === compiler.findHelper(
- const SourceString('UNINTERCEPTED'))) {
+ } else if (element.name == const SourceString('UNINTERCEPTED')) {
handleForeignUnintercepted(node);
- } else if (element === compiler.findHelper(
- const SourceString('JS_HAS_EQUALS'))) {
+ } else if (element.name == const SourceString('JS_HAS_EQUALS')) {
handleForeignJsHasEquals(node);
- } else if (element === compiler.findHelper(
- const SourceString('JS_CURRENT_ISOLATE'))) {
+ } else if (element.name == const SourceString('JS_CURRENT_ISOLATE')) {
handleForeignJsCurrentIsolate(node);
- } else if (element === compiler.findHelper(
- const SourceString('JS_CALL_IN_ISOLATE'))) {
+ } else if (element.name == const SourceString('JS_CALL_IN_ISOLATE')) {
handleForeignJsCallInIsolate(node);
- } else if (element === currentLibrary.find(const SourceString('native'))) {
+ } else if (element.name == const SourceString('DART_CLOSURE_TO_JS')) {
+ handleForeignDartClosureToJs(node);
+ } else if (element.name == const SourceString('native')) {
native.handleSsaNative(this, node);
} else {
throw "Unknown foreign: ${node.selector}";

Powered by Google App Engine
This is Rietveld 408576698