[dart2js] make js_runtime a proper package

Change-Id: Ib5583f79abc0ab00a96ce6473282f4322da5143c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/180720
Reviewed-by: Stephen Adams <sra@google.com>
Commit-Queue: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
Sigmund Cherem 2021-01-25 22:39:23 +00:00 committed by commit-bot@chromium.org
parent 436c12e8ea
commit 7c1b43d10a
11 changed files with 603 additions and 6 deletions

View file

@ -354,8 +354,9 @@
},
{
"name": "js_runtime",
"rootUri": "../sdk/lib/_internal/js_runtime",
"packageUri": "lib/"
"rootUri": "../pkg/js_runtime",
"packageUri": "lib/",
"languageVersion": "2.12"
},
{
"name": "json_rpc_2",

View file

@ -54,7 +54,7 @@ http_throttle:third_party/pkg/http_throttle/lib
intl:third_party/pkg/intl/lib
js:pkg/js/lib
js_ast:pkg/js_ast/lib
js_runtime:sdk/lib/_internal/js_runtime/lib
js_runtime:pkg/js_runtime/lib
json_rpc_2:third_party/pkg/json_rpc_2/lib
kernel:pkg/kernel/lib
linter:third_party/pkg/linter/lib

View file

@ -26,7 +26,7 @@ dependencies:
js_ast:
path: ../js_ast
js_runtime:
path: ../../sdk/lib/_internal/js_runtime
path: ../js_runtime
dev_dependencies:
# Published packages - repo version ensured via dependency_overrides

9
pkg/js_runtime/README.md Normal file
View file

@ -0,0 +1,9 @@
# Package `js_runtime`:
This package contains code that is shared between the dart2js compiler and the
dart2js runtime libraries.
*Important*: all code under the `lib/shared/` must be kept in sync with the
runtime at all times (in `sdk/lib/_internal/js_runtime/lib/shared`). The
`test/in_sync_test.dart` test verifies this.

View file

@ -0,0 +1,10 @@
// 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.
/// Contains error codes that transformed async/async* functions use to
/// communicate with js_helper functions.
const int SUCCESS = 0;
const int ERROR = 1;
const int STREAM_WAS_CANCELED = 2;

View file

@ -0,0 +1,281 @@
// Copyright (c) 2014, 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.
/// Contains the names of globals that are embedded into the output by the
/// compiler.
///
/// Variables embedded this way should be access with `JS_EMBEDDED_GLOBAL` from
/// the `_foreign_helper` library.
///
/// This library is shared between the compiler and the runtime system.
library dart2js._embedded_names;
/// The name of the property that is used to find the native superclass of
/// an extended class.
///
/// Every class that extends a native class has this property set on its
/// native class.
const NATIVE_SUPERCLASS_TAG_NAME = r"$nativeSuperclassTag";
/// The name of the static-function property name.
///
/// This property is set for all tear-offs of static functions, and provides
/// the static function's unique (potentially minified) name.
const STATIC_FUNCTION_NAME_PROPERTY_NAME = r'$static_name';
/// The name of a property on the constructor function of Dart Object
/// and interceptor types, used for caching Rti types.
const CONSTRUCTOR_RTI_CACHE_PROPERTY_NAME = r'$ccache';
/// The name of the embedded global for metadata.
///
/// Use [JsBuiltin.getMetadata] instead of directly accessing this embedded
/// global.
const METADATA = 'metadata';
/// A list of types used in the program e.g. for reflection or encoding of
/// function types.
///
/// Use [JsBuiltin.getType] instead of directly accessing this embedded global.
const TYPES = 'types';
/// Returns a function that maps a name of a class to its type.
///
/// This embedded global is used by the runtime when computing the internal
/// runtime-type-information (rti) object.
const GET_TYPE_FROM_NAME = 'getTypeFromName';
/// A JS map from mangled global names to their unmangled names.
///
/// If the program does not use reflection, this embedded global may be empty
/// (but not null or undefined).
const MANGLED_GLOBAL_NAMES = 'mangledGlobalNames';
/// A JS map from mangled instance names to their unmangled names.
///
/// This embedded global is mainly used for reflection, but is also used to
/// map const-symbols (`const Symbol('x')`) to the mangled instance names.
///
/// This embedded global may be empty (but not null or undefined).
const MANGLED_NAMES = 'mangledNames';
/// A JS map from dispatch tags (usually constructor names of DOM classes) to
/// interceptor class. This map is used to find the correct interceptor for
/// native classes.
///
/// This embedded global is used for natives.
const INTERCEPTORS_BY_TAG = 'interceptorsByTag';
/// A JS map from dispatch tags (usually constructor names of DOM classes) to
/// booleans. Every tag entry of [INTERCEPTORS_BY_TAG] has a corresponding
/// entry in the leaf-tags map.
///
/// A tag-entry is true, when a class can be treated as leaf class in the
/// hierarchy. That is, even though it might have subclasses, all subclasses
/// have the same code for the used methods.
///
/// This embedded global is used for natives.
const LEAF_TAGS = 'leafTags';
/// A JS function that returns the isolate tag for a given name.
///
/// This function uses the [ISOLATE_TAG] (below) to construct a name that is
/// unique per isolate.
///
/// This embedded global is used for natives.
// TODO(floitsch): should we rename this variable to avoid confusion with
// [INTERCEPTORS_BY_TAG] and [LEAF_TAGS].
const GET_ISOLATE_TAG = 'getIsolateTag';
/// A string that is different for each running isolate.
///
/// When this embedded global is initialized a global variable is used to
/// ensure that no other running isolate uses the same isolate-tag string.
///
/// This embedded global is used for natives.
// TODO(floitsch): should we rename this variable to avoid confusion with
// [INTERCEPTORS_BY_TAG] and [LEAF_TAGS].
const ISOLATE_TAG = 'isolateTag';
/// An embedded global that contains the property used to store type information
/// on JavaScript Array instances. This is a Symbol (except for IE11, where is
/// is a String).
const ARRAY_RTI_PROPERTY = 'arrayRti';
/// This embedded global (a function) returns the isolate-specific dispatch-tag
/// that is used to accelerate interceptor calls.
const DISPATCH_PROPERTY_NAME = "dispatchPropertyName";
/// An embedded global that maps a [Type] to the [Interceptor] and constructors
/// for that type.
///
/// More documentation can be found in the interceptors library (close to its
/// use).
const TYPE_TO_INTERCEPTOR_MAP = "typeToInterceptorMap";
/// The current script's URI when the program was loaded.
///
/// This embedded global is set at startup, just before invoking `main`.
const CURRENT_SCRIPT = 'currentScript';
/// Contains a map from load-ids to lists of part indexes.
///
/// To load the deferred library that is represented by the load-id, the runtime
/// must load all associated URIs (named in DEFERRED_PART_URIS) and initialize
/// all the loaded hunks (DEFERRED_PART_HASHES).
///
/// This embedded global is only used for deferred loading.
const DEFERRED_LIBRARY_PARTS = 'deferredLibraryParts';
/// Contains a list of URIs (Strings), indexed by part.
///
/// The lists in the DEFERRED_LIBRARY_PARTS map contain indexes into this list.
///
/// This embedded global is only used for deferred loading.
const DEFERRED_PART_URIS = 'deferredPartUris';
/// Contains a list of hashes, indexed by part.
///
/// The lists in the DEFERRED_LIBRARY_PARTS map contain indexes into this list.
///
/// The hashes are associated with the URIs of the load-ids (see
/// [DEFERRED_PART_URIS]). They are SHA1 (or similar) hashes of the code that
/// must be loaded. By using cryptographic hashes we can (1) handle loading in
/// the same web page the parts from multiple Dart applications (2) avoid
/// loading similar code multiple times.
///
/// This embedded global is only used for deferred loading.
const DEFERRED_PART_HASHES = 'deferredPartHashes';
/// Initialize a loaded hunk.
///
/// Once a hunk (the code from a deferred URI) has been loaded it must be
/// initialized. Calling this function with the corresponding hash (see
/// [DEFERRED_LIBRARY_HASHES]) initializes the code.
///
/// This embedded global is only used for deferred loading.
const INITIALIZE_LOADED_HUNK = 'initializeLoadedHunk';
/// Returns, whether a hunk (identified by its hash) has already been loaded.
///
/// This embedded global is only used for deferred loading.
const IS_HUNK_LOADED = 'isHunkLoaded';
/// Returns, whether a hunk (identified by its hash) has already been
/// initialized.
///
/// This embedded global is only used for deferred loading.
const IS_HUNK_INITIALIZED = 'isHunkInitialized';
/// A set (implemented as map to booleans) of hunks (identified by hashes) that
/// have already been initialized.
///
/// This embedded global is only used for deferred loading.
///
/// This global is an emitter-internal embedded global, and not used by the
/// runtime. The constant remains in this file to make sure that other embedded
/// globals don't clash with it.
const DEFERRED_INITIALIZED = 'deferredInitialized';
/// A 'Universe' object used by 'dart:_rti'.
///
/// This embedded global is used for --experiment-new-rti.
const RTI_UNIVERSE = 'typeUniverse';
/// Names that are supported by [JS_GET_NAME].
// TODO(herhut): Make entries lower case (as in fields) and find a better name.
enum JsGetName {
GETTER_PREFIX,
SETTER_PREFIX,
CALL_PREFIX,
CALL_PREFIX0,
CALL_PREFIX1,
CALL_PREFIX2,
CALL_PREFIX3,
CALL_PREFIX4,
CALL_PREFIX5,
CALL_CATCH_ALL,
REQUIRED_PARAMETER_PROPERTY,
DEFAULT_VALUES_PROPERTY,
CALL_NAME_PROPERTY,
DEFERRED_ACTION_PROPERTY,
/// Prefix used for generated type argument substitutions on classes.
OPERATOR_AS_PREFIX,
/// Prefix used for generated type test property on classes.
OPERATOR_IS_PREFIX,
/// Name used for generated function types on classes and methods.
SIGNATURE_NAME,
/// Name of JavaScript property used to store runtime-type information on
/// instances of parameterized classes.
RTI_NAME,
/// String representation of the type of the Future class.
FUTURE_CLASS_TYPE_NAME,
/// Field name used for determining if an object or its interceptor has
/// JavaScript indexing behavior.
IS_INDEXABLE_FIELD_NAME,
/// String representation of the type of the null class.
NULL_CLASS_TYPE_NAME,
/// String representation of the type of the object class.
OBJECT_CLASS_TYPE_NAME,
/// Property name for Rti._as field.
RTI_FIELD_AS,
/// Property name for Rti._is field.
RTI_FIELD_IS,
}
enum JsBuiltin {
/// Returns the JavaScript constructor function for Dart's Object class.
/// This can be used for type tests, as in
///
/// var constructor = JS_BUILTIN('', JsBuiltin.dartObjectConstructor);
/// if (JS('bool', '# instanceof #', obj, constructor))
/// ...
dartObjectConstructor,
/// Returns the JavaScript constructor function for the runtime's Closure
/// class, the base class of all closure objects. This can be used for type
/// tests, as in
///
/// var constructor = JS_BUILTIN('', JsBuiltin.dartClosureConstructor);
/// if (JS('bool', '# instanceof #', obj, constructor))
/// ...
dartClosureConstructor,
/// Returns true if the given type is a type argument of a js-interop class
/// or a supertype of a js-interop class.
///
/// JS_BUILTIN('bool', JsBuiltin.isJsInteropTypeArgument, o)
isJsInteropTypeArgument,
/// Returns the metadata of the given [index].
///
/// JS_BUILTIN('returns:var;effects:none;depends:none',
/// JsBuiltin.getMetadata, index);
getMetadata,
/// Returns the type of the given [index].
///
/// JS_BUILTIN('returns:var;effects:none;depends:none',
/// JsBuiltin.getType, index);
getType,
}
/// Names of fields of the Rti Universe object.
class RtiUniverseFieldNames {
static String evalCache = 'eC';
static String typeRules = 'tR';
static String erasedTypes = 'eT';
static String typeParameterVariances = 'tPV';
static String sharedEmptyArray = 'sEA';
}

View file

@ -0,0 +1,237 @@
// Copyright (c) 2019, 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.
/// Constants and predicates used for encoding and decoding type recipes.
///
/// This library is shared between the compiler and the runtime system.
library dart2js._recipe_syntax;
abstract class Recipe {
Recipe._();
// Operators.
static const int separator = _comma;
static const String separatorString = _commaString;
static const int toType = _semicolon;
static const String toTypeString = _semicolonString;
static const int pushErased = _hash;
static const String pushErasedString = _hashString;
static const int pushDynamic = _at;
static const String pushDynamicString = _atString;
static const int pushVoid = _tilde;
static const String pushVoidString = _tildeString;
static const int wrapStar = _asterisk;
static const String wrapStarString = _asteriskString;
static const int wrapQuestion = _question;
static const String wrapQuestionString = _questionString;
static const int wrapFutureOr = _slash;
static const String wrapFutureOrString = _slashString;
static const int startTypeArguments = _lessThan;
static const String startTypeArgumentsString = _lessThanString;
static const int endTypeArguments = _greaterThan;
static const String endTypeArgumentsString = _greaterThanString;
static const int startFunctionArguments = _leftParen;
static const String startFunctionArgumentsString = _leftParenString;
static const int endFunctionArguments = _rightParen;
static const String endFunctionArgumentsString = _rightParenString;
static const int startOptionalGroup = _leftBracket;
static const String startOptionalGroupString = _leftBracketString;
static const int endOptionalGroup = _rightBracket;
static const String endOptionalGroupString = _rightBracketString;
static const int startNamedGroup = _leftBrace;
static const String startNamedGroupString = _leftBraceString;
static const int endNamedGroup = _rightBrace;
static const String endNamedGroupString = _rightBraceString;
static const int nameSeparator = _colon;
static const String nameSeparatorString = _colonString;
static const int requiredNameSeparator = _exclamation;
static const String requiredNameSeparatorString = _exclamationString;
static const int genericFunctionTypeParameterIndex = _circumflex;
static const String genericFunctionTypeParameterIndexString =
_circumflexString;
static const int extensionOp = _ampersand;
static const String extensionOpString = _ampersandString;
static const int pushNeverExtension = 0;
static const String pushNeverExtensionString = '$pushNeverExtension';
static const int pushAnyExtension = 1;
static const String pushAnyExtensionString = '$pushAnyExtension';
// Number and name components.
static bool isDigit(int code) => code >= _digit0 && code <= _digit9;
static int digitValue(int code) => code - _digit0;
static bool isIdentifierStart(int ch) =>
(((ch | 32) - _lowercaseA) & 0xffff) < 26 ||
(ch == _underscore) ||
(ch == _dollar);
static const int period = _period;
// Private names.
static const int _formfeed = 0x0C;
static const String _formfeedString = '\f';
static const int _space = 0x20;
static const String _spaceString = ' ';
static const int _exclamation = 0x21;
static const String _exclamationString = '!';
static const int _hash = 0x23;
static const String _hashString = '#';
static const int _dollar = 0x24;
static const String _dollarString = r'$';
static const int _percent = 0x25;
static const String _percentString = '%';
static const int _ampersand = 0x26;
static const String _ampersandString = '&';
static const int _apostrophe = 0x27;
static const String _apostropheString = "'";
static const int _leftParen = 0x28;
static const String _leftParenString = '(';
static const int _rightParen = 0x29;
static const String _rightParenString = ')';
static const int _asterisk = 0x2A;
static const String _asteriskString = '*';
static const int _plus = 0x2B;
static const String _plusString = '+';
static const int _comma = 0x2C;
static const String _commaString = ',';
static const int _minus = 0x2D;
static const String _minusString = '-';
static const int _period = 0x2E;
static const String _periodString = '.';
static const int _slash = 0x2F;
static const String _slashString = '/';
static const int _digit0 = 0x30;
static const int _digit9 = 0x39;
static const int _colon = 0x3A;
static const String _colonString = ':';
static const int _semicolon = 0x3B;
static const String _semicolonString = ';';
static const int _lessThan = 0x3C;
static const String _lessThanString = '<';
static const int _equals = 0x3D;
static const String _equalsString = '=';
static const int _greaterThan = 0x3E;
static const String _greaterThanString = '>';
static const int _question = 0x3F;
static const String _questionString = '?';
static const int _at = 0x40;
static const String _atString = '@';
static const int _uppercaseA = 0x41;
static const int _uppercaseZ = 0x5A;
static const int _leftBracket = 0x5B;
static const String _leftBracketString = '[';
static const int _backslash = 0x5C;
static const String _backslashString = r'\';
static const int _rightBracket = 0x5D;
static const String _rightBracketString = ']';
static const int _circumflex = 0x5E;
static const String _circumflexString = '^';
static const int _underscore = 0x5F;
static const String _underscoreString = '_';
static const int _backtick = 0x60;
static const String _backtickString = '`';
static const int _lowercaseA = 0x61;
static const int _lowercaseZ = 0x7A;
static const int _leftBrace = 0x7B;
static const String _leftBraceString = '{';
static const int _vertical = 0x7C;
static const String _verticalString = '|';
static const int _rightBrace = 0x7D;
static const String _rightBraceString = '}';
static const int _tilde = 0x7E;
static const String _tildeString = '~';
static void testEquivalence() {
void test(String label, int charCode, String str) {
if (String.fromCharCode(charCode) != str) {
throw StateError("$label: String.fromCharCode($charCode) != $str");
}
}
void testExtension(String label, int op, String str) {
if ('$op' != str) {
throw StateError("$label: $op.toString() != $str");
}
}
test("separator", separator, separatorString);
test("toType", toType, toTypeString);
test("pushErased", pushErased, pushErasedString);
test("pushDynamic", pushDynamic, pushDynamicString);
test("pushVoid", pushVoid, pushVoidString);
test("wrapStar", wrapStar, wrapStarString);
test("wrapQuestion", wrapQuestion, wrapQuestionString);
test("wrapFutureOr", wrapFutureOr, wrapFutureOrString);
test("startTypeArguments", startTypeArguments, startTypeArgumentsString);
test("endTypeArguments", endTypeArguments, endTypeArgumentsString);
test("startFunctionArguments", startFunctionArguments,
startFunctionArgumentsString);
test("endFunctionArguments", endFunctionArguments,
endFunctionArgumentsString);
test("startOptionalGroup", startOptionalGroup, startOptionalGroupString);
test("endOptionalGroup", endOptionalGroup, endOptionalGroupString);
test("startNamedGroup", startNamedGroup, startNamedGroupString);
test("endNamedGroup", endNamedGroup, endNamedGroupString);
test("nameSeparator", nameSeparator, nameSeparatorString);
test("requiredNameSeparator", requiredNameSeparator,
requiredNameSeparatorString);
test("genericFunctionTypeParameterIndex", genericFunctionTypeParameterIndex,
genericFunctionTypeParameterIndexString);
test("extensionOp", extensionOp, extensionOpString);
testExtension(
"pushNeverExtension", pushNeverExtension, pushNeverExtensionString);
testExtension("pushAnyExtension", pushAnyExtension, pushAnyExtensionString);
test("_formfeed", _formfeed, _formfeedString);
test("_space", _space, _spaceString);
test("_exclamation", _exclamation, _exclamationString);
test("_hash", _hash, _hashString);
test("_dollar", _dollar, _dollarString);
test("_percent", _percent, _percentString);
test("_ampersand", _ampersand, _ampersandString);
test("_apostrophe", _apostrophe, _apostropheString);
test("_leftParen", _leftParen, _leftParenString);
test("_rightParen", _rightParen, _rightParenString);
test("_asterisk", _asterisk, _asteriskString);
test("_plus", _plus, _plusString);
test("_comma", _comma, _commaString);
test("_minus", _minus, _minusString);
test("_period", _period, _periodString);
test("_slash", _slash, _slashString);
test("_colon", _colon, _colonString);
test("_semicolon", _semicolon, _semicolonString);
test("_lessThan", _lessThan, _lessThanString);
test("_equals", _equals, _equalsString);
test("_greaterThan", _greaterThan, _greaterThanString);
test("_question", _question, _questionString);
test("_at", _at, _atString);
test("_leftBracket", _leftBracket, _leftBracketString);
test("_backslash", _backslash, _backslashString);
test("_rightBracket", _rightBracket, _rightBracketString);
test("_circumflex", _circumflex, _circumflexString);
test("_underscore", _underscore, _underscoreString);
test("_backtick", _backtick, _backtickString);
test("_leftBrace", _leftBrace, _leftBraceString);
test("_vertical", _vertical, _verticalString);
test("_rightBrace", _rightBrace, _rightBraceString);
test("_tilde", _tilde, _tildeString);
}
}

View file

@ -0,0 +1,12 @@
name: js_runtime
# This package is not intended for consumption on pub.dev. DO NOT publish.
publish_to: none
environment:
sdk: '>=2.12.0 <3.0.0'
dev_dependencies:
expect:
path: ../expect
_fe_analyzer_shared:
path: ../_fe_analyzer_shared

View file

@ -0,0 +1,39 @@
// Copyright (c) 2020, 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.
// @dart = 2.9
/// Test to verify that this package is in-sync with dart2js runtime libraries.
import 'dart:io';
import 'package:_fe_analyzer_shared/src/util/relativize.dart';
import 'package:expect/expect.dart';
void main(List<String> argv) {
var packageDir = Platform.script.resolve('../lib/shared/');
var sdkDir = Platform.script
.resolve('../../../sdk/lib/_internal/js_runtime/lib/shared/');
var rPackageDir =
relativizeUri(Directory.current.uri, packageDir, Platform.isWindows);
var rSdkDir =
relativizeUri(Directory.current.uri, sdkDir, Platform.isWindows);
for (var file in Directory.fromUri(sdkDir).listSync()) {
if (file is File) {
var filename = file.uri.pathSegments.last;
var packageFile = File.fromUri(packageDir.resolve(filename));
Expect.isTrue(
packageFile.existsSync(),
"$filename not in sync. Please update it by running:\n"
" cp $rSdkDir$filename $rPackageDir$filename");
var original = file.readAsBytesSync();
var copy = packageFile.readAsBytesSync();
Expect.listEquals(
original,
copy,
"$filename not in sync. Please update it by running:\n"
" cp $rSdkDir$filename $rPackageDir$filename");
}
}
}

View file

@ -173,6 +173,7 @@ dds/test/*: SkipByDesign # Only meant to run on vm
dev_compiler/test/options/*: SkipByDesign
front_end/test/hot_reload_e2e_test: Skip
frontend_server/test/*: SkipByDesign # Only meant to run on vm
js_runtime/test/*: SkipByDesign # Only meant to run on vm
vm/test/*: SkipByDesign # Only meant to run on vm
vm_service/test/*: SkipByDesign # Uses dart:io
vm_snapshot_analysis/test/*: SkipByDesign # Only meant to run on vm

View file

@ -2204,6 +2204,13 @@
"--use-sdk"
]
},
{
"name": "js_runtime unit tests",
"arguments": [
"-nunittest-asserts-no-sdk-linux",
"pkg//js_runtime/"
]
},
{
"name": "dart2js unit tests",
"arguments": [
@ -3218,7 +3225,7 @@
"name": "package unit tests",
"arguments": [
"-nunittest-asserts-${mode}-${system}",
"pkg/pkg/(?!(analyzer*|analysis_server|compiler|front_end|kernel|nnbd_migration)/)"
"pkg/pkg/(?!(analyzer*|analysis_server|compiler|js_runtime|front_end|kernel|nnbd_migration)/)"
]
},
{
@ -3256,7 +3263,7 @@
"name": "package unit tests",
"arguments": [
"-nunittest-asserts-${mode}-${system}",
"pkg/pkg/(?!(analyzer*|analysis_server|compiler|front_end|kernel|nnbd_migration)/)"
"pkg/pkg/(?!(analyzer*|analysis_server|compiler|js_runtime|front_end|kernel|nnbd_migration)/)"
]
},
{