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

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

Issue 974803002: Defer addStubs to class instantiation time. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 // TODO(ahe): Share these with js_helper.dart. 7 // TODO(ahe): Share these with js_helper.dart.
8 const FUNCTION_INDEX = 0; 8 const FUNCTION_INDEX = 0;
9 const NAME_INDEX = 1; 9 const NAME_INDEX = 1;
10 const CALL_NAME_INDEX = 2; 10 const CALL_NAME_INDEX = 2;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 emitter.generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTED_NAMES); 46 emitter.generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTED_NAMES);
47 jsAst.Expression mangledGlobalNamesAccess = 47 jsAst.Expression mangledGlobalNamesAccess =
48 emitter.generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES); 48 emitter.generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES);
49 jsAst.Expression mangledNamesAccess = 49 jsAst.Expression mangledNamesAccess =
50 emitter.generateEmbeddedGlobalAccess(embeddedNames.MANGLED_NAMES); 50 emitter.generateEmbeddedGlobalAccess(embeddedNames.MANGLED_NAMES);
51 jsAst.Expression librariesAccess = 51 jsAst.Expression librariesAccess =
52 emitter.generateEmbeddedGlobalAccess(embeddedNames.LIBRARIES); 52 emitter.generateEmbeddedGlobalAccess(embeddedNames.LIBRARIES);
53 jsAst.Expression metadataAccess = 53 jsAst.Expression metadataAccess =
54 emitter.generateEmbeddedGlobalAccess(embeddedNames.METADATA); 54 emitter.generateEmbeddedGlobalAccess(embeddedNames.METADATA);
55 55
56
56 jsAst.Statement processClassData = js.statement('''{ 57 jsAst.Statement processClassData = js.statement('''{
58 function finishAddStubsHelper() {
59 var prototype = this;
60 var object;
61 while (prototype.#deferredAction) {
62 if (prototype.hasOwnProperty(#deferredActionString)) {
63 delete prototype.#deferredAction; // Intended to make it slow, too.
64 var properties = Object.keys(prototype);
65 for (var index = 0; index < properties.length; index++) {
66 var property = properties[index];
67 var firstChar = property.charCodeAt(0);
68 var elem;
69 if (property !== "${namer.classDescriptorProperty}" &&
70 property !== "$reflectableField" &&
71 firstChar !== 43 && // 43 is aka "+".
72 firstChar !== 42 && // 42 is aka "*"
73 (elem = prototype[property]) != null &&
74 elem.constructor === Array &&
75 property !== "<>") {
76 addStubs(prototype, elem, property, false, null);
77 }
78 }
79 }
80 prototype = prototype.__proto__;
81 }
82 }
83
57 function processClassData(cls, descriptor, processedClasses) { 84 function processClassData(cls, descriptor, processedClasses) {
58 descriptor = convertToSlowObject(descriptor); // Use a slow object. 85 descriptor = convertToSlowObject(descriptor); // Use a slow object.
59 var previousProperty; 86 var previousProperty;
60 var properties = Object.keys(descriptor); 87 var properties = Object.keys(descriptor);
88 var hasDeferredWork = false;
61 for (var i = 0; i < properties.length; i++) { 89 for (var i = 0; i < properties.length; i++) {
62 var property = properties[i]; 90 var property = properties[i];
63 var firstChar = property.charCodeAt(0); 91 var firstChar = property.charCodeAt(0);
64 if (property === "static") { 92 if (property === "static") {
65 processStatics(#embeddedStatics[cls] = descriptor.static, 93 processStatics(#embeddedStatics[cls] = descriptor.static,
66 processedClasses); 94 processedClasses);
95 delete descriptor.static;
67 } else if (firstChar === 43) { // 43 is aka "+". 96 } else if (firstChar === 43) { // 43 is aka "+".
68 mangledNames[previousProperty] = property.substring(1); 97 mangledNames[previousProperty] = property.substring(1);
69 var flag = descriptor[property]; 98 var flag = descriptor[property];
70 if (flag > 0) 99 if (flag > 0)
71 descriptor[previousProperty].$reflectableField = flag; 100 descriptor[previousProperty].$reflectableField = flag;
72 } else if (firstChar === 42) { // 42 is aka "*" 101 } else if (firstChar === 42) { // 42 is aka "*"
73 descriptor[previousProperty].$defaultValuesField = descriptor[property]; 102 descriptor[previousProperty].$defaultValuesField = descriptor[property];
74 var optionalMethods = descriptor.$methodsWithOptionalArgumentsField; 103 var optionalMethods = descriptor.$methodsWithOptionalArgumentsField;
75 if (!optionalMethods) { 104 if (!optionalMethods) {
76 descriptor.$methodsWithOptionalArgumentsField = optionalMethods={} 105 descriptor.$methodsWithOptionalArgumentsField = optionalMethods={}
77 } 106 }
78 optionalMethods[property] = previousProperty; 107 optionalMethods[property] = previousProperty;
79 } else { 108 } else {
80 var elem = descriptor[property]; 109 var elem = descriptor[property];
81 if (property !== "${namer.classDescriptorProperty}" && 110 if (property !== "${namer.classDescriptorProperty}" &&
82 elem != null && 111 elem != null &&
83 elem.constructor === Array && 112 elem.constructor === Array &&
84 property !== "<>") { 113 property !== "<>") {
85 addStubs(descriptor, elem, property, false, []); 114 if (supportsDirectProtoAccess) {
115 hasDeferredWork = true;
116 } else {
117 addStubs(descriptor, elem, property, false, null);
118 }
86 } else { 119 } else {
87 previousProperty = property; 120 previousProperty = property;
88 } 121 }
89 } 122 }
90 } 123 }
124
125 if (hasDeferredWork)
126 descriptor.#deferredAction = finishAddStubsHelper;
91 127
92 /* The 'fields' are either a constructor function or a 128 /* The 'fields' are either a constructor function or a
93 * string encoding fields, constructor and superclass. Gets the 129 * string encoding fields, constructor and superclass. Gets the
94 * superclass and fields in the format 130 * superclass and fields in the format
95 * 'Super;field1,field2' 131 * 'Super;field1,field2'
96 * from the CLASS_DESCRIPTOR_PROPERTY property on the descriptor. 132 * from the CLASS_DESCRIPTOR_PROPERTY property on the descriptor.
97 */ 133 */
98 var classData = descriptor["${namer.classDescriptorProperty}"], 134 var classData = descriptor["${namer.classDescriptorProperty}"],
99 split, supr, fields = classData; 135 split, supr, fields = classData;
100 136
(...skipping 20 matching lines...) Expand all
121 } 157 }
122 158
123 if (supr) processedClasses.pending[cls] = supr; 159 if (supr) processedClasses.pending[cls] = supr;
124 if (#notInCspMode) { 160 if (#notInCspMode) {
125 processedClasses.combinedConstructorFunction += defineClass(cls, fields); 161 processedClasses.combinedConstructorFunction += defineClass(cls, fields);
126 processedClasses.constructorsList.push(cls); 162 processedClasses.constructorsList.push(cls);
127 } 163 }
128 processedClasses.collected[cls] = [globalObject, descriptor]; 164 processedClasses.collected[cls] = [globalObject, descriptor];
129 classes.push(cls); 165 classes.push(cls);
130 } 166 }
131 }''', {'embeddedStatics': staticsAccess, 167 }''', {'deferredAction': namer.deferredAction,
168 'deferredActionString': js.string(namer.deferredAction),
169 'embeddedStatics': staticsAccess,
132 'hasRetainedMetadata': backend.hasRetainedMetadata, 170 'hasRetainedMetadata': backend.hasRetainedMetadata,
133 'metadata': metadataAccess, 171 'metadata': metadataAccess,
134 'notInCspMode': !compiler.useContentSecurityPolicy}); 172 'notInCspMode': !compiler.useContentSecurityPolicy});
135 173
136 // TODO(zarah): Remove empty else branches in output when if(#hole) is false. 174 // TODO(zarah): Remove empty else branches in output when if(#hole) is false.
137 jsAst.Statement processStatics = js.statement(''' 175 jsAst.Statement processStatics = js.statement('''
138 function processStatics(descriptor, processedClasses) { 176 function processStatics(descriptor, processedClasses) {
139 var properties = Object.keys(descriptor); 177 var properties = Object.keys(descriptor);
140 for (var i = 0; i < properties.length; i++) { 178 for (var i = 0; i < properties.length; i++) {
141 var property = properties[i]; 179 var property = properties[i];
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 function addStubs(descriptor, array, name, isStatic, functions) { 226 function addStubs(descriptor, array, name, isStatic, functions) {
189 var index = $FUNCTION_INDEX, alias = array[index], f; 227 var index = $FUNCTION_INDEX, alias = array[index], f;
190 if (typeof alias == "string") { 228 if (typeof alias == "string") {
191 f = array[++index]; 229 f = array[++index];
192 } else { 230 } else {
193 f = alias; 231 f = alias;
194 alias = name; 232 alias = name;
195 } 233 }
196 var funcs = [descriptor[name] = descriptor[alias] = f]; 234 var funcs = [descriptor[name] = descriptor[alias] = f];
197 f.\$stubName = name; 235 f.\$stubName = name;
198 functions.push(name); 236 if (isStatic) functions.push(name);
199 for (; index < array.length; index += 2) { 237 for (; index < array.length; index += 2) {
200 f = array[index + 1]; 238 f = array[index + 1];
201 if (typeof f != "function") break; 239 if (typeof f != "function") break;
202 f.\$stubName = ${readString("array", "index + 2")}; 240 f.\$stubName = ${readString("array", "index + 2")};
203 funcs.push(f); 241 funcs.push(f);
204 if (f.\$stubName) { 242 if (f.\$stubName) {
205 descriptor[f.\$stubName] = f; 243 descriptor[f.\$stubName] = f;
206 functions.push(f.\$stubName); 244 if (isStatic) functions.push(f.\$stubName);
207 } 245 }
208 } 246 }
209 index++; 247 index++;
210 for (var i = 0; i < funcs.length; index++, i++) { 248 for (var i = 0; i < funcs.length; index++, i++) {
211 funcs[i].\$callName = ${readString("array", "index")}; 249 funcs[i].\$callName = ${readString("array", "index")};
212 } 250 }
213 var getterStubName = ${readString("array", "index")}; 251 var getterStubName = ${readString("array", "index")};
214 array = array.slice(++index); 252 array = array.slice(++index);
215 var requiredParameterInfo = ${readInt("array", "0")}; 253 var requiredParameterInfo = ${readInt("array", "0")};
216 var requiredParameterCount = requiredParameterInfo >> 1; 254 var requiredParameterCount = requiredParameterInfo >> 1;
217 var isAccessor = (requiredParameterInfo & 1) === 1; 255 var isAccessor = (requiredParameterInfo & 1) === 1;
218 var isSetter = requiredParameterInfo === 3; 256 var isSetter = requiredParameterInfo === 3;
219 var isGetter = requiredParameterInfo === 1; 257 var isGetter = requiredParameterInfo === 1;
220 var optionalParameterInfo = ${readInt("array", "1")}; 258 var optionalParameterInfo = ${readInt("array", "1")};
221 var optionalParameterCount = optionalParameterInfo >> 1; 259 var optionalParameterCount = optionalParameterInfo >> 1;
222 var optionalParametersAreNamed = (optionalParameterInfo & 1) === 1; 260 var optionalParametersAreNamed = (optionalParameterInfo & 1) === 1;
223 var isIntercepted = 261 var isIntercepted =
224 requiredParameterCount + optionalParameterCount != funcs[0].length; 262 requiredParameterCount + optionalParameterCount != funcs[0].length;
225 var functionTypeIndex = ${readFunctionType("array", "2")}; 263 var functionTypeIndex = ${readFunctionType("array", "2")};
226 var unmangledNameIndex = $unmangledNameIndex; 264 var unmangledNameIndex = $unmangledNameIndex;
227 265
228 if (getterStubName) { 266 if (getterStubName) {
229 f = tearOff(funcs, array, isStatic, name, isIntercepted); 267 f = tearOff(funcs, array, isStatic, name, isIntercepted);
230 descriptor[name].\$getter = f; 268 descriptor[name].\$getter = f;
231 f.\$getterStub = true; 269 f.\$getterStub = true;
232 // Used to create an isolate using spawnFunction. 270 // Used to create an isolate using spawnFunction.
233 if (isStatic) #globalFunctions[name] = f; 271 if (isStatic) {
272 #globalFunctions[name] = f;
273 functions.push(getterStubName);
274 }
234 descriptor[getterStubName] = f; 275 descriptor[getterStubName] = f;
235 funcs.push(f); 276 funcs.push(f);
236 if (getterStubName) functions.push(getterStubName);
237 f.\$stubName = getterStubName; 277 f.\$stubName = getterStubName;
238 f.\$callName = null; 278 f.\$callName = null;
239 // Update the interceptedNames map (which only exists if `invokeOn` was 279 // Update the interceptedNames map (which only exists if `invokeOn` was
240 // enabled). 280 // enabled).
241 if (#enabledInvokeOn) 281 if (#enabledInvokeOn)
242 if (isIntercepted) #interceptedNames[getterStubName] = 1; 282 if (isIntercepted) #interceptedNames[getterStubName] = 1;
243 } 283 }
244 284
245 if (#usesMangledNames) { 285 if (#usesMangledNames) {
246 var isReflectable = array.length > unmangledNameIndex; 286 var isReflectable = array.length > unmangledNameIndex;
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 (function() { 522 (function() {
483 var result = $array[$index]; 523 var result = $array[$index];
484 if ($check) { 524 if ($check) {
485 throw new Error( 525 throw new Error(
486 name + ": expected value of type \'$type\' at index " + ($index) + 526 name + ": expected value of type \'$type\' at index " + ($index) +
487 " but got " + (typeof result)); 527 " but got " + (typeof result));
488 } 528 }
489 return result; 529 return result;
490 })()'''; 530 })()''';
491 } 531 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698