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

Unified Diff: pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart

Issue 880773003: dart2js: support native classes in the new emitter. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rename blob to info. Created 5 years, 11 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 | « pkg/compiler/lib/src/js_emitter/new_emitter/emitter.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
diff --git a/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
index 9139905a587a9a72e45d6a183f8770900c91f520..b2b9d3292697b51105dae16d8384914cd2a535c9 100644
--- a/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
@@ -11,13 +11,18 @@ import '../../js_backend/js_backend.dart' show
Namer,
ConstantEmitter;
+import '../js_emitter.dart' show
+ NativeEmitter;
+
import 'package:_internal/compiler/js_lib/shared/embedded_names.dart' show
DEFERRED_LIBRARY_URIS,
DEFERRED_LIBRARY_HASHES,
GET_TYPE_FROM_NAME,
INITIALIZE_LOADED_HUNK,
+ INTERCEPTORS_BY_TAG,
IS_HUNK_INITIALIZED,
IS_HUNK_LOADED,
+ LEAF_TAGS,
TYPE_TO_INTERCEPTOR_MAP;
import '../js_emitter.dart' show NativeGenerator;
@@ -27,6 +32,7 @@ class ModelEmitter {
final Compiler compiler;
final Namer namer;
final ConstantEmitter constantEmitter;
+ final NativeEmitter nativeEmitter;
JavaScriptBackend get backend => compiler.backend;
@@ -36,7 +42,7 @@ class ModelEmitter {
static const String deferredExtension = "part.js";
- ModelEmitter(Compiler compiler, Namer namer)
+ ModelEmitter(Compiler compiler, Namer namer, this.nativeEmitter)
: this.compiler = compiler,
this.namer = namer,
constantEmitter =
@@ -88,34 +94,66 @@ class ModelEmitter {
elements.add(
emitLazilyInitializedStatics(fragment.staticLazilyInitializedFields));
- js.Statement nativeBoilerplate;
+ js.Expression code = new js.ArrayInitializer(elements);
+
+ Map<String, dynamic> holes =
+ {'deferredInitializer': emitDeferredInitializerGlobal(program.loadMap),
+ 'holders': emitHolders(fragment.holders),
+ 'cyclicThrow':
+ backend.emitter.staticFunctionAccess(backend.getCyclicThrowHelper()),
+ 'outputContainsConstantList': program.outputContainsConstantList,
+ 'embeddedGlobals': emitEmbeddedGlobals(program),
+ 'constants': emitConstants(fragment.constants),
+ 'staticNonFinals':
+ emitStaticNonFinalFields(fragment.staticNonFinalFields),
+ 'eagerClasses': emitEagerClassInitializations(fragment.libraries),
+ 'main': fragment.main,
+ 'code': code};
+
+ holes.addAll(nativeHoles(program));
+
+ return js.js.statement(boilerplate, holes);
+ }
+
+ Map<String, dynamic> nativeHoles(Program program) {
+ Map<String, dynamic> nativeHoles = <String, dynamic>{};
+
+ js.Statement nativeIsolateAffinityTagInitialization;
if (NativeGenerator.needsIsolateAffinityTagInitialization(backend)) {
- nativeBoilerplate =
+ nativeIsolateAffinityTagInitialization =
NativeGenerator.generateIsolateAffinityTagInitialization(
backend,
generateEmbeddedGlobalAccess,
// TODO(floitsch): convertToFastObject.
js.js("(function(x) { return x; })", []));
} else {
- nativeBoilerplate = js.js.statement(";");
+ nativeIsolateAffinityTagInitialization = js.js.statement(";");
}
+ nativeHoles['nativeIsolateAffinityTagInitialization'] =
+ nativeIsolateAffinityTagInitialization;
- js.Expression code = new js.ArrayInitializer(elements);
- return js.js.statement(
- boilerplate,
- {'deferredInitializer': emitDeferredInitializerGlobal(program.loadMap),
- 'holders': emitHolders(fragment.holders),
- 'cyclicThrow':
- backend.emitter.staticFunctionAccess(backend.getCyclicThrowHelper()),
- 'outputContainsConstantList': program.outputContainsConstantList,
- 'embeddedGlobals': emitEmbeddedGlobals(program),
- 'constants': emitConstants(fragment.constants),
- 'staticNonFinals': emitStaticNonFinalFields(fragment.staticNonFinalFields),
- 'nativeBoilerplate': nativeBoilerplate,
- 'eagerClasses': emitEagerClassInitializations(fragment.libraries),
- 'main': fragment.main,
- 'code': code});
+ js.Expression nativeInfoAccess = js.js('nativeInfo', []);
+ js.Expression constructorAccess = js.js('constructor', []);
+ Function subclassReadGenerator = (js.Expression subclass) {
+ return js.js('holdersMap[#][#].ensureResolved()', [subclass, subclass]);
+ };
+ js.Expression interceptorsByTagAccess =
+ generateEmbeddedGlobalAccess(INTERCEPTORS_BY_TAG);
+ js.Expression leafTagsAccess =
+ generateEmbeddedGlobalAccess(LEAF_TAGS);
+ js.Statement nativeInfoHandler = nativeEmitter.buildNativeInfoHandler(
+ nativeInfoAccess,
+ constructorAccess,
+ subclassReadGenerator,
+ interceptorsByTagAccess,
+ leafTagsAccess);
+
+ nativeHoles['hasNativeClasses'] = program.outputContainsNativeClasses;
+ nativeHoles['hasNotNativeClasses'] = !program.outputContainsNativeClasses;
+ nativeHoles['nativeInfoHandler'] = nativeInfoHandler;
+
+ return nativeHoles;
}
js.Block emitHolders(List<Holder> holders) {
@@ -165,6 +203,13 @@ class ModelEmitter {
program.typeToInterceptorMap));
}
+ if (program.outputContainsNativeClasses) {
+ globals.add(new js.Property(js.string(INTERCEPTORS_BY_TAG),
+ js.js('Object.create(null)', [])));
+ globals.add(new js.Property(js.string(LEAF_TAGS),
+ js.js('Object.create(null)', [])));
+ }
+
js.ObjectInitializer globalsObject = new js.ObjectInitializer(globals);
List<js.Statement> statements =
@@ -288,11 +333,27 @@ class ModelEmitter {
return new js.Block(instantiations);
}
+ // This string should be referenced wherever JavaScript code makes assumptions
+ // on the mixin format.
+ static final String nativeInfoDescription =
+ "A class is encoded as follows:"
+ " [name, class-code, holder-index], or "
+ " [name, class-code, native-info, holder-index].";
+
js.Expression emitLibrary(Library library) {
- Iterable staticDescriptors = library.statics.expand((e) =>
- [ js.string(e.name), js.number(e.holder.index), emitStaticMethod(e) ]);
- Iterable classDescriptors = library.classes.expand((e) =>
- [ js.string(e.name), js.number(e.holder.index), emitClass(e) ]);
+ Iterable staticDescriptors = library.statics.expand((StaticMethod m) =>
+ [js.string(m.name), js.number(m.holder.index), emitStaticMethod(m)]);
+
+ Iterable classDescriptors = library.classes.expand((Class cls) {
+ js.LiteralString name = js.string(cls.name);
+ js.LiteralNumber holderIndex = js.number(cls.holder.index);
+ js.Expression emittedClass = emitClass(cls);
+ if (cls.nativeInfo == null) {
+ return [name, emittedClass, holderIndex];
+ } else {
+ return [name, emittedClass, js.string(cls.nativeInfo), holderIndex];
+ }
+ });
js.Expression staticArray =
new js.ArrayInitializer(staticDescriptors.toList(growable: false));
@@ -406,6 +467,7 @@ class ModelEmitter {
// Initialize holder objects.
#holders;
+ var nativeInfos = Object.create(null);
function setupProgram() {
for (var i = 0; i < program.length - 1; i++) {
@@ -423,9 +485,27 @@ class ModelEmitter {
var classes = library[1];
for (var i = 0; i < classes.length; i += 3) {
- var holderIndex = classes[i + 1];
- holdersMap[classes[i]] = holders[holderIndex];
- setupClass(classes[i], holders[holderIndex], classes[i + 2]);
+ var name = classes[i];
+ var cls = classes[i + 1];
+
+ if (#hasNativeClasses) {
+ // $nativeInfoDescription.
+ var indexOrNativeInfo = classes[i + 2];
+ if (typeof indexOrNativeInfo == "number") {
+ var holderIndex = classes[i + 2];
+ } else {
+ nativeInfos[name] = indexOrNativeInfo;
+ holderIndex = classes[i + 3];
+ i++;
+ }
+ }
+
+ if (#hasNotNativeClasses) {
zarah 2015/01/28 10:54:40 hasNoNativeClasses
floitsch 2015/01/28 13:28:27 Done.
+ var holderIndex = classes[i + 2];
+ }
+
+ holdersMap[name] = holders[holderIndex];
+ setupClass(name, holders[holderIndex], cls);
}
}
@@ -565,6 +645,16 @@ class ModelEmitter {
}
}
+ if (#hasNativeClasses) {
+ function handleNativeClassInfos() {
+ for (var nativeClass in nativeInfos) {
+ var constructor = holdersMap[nativeClass][nativeClass].ensureResolved();
+ var nativeInfo = nativeInfos[nativeClass];
+ #nativeInfoHandler;
+ }
+ }
+ }
+
setupProgram();
// Initialize constants.
@@ -573,11 +663,18 @@ class ModelEmitter {
// Initialize globals.
#embeddedGlobals;
+ // TODO(floitsch): this order means that native classes may not be
+ // referenced from constants. I'm mostly afraid of things like using them as
+ // generic arguments (which should be fine, but maybe there are other
+ // similar things).
+ // Initialize natives.
+ if (#hasNativeClasses) handleNativeClassInfos();
+
// Initialize static non-final fields.
#staticNonFinals;
// Add native boilerplate code.
- #nativeBoilerplate;
+ #nativeIsolateAffinityTagInitialization;
// Initialize eager classes.
#eagerClasses;
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/new_emitter/emitter.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698