OLD | NEW |
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 | 7 |
8 class OldEmitter implements Emitter { | 8 class OldEmitter implements Emitter { |
9 final Compiler compiler; | 9 final Compiler compiler; |
10 final CodeEmitterTask task; | 10 final CodeEmitterTask task; |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 accessors.push(property + "\$reflectable(" + fn + ");\\n"); | 245 accessors.push(property + "\$reflectable(" + fn + ");\\n"); |
246 else | 246 else |
247 accessors.push(property + fn + ";\\n"); | 247 accessors.push(property + fn + ";\\n"); |
248 } | 248 } |
249 } | 249 } |
250 | 250 |
251 return field; | 251 return field; |
252 }'''); | 252 }'''); |
253 } | 253 } |
254 | 254 |
255 List get defineClassFunction { | 255 List<jsAst.Node> get defineClassFunction { |
256 // First the class name, then the field names in an array and the members | 256 // First the class name, then the field names in an array and the members |
257 // (inside an Object literal). | 257 // (inside an Object literal). |
258 // The caller can also pass in the constructor as a function if needed. | 258 // The caller can also pass in the constructor as a function if needed. |
259 // | 259 // |
260 // Example: | 260 // Example: |
261 // defineClass("A", ["x", "y"], { | 261 // defineClass("A", ["x", "y"], { |
262 // foo$1: function(y) { | 262 // foo$1: function(y) { |
263 // print(this.x + y); | 263 // print(this.x + y); |
264 // }, | 264 // }, |
265 // bar$2: function(t, v) { | 265 // bar$2: function(t, v) { |
266 // this.x = t - v; | 266 // this.x = t - v; |
267 // }, | 267 // }, |
268 // }); | 268 // }); |
269 | 269 |
270 var defineClass = js('''function(name, cls, fields) { | 270 bool hasIsolateSupport = compiler.hasIsolateSupport; |
| 271 String fieldNamesProperty = r"$__fields__"; |
| 272 |
| 273 jsAst.Expression defineClass = js('''function(name, cls, fields) { |
271 var accessors = []; | 274 var accessors = []; |
272 | 275 |
273 var str = "function " + cls + "("; | 276 var str = "function " + cls + "("; |
274 var body = ""; | 277 var body = ""; |
| 278 if (#hasIsolateSupport) { var fieldNames = ""; } |
275 | 279 |
276 for (var i = 0; i < fields.length; i++) { | 280 for (var i = 0; i < fields.length; i++) { |
277 if(i != 0) str += ", "; | 281 if(i != 0) str += ", "; |
278 | 282 |
279 var field = generateAccessor(fields[i], accessors, cls); | 283 var field = generateAccessor(fields[i], accessors, cls); |
| 284 if (#hasIsolateSupport) { fieldNames += "'" + field + "',"; } |
280 var parameter = "parameter_" + field; | 285 var parameter = "parameter_" + field; |
281 str += parameter; | 286 str += parameter; |
282 body += ("this." + field + " = " + parameter + ";\\n"); | 287 body += ("this." + field + " = " + parameter + ";\\n"); |
283 } | 288 } |
284 str += ") {\\n" + body + "}\\n"; | 289 str += ") {\\n" + body + "}\\n"; |
285 str += cls + ".builtin\$cls=\\"" + name + "\\";\\n"; | 290 str += cls + ".builtin\$cls=\\"" + name + "\\";\\n"; |
286 str += "\$desc=\$collectedClasses." + cls + ";\\n"; | 291 str += "\$desc=\$collectedClasses." + cls + ";\\n"; |
287 str += "if(\$desc instanceof Array) \$desc = \$desc[1];\\n"; | 292 str += "if(\$desc instanceof Array) \$desc = \$desc[1];\\n"; |
288 str += cls + ".prototype = \$desc;\\n"; | 293 str += cls + ".prototype = \$desc;\\n"; |
289 if (typeof defineClass.name != "string") { | 294 if (typeof defineClass.name != "string") { |
290 str += cls + ".name=\\"" + cls + "\\";\\n"; | 295 str += cls + ".name=\\"" + cls + "\\";\\n"; |
291 } | 296 } |
| 297 if (#hasIsolateSupport) { |
| 298 str += cls + ".$fieldNamesProperty=[" + fieldNames + "];\\n"; |
| 299 } |
292 str += accessors.join(""); | 300 str += accessors.join(""); |
293 | 301 |
294 return str; | 302 return str; |
295 }'''); | 303 }''', { 'hasIsolateSupport': hasIsolateSupport }); |
| 304 |
296 // Declare a function called "generateAccessor". This is used in | 305 // Declare a function called "generateAccessor". This is used in |
297 // defineClassFunction (it's a local declaration in init()). | 306 // defineClassFunction (it's a local declaration in init()). |
298 return [ | 307 List result = <jsAst.Node>[ |
299 generateAccessorFunction, | 308 generateAccessorFunction, |
300 js('$generateAccessorHolder = generateAccessor'), | 309 js('$generateAccessorHolder = generateAccessor'), |
301 new jsAst.FunctionDeclaration( | 310 new jsAst.FunctionDeclaration( |
302 new jsAst.VariableDeclaration('defineClass'), defineClass) ]; | 311 new jsAst.VariableDeclaration('defineClass'), defineClass) ]; |
| 312 |
| 313 if (hasIsolateSupport) { |
| 314 jsAst.Expression classIdExtractorAccess = |
| 315 generateEmbeddedGlobalAccess(embeddedNames.CLASS_ID_EXTRACTOR); |
| 316 var classIdExtractorAssignment = |
| 317 js('# = function(o) { return o.constructor.name; }', |
| 318 classIdExtractorAccess); |
| 319 |
| 320 jsAst.Expression classFieldsExtractorAccess = |
| 321 generateEmbeddedGlobalAccess(embeddedNames.CLASS_FIELDS_EXTRACTOR); |
| 322 var classFieldsExtractorAssignment = js(''' |
| 323 # = function(o) { |
| 324 var fieldNames = o.constructor.$fieldNamesProperty; |
| 325 if (!fieldNames) return []; // TODO(floitsch): do something else here. |
| 326 var result = []; |
| 327 result.length = fieldNames.length; |
| 328 for (var i = 0; i < fieldNames.length; i++) { |
| 329 result[i] = o[fieldNames[i]]; |
| 330 } |
| 331 return result; |
| 332 }''', classFieldsExtractorAccess); |
| 333 |
| 334 jsAst.Expression instanceFromClassIdAccess = |
| 335 generateEmbeddedGlobalAccess(embeddedNames.INSTANCE_FROM_CLASS_ID); |
| 336 jsAst.Expression allClassesAccess = |
| 337 generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES); |
| 338 var instanceFromClassIdAssignment = |
| 339 js('# = function(name) { return new #[name](); }', |
| 340 [instanceFromClassIdAccess, allClassesAccess]); |
| 341 |
| 342 jsAst.Expression initializeEmptyInstanceAccess = |
| 343 generateEmbeddedGlobalAccess(embeddedNames.INITIALIZE_EMPTY_INSTANCE); |
| 344 var initializeEmptyInstanceAssignment = js(''' |
| 345 # = function(name, o, fields) { |
| 346 #[name].apply(o, fields); |
| 347 return o; |
| 348 }''', [ initializeEmptyInstanceAccess, allClassesAccess ]); |
| 349 |
| 350 result.addAll([classIdExtractorAssignment, |
| 351 classFieldsExtractorAssignment, |
| 352 instanceFromClassIdAssignment, |
| 353 initializeEmptyInstanceAssignment]); |
| 354 } |
| 355 return result; |
303 } | 356 } |
304 | 357 |
305 /** Needs defineClass to be defined. */ | 358 /** Needs defineClass to be defined. */ |
306 jsAst.Expression buildInheritFrom() { | 359 jsAst.Expression buildInheritFrom() { |
307 jsAst.Expression result = js(r''' | 360 jsAst.Expression result = js(r''' |
308 function() { | 361 function() { |
309 function tmp() {} | 362 function tmp() {} |
310 var hasOwnProperty = Object.prototype.hasOwnProperty; | 363 var hasOwnProperty = Object.prototype.hasOwnProperty; |
311 return function (constructor, superConstructor) { | 364 return function (constructor, superConstructor) { |
312 tmp.prototype = superConstructor.prototype; | 365 tmp.prototype = superConstructor.prototype; |
(...skipping 1696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2009 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 2062 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
2010 if (element.isInstanceMember) { | 2063 if (element.isInstanceMember) { |
2011 cachedClassBuilders.remove(element.enclosingClass); | 2064 cachedClassBuilders.remove(element.enclosingClass); |
2012 | 2065 |
2013 nativeEmitter.cachedBuilders.remove(element.enclosingClass); | 2066 nativeEmitter.cachedBuilders.remove(element.enclosingClass); |
2014 | 2067 |
2015 } | 2068 } |
2016 } | 2069 } |
2017 } | 2070 } |
2018 } | 2071 } |
OLD | NEW |