Chromium Code Reviews| Index: pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart |
| diff --git a/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart |
| index 081270bbf351ae88e7fc01d80dc49a54dc98b8d1..8902af8448a276b3bbfc9e5b51a56b29f560ce78 100644 |
| --- a/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart |
| +++ b/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart |
| @@ -200,6 +200,7 @@ class ModelEmitter { |
| backend.emitter.staticFunctionAccess(backend.getCyclicThrowHelper()), |
| 'outputContainsConstantList': program.outputContainsConstantList, |
| 'embeddedGlobals': emitEmbeddedGlobals(program), |
| + 'readMetadataTypeFunction': readMetadataTypeFunction, |
| 'staticNonFinals': |
| emitStaticNonFinalFields(fragment.staticNonFinalFields), |
| 'operatorIsPrefix': js.string(namer.operatorIsPrefix), |
| @@ -420,6 +421,31 @@ class ModelEmitter { |
| return new js.Property(js.string(GET_TYPE_FROM_NAME), function); |
| } |
| + static final metadataTypeComment = |
| + "Types are non-evaluated and must be compiled at first use. " |
| + "Compiled strings are guaranteed not to be strings, and it's thus safe " |
| + "to use a type-test to determine if a type has already been compiled."; |
| + |
| + static final String readMetadataTypeName = "readMetadataType"; |
| + |
| + js.Statement get readMetadataTypeFunction { |
| + return js.js.statement('''function $readMetadataTypeName(index) { |
| + // $metadataTypeComment. |
|
sra1
2015/05/07 03:39:30
Just put the comment here.
floitsch
2015/05/07 04:08:59
Done.
|
| + var type = #typesAccess[index]; |
| + if (typeof type == 'string') { |
| + type = expressionCompile(type); |
| + #typesAccess[index] = type; |
| + } |
| + return type; |
| + }''', {"typesAccess": generateEmbeddedGlobalAccess(TYPES)}); |
| + } |
| + |
| + js.Template get templateForReadType { |
| + // TODO(floitsch): make sure that no local variable shadows the access to |
| + // the readMetadataType function. |
| + return js.js.expressionTemplateFor('$readMetadataTypeName(#)'); |
| + } |
| + |
| List<js.Property> emitMetadata(Program program) { |
| List<js.Property> metadataGlobals = <js.Property>[]; |
| @@ -435,7 +461,9 @@ class ModelEmitter { |
| List<String> types = |
| program.metadataTypes[program.fragments.first.outputUnit]; |
| if (types == null) types = <String>[]; |
| - metadataGlobals.add(createGlobal(types, TYPES)); |
| + // The strings in the array are already pretty-printed JS expressions. |
| + js.Expression unparsedTypes = js.stringArray(types); |
| + metadataGlobals.add(new js.Property(js.string(TYPES), unparsedTypes)); |
| return metadataGlobals; |
| } |
| @@ -464,7 +492,7 @@ class ModelEmitter { |
| js.LiteralString immediateString = unparse(compiler, immediateCode); |
| - js.Expression deferredTypes = types == null |
| + js.Expression deferredTypes = (types == null) |
| ? js.string("[]") |
| : js.string("[${types.join(",")}]"); |
| @@ -1162,6 +1190,13 @@ function parseFunctionDescriptor(proto, name, descriptor, typesOffset) { |
| // Initialize globals. |
| #embeddedGlobals; |
| + function expressionCompile(__s__) { |
| + 'use strict'; |
| + return eval('(' + __s__ + ')'); |
| + } |
| + |
| + #readMetadataTypeFunction; |
| + |
| // TODO(floitsch): this order means that native classes may not be |
| // referenced from constants. I'm mostly afraid of things like using them as |
| // generic arguments (which should be fine, but maybe there are other |