Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart |
| index 92be012cd9ff063abeb9340e4ed022e3ffa16621..4910225fa0bfd83b85bfade4b9ae686074e3369a 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart |
| @@ -290,20 +290,16 @@ class CodeEmitterTask extends CompilerTask { |
| // }, |
| // }); |
| - // function(cls, fields, prototype) { |
| - var defineClass = js.fun(['cls', 'fields', 'prototype'], [ |
| + var defineClass = js.fun(['name', 'cls', 'fields', 'prototype'], [ |
| js('var constructor'), |
| - // if (typeof fields == "function") { |
| js.if_(js('typeof fields == "function"'), [ |
| js('constructor = fields') |
| ], /* else */ [ |
| js('var str = "function " + cls + "("'), |
| js('var body = ""'), |
| - // for (var i = 0; i < fields.length; i++) { |
| js.for_('var i = 0', 'i < fields.length', 'i++', [ |
| - // if (i != 0) str += ", "; |
| js.if_('i != 0', js('str += ", "')), |
| js('var field = fields[i]'), |
| @@ -318,9 +314,8 @@ class CodeEmitterTask extends CompilerTask { |
| ]), |
| js('constructor.prototype = prototype'), |
| - js('constructor.builtin\$cls = cls'), |
| + js(r'constructor.builtin$cls = name'), |
| - // return constructor; |
| js.return_('constructor') |
| ]); |
| // Declare a function called "generateAccessor". This is used in |
| @@ -346,7 +341,7 @@ class CodeEmitterTask extends CompilerTask { |
| return [ |
| js('var $supportsProtoName = false'), |
| - js('var tmp = defineClass("c", ["f?"], {}).prototype'), |
| + js('var tmp = defineClass("c", "c", ["f?"], {}).prototype'), |
| js.if_(js('tmp.__proto__'), [ |
| js('tmp.__proto__ = {}'), |
| @@ -594,20 +589,25 @@ class CodeEmitterTask extends CompilerTask { |
| js('var hasOwnProperty = Object.prototype.hasOwnProperty'), |
| - // for (var cls in collectedClasses) |
| js.forIn('cls', 'collectedClasses', [ |
| - // if (hasOwnProperty.call(collectedClasses, cls)) |
| js.if_('hasOwnProperty.call(collectedClasses, cls)', [ |
| js('var desc = collectedClasses[cls]'), |
| /* The 'fields' are either a constructor function or a |
| * string encoding fields, constructor and superclass. Get |
| * the superclass and the fields in the format |
| - * Super;field1,field2 from the null-string property on the |
| + * name/Super;field1,field2 from the null-string property on the |
| * descriptor. |
| */ |
| - // var fields = desc[""], supr; |
| - js('var fields = desc[""], supr'), |
| + js('var classData = desc[""], supr, name, fields'), |
| + js('var split = classData.split("/")'), |
| + js.if_('split.length == 2', [ |
| + js('name = split[0]'), |
| + js('fields = split[1]') |
| + ], /* else */ [ |
| + js('name = cls'), |
| + js('fields = classData') |
| + ]), |
| js.if_('typeof fields == "string"', [ |
| js('var s = fields.split(";")'), |
| @@ -617,9 +617,8 @@ class CodeEmitterTask extends CompilerTask { |
| js('supr = desc.super') |
| ]), |
| - js('isolateProperties[cls] = defineClass(cls, fields, desc)'), |
| + js('isolateProperties[cls] = defineClass(name, cls, fields, desc)'), |
| - // if (supr) pendingClasses[cls] = supr; |
| js.if_('supr', js('pendingClasses[cls] = supr')) |
| ]) |
| ]), |
| @@ -1179,6 +1178,7 @@ class CodeEmitterTask extends CompilerTask { |
| // Avoid emitting [:$isObject:] on all classes but [Object]. |
| return; |
| } |
| + other = backend.getImplementationClass(other); |
| builder.addProperty(namer.operatorIs(other), js('true')); |
| } |
| @@ -1217,49 +1217,11 @@ class CodeEmitterTask extends CompilerTask { |
| void emitRuntimeTypeSupport(CodeBuffer buffer) { |
| RuntimeTypes rti = backend.rti; |
| - TypeChecks typeChecks = rti.getRequiredChecks(); |
| - |
| - /// Classes that are not instantiated and native classes need a holder |
| - /// object for their checks, because there will be no class defined for |
| - /// them. |
| - |
| - // TODO(9556): Get rid of holders. |
| - // |
| - // - For primitive classes, use the interceptors (e.g JSInt). |
| - // |
| - // - For uninstantiated classes, define the class anyway. It will not need |
| - // fields or a constructor, or any methods, so the class definition will |
| - // be smaller than a holder. |
| - |
| - bool needsHolder(ClassElement cls) { |
| - return !neededClasses.contains(cls) || |
| - rti.isJsNative(cls); |
| - } |
| - |
| - /** |
| - * Generates a holder object if it is needed. A holder is a JavaScript |
| - * object literal with a field [builtin$cls] that contains the name of the |
| - * class as a string (just like object constructors do). The is-checks for |
| - * the class are are added to the holder object later. |
| - */ |
| - void maybeGenerateHolder(ClassElement cls) { |
| - if (!needsHolder(cls)) return; |
| - String holder = namer.isolateAccess(cls); |
| - String name = namer.getRuntimeTypeName(cls); |
| - buffer.write('$holder$_=$_{builtin\$cls:$_"$name"'); |
| - buffer.write('}$N'); |
| - } |
| + TypeChecks typeChecks = rti.requiredChecks; |
| - // Create representation objects for classes that we do not have a class |
| - // definition for (because they are uninstantiated or native). |
| - for (ClassElement cls in rti.allArguments) { |
| - maybeGenerateHolder(cls); |
| - } |
| - |
| - // Add checks to the constructors of instantiated classes or to the created |
| - // holder object. |
| + // Add checks to the constructors of instantiated classes. |
| for (ClassElement cls in typeChecks) { |
| - String holder = namer.isolateAccess(cls); |
| + String holder = namer.isolateAccess(backend.getImplementationClass(cls)); |
| for (ClassElement check in typeChecks[cls]) { |
| buffer.write('$holder.${namer.operatorIs(check)}$_=${_}true$N'); |
| String body = rti.getSupertypeSubstitution(cls, check); |
| @@ -1434,6 +1396,10 @@ class CodeEmitterTask extends CompilerTask { |
| bool classIsNative: false }) { |
| String separator = ''; |
| StringBuffer buffer = new StringBuffer(); |
| + String nativeName = namer.getNativeName(classElement); |
| + if (nativeName != null) { |
| + buffer.write('$nativeName/'); |
| + } |
| if (superClass != null) { |
| buffer.write('$superClass;'); |
| } |
| @@ -2589,9 +2555,16 @@ if (typeof document !== "undefined" && document.readyState !== "complete") { |
| compiler.codegenWorld.instantiatedClasses.where(computeClassFilter()) |
| .toSet(); |
| + RuntimeTypes rti = backend.rti; |
| + |
| // The set of classes that must be emitted are based on instantiated |
| // classes. |
| neededClasses.addAll(instantiatedClasses); |
| + rti.allArguments.forEach((ClassElement c) { |
|
ngeoffray
2013/04/29 14:14:22
Please add a comment on why you're iterating over
karlklose
2013/04/30 09:29:41
Done.
|
| + if (!rti.isJsNative(c)) { |
| + neededClasses.add(c); |
| + } |
| + }); |
| // Then add all superclasses of these classes. |
| for (ClassElement element in neededClasses.toList() /* copy */) { |
| @@ -2853,12 +2826,12 @@ if (typeof document !== "undefined" && document.readyState !== "complete") { |
| String assembleProgram() { |
| measure(() { |
| - computeNeededClasses(); |
| - |
| // Compute the required type checks to know which classes need a |
| // 'is$' method. |
| computeRequiredTypeChecks(); |
| + computeNeededClasses(); |
| + |
| mainBuffer.add(GENERATED_BY); |
| addComment(HOOKS_API_USAGE, mainBuffer); |
| mainBuffer.add('function ${namer.isolateName}()$_{}\n'); |