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

Unified Diff: pkg/compiler/lib/src/js_emitter/native_emitter.dart

Issue 1215463006: Move nativeInfo encoding into NativeGenerator. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 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
Index: pkg/compiler/lib/src/js_emitter/native_emitter.dart
diff --git a/pkg/compiler/lib/src/js_emitter/native_emitter.dart b/pkg/compiler/lib/src/js_emitter/native_emitter.dart
index 3e7b649676770d60300c45f1c7aa0a9de03c6eff..b9e72669f4c65844555b801faa6a8080a4bb2ab0 100644
--- a/pkg/compiler/lib/src/js_emitter/native_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/native_emitter.dart
@@ -30,6 +30,7 @@ class NativeEmitter {
cachedBuilders = emitterTask.compiler.cacheStrategy.newMap();
Compiler get compiler => emitterTask.compiler;
+
JavaScriptBackend get backend => compiler.backend;
jsAst.Expression get defPropFunction {
@@ -43,8 +44,9 @@ class NativeEmitter {
* Removes trivial classes (that can be represented by a super type) and
* generates properties that have to be added to classes (native or not).
*
- * Updates the `nativeInfo` field of the given classes. This data
- * must be emitted with the corresponding classes.
+ * Updates the `nativeLeafTags`, `nativeNonLeafTags` and `nativeExtensions`
+ * fields of the given classes. This data must be emitted with the
+ * corresponding classes.
*
* The interceptors are filtered to avoid emitting trivial interceptors. For
* example, if the program contains no code that can distinguish between the
@@ -73,6 +75,7 @@ class NativeEmitter {
Class objectClass = null;
Class jsInterceptorClass = null;
+
void walk(Class cls) {
if (cls.element == compiler.objectClass) {
objectClass = cls;
@@ -94,7 +97,7 @@ class NativeEmitter {
// needed class.
Set<Class> neededClasses = new Set<Class>();
- Set<Class> nonleafClasses = new Set<Class>();
+ Set<Class> nonLeafClasses = new Set<Class>();
Map<Class, List<Class>> extensionPoints = computeExtensionPoints(preOrder);
@@ -130,13 +133,13 @@ class NativeEmitter {
if (cls.isNative &&
native.nativeTagsForcedNonLeaf(classElement)) {
needed = true;
- nonleafClasses.add(cls);
+ nonLeafClasses.add(cls);
}
if (needed || neededClasses.contains(cls)) {
neededClasses.add(cls);
neededClasses.add(cls.superclass);
- nonleafClasses.add(cls.superclass);
+ nonLeafClasses.add(cls.superclass);
}
}
@@ -149,7 +152,7 @@ class NativeEmitter {
if (!cls.isNative) continue;
List<String> nativeTags = native.nativeTagsOfClass(cls.element);
- if (nonleafClasses.contains(cls) ||
+ if (nonLeafClasses.contains(cls) ||
extensionPoints.containsKey(cls)) {
nonleafTags
.putIfAbsent(cls, () => new Set<String>())
@@ -168,51 +171,22 @@ class NativeEmitter {
}
}
+ void fillNativeInfo(Class cls) {
+ assert(cls.nativeLeafTags == null &&
+ cls.nativeNonLeafTags == null &&
+ cls.nativeExtensions == null);
+ cls.nativeLeafTags = leafTags[cls].toList(growable: false);
+ cls.nativeNonLeafTags = nonleafTags[cls].toList(growable: false);
+ cls.nativeExtensions = extensionPoints[cls];
+ }
// Add properties containing the information needed to construct maps used
// by getNativeInterceptor and custom elements.
if (compiler.enqueuer.codegen.nativeEnqueuer
.hasInstantiatedNativeClasses()) {
- void generateClassInfo(Class cls) {
- // Property has the form:
- //
- // "%": "leafTag1|leafTag2|...;nonleafTag1|...;Class1|Class2|...",
- //
- // If there is no data following a semicolon, the semicolon can be
- // omitted.
-
- String formatTags(Iterable<String> tags) {
- if (tags == null) return '';
- return (tags.toList()..sort()).join('|');
- }
-
- List<Class> extensions = extensionPoints[cls];
-
- String leafStr = formatTags(leafTags[cls]);
- String nonleafStr = formatTags(nonleafTags[cls]);
-
- StringBuffer sb = new StringBuffer(leafStr);
- if (nonleafStr != '') {
- sb..write(';')..write(nonleafStr);
- }
-
- String encoding = sb.toString();
-
- if (cls.isNative || encoding != '' || extensions != null) {
- List<jsAst.Literal> parts = <jsAst.Literal>[js.stringPart(encoding)];
- if (extensions != null) {
- parts..add(js.stringPart(';'))
- ..addAll(
- js.joinLiterals(extensions.map((Class cls) => cls.name),
- js.stringPart('|')));
- }
- assert(cls.nativeInfo == null);
- cls.nativeInfo = js.concatenateStrings(parts, addQuotes: true);
- }
- }
- generateClassInfo(jsInterceptorClass);
+ fillNativeInfo(jsInterceptorClass);
for (Class cls in classes) {
if (!cls.isNative || neededClasses.contains(cls)) {
- generateClassInfo(cls);
+ fillNativeInfo(cls);
}
}
}
@@ -367,96 +341,4 @@ class NativeEmitter {
if (Elements.isNativeOrExtendsNative(cls)) return true;
return isSupertypeOfNativeClass(element);
}
-
- /// Returns a JavaScript template that fills the embedded globals referenced
- /// by [interceptorsByTagAccess] and [leafTagsAccess].
- ///
- /// This code must be invoked for every class that has a native info before
- /// the program starts.
- ///
- /// The [infoAccess] parameter must evaluate to an expression that contains
- /// the info (as a JavaScript string).
- ///
- /// The [constructorAccess] parameter must evaluate to an expression that
- /// contains the constructor of the class. The constructor's prototype must
- /// be set up.
- ///
- /// The [subclassReadGenerator] function must evaluate to a JS expression
- /// that returns a reference to the constructor (with evaluated prototype)
- /// of the given JS expression.
- ///
- /// The [interceptorsByTagAccess] must point to the embedded global
- /// [embeddedNames.INTERCEPTORS_BY_TAG] and must be initialized with an empty
- /// JS Object (used as a map).
- ///
- /// Similarly, the [leafTagsAccess] must point to the embedded global
- /// [embeddedNames.LEAF_TAGS] and must be initialized with an empty JS Object
- /// (used as a map).
- ///
- /// Both variables are passed in (instead of creating the access here) to
- /// make sure the caller is aware of these globals.
- jsAst.Statement buildNativeInfoHandler(
- jsAst.Expression infoAccess,
- jsAst.Expression constructorAccess,
- jsAst.Expression subclassReadGenerator(jsAst.Expression subclass),
- jsAst.Expression interceptorsByTagAccess,
- jsAst.Expression leafTagsAccess) {
- jsAst.Expression subclassRead =
- subclassReadGenerator(js('subclasses[i]', []));
- return js.statement('''
- // The native info looks like this:
- //
- // HtmlElement: {
- // "%": "HTMLDivElement|HTMLAnchorElement;HTMLElement;FancyButton"
- //
- // The first two semicolon-separated parts contain dispatch tags, the
- // third contains the JavaScript names for classes.
- //
- // The tags indicate that JavaScript objects with the dispatch tags
- // (usually constructor names) HTMLDivElement, HTMLAnchorElement and
- // HTMLElement all map to the Dart native class named HtmlElement.
- // The first set is for effective leaf nodes in the hierarchy, the
- // second set is non-leaf nodes.
- //
- // The third part contains the JavaScript names of Dart classes that
- // extend the native class. Here, FancyButton extends HtmlElement, so
- // the runtime needs to know that window.HTMLElement.prototype is the
- // prototype that needs to be extended in creating the custom element.
- //
- // The information is used to build tables referenced by
- // getNativeInterceptor and custom element support.
- {
- var nativeSpec = #info.split(";");
- if (nativeSpec[0]) {
- var tags = nativeSpec[0].split("|");
- for (var i = 0; i < tags.length; i++) {
- #interceptorsByTagAccess[tags[i]] = #constructor;
- #leafTagsAccess[tags[i]] = true;
- }
- }
- if (nativeSpec[1]) {
- tags = nativeSpec[1].split("|");
- if (#allowNativesSubclassing) {
- if (nativeSpec[2]) {
- var subclasses = nativeSpec[2].split("|");
- for (var i = 0; i < subclasses.length; i++) {
- var subclass = #subclassRead;
- subclass.#nativeSuperclassTagName = tags[0];
- }
- }
- for (i = 0; i < tags.length; i++) {
- #interceptorsByTagAccess[tags[i]] = #constructor;
- #leafTagsAccess[tags[i]] = false;
- }
- }
- }
- }
- ''', {'info': infoAccess,
- 'constructor': constructorAccess,
- 'subclassRead': subclassRead,
- 'interceptorsByTagAccess': interceptorsByTagAccess,
- 'leafTagsAccess': leafTagsAccess,
- 'nativeSuperclassTagName': embeddedNames.NATIVE_SUPERCLASS_TAG_NAME,
- 'allowNativesSubclassing': true});
- }
-}
+}

Powered by Google App Engine
This is Rietveld 408576698