| Index: pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
|
| diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5048fe5f5cb7ea9024cd7c2a60ab652a034bcafa
|
| --- /dev/null
|
| +++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
|
| @@ -0,0 +1,130 @@
|
| +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +library dart2js.js_emitter.startup_emitter.model_emitter;
|
| +
|
| +import '../../constants/values.dart' show ConstantValue, FunctionConstantValue;
|
| +import '../../dart2jslib.dart' show Compiler;
|
| +import '../../elements/elements.dart' show ClassElement, FunctionElement;
|
| +import '../../js/js.dart' as js;
|
| +import '../../js_backend/js_backend.dart' show
|
| + JavaScriptBackend,
|
| + Namer,
|
| + ConstantEmitter;
|
| +
|
| +import '../js_emitter.dart' show AstContainer, NativeEmitter;
|
| +
|
| +import 'package:js_runtime/shared/embedded_names.dart' show
|
| + CREATE_NEW_ISOLATE,
|
| + DEFERRED_INITIALIZED,
|
| + DEFERRED_LIBRARY_URIS,
|
| + DEFERRED_LIBRARY_HASHES,
|
| + GET_TYPE_FROM_NAME,
|
| + INITIALIZE_LOADED_HUNK,
|
| + INTERCEPTORS_BY_TAG,
|
| + IS_HUNK_INITIALIZED,
|
| + IS_HUNK_LOADED,
|
| + LEAF_TAGS,
|
| + MANGLED_GLOBAL_NAMES,
|
| + METADATA,
|
| + NATIVE_SUPERCLASS_TAG_NAME,
|
| + TYPE_TO_INTERCEPTOR_MAP,
|
| + TYPES;
|
| +
|
| +import '../js_emitter.dart' show NativeGenerator, buildTearOffCode;
|
| +import '../model.dart';
|
| +
|
| +class ModelEmitter {
|
| + final Compiler compiler;
|
| + final Namer namer;
|
| + ConstantEmitter constantEmitter;
|
| + final NativeEmitter nativeEmitter;
|
| +
|
| + JavaScriptBackend get backend => compiler.backend;
|
| +
|
| + /// For deferred loading we communicate the initializers via this global var.
|
| + static const String deferredInitializersGlobal =
|
| + r"$__dart_deferred_initializers__";
|
| +
|
| + static const String deferredExtension = "part.js";
|
| +
|
| + static const String typeNameProperty = r"builtin$cls";
|
| +
|
| + ModelEmitter(Compiler compiler, Namer namer, this.nativeEmitter)
|
| + : this.compiler = compiler,
|
| + this.namer = namer {
|
| + this.constantEmitter = new ConstantEmitter(
|
| + compiler, namer, this.generateConstantReference,
|
| + constantListGenerator);
|
| + }
|
| +
|
| + js.Expression constantListGenerator(js.Expression array) {
|
| + // TODO(floitsch): remove hard-coded name.
|
| + return js.js('makeConstList(#)', [array]);
|
| + }
|
| +
|
| + js.Expression generateEmbeddedGlobalAccess(String global) {
|
| + return js.js(generateEmbeddedGlobalAccessString(global));
|
| + }
|
| +
|
| + String generateEmbeddedGlobalAccessString(String global) {
|
| + // TODO(floitsch): don't use 'init' as global embedder storage.
|
| + return 'init.$global';
|
| + }
|
| +
|
| + bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) {
|
| + if (constant.isFunction) return true; // Already emitted.
|
| + if (constant.isPrimitive) return true; // Inlined.
|
| + if (constant.isDummy) return true; // Inlined.
|
| + return false;
|
| + }
|
| +
|
| + // TODO(floitsch): copied from OldEmitter. Adjust or share.
|
| + int compareConstants(ConstantValue a, ConstantValue b) {
|
| + // Inlined constants don't affect the order and sometimes don't even have
|
| + // names.
|
| + int cmp1 = isConstantInlinedOrAlreadyEmitted(a) ? 0 : 1;
|
| + int cmp2 = isConstantInlinedOrAlreadyEmitted(b) ? 0 : 1;
|
| + if (cmp1 + cmp2 < 2) return cmp1 - cmp2;
|
| +
|
| + // Emit constant interceptors first. Constant interceptors for primitives
|
| + // might be used by code that builds other constants. See Issue 18173.
|
| + if (a.isInterceptor != b.isInterceptor) {
|
| + return a.isInterceptor ? -1 : 1;
|
| + }
|
| +
|
| + // Sorting by the long name clusters constants with the same constructor
|
| + // which compresses a tiny bit better.
|
| + int r = namer.constantLongName(a).compareTo(namer.constantLongName(b));
|
| + if (r != 0) return r;
|
| + // Resolve collisions in the long name by using the constant name (i.e. JS
|
| + // name) which is unique.
|
| + return namer.constantName(a).compareTo(namer.constantName(b));
|
| + }
|
| +
|
| + js.Expression generateStaticClosureAccess(FunctionElement element) {
|
| + return js.js('#.#()',
|
| + [namer.globalObjectFor(element), namer.staticClosureName(element)]);
|
| + }
|
| +
|
| + js.Expression generateConstantReference(ConstantValue value) {
|
| + if (value.isFunction) {
|
| + FunctionConstantValue functionConstant = value;
|
| + return generateStaticClosureAccess(functionConstant.element);
|
| + }
|
| +
|
| + // We are only interested in the "isInlined" part, but it does not hurt to
|
| + // test for the other predicates.
|
| + if (isConstantInlinedOrAlreadyEmitted(value)) {
|
| + return constantEmitter.generate(value);
|
| + }
|
| + return js.js('#.#', [namer.globalObjectForConstant(value),
|
| + namer.constantName(value)]);
|
| + }
|
| +
|
| + int emitProgram(Program program) {
|
| + // TODO(floitsch): implement.
|
| + throw new UnimplementedError("startup-emitter.emitProgram");
|
| + }
|
| +}
|
|
|