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

Unified Diff: dart/lib/compiler/implementation/native_handler.dart

Issue 9909011: Implement redirecting natives. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/
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
« no previous file with comments | « dart/frog/tests/native/native.status ('k') | dart/lib/compiler/implementation/ssa/nodes.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: dart/lib/compiler/implementation/native_handler.dart
===================================================================
--- dart/lib/compiler/implementation/native_handler.dart (revision 5968)
+++ dart/lib/compiler/implementation/native_handler.dart (working copy)
@@ -178,16 +178,7 @@
}
void handleSsaNative(SsaBuilder builder, Send node) {
- // Register NoSuchMethodException and captureStackTrace in the compiler
- // because the dynamic dispatch for native classes may use them.
Compiler compiler = builder.compiler;
- ClassElement cls = compiler.coreLibrary.find(
floitsch 2012/03/29 23:25:52 this is not necessary anymore, because the functio
ngeoffray 2012/03/30 09:30:19 Correct.
- Compiler.NO_SUCH_METHOD_EXCEPTION);
- cls.ensureResolved(compiler);
- compiler.addToWorkList(cls.lookupConstructor(cls.name));
- compiler.registerStaticUse(
- compiler.findHelper(new SourceString('captureStackTrace')));
-
FunctionElement element = builder.work.element;
element.setNative();
NativeEmitter nativeEmitter = compiler.emitter.nativeEmitter;
@@ -199,19 +190,19 @@
if (element.name == const SourceString('typeName')
&& element.isGetter()
&& nativeEmitter.toNativeName(element.enclosingElement) == 'DOMType') {
- DartString jsCode = new DartString.literal(
- '${nativeEmitter.typeNameOfName}(#)');
- List<HInstruction> inputs =
- <HInstruction>[builder.localsHandler.readThis()];
- builder.push(new HForeign(
- jsCode, const LiteralDartString('String'), inputs));
+ Element element = compiler.findHelper(
floitsch 2012/03/29 23:25:52 Are you sure this doesn't fit on one line? If not,
ngeoffray 2012/03/30 09:30:19 Done.
+ const SourceString('getTypeNameOf'));
+ HStatic method = new HStatic(element);
+ builder.add(method);
+ builder.push(new HInvokeStatic(Selector.INVOCATION_1,
+ <HInstruction>[method, builder.localsHandler.readThis()]));
return;
}
HInstruction convertDartClosure(Element parameter) {
HInstruction local = builder.localsHandler.readLocal(parameter);
// TODO(ngeoffray): by better analyzing the function type and
- // its formal parameters, we could just pass, eg closure.$call$0.
+ // its formal parameters, we could pass a method with a defined arity.
builder.push(new HStatic(builder.interceptors.getClosureConverter()));
List<HInstruction> callInputs = <HInstruction>[builder.pop(), local];
HInstruction closure = new HInvokeStatic(Selector.INVOCATION_1, callInputs);
@@ -219,8 +210,30 @@
return closure;
}
+
+ // Check which pattern this native method follows:
+ // 1) foo() native; hasBody = false, isRedirecting = false
+ // 2) foo() native "bar"; hasBody = false, isRedirecting = true
+ // 3) foo() native "return 42"; hasBody = true, isRedirecting = false
+ bool hasBody = false;
+ bool isRedirecting = false;
+ String nativeMethodName = element.name.slowToString();
+ if (!node.arguments.isEmpty()) {
+ if (!node.arguments.tail.isEmpty()) {
+ builder.compiler.cancel('More than one argument to native');
+ }
+ LiteralString jsCode = node.arguments.head;
+ String str = jsCode.dartString.slowToString();
+ if (const RegExp(@'^[a-zA-Z][a-zA-Z_$0-9]*$').hasMatch(str)) {
+ nativeMethodName = str;
+ isRedirecting = true;
+ } else {
+ hasBody = true;
+ }
+ }
+
FunctionParameters parameters = element.computeParameters(builder.compiler);
- if (node.arguments.isEmpty()) {
+ if (!hasBody) {
List<String> arguments = <String>[];
List<HInstruction> inputs = <HInstruction>[];
String receiver = '';
@@ -238,7 +251,6 @@
String foreignParameters = Strings.join(arguments, ',');
String dartMethodName;
- String nativeMethodName = element.name.slowToString();
String nativeMethodCall;
if (element.kind == ElementKind.FUNCTION) {
@@ -321,9 +333,13 @@
builder.current.addPhi(phi);
builder.stack.add(phi);
}
-
- } else if (!node.arguments.tail.isEmpty()) {
- builder.compiler.cancel('More than one argument to native');
+ if (isRedirecting) {
+ // The parser creates a return node if there is no string literal
+ // after the native keyword. In case of a redirecting method, there
+ // is a string literal, therefore we must emit a return instruction
+ // in the builder.
+ builder.push(new HReturn(builder.pop()));
+ }
} else {
// This is JS code written in a Dart file with the construct
// native """ ... """;. It does not work well with mangling,
« no previous file with comments | « dart/frog/tests/native/native.status ('k') | dart/lib/compiler/implementation/ssa/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698