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

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

Issue 10781019: Fix compilation for Opera. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comment. Created 8 years, 5 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 | « no previous file | lib/compiler/implementation/lib/native_helper.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/compiler/implementation/emitter.dart
diff --git a/lib/compiler/implementation/emitter.dart b/lib/compiler/implementation/emitter.dart
index 61efdc0936603fe2684d30e0a7b8152654877182..9cd1ea2044529a829af5aefa152220de1cc04473 100644
--- a/lib/compiler/implementation/emitter.dart
+++ b/lib/compiler/implementation/emitter.dart
@@ -60,6 +60,8 @@ class CodeEmitterTask extends CompilerTask {
=> '${namer.ISOLATE}.\$pendingClasses';
String get isolatePropertiesName()
=> '${namer.ISOLATE}.${namer.ISOLATE_PROPERTIES}';
+ String get supportsProtoName()
+ => 'supportsProto';
final String GETTER_SUFFIX = "?";
final String SETTER_SUFFIX = "!";
@@ -75,6 +77,8 @@ function(field, prototype) {
if (needsGetter || needsSetter) field = field.substring(0, len - 1);
if (needsGetter) {
var getterString = "return this." + field + ";";
+""" /* The supportsProtoCheck below depends on the getter/setter convention.
+ When changing here, update the protoCheck too. */ """
prototype["get\$" + field] = new Function(getterString);
}
if (needsSetter) {
@@ -100,7 +104,7 @@ function(field, prototype) {
// },
// });
return """
-function(cls, superclass, fields, prototype) {
+function(cls, fields, prototype) {
var generateGetterSetter = $generateGetterSetterFunction;
var constructor;
if (typeof fields == 'function') {
@@ -119,14 +123,30 @@ function(cls, superclass, fields, prototype) {
str += "return " + cls + ";";
constructor = new Function(str)();
}
- $isolatePropertiesName[cls] = constructor;
constructor.prototype = prototype;
- if (superclass !== "") {
- $pendingClassesName[cls] = superclass;
- }
+ return constructor;
}""";
}
+ /** Needs defineClass to be defined. */
+ String get protoSupportCheck() {
+ // On Firefox and Webkit browsers we can manipulate the __proto__
+ // directly. Opera claims to have __proto__ support, but it is buggy.
+ // So we have to do more checks.
+ // If the browser does not support __proto__ we need to instantiate an
+ // object with the correct (internal) prototype set up correctly, and then
+ // copy the members.
+
+ return '''
+var $supportsProtoName = false;
+var tmp = $defineClassName('c', ['f?'], {}).prototype;
+if (tmp.__proto__) {
+ tmp.__proto__ = {};
+ if (typeof tmp.get\$f !== "undefined") $supportsProtoName = true;
+}
+''';
+ }
+
String get finishClassesFunction() {
// 'defineClass' does not require the classes to be constructed in order.
// Classes are initially just stored in the 'pendingClasses' field.
@@ -142,10 +162,11 @@ function(cls, superclass, fields, prototype) {
// object and copy over the members.
return '''
function(collectedClasses) {
- for (var collected in collectedClasses) {
- if (Object.prototype.hasOwnProperty.call(collectedClasses, collected)) {
- var desc = collectedClasses[collected];
- $defineClassName(collected, desc.super, desc[''], desc);
+ for (var cls in collectedClasses) {
+ if (Object.prototype.hasOwnProperty.call(collectedClasses, cls)) {
+ var desc = collectedClasses[cls];
+ $isolatePropertiesName[cls] = $defineClassName(cls, desc[''], desc);
+ if (desc['super'] !== "") $pendingClassesName[cls] = desc['super'];
}
}
var pendingClasses = $pendingClassesName;
@@ -163,15 +184,10 @@ function(collectedClasses) {
var constructor = $isolatePropertiesName[cls];
var superConstructor = $isolatePropertiesName[superclass];
var prototype = constructor.prototype;
- if (prototype.__proto__) {
-'''/* On Firefox and Webkit browsers we can manipulate the __proto__
- directly. */'''
+ if ($supportsProtoName) {
prototype.__proto__ = superConstructor.prototype;
prototype.constructor = constructor;
} else {
-'''/* On the remaining browsers we need to instantiate an object with the
- correct (internal) prototype set up correctly, and then copy the
- members. */'''
function tmp() {};
tmp.prototype = superConstructor.prototype;
var newPrototype = new tmp();
@@ -237,6 +253,7 @@ function(collectedClasses) {
if (needsDefineClass) {
String isolate = namer.ISOLATE;
buffer.add("$defineClassName = $defineClassFunction;\n");
+ buffer.add(protoSupportCheck);
buffer.add("$pendingClassesName = {};\n");
buffer.add("$finishClassesName = $finishClassesFunction;\n");
}
@@ -711,9 +728,11 @@ function(collectedClasses) {
// Define the constructor with a name so that Object.toString can
// find the class name of the closure class.
- boundClosureBuffer.add("$defineClassName('$mangledName', '$superName', ");
- boundClosureBuffer.add("['self', 'target'], {\n");
-
+ boundClosureBuffer.add("""
+$classesCollector.$mangledName = {'':
+ ['self', 'target'],
+ 'super': '$superName',
+""");
// Now add the methods on the closure class. The instance method does not
// have the correct name. Since [addParameterStubs] use the name to create
// its stubs we simply create a fake element with the correct name.
@@ -736,7 +755,7 @@ function(collectedClasses) {
addParameterStubs(callElement, (String stubName, CodeBuffer memberValue) {
boundClosureBuffer.add(',\n $stubName: $memberValue');
});
- boundClosureBuffer.add("\n});\n");
+ boundClosureBuffer.add("\n};\n");
closureClass = namer.isolateAccess(closureClassElement);
@@ -1040,7 +1059,7 @@ if (typeof window != 'undefined' && typeof document != 'undefined' &&
nativeEmitter.assembleCode(mainBuffer);
emitMain(mainBuffer);
mainBuffer.add('function init() {\n');
- mainBuffer.add(' $isolateProperties = {};\n');
+ mainBuffer.add('$isolateProperties = {};\n');
addDefineClassAndFinishClassFunctionsIfNecessary(mainBuffer);
emitFinishIsolateConstructor(mainBuffer);
mainBuffer.add('}\n');
« no previous file with comments | « no previous file | lib/compiler/implementation/lib/native_helper.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698