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

Side by Side Diff: lib/compiler/implementation/emitter.dart

Issue 10052020: Reduce size by emitting $.foo instead of Isolate.prototype.foo. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: rebase Created 8 years, 8 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
« no previous file with comments | « no previous file | lib/compiler/implementation/namer.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 /** 5 /**
6 * A function element that represents a closure call. The signature is copied 6 * A function element that represents a closure call. The signature is copied
7 * from the given element. 7 * from the given element.
8 */ 8 */
9 class ClosureInvocationElement extends FunctionElement { 9 class ClosureInvocationElement extends FunctionElement {
10 ClosureInvocationElement(SourceString name, 10 ClosureInvocationElement(SourceString name,
(...skipping 20 matching lines...) Expand all
31 child.prototype = new tmp(); 31 child.prototype = new tmp();
32 child.prototype.constructor = child; 32 child.prototype.constructor = child;
33 } 33 }
34 }'''; 34 }''';
35 35
36 bool addedInheritFunction = false; 36 bool addedInheritFunction = false;
37 final Namer namer; 37 final Namer namer;
38 final NativeEmitter nativeEmitter; 38 final NativeEmitter nativeEmitter;
39 Set<ClassElement> generatedClasses; 39 Set<ClassElement> generatedClasses;
40 StringBuffer mainBuffer; 40 StringBuffer mainBuffer;
41 String isolatePrototype;
41 42
42 CodeEmitterTask(Compiler compiler) 43 CodeEmitterTask(Compiler compiler)
43 : namer = compiler.namer, 44 : namer = compiler.namer,
44 nativeEmitter = new NativeEmitter(compiler), 45 nativeEmitter = new NativeEmitter(compiler),
45 generatedClasses = new Set<ClassElement>(), 46 generatedClasses = new Set<ClassElement>(),
46 mainBuffer = new StringBuffer(), 47 mainBuffer = new StringBuffer(),
47 super(compiler); 48 super(compiler);
48 49
49 String get name() => 'CodeEmitter'; 50 String get name() => 'CodeEmitter';
50 51
51 String get inheritsName() => '${namer.ISOLATE}.\$inherits'; 52 String get inheritsName() => '${namer.ISOLATE}.\$inherits';
52 53
53 String get objectClassName() {
54 ClassElement objectClass =
55 compiler.coreLibrary.find(const SourceString('Object'));
56 return namer.isolatePropertyAccess(objectClass);
57 }
58
59 void addInheritFunctionIfNecessary() { 54 void addInheritFunctionIfNecessary() {
60 if (addedInheritFunction) return; 55 if (addedInheritFunction) return;
61 addedInheritFunction = true; 56 addedInheritFunction = true;
62 mainBuffer.add('$inheritsName = '); 57 mainBuffer.add('$inheritsName = ');
63 mainBuffer.add(INHERIT_FUNCTION); 58 mainBuffer.add(INHERIT_FUNCTION);
64 mainBuffer.add(';\n'); 59 mainBuffer.add(';\n');
65 } 60 }
66 61
67 void addParameterStub(FunctionElement member, 62 void addParameterStub(FunctionElement member,
68 String attachTo(String invocationName), 63 String attachTo(String invocationName),
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 244
250 classElement.forEachInstanceField(generateFieldInit, 245 classElement.forEachInstanceField(generateFieldInit,
251 includeBackendMembers: true, 246 includeBackendMembers: true,
252 includeSuperMembers: true); 247 includeSuperMembers: true);
253 } 248 }
254 249
255 void emitInherits(ClassElement cls, StringBuffer buffer) { 250 void emitInherits(ClassElement cls, StringBuffer buffer) {
256 ClassElement superclass = cls.superclass; 251 ClassElement superclass = cls.superclass;
257 if (superclass !== null) { 252 if (superclass !== null) {
258 addInheritFunctionIfNecessary(); 253 addInheritFunctionIfNecessary();
259 String className = namer.isolatePropertyAccess(cls); 254 String className = namer.getName(cls);
260 String superName = namer.isolatePropertyAccess(superclass); 255 String superName = namer.getName(superclass);
261 buffer.add('${inheritsName}($className, $superName);\n'); 256 buffer.add('${inheritsName}($isolatePrototype.$className, ');
257 buffer.add('$isolatePrototype.$superName);\n');
262 } 258 }
263 } 259 }
264 260
265 void ensureGenerated(ClassElement classElement, StringBuffer buffer) { 261 void ensureGenerated(ClassElement classElement, StringBuffer buffer) {
266 if (classElement == null) return; 262 if (classElement == null) return;
267 if (generatedClasses.contains(classElement)) return; 263 if (generatedClasses.contains(classElement)) return;
268 generatedClasses.add(classElement); 264 generatedClasses.add(classElement);
269 generateClass(classElement, buffer); 265 generateClass(classElement, buffer);
270 } 266 }
271 267
272 void generateClass(ClassElement classElement, StringBuffer buffer) { 268 void generateClass(ClassElement classElement, StringBuffer buffer) {
273 ensureGenerated(classElement.superclass, buffer); 269 ensureGenerated(classElement.superclass, buffer);
274 270
275 if (classElement.isNative()) { 271 if (classElement.isNative()) {
276 nativeEmitter.generateNativeClass(classElement); 272 nativeEmitter.generateNativeClass(classElement);
277 return; 273 return;
278 } else { 274 } else {
279 // TODO(ngeoffray): Instead of switching between buffer, we 275 // TODO(ngeoffray): Instead of switching between buffer, we
280 // should create code sections, and decide where to emit them at 276 // should create code sections, and decide where to emit them at
281 // the end. 277 // the end.
282 buffer = mainBuffer; 278 buffer = mainBuffer;
283 } 279 }
284 280
285 String className = namer.isolatePropertyAccess(classElement); 281 String className = '${isolatePrototype}.${namer.getName(classElement)}';
286 String constructorName = namer.safeName(classElement.name.slowToString()); 282 String constructorName = namer.safeName(classElement.name.slowToString());
287 buffer.add('$className = function $constructorName('); 283 buffer.add('$className = function $constructorName(');
288 StringBuffer bodyBuffer = new StringBuffer(); 284 StringBuffer bodyBuffer = new StringBuffer();
289 // If the class is never instantiated we still need to set it up for 285 // If the class is never instantiated we still need to set it up for
290 // inheritance purposes, but we can leave its JavaScript constructor empty. 286 // inheritance purposes, but we can leave its JavaScript constructor empty.
291 if (compiler.universe.instantiatedClasses.contains(classElement)) { 287 if (compiler.universe.instantiatedClasses.contains(classElement)) {
292 generateFieldInits(classElement, buffer, bodyBuffer); 288 generateFieldInits(classElement, buffer, bodyBuffer);
293 } 289 }
294 buffer.add(') {\n'); 290 buffer.add(') {\n');
295 buffer.add(bodyBuffer); 291 buffer.add(bodyBuffer);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 for (ClassElement element in compiler.universe.instantiatedClasses) { 347 for (ClassElement element in compiler.universe.instantiatedClasses) {
352 ensureGenerated(element, buffer); 348 ensureGenerated(element, buffer);
353 } 349 }
354 } 350 }
355 351
356 void emitStaticFunctionsWithNamer(StringBuffer buffer, 352 void emitStaticFunctionsWithNamer(StringBuffer buffer,
357 Map<Element, String> generatedCode, 353 Map<Element, String> generatedCode,
358 String functionNamer(Element element)) { 354 String functionNamer(Element element)) {
359 generatedCode.forEach((Element element, String codeBlock) { 355 generatedCode.forEach((Element element, String codeBlock) {
360 if (!element.isInstanceMember()) { 356 if (!element.isInstanceMember()) {
361 buffer.add('${functionNamer(element)} = '); 357 buffer.add(isolatePrototype);
358 buffer.add('.${functionNamer(element)} = ');
362 buffer.add(codeBlock); 359 buffer.add(codeBlock);
363 buffer.add(';\n\n'); 360 buffer.add(';\n\n');
364 } 361 }
365 }); 362 });
366 } 363 }
367 364
368 void emitStaticFunctions(StringBuffer buffer) { 365 void emitStaticFunctions(StringBuffer buffer) {
369 emitStaticFunctionsWithNamer(buffer, 366 emitStaticFunctionsWithNamer(buffer,
370 compiler.universe.generatedCode, 367 compiler.universe.generatedCode,
371 namer.isolatePropertyAccess); 368 namer.getName);
372 emitStaticFunctionsWithNamer(buffer, 369 emitStaticFunctionsWithNamer(buffer,
373 compiler.universe.generatedBailoutCode, 370 compiler.universe.generatedBailoutCode,
374 namer.isolateBailoutPropertyAccess); 371 namer.getBailoutName);
375 } 372 }
376 373
377 void emitStaticFunctionGetters(StringBuffer buffer) { 374 void emitStaticFunctionGetters(StringBuffer buffer) {
378 Set<FunctionElement> functionsNeedingGetter = 375 Set<FunctionElement> functionsNeedingGetter =
379 compiler.universe.staticFunctionsNeedingGetter; 376 compiler.universe.staticFunctionsNeedingGetter;
380 for (FunctionElement element in functionsNeedingGetter) { 377 for (FunctionElement element in functionsNeedingGetter) {
381 // The static function does not have the correct name. Since 378 // The static function does not have the correct name. Since
382 // [addParameterStubs] use the name to create its stubs we simply 379 // [addParameterStubs] use the name to create its stubs we simply
383 // create a fake element with the correct name. 380 // create a fake element with the correct name.
384 // Note: the callElement will not have any enclosingElement. 381 // Note: the callElement will not have any enclosingElement.
385 FunctionElement callElement = 382 FunctionElement callElement =
386 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, element); 383 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, element);
387 String staticName = namer.isolatePropertyAccess(element); 384 String staticName = namer.getName(element);
388 int parameterCount = element.parameterCount(compiler); 385 int parameterCount = element.parameterCount(compiler);
389 String invocationName = 386 String invocationName =
390 namer.instanceMethodName(element.getLibrary(), callElement.name, 387 namer.instanceMethodName(element.getLibrary(), callElement.name,
391 parameterCount); 388 parameterCount);
392 buffer.add("$staticName.$invocationName = $staticName;\n"); 389 buffer.add(isolatePrototype);
393 addParameterStubs(callElement, (name) => '$staticName.$name', buffer); 390 buffer.add(".$staticName.$invocationName = ");
391 buffer.add(isolatePrototype);
392 buffer.add(".$staticName;\n");
393 addParameterStubs(callElement,
394 (name) => '$isolatePrototype.$staticName.$name',
395 buffer);
394 } 396 }
395 } 397 }
396 398
397 void emitDynamicFunctionGetter(StringBuffer buffer, 399 void emitDynamicFunctionGetter(StringBuffer buffer,
398 String attachTo(String invocationName), 400 String attachTo(String invocationName),
399 FunctionElement member) { 401 FunctionElement member) {
400 // For every method that has the same name as a property-get we create a 402 // For every method that has the same name as a property-get we create a
401 // getter that returns a bound closure. Say we have a class 'A' with method 403 // getter that returns a bound closure. Say we have a class 'A' with method
402 // 'foo' and somewhere in the code there is a dynamic property get of 404 // 'foo' and somewhere in the code there is a dynamic property get of
403 // 'foo'. Then we generate the following code (in pseudo Dart): 405 // 'foo'. Then we generate the following code (in pseudo Dart):
404 // 406 //
405 // class A { 407 // class A {
406 // foo(x, y, z) { ... } // Original function. 408 // foo(x, y, z) { ... } // Original function.
407 // get foo() { return new BoundClosure499(this); } 409 // get foo() { return new BoundClosure499(this); }
408 // } 410 // }
409 // class BoundClosure499 extends Closure { 411 // class BoundClosure499 extends Closure {
410 // var self; 412 // var self;
411 // BoundClosure499(this.self); 413 // BoundClosure499(this.self);
412 // $call3(x, y, z) { return self.foo(x, y, z); } 414 // $call3(x, y, z) { return self.foo(x, y, z); }
413 // } 415 // }
414 416
415 // TODO(floitsch): share the closure classes with other classes 417 // TODO(floitsch): share the closure classes with other classes
416 // if they share methods with the same signature. 418 // if they share methods with the same signature.
417 419
418 // The closure class. 420 // The closure class.
419 SourceString name = const SourceString("BoundClosure"); 421 SourceString name = const SourceString("BoundClosure");
420 ClassElement closureClassElement = 422 ClassElement closureClassElement =
421 new ClosureClassElement(compiler, member.getCompilationUnit()); 423 new ClosureClassElement(compiler, member.getCompilationUnit());
422 String isolateAccess = namer.isolatePropertyAccess(closureClassElement); 424 String mangledName = namer.getName(closureClassElement);
423 ensureGenerated(closureClassElement.superclass, buffer); 425 ensureGenerated(closureClassElement.superclass, buffer);
424 426
425 // Define the constructor with a name so that Object.toString can 427 // Define the constructor with a name so that Object.toString can
426 // find the class name of the closure class. 428 // find the class name of the closure class.
427 buffer.add("$isolateAccess = function $name(self) "); 429 buffer.add(isolatePrototype);
430 buffer.add(".$mangledName = function $name(self) ");
428 buffer.add("{ this.self = self; };\n"); 431 buffer.add("{ this.self = self; };\n");
429 emitInherits(closureClassElement, buffer); 432 emitInherits(closureClassElement, buffer);
430 433
431 String prototype = "$isolateAccess.prototype"; 434 String prototype = "$isolatePrototype.$mangledName.prototype";
432 435
433 // Now add the methods on the closure class. The instance method does not 436 // Now add the methods on the closure class. The instance method does not
434 // have the correct name. Since [addParameterStubs] use the name to create 437 // have the correct name. Since [addParameterStubs] use the name to create
435 // its stubs we simply create a fake element with the correct name. 438 // its stubs we simply create a fake element with the correct name.
436 // Note: the callElement will not have any enclosingElement. 439 // Note: the callElement will not have any enclosingElement.
437 FunctionElement callElement = 440 FunctionElement callElement =
438 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, member); 441 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, member);
439 442
440 int parameterCount = member.parameterCount(compiler); 443 int parameterCount = member.parameterCount(compiler);
441 String invocationName = 444 String invocationName =
442 namer.instanceMethodName(member.getLibrary(), 445 namer.instanceMethodName(member.getLibrary(),
443 callElement.name, parameterCount); 446 callElement.name, parameterCount);
444 String targetName = namer.instanceMethodName(member.getLibrary(), 447 String targetName = namer.instanceMethodName(member.getLibrary(),
445 member.name, parameterCount); 448 member.name, parameterCount);
446 List<String> arguments = new List<String>(parameterCount); 449 List<String> arguments = new List<String>(parameterCount);
447 for (int i = 0; i < parameterCount; i++) { 450 for (int i = 0; i < parameterCount; i++) {
448 arguments[i] = "arg$i"; 451 arguments[i] = "arg$i";
449 } 452 }
450 String joinedArgs = Strings.join(arguments, ", "); 453 String joinedArgs = Strings.join(arguments, ", ");
451 buffer.add("$prototype.$invocationName = function($joinedArgs) {\n"); 454 buffer.add("$prototype.$invocationName = function($joinedArgs) {\n");
452 buffer.add(" return this.self.$targetName($joinedArgs);\n"); 455 buffer.add(" return this.self.$targetName($joinedArgs);\n");
453 buffer.add("};\n"); 456 buffer.add("};\n");
454 addParameterStubs(callElement, 457 addParameterStubs(callElement,
455 (invocationName) => '$prototype.$invocationName', 458 (stubName) => '$prototype.$stubName',
456 buffer); 459 buffer);
457 460
458 // And finally the getter. 461 // And finally the getter.
459 String getterName = namer.getterName(member.getLibrary(), member.name); 462 String getterName = namer.getterName(member.getLibrary(), member.name);
460 String closureClass = namer.isolateAccess(closureClassElement); 463 String closureClass = namer.isolateAccess(closureClassElement);
461 buffer.add("${attachTo(getterName)} = function() {\n"); 464 buffer.add("${attachTo(getterName)} = function() {\n");
462 buffer.add(" return new $closureClass(this);\n"); 465 buffer.add(" return new $closureClass(this);\n");
463 buffer.add("};\n"); 466 buffer.add("};\n");
464 } 467 }
465 468
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 compiler.withCurrentElement(element, () { 512 compiler.withCurrentElement(element, () {
510 handler.writeJsCodeForVariable(buffer, element); 513 handler.writeJsCodeForVariable(buffer, element);
511 }); 514 });
512 buffer.add(';\n'); 515 buffer.add(';\n');
513 } 516 }
514 } 517 }
515 518
516 void emitCompileTimeConstants(StringBuffer buffer) { 519 void emitCompileTimeConstants(StringBuffer buffer) {
517 ConstantHandler handler = compiler.constantHandler; 520 ConstantHandler handler = compiler.constantHandler;
518 List<Constant> constants = handler.getConstantsForEmission(); 521 List<Constant> constants = handler.getConstantsForEmission();
519 String prototype = "${namer.ISOLATE}.prototype";
520 bool addedMakeConstantList = false; 522 bool addedMakeConstantList = false;
521 for (Constant constant in constants) { 523 for (Constant constant in constants) {
522 String name = handler.getNameForConstant(constant); 524 String name = handler.getNameForConstant(constant);
523 // The name is null when the constant is already a JS constant. 525 // The name is null when the constant is already a JS constant.
524 // TODO(floitsch): every constant should be registered, so that we can 526 // TODO(floitsch): every constant should be registered, so that we can
525 // share the ones that take up too much space (like some strings). 527 // share the ones that take up too much space (like some strings).
526 if (name === null) continue; 528 if (name === null) continue;
527 if (!addedMakeConstantList && constant.isList()) { 529 if (!addedMakeConstantList && constant.isList()) {
528 addedMakeConstantList = true; 530 addedMakeConstantList = true;
529 emitMakeConstantList(prototype, buffer); 531 emitMakeConstantList(buffer);
530 } 532 }
531 buffer.add('$prototype.$name = '); 533 buffer.add('$isolatePrototype.$name = ');
532 handler.writeJsCode(buffer, constant); 534 handler.writeJsCode(buffer, constant);
533 buffer.add(';\n'); 535 buffer.add(';\n');
534 } 536 }
535 } 537 }
536 538
537 void emitMakeConstantList(String prototype, StringBuffer buffer) { 539 void emitMakeConstantList(StringBuffer buffer) {
538 buffer.add(prototype); 540 buffer.add(isolatePrototype);
539 buffer.add(@'''.makeConstantList = function(list) { 541 buffer.add(@'''.makeConstantList = function(list) {
540 list.immutable$list = true; 542 list.immutable$list = true;
541 list.fixed$length = true; 543 list.fixed$length = true;
542 return list; 544 return list;
543 }; 545 };
544 '''); 546 ''');
545 } 547 }
546 548
547 void emitStaticFinalFieldInitializations(StringBuffer buffer) { 549 void emitStaticFinalFieldInitializations(StringBuffer buffer) {
548 ConstantHandler handler = compiler.constantHandler; 550 ConstantHandler handler = compiler.constantHandler;
549 List<VariableElement> staticFinalFields = 551 List<VariableElement> staticFinalFields =
550 handler.getStaticFinalFieldsForEmission(); 552 handler.getStaticFinalFieldsForEmission();
551 for (VariableElement element in staticFinalFields) { 553 for (VariableElement element in staticFinalFields) {
552 buffer.add('${namer.isolatePropertyAccess(element)} = '); 554 buffer.add(isolatePrototype);
555 buffer.add('.${namer.getName(element)} = ');
553 compiler.withCurrentElement(element, () { 556 compiler.withCurrentElement(element, () {
554 handler.writeJsCodeForVariable(buffer, element); 557 handler.writeJsCodeForVariable(buffer, element);
555 }); 558 });
556 buffer.add(';\n'); 559 buffer.add(';\n');
557 } 560 }
558 } 561 }
559 562
560 void emitExtraAccessors(Element member, 563 void emitExtraAccessors(Element member,
561 String attachTo(String name), 564 String attachTo(String name),
562 StringBuffer buffer) { 565 StringBuffer buffer) {
563 if (member.kind == ElementKind.GETTER || member.kind == ElementKind.FIELD) { 566 if (member.kind == ElementKind.GETTER || member.kind == ElementKind.FIELD) {
564 Set<Selector> selectors = compiler.universe.invokedNames[member.name]; 567 Set<Selector> selectors = compiler.universe.invokedNames[member.name];
565 if (selectors !== null && !selectors.isEmpty()) { 568 if (selectors !== null && !selectors.isEmpty()) {
566 compiler.emitter.emitCallStubForGetter( 569 compiler.emitter.emitCallStubForGetter(
567 buffer, attachTo, member, selectors); 570 buffer, attachTo, member, selectors);
568 } 571 }
569 } else if (member.kind == ElementKind.FUNCTION) { 572 } else if (member.kind == ElementKind.FUNCTION) {
570 if (compiler.universe.invokedGetters.contains(member.name)) { 573 if (compiler.universe.invokedGetters.contains(member.name)) {
571 compiler.emitter.emitDynamicFunctionGetter( 574 compiler.emitter.emitDynamicFunctionGetter(buffer, attachTo, member);
572 buffer, attachTo, member);
573 } 575 }
574 } 576 }
575 } 577 }
576 578
577 void emitNoSuchMethodCalls(StringBuffer buffer) { 579 void emitNoSuchMethodCalls(StringBuffer buffer) {
578 // Do not generate no such method calls if there is no class. 580 // Do not generate no such method calls if there is no class.
579 if (compiler.universe.instantiatedClasses.isEmpty()) return; 581 if (compiler.universe.instantiatedClasses.isEmpty()) return;
580 582
581 ClassElement objectClass = 583 ClassElement objectClass =
582 compiler.coreLibrary.find(const SourceString('Object')); 584 compiler.coreLibrary.find(const SourceString('Object'));
583 String className = namer.isolatePropertyAccess(objectClass); 585 String className = namer.getName(objectClass);
584 String prototype = '$className.prototype'; 586 String prototype = '$isolatePrototype.$className.prototype';
587 String runtimeObjectPrototype =
588 '${namer.isolateAccess(objectClass)}.prototype';
585 String noSuchMethodName = 589 String noSuchMethodName =
586 namer.instanceMethodName(null, Compiler.NO_SUCH_METHOD, 2); 590 namer.instanceMethodName(null, Compiler.NO_SUCH_METHOD, 2);
587 Collection<LibraryElement> libraries = 591 Collection<LibraryElement> libraries =
588 compiler.universe.libraries.getValues(); 592 compiler.universe.libraries.getValues();
589 593
590 void generateMethod(String methodName, String jsName, Selector selector) { 594 void generateMethod(String methodName, String jsName, Selector selector) {
591 buffer.add('$prototype.$jsName = function'); 595 buffer.add('$prototype.$jsName = function');
592 StringBuffer args = new StringBuffer(); 596 StringBuffer args = new StringBuffer();
593 for (int i = 0; i < selector.argumentCount; i++) { 597 for (int i = 0; i < selector.argumentCount; i++) {
594 if (i != 0) args.add(', '); 598 if (i != 0) args.add(', ');
595 args.add('arg$i'); 599 args.add('arg$i');
596 } 600 }
597 // We need to check if the object has a noSuchMethod. If not, it 601 // We need to check if the object has a noSuchMethod. If not, it
598 // means the object is a native object, and we can just call our 602 // means the object is a native object, and we can just call our
599 // generic noSuchMethod. Note that when calling this method, the 603 // generic noSuchMethod. Note that when calling this method, the
600 // 'this' object is not a Dart object. 604 // 'this' object is not a Dart object.
601 buffer.add(' ($args) {\n'); 605 buffer.add(' ($args) {\n');
602 buffer.add(' return this.$noSuchMethodName\n'); 606 buffer.add(' return this.$noSuchMethodName\n');
603 buffer.add(" ? this.$noSuchMethodName('$methodName', [$args])\n"); 607 buffer.add(" ? this.$noSuchMethodName('$methodName', [$args])\n");
604 buffer.add(" : $objectClassName.prototype.$noSuchMethodName.call("); 608 buffer.add(" : $runtimeObjectPrototype.$noSuchMethodName.call(");
605 buffer.add("this, '$methodName', [$args])\n"); 609 buffer.add("this, '$methodName', [$args])\n");
606 buffer.add('}\n'); 610 buffer.add('}\n');
607 } 611 }
608 612
609 compiler.universe.invokedNames.forEach((SourceString methodName, 613 compiler.universe.invokedNames.forEach((SourceString methodName,
610 Set<Selector> selectors) { 614 Set<Selector> selectors) {
611 if (objectClass.lookupLocalMember(methodName) === null 615 if (objectClass.lookupLocalMember(methodName) === null
612 && methodName != Namer.OPERATOR_EQUALS) { 616 && methodName != Namer.OPERATOR_EQUALS) {
613 for (Selector selector in selectors) { 617 for (Selector selector in selectors) {
614 if (methodName.isPrivate()) { 618 if (methodName.isPrivate()) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 ${mainCall}; 715 ${mainCall};
712 } 716 }
713 """); 717 """);
714 } 718 }
715 719
716 String assembleProgram() { 720 String assembleProgram() {
717 measure(() { 721 measure(() {
718 mainBuffer.add('function ${namer.ISOLATE}() {'); 722 mainBuffer.add('function ${namer.ISOLATE}() {');
719 emitStaticNonFinalFieldInitializations(mainBuffer); 723 emitStaticNonFinalFieldInitializations(mainBuffer);
720 mainBuffer.add('}\n\n'); 724 mainBuffer.add('}\n\n');
725 // Shorten the code by using [namer.CURRENT_ISOLATE] as temporary.
726 isolatePrototype = namer.CURRENT_ISOLATE;
727 mainBuffer.add('var $isolatePrototype = ${namer.ISOLATE}.prototype;\n');
721 emitClasses(mainBuffer); 728 emitClasses(mainBuffer);
722 emitStaticFunctions(mainBuffer); 729 emitStaticFunctions(mainBuffer);
723 emitStaticFunctionGetters(mainBuffer); 730 emitStaticFunctionGetters(mainBuffer);
724 emitCompileTimeConstants(mainBuffer); 731 emitCompileTimeConstants(mainBuffer);
725 emitStaticFinalFieldInitializations(mainBuffer); 732 emitStaticFinalFieldInitializations(mainBuffer);
726 nativeEmitter.emitDynamicDispatchMetadata(); 733
734 isolatePrototype = '${namer.ISOLATE}.prototype;\n';
727 mainBuffer.add( 735 mainBuffer.add(
728 'var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n'); 736 'var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n');
737 nativeEmitter.emitDynamicDispatchMetadata();
729 nativeEmitter.assembleCode(mainBuffer); 738 nativeEmitter.assembleCode(mainBuffer);
730 emitMain(mainBuffer); 739 emitMain(mainBuffer);
731 compiler.assembledCode = mainBuffer.toString(); 740 compiler.assembledCode = mainBuffer.toString();
732 }); 741 });
733 return compiler.assembledCode; 742 return compiler.assembledCode;
734 } 743 }
735 } 744 }
OLDNEW
« no previous file with comments | « no previous file | lib/compiler/implementation/namer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698