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

Side by Side Diff: pkg/compiler/lib/src/js_emitter/native_generator.dart

Issue 1215463006: Move nativeInfo encoding into NativeGenerator. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address comments and fix null-pointer error. 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of dart2js.js_emitter; 5 part of dart2js.js_emitter;
6 6
7 class NativeGenerator { 7 class NativeGenerator {
8 8
9 static bool needsIsolateAffinityTagInitialization(JavaScriptBackend backend) { 9 static bool needsIsolateAffinityTagInitialization(JavaScriptBackend backend) {
10 return backend.needToInitializeIsolateAffinityTag; 10 return backend.needToInitializeIsolateAffinityTag;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 'convertToFastObject': convertToFastObject, 66 'convertToFastObject': convertToFastObject,
67 'getIsolateTag': getIsolateTagAccess, 67 'getIsolateTag': getIsolateTagAccess,
68 'isolateTag': isolateTagAccess, 68 'isolateTag': isolateTagAccess,
69 'dispatchPropertyName': dispatchPropertyNameAccess}); 69 'dispatchPropertyName': dispatchPropertyNameAccess});
70 } 70 }
71 71
72 static String generateIsolateTagRoot() { 72 static String generateIsolateTagRoot() {
73 // TODO(sra): MD5 of contributing source code or URIs? 73 // TODO(sra): MD5 of contributing source code or URIs?
74 return 'ZxYxX'; 74 return 'ZxYxX';
75 } 75 }
76
77 /// Encodes the collected native information so that it can be treated by
78 /// the native info-handler below.
79 ///
80 /// The encoded information has the form:
81 ///
82 // "%": "leafTag1|leafTag2|...;nonleafTag1|...;Class1|Class2|...",
83 //
84 // If there is no data following a semicolon, the semicolon can be omitted.
85 static jsAst.Expression encodeNativeInfo(Class cls) {
86 List<String> leafTags = cls.nativeLeafTags;
87 List<String> nonLeafTags = cls.nativeNonLeafTags;
88 List<Class> extensions = cls.nativeExtensions;
89
90 String formatTags(Iterable<String> tags) {
91 if (tags == null) return '';
92 return (tags.toList()
93 ..sort()).join('|');
94 }
95
96 String leafStr = formatTags(leafTags);
97 String nonLeafStr = formatTags(nonLeafTags);
98
99 StringBuffer sb = new StringBuffer(leafStr);
100 if (nonLeafStr != '') {
101 sb
102 ..write(';')
103 ..write(nonLeafStr);
104 }
105
106 String encoding = sb.toString();
107
108 if (cls.isNative || encoding != '' || extensions != null) {
109 List<jsAst.Literal> parts = <jsAst.Literal>[js.stringPart(encoding)];
110 if (extensions != null) {
111 parts
112 ..add(js.stringPart(';'))
113 ..addAll(
114 js.joinLiterals(extensions.map((Class cls) => cls.name),
115 js.stringPart('|')));
116 }
117 return jsAst.concatenateStrings(parts, addQuotes: true);
118 }
119 return null;
120 }
121
122 /// Returns a JavaScript template that fills the embedded globals referenced
123 /// by [interceptorsByTagAccess] and [leafTagsAccess].
124 ///
125 /// This code must be invoked for every class that has a native info before
126 /// the program starts.
127 ///
128 /// The [infoAccess] parameter must evaluate to an expression that contains
129 /// the info (as a JavaScript string).
130 ///
131 /// The [constructorAccess] parameter must evaluate to an expression that
132 /// contains the constructor of the class. The constructor's prototype must
133 /// be set up.
134 ///
135 /// The [subclassReadGenerator] function must evaluate to a JS expression
136 /// that returns a reference to the constructor (with evaluated prototype)
137 /// of the given JS expression.
138 ///
139 /// The [interceptorsByTagAccess] must point to the embedded global
140 /// [embeddedNames.INTERCEPTORS_BY_TAG] and must be initialized with an empty
141 /// JS Object (used as a map).
142 ///
143 /// Similarly, the [leafTagsAccess] must point to the embedded global
144 /// [embeddedNames.LEAF_TAGS] and must be initialized with an empty JS Object
145 /// (used as a map).
146 ///
147 /// Both variables are passed in (instead of creating the access here) to
148 /// make sure the caller is aware of these globals.
149 static jsAst.Statement buildNativeInfoHandler(
150 jsAst.Expression infoAccess,
151 jsAst.Expression constructorAccess,
152 jsAst.Expression subclassReadGenerator(jsAst.Expression subclass),
153 jsAst.Expression interceptorsByTagAccess,
154 jsAst.Expression leafTagsAccess) {
155 jsAst.Expression subclassRead =
156 subclassReadGenerator(js('subclasses[i]', []));
157 return js.statement('''
158 // The native info looks like this:
159 //
160 // HtmlElement: {
161 // "%": "HTMLDivElement|HTMLAnchorElement;HTMLElement;FancyButton"
162 //
163 // The first two semicolon-separated parts contain dispatch tags, the
164 // third contains the JavaScript names for classes.
165 //
166 // The tags indicate that JavaScript objects with the dispatch tags
167 // (usually constructor names) HTMLDivElement, HTMLAnchorElement and
168 // HTMLElement all map to the Dart native class named HtmlElement.
169 // The first set is for effective leaf nodes in the hierarchy, the
170 // second set is non-leaf nodes.
171 //
172 // The third part contains the JavaScript names of Dart classes that
173 // extend the native class. Here, FancyButton extends HtmlElement, so
174 // the runtime needs to know that window.HTMLElement.prototype is the
175 // prototype that needs to be extended in creating the custom element.
176 //
177 // The information is used to build tables referenced by
178 // getNativeInterceptor and custom element support.
179 {
180 var nativeSpec = #info.split(";");
181 if (nativeSpec[0]) {
182 var tags = nativeSpec[0].split("|");
183 for (var i = 0; i < tags.length; i++) {
184 #interceptorsByTagAccess[tags[i]] = #constructor;
185 #leafTagsAccess[tags[i]] = true;
186 }
187 }
188 if (nativeSpec[1]) {
189 tags = nativeSpec[1].split("|");
190 if (#allowNativesSubclassing) {
191 if (nativeSpec[2]) {
192 var subclasses = nativeSpec[2].split("|");
193 for (var i = 0; i < subclasses.length; i++) {
194 var subclass = #subclassRead;
195 subclass.#nativeSuperclassTagName = tags[0];
196 }
197 }
198 for (i = 0; i < tags.length; i++) {
199 #interceptorsByTagAccess[tags[i]] = #constructor;
200 #leafTagsAccess[tags[i]] = false;
201 }
202 }
203 }
204 }
205 ''', {'info': infoAccess,
206 'constructor': constructorAccess,
207 'subclassRead': subclassRead,
208 'interceptorsByTagAccess': interceptorsByTagAccess,
209 'leafTagsAccess': leafTagsAccess,
210 'nativeSuperclassTagName': embeddedNames.NATIVE_SUPERCLASS_TAG_NAME,
211 'allowNativesSubclassing': true});
212 }
76 } 213 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/native_emitter.dart ('k') | pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698