Version 1.22.0-dev.4.0 Merge commit '76e600aea6018e26e8996e492c531d70c3860ca6' into dev
diff --git a/DEPS b/DEPS index 896e0d3..882fa0f 100644 --- a/DEPS +++ b/DEPS
@@ -92,7 +92,7 @@ "ply_rev": "@604b32590ffad5cbb82e4afef1d305512d06ae93", "pool_tag": "@1.2.4", "protobuf_tag": "@0.5.3", - "pub_rev": "@9309be93140638fb19903648d07de59681a08989", + "pub_rev": "@d7649be15213c43669a40c33af516d8eb210e876", "pub_semver_tag": "@1.3.0", "quiver_tag": "@0.22.0", "resource_rev":"@a49101ba2deb29c728acba6fb86000a8f730f4b1",
diff --git a/docs/language/informal/README.md b/docs/language/informal/README.md new file mode 100644 index 0000000..5774998 --- /dev/null +++ b/docs/language/informal/README.md
@@ -0,0 +1,17 @@ +This directory contains "informal specifications". + +In order to move faster and get better feedback, we implement and iterate on +language changes before the full official specification has been written. Still, +the implementers need *something* to go on. + +For that, the language team writes "informal specifications". These are +intended to be precise enough for a good faith implementer to correctly +understand the syntax and semantics of the language, but without all of the +laborious detail of the complete specification. + +Once the feature has been implemented, tested, and we are confident in it, the +language team will write the real text in the language specification and the +document here becomes deprecated and no longer canonical. + +Until then, while the feature is in progress, a live pull request for the +informal spec is the source of truth for the feature.
diff --git a/pkg/analyzer/lib/src/command_line/arguments.dart b/pkg/analyzer/lib/src/command_line/arguments.dart index 5ea958e..22a9670 100644 --- a/pkg/analyzer/lib/src/command_line/arguments.dart +++ b/pkg/analyzer/lib/src/command_line/arguments.dart
@@ -18,7 +18,7 @@ const String defineVariableOption = 'D'; const String enableInitializingFormalAccessFlag = 'initializing-formal-access'; const String enableStrictCallChecksFlag = 'enable-strict-call-checks'; -const String enableSuperInMixinFlag = 'supermixin'; +const String enableSuperMixinFlag = 'supermixin'; const String ignoreUnrecognizedFlagsFlag = 'ignore-unrecognized-flags'; const String noImplicitCastsFlag = 'no-implicit-casts'; const String noImplicitDynamicFlag = 'no-implicit-dynamic'; @@ -29,11 +29,33 @@ const String strongModeFlag = 'strong'; /** + * Update [options] with the value of each analysis option command line flag. + */ +void applyAnalysisOptionFlags(AnalysisOptionsImpl options, ArgResults args) { + if (args.wasParsed(enableStrictCallChecksFlag)) { + options.enableStrictCallChecks = args[enableStrictCallChecksFlag]; + } + if (args.wasParsed(enableSuperMixinFlag)) { + options.enableSuperMixins = args[enableSuperMixinFlag]; + } + if (args.wasParsed(noImplicitCastsFlag)) { + options.implicitCasts = !args[noImplicitCastsFlag]; + } + if (args.wasParsed(noImplicitDynamicFlag)) { + options.implicitDynamic = !args[noImplicitDynamicFlag]; + } + if (args.wasParsed(strongModeFlag)) { + options.strongMode = args[strongModeFlag]; + } +} + +/** * Use the given [resourceProvider], [contentCache] and command-line [args] to * create a context builder. */ ContextBuilderOptions createContextBuilderOptions(ArgResults args) { ContextBuilderOptions builderOptions = new ContextBuilderOptions(); + builderOptions.argResults = args; // // File locations. // @@ -46,11 +68,7 @@ // Analysis options. // AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl(); - defaultOptions.enableStrictCallChecks = args[enableStrictCallChecksFlag]; - defaultOptions.enableSuperMixins = args[enableSuperInMixinFlag]; - defaultOptions.implicitCasts = !args[noImplicitCastsFlag]; - defaultOptions.implicitDynamic = !args[noImplicitDynamicFlag]; - defaultOptions.strongMode = args[strongModeFlag]; + applyAnalysisOptionFlags(defaultOptions, args); builderOptions.defaultOptions = defaultOptions; // // Declared variables. @@ -163,7 +181,7 @@ defaultsTo: false, negatable: false, hide: hide || ddc); - parser.addFlag(enableSuperInMixinFlag, + parser.addFlag(enableSuperMixinFlag, help: 'Relax restrictions on mixins (DEP 34).', defaultsTo: false, negatable: false,
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart index 95b9465..aad53cf 100644 --- a/pkg/analyzer/lib/src/context/builder.dart +++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -12,6 +12,8 @@ import 'package:analyzer/plugin/resolver_provider.dart'; import 'package:analyzer/source/analysis_options_provider.dart'; import 'package:analyzer/source/package_map_resolver.dart'; +import 'package:analyzer/src/command_line/arguments.dart' + show applyAnalysisOptionFlags; import 'package:analyzer/src/dart/sdk/sdk.dart'; import 'package:analyzer/src/generated/bazel.dart'; import 'package:analyzer/src/generated/engine.dart'; @@ -21,6 +23,7 @@ import 'package:analyzer/src/summary/pub_summary.dart'; import 'package:analyzer/src/summary/summary_sdk.dart'; import 'package:analyzer/src/task/options.dart'; +import 'package:args/args.dart'; import 'package:package_config/packages.dart'; import 'package:package_config/packages_file.dart'; import 'package:package_config/src/packages_impl.dart'; @@ -349,6 +352,9 @@ } catch (_) { // Ignore exceptions thrown while trying to load the options file. } + if (builderOptions.argResults != null) { + applyAnalysisOptionFlags(options, builderOptions.argResults); + } } return options; } @@ -481,6 +487,12 @@ */ class ContextBuilderOptions { /** + * The results of parsing the command line arguments as defined by + * [defineAnalysisArguments] or `null` if none. + */ + ArgResults argResults; + + /** * The file path of the file containing the summary of the SDK that should be * used to "analyze" the SDK. This option should only be specified by * command-line tools such as 'dartanalyzer' or 'ddc'.
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart index 6995b2a..050d3bc 100644 --- a/pkg/analyzer/lib/src/task/options.dart +++ b/pkg/analyzer/lib/src/task/options.dart
@@ -538,7 +538,7 @@ if (feature == AnalyzerOptions.enableAssertInitializer) { options.enableAssertInitializer = boolValue; } else if (feature == AnalyzerOptions.enableStrictCallChecks) { - options.enableStrictCallChecks = true; + options.enableStrictCallChecks = boolValue; } else if (feature == AnalyzerOptions.enableSuperMixins) { options.enableSuperMixins = boolValue; }
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart index c2eb6ce..4569f8e 100644 --- a/pkg/analyzer/test/src/context/builder_test.dart +++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -6,12 +6,14 @@ import 'package:analyzer/file_system/file_system.dart'; import 'package:analyzer/file_system/memory_file_system.dart'; +import 'package:analyzer/src/command_line/arguments.dart'; import 'package:analyzer/src/context/builder.dart'; import 'package:analyzer/src/context/source.dart'; import 'package:analyzer/src/generated/bazel.dart'; import 'package:analyzer/src/generated/engine.dart'; import 'package:analyzer/src/generated/sdk.dart'; import 'package:analyzer/src/generated/source.dart'; +import 'package:args/args.dart'; import 'package:package_config/packages.dart'; import 'package:package_config/src/packages_impl.dart'; import 'package:path/path.dart' as path; @@ -110,6 +112,33 @@ fail('Incomplete test'); } + void test_cmdline_options_override_options_file() { + ArgParser argParser = new ArgParser(); + defineAnalysisArguments(argParser); + ArgResults argResults = argParser.parse(['--$enableStrictCallChecksFlag']); + var builder = new ContextBuilder(resourceProvider, sdkManager, contentCache, + options: createContextBuilderOptions(argResults)); + + AnalysisOptionsImpl expected = new AnalysisOptionsImpl(); + expected.enableSuperMixins = true; + expected.enableStrictCallChecks = true; + + String path = resourceProvider.convertPath('/some/directory/path'); + String filePath = + pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE); + resourceProvider.newFile( + filePath, + ''' +analyzer: + language: + enableSuperMixins : true + enableStrictCallChecks : false +'''); + + AnalysisOptions options = builder.getAnalysisOptions(path); + _expectEqualOptions(options, expected); + } + void test_convertPackagesToMap_noPackages() { expect(builder.convertPackagesToMap(Packages.noPackages), isEmpty); }
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart index fc92457..2861f6b 100644 --- a/pkg/compiler/lib/src/apiimpl.dart +++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -47,7 +47,7 @@ CompilerImpl(this.provider, api.CompilerOutput outputProvider, this.handler, CompilerOptions options, - {MakeBackendFuncion makeBackend, MakeReporterFunction makeReporter}) + {MakeBackendFunction makeBackend, MakeReporterFunction makeReporter}) // NOTE: allocating measurer is done upfront to ensure the wallclock is // started before other computations. : measurer = new Measurer(enableTaskMeasurements: options.verbose),
diff --git a/pkg/compiler/lib/src/common/backend_api.dart b/pkg/compiler/lib/src/common/backend_api.dart index e0c396c..639b9a3 100644 --- a/pkg/compiler/lib/src/common/backend_api.dart +++ b/pkg/compiler/lib/src/common/backend_api.dart
@@ -17,7 +17,13 @@ import '../constants/values.dart' show ConstantValue; import '../dart_types.dart' show DartType, InterfaceType; import '../elements/elements.dart' - show ClassElement, Element, FunctionElement, MethodElement, LibraryElement; + show + ClassElement, + Element, + FunctionElement, + MemberElement, + MethodElement, + LibraryElement; import '../elements/entities.dart'; import '../enqueue.dart' show Enqueuer, EnqueueTask, ResolutionEnqueuer; import '../io/code_output.dart' show CodeBuffer; @@ -151,15 +157,6 @@ void registerTypeVariableBoundsSubtypeCheck( DartType typeArgument, DartType bound) {} - /// Called to register that an instantiated generic class has a call method. - /// Any backend specific [WorldImpact] of this is returned. - /// - /// Note: The [callMethod] is registered even thought it doesn't reference - /// the type variables. - WorldImpact registerCallMethodWithFreeTypeVariables(Element callMethod, - {bool forResolution}) => - const WorldImpact(); - /// Called to instruct the backend to register that a closure exists for a /// function on an instantiated generic class. Any backend specific /// [WorldImpact] of this is returned. @@ -175,10 +172,6 @@ /// specific [WorldImpact] of this is returned. WorldImpact registerGetOfStaticFunction() => const WorldImpact(); - /// Called to enable support for `noSuchMethod`. Any backend specific - /// [WorldImpact] of this is returned. - WorldImpact enableNoSuchMethod() => const WorldImpact(); - /// Returns whether or not `noSuchMethod` support has been enabled. bool get enabledNoSuchMethod => false; @@ -189,7 +182,7 @@ void registerConstSymbol(String name) {} ClassElement defaultSuperclass(ClassElement element) { - return compiler.coreClasses.objectClass; + return compiler.commonElements.objectClass; } bool isInterceptorClass(ClassElement element) => false; @@ -218,7 +211,8 @@ /// Called to register that [element] is statically known to be used. Any /// backend specific [WorldImpact] of this is returned. - WorldImpact registerUsedElement(Element element, {bool forResolution}) => + WorldImpact registerUsedElement(MemberElement element, + {bool forResolution}) => const WorldImpact(); /// This method is called immediately after the [LibraryElement] [library] has
diff --git a/pkg/compiler/lib/src/common/resolution.dart b/pkg/compiler/lib/src/common/resolution.dart index 2adfe26..9d3c852 100644 --- a/pkg/compiler/lib/src/common/resolution.dart +++ b/pkg/compiler/lib/src/common/resolution.dart
@@ -9,13 +9,12 @@ import '../compiler.dart' show Compiler; import '../constants/expressions.dart' show ConstantExpression; import '../constants/values.dart' show ConstantValue; -import '../core_types.dart' show CoreClasses, CoreTypes, CommonElements; +import '../core_types.dart' show CommonElements; import '../dart_types.dart' show DartType, Types; import '../elements/elements.dart' show AstElement, ClassElement, - ConstructorElement, Element, ExecutableElement, FunctionElement, @@ -127,8 +126,6 @@ abstract class Resolution implements Frontend { ParsingContext get parsingContext; DiagnosticReporter get reporter; - CoreClasses get coreClasses; - CoreTypes get coreTypes; CommonElements get commonElements; Types get types; Target get target;
diff --git a/pkg/compiler/lib/src/compile_time_constants.dart b/pkg/compiler/lib/src/compile_time_constants.dart index a1d62a2..d99734e 100644 --- a/pkg/compiler/lib/src/compile_time_constants.dart +++ b/pkg/compiler/lib/src/compile_time_constants.dart
@@ -13,7 +13,7 @@ import 'constants/evaluation.dart'; import 'constants/expressions.dart'; import 'constants/values.dart'; -import 'core_types.dart' show CoreTypes; +import 'core_types.dart' show CommonElements; import 'dart_types.dart'; import 'elements/elements.dart'; import 'elements/modelx.dart' show ConstantVariableMixin; @@ -159,7 +159,7 @@ DiagnosticReporter get reporter => compiler.reporter; - CoreTypes get coreTypes => compiler.coreTypes; + CommonElements get commonElements => compiler.commonElements; @override @deprecated @@ -272,7 +272,7 @@ expression = null; } } else { - DartType constantType = value.getType(coreTypes); + DartType constantType = value.getType(commonElements); if (!constantSystem.isSubtype( compiler.types, constantType, elementType)) { if (isConst) { @@ -407,7 +407,7 @@ ConstantSystem get constantSystem => handler.constantSystem; Resolution get resolution => compiler.resolution; - CoreTypes get coreTypes => compiler.coreTypes; + CommonElements get commonElements => compiler.commonElements; DiagnosticReporter get reporter => compiler.reporter; AstConstant evaluate(Node node) { @@ -594,7 +594,7 @@ } AstConstant visitLiteralSymbol(LiteralSymbol node) { - InterfaceType type = coreTypes.symbolType; + InterfaceType type = commonElements.symbolType; String text = node.slowNameString; List<AstConstant> arguments = <AstConstant>[ new AstConstant(context, node, new StringConstantExpression(text), @@ -810,10 +810,10 @@ if (condition == null || condition.isError) { return condition; } else if (!condition.value.isBool) { - DartType conditionType = condition.value.getType(coreTypes); + DartType conditionType = condition.value.getType(commonElements); if (isEvaluatingConstant) { reporter.reportErrorMessage(node.condition, MessageKind.NOT_ASSIGNABLE, - {'fromType': conditionType, 'toType': coreTypes.boolType}); + {'fromType': conditionType, 'toType': commonElements.boolType}); return new ErroneousAstConstant(context, node); } return null; @@ -1008,38 +1008,38 @@ } if (!firstArgument.isString) { - DartType type = defaultValue.getType(coreTypes); + DartType type = defaultValue.getType(commonElements); return reportNotCompileTimeConstant( normalizedArguments[0].node, MessageKind.NOT_ASSIGNABLE, - {'fromType': type, 'toType': coreTypes.stringType}); + {'fromType': type, 'toType': commonElements.stringType}); } if (constructor.isIntFromEnvironmentConstructor && !(defaultValue.isNull || defaultValue.isInt)) { - DartType type = defaultValue.getType(coreTypes); + DartType type = defaultValue.getType(commonElements); return reportNotCompileTimeConstant( normalizedArguments[1].node, MessageKind.NOT_ASSIGNABLE, - {'fromType': type, 'toType': coreTypes.intType}); + {'fromType': type, 'toType': commonElements.intType}); } if (constructor.isBoolFromEnvironmentConstructor && !(defaultValue.isNull || defaultValue.isBool)) { - DartType type = defaultValue.getType(coreTypes); + DartType type = defaultValue.getType(commonElements); return reportNotCompileTimeConstant( normalizedArguments[1].node, MessageKind.NOT_ASSIGNABLE, - {'fromType': type, 'toType': coreTypes.boolType}); + {'fromType': type, 'toType': commonElements.boolType}); } if (constructor.isStringFromEnvironmentConstructor && !(defaultValue.isNull || defaultValue.isString)) { - DartType type = defaultValue.getType(coreTypes); + DartType type = defaultValue.getType(commonElements); return reportNotCompileTimeConstant( normalizedArguments[1].node, MessageKind.NOT_ASSIGNABLE, - {'fromType': type, 'toType': coreTypes.stringType}); + {'fromType': type, 'toType': commonElements.stringType}); } String name = firstArgument.primitiveValue.slowToString(); @@ -1209,7 +1209,7 @@ void potentiallyCheckType(TypedElement element, AstConstant constant) { if (compiler.options.enableTypeAssertions) { DartType elementType = element.type.substByContext(constructedType); - DartType constantType = constant.value.getType(coreTypes); + DartType constantType = constant.value.getType(commonElements); if (!constantSystem.isSubtype( compiler.types, constantType, elementType)) { reporter.withCurrentElement(constant.element, () {
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart index 07d9c89..9670004 100644 --- a/pkg/compiler/lib/src/compiler.dart +++ b/pkg/compiler/lib/src/compiler.dart
@@ -10,7 +10,6 @@ import 'cache_strategy.dart' show CacheStrategy; import 'closure.dart' as closureMapping show ClosureTask; import 'common/backend_api.dart' show Backend; -import 'common/codegen.dart' show CodegenWorkItem; import 'common/names.dart' show Selectors; import 'common/names.dart' show Identifiers, Uris; import 'common/resolution.dart' @@ -25,7 +24,7 @@ import 'common.dart'; import 'compile_time_constants.dart'; import 'constants/values.dart'; -import 'core_types.dart' show CoreClasses, CommonElements, CoreTypes; +import 'core_types.dart' show CommonElements; import 'dart_types.dart' show DartType, DynamicType, InterfaceType, Types; import 'deferred_load.dart' show DeferredLoadTask; import 'diagnostics/code_location.dart'; @@ -78,9 +77,9 @@ WorldImpactBuilder, WorldImpactBuilderImpl; import 'util/util.dart' show Link, Setlet; -import 'world.dart' show ClosedWorld, ClosedWorldRefiner, WorldImpl; +import 'world.dart' show ClosedWorld, ClosedWorldRefiner, ClosedWorldImpl; -typedef Backend MakeBackendFuncion(Compiler compiler); +typedef Backend MakeBackendFunction(Compiler compiler); typedef CompilerDiagnosticReporter MakeReporterFunction( Compiler compiler, CompilerOptions options); @@ -90,7 +89,7 @@ final IdGenerator idGenerator = new IdGenerator(); Types types; - _CompilerCoreTypes _coreTypes; + _CompilerCommonElements _commonElements; CompilerDiagnosticReporter _reporter; CompilerResolution _resolution; ParsingContext _parsingContext; @@ -133,9 +132,7 @@ FunctionElement mainFunction; DiagnosticReporter get reporter => _reporter; - CommonElements get commonElements => _coreTypes; - CoreClasses get coreClasses => _coreTypes; - CoreTypes get coreTypes => _coreTypes; + CommonElements get commonElements => _commonElements; Resolution get resolution => _resolution; ParsingContext get parsingContext => _parsingContext; @@ -197,7 +194,7 @@ {CompilerOptions options, api.CompilerOutput outputProvider, this.environment: const _EmptyEnvironment(), - MakeBackendFuncion makeBackend, + MakeBackendFunction makeBackend, MakeReporterFunction makeReporter}) : this.options = options, this.cacheStrategy = new CacheStrategy(options.hasIncrementalSupport), @@ -210,9 +207,7 @@ _reporter = new CompilerDiagnosticReporter(this, options); } _resolution = createResolution(); - // TODO(johnniwinther): Initialize core types in [initializeCoreClasses] and - // make its field final. - _coreTypes = new _CompilerCoreTypes(_resolution, reporter); + _commonElements = new _CompilerCommonElements(_resolution, reporter); types = new Types(_resolution); if (options.verbose) { @@ -346,7 +341,7 @@ /// Note that [library] has not been scanned yet, nor has its imports/exports /// been resolved. void onLibraryCreated(LibraryElement library) { - _coreTypes.onLibraryCreated(library); + _commonElements.onLibraryCreated(library); backend.onLibraryCreated(library); } @@ -737,7 +732,7 @@ ClosedWorldRefiner closeResolution() { phase = PHASE_DONE_RESOLVING; - WorldImpl world = resolverWorld.openWorld.closeWorld(reporter); + ClosedWorldImpl world = resolverWorld.closeWorld(reporter); // Compute whole-program-knowledge that the backend needs. (This might // require the information computed in [world.closeWorld].) backend.onResolutionComplete(world, world); @@ -764,6 +759,9 @@ cls.ensureResolved(resolution); cls.forEachLocalMember(registerStaticUse); impactBuilder.registerTypeUse(new TypeUse.instantiation(cls.rawType)); + } else if (element.isTypedef) { + TypedefElement typdef = element; + typdef.ensureResolved(resolution); } else { registerStaticUse(element); } @@ -1127,7 +1125,7 @@ int hints = 0; } -class _CompilerCoreTypes implements CoreTypes, CoreClasses, CommonElements { +class _CompilerCommonElements implements CommonElements { final Resolution resolution; final DiagnosticReporter reporter; @@ -1144,7 +1142,7 @@ // specific backend. LibraryElement jsHelperLibrary; - _CompilerCoreTypes(this.resolution, this.reporter); + _CompilerCommonElements(this.resolution, this.reporter); // From dart:core @@ -1914,12 +1912,6 @@ ParsingContext get parsingContext => _compiler.parsingContext; @override - CoreClasses get coreClasses => _compiler.coreClasses; - - @override - CoreTypes get coreTypes => _compiler.coreTypes; - - @override CommonElements get commonElements => _compiler.commonElements; @override @@ -1948,14 +1940,14 @@ _compiler.mirrorUsageAnalyzerTask; @override - LibraryElement get coreLibrary => _compiler._coreTypes.coreLibrary; + LibraryElement get coreLibrary => _compiler._commonElements.coreLibrary; @override bool get wasProxyConstantComputedTestingOnly => _proxyConstant != null; @override void registerClass(ClassElement cls) { - enqueuer.universe.openWorld.registerClass(cls); + enqueuer.universe.registerClass(cls); } @override
diff --git a/pkg/compiler/lib/src/constant_system_dart.dart b/pkg/compiler/lib/src/constant_system_dart.dart index e1d468d..8df511f 100644 --- a/pkg/compiler/lib/src/constant_system_dart.dart +++ b/pkg/compiler/lib/src/constant_system_dart.dart
@@ -446,8 +446,8 @@ @override ConstantValue createType(Compiler compiler, DartType type) { // TODO(johnniwinther): Change the `Type` type to - // `compiler.coreTypes.typeType` and check the backend specific value in - // [checkConstMapKeysDontOverrideEquals] in 'members.dart'. + // `compiler.commonElements.typeType` and check the backend specific value + // in [checkConstMapKeysDontOverrideEquals] in 'members.dart'. return new TypeConstantValue( type, compiler.backend.backendClasses.typeImplementation
diff --git a/pkg/compiler/lib/src/constants/evaluation.dart b/pkg/compiler/lib/src/constants/evaluation.dart index 88aad8a..5b2428b 100644 --- a/pkg/compiler/lib/src/constants/evaluation.dart +++ b/pkg/compiler/lib/src/constants/evaluation.dart
@@ -10,7 +10,8 @@ /// Environment used for evaluating constant expressions. abstract class Environment { - // TODO(johnniwinther): Replace this with [CoreTypes] and maybe [Backend]. + // TODO(johnniwinther): Replace this with [CommonElements] and maybe + // [Backend]. Compiler get compiler; /// Read environments string passed in using the '-Dname=value' option.
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart index 6fc55de..f68dbe1 100644 --- a/pkg/compiler/lib/src/constants/expressions.dart +++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -80,7 +80,7 @@ /// Returns the type of this constant expression, if it is independent of the /// environment values. - DartType getKnownType(CoreTypes coreTypes) => null; + DartType getKnownType(CommonElements commonElements) => null; /// Returns a text string resembling the Dart code creating this constant. String toDartText() { @@ -236,7 +236,8 @@ } @override - DartType getKnownType(CoreTypes coreTypes) => coreTypes.boolType; + DartType getKnownType(CommonElements commonElements) => + commonElements.boolType; } /// Integer literal constant. @@ -271,7 +272,8 @@ } @override - DartType getKnownType(CoreTypes coreTypes) => coreTypes.intType; + DartType getKnownType(CommonElements commonElements) => + commonElements.intType; } /// Double literal constant. @@ -306,7 +308,8 @@ } @override - DartType getKnownType(CoreTypes coreTypes) => coreTypes.doubleType; + DartType getKnownType(CommonElements commonElements) => + commonElements.doubleType; } /// String literal constant. @@ -341,7 +344,8 @@ } @override - DartType getKnownType(CoreTypes coreTypes) => coreTypes.stringType; + DartType getKnownType(CommonElements commonElements) => + commonElements.stringType; } /// Null literal constant. @@ -374,7 +378,8 @@ bool _equals(NullConstantExpression other) => true; @override - DartType getKnownType(CoreTypes coreTypes) => coreTypes.nullType; + DartType getKnownType(CommonElements commonElements) => + commonElements.nullType; } /// Literal list constant. @@ -434,7 +439,7 @@ } @override - DartType getKnownType(CoreTypes coreTypes) => type; + DartType getKnownType(CommonElements commonElements) => type; @override bool get isImplicit => false; @@ -513,7 +518,7 @@ } @override - DartType getKnownType(CoreTypes coreTypes) => type; + DartType getKnownType(CommonElements commonElements) => type; @override bool get isImplicit => false; @@ -690,7 +695,8 @@ } @override - DartType getKnownType(CoreTypes coreTypes) => coreTypes.stringType; + DartType getKnownType(CommonElements commonElements) => + commonElements.stringType; @override bool get isPotential { @@ -730,7 +736,8 @@ } @override - DartType getKnownType(CoreTypes coreTypes) => coreTypes.symbolType; + DartType getKnownType(CommonElements commonElements) => + commonElements.symbolType; } /// Type literal. @@ -768,7 +775,8 @@ } @override - DartType getKnownType(CoreTypes coreTypes) => coreTypes.typeType; + DartType getKnownType(CommonElements commonElements) => + commonElements.typeType; } /// Reference to a constant local, top-level, or static variable. @@ -835,7 +843,8 @@ } @override - DartType getKnownType(CoreTypes coreTypes) => coreTypes.functionType; + DartType getKnownType(CommonElements commonElements) => + commonElements.functionType; } /// A constant binary expression like `a * b`. @@ -885,9 +894,9 @@ left.apply(arguments), operator, right.apply(arguments)); } - DartType getKnownType(CoreTypes coreTypes) { - DartType knownLeftType = left.getKnownType(coreTypes); - DartType knownRightType = right.getKnownType(coreTypes); + DartType getKnownType(CommonElements commonElements) { + DartType knownLeftType = left.getKnownType(commonElements); + DartType knownRightType = right.getKnownType(commonElements); switch (operator.kind) { case BinaryOperatorKind.EQ: case BinaryOperatorKind.NOT_EQ: @@ -897,38 +906,38 @@ case BinaryOperatorKind.LT: case BinaryOperatorKind.GTEQ: case BinaryOperatorKind.LTEQ: - return coreTypes.boolType; + return commonElements.boolType; case BinaryOperatorKind.ADD: - if (knownLeftType == coreTypes.stringType) { - assert(knownRightType == coreTypes.stringType); - return coreTypes.stringType; - } else if (knownLeftType == coreTypes.intType && - knownRightType == coreTypes.intType) { - return coreTypes.intType; + if (knownLeftType == commonElements.stringType) { + assert(knownRightType == commonElements.stringType); + return commonElements.stringType; + } else if (knownLeftType == commonElements.intType && + knownRightType == commonElements.intType) { + return commonElements.intType; } - assert(knownLeftType == coreTypes.doubleType || - knownRightType == coreTypes.doubleType); - return coreTypes.doubleType; + assert(knownLeftType == commonElements.doubleType || + knownRightType == commonElements.doubleType); + return commonElements.doubleType; case BinaryOperatorKind.SUB: case BinaryOperatorKind.MUL: case BinaryOperatorKind.MOD: - if (knownLeftType == coreTypes.intType && - knownRightType == coreTypes.intType) { - return coreTypes.intType; + if (knownLeftType == commonElements.intType && + knownRightType == commonElements.intType) { + return commonElements.intType; } - assert(knownLeftType == coreTypes.doubleType || - knownRightType == coreTypes.doubleType); - return coreTypes.doubleType; + assert(knownLeftType == commonElements.doubleType || + knownRightType == commonElements.doubleType); + return commonElements.doubleType; case BinaryOperatorKind.DIV: - return coreTypes.doubleType; + return commonElements.doubleType; case BinaryOperatorKind.IDIV: - return coreTypes.intType; + return commonElements.intType; case BinaryOperatorKind.AND: case BinaryOperatorKind.OR: case BinaryOperatorKind.XOR: case BinaryOperatorKind.SHR: case BinaryOperatorKind.SHL: - return coreTypes.intType; + return commonElements.intType; case BinaryOperatorKind.IF_NULL: case BinaryOperatorKind.INDEX: throw new UnsupportedError( @@ -1027,7 +1036,8 @@ } @override - DartType getKnownType(CoreTypes coreTypes) => coreTypes.boolType; + DartType getKnownType(CommonElements commonElements) => + commonElements.boolType; @override bool get isPotential { @@ -1082,8 +1092,8 @@ } @override - DartType getKnownType(CoreTypes coreTypes) { - return expression.getKnownType(coreTypes); + DartType getKnownType(CommonElements commonElements) { + return expression.getKnownType(commonElements); } @override @@ -1145,7 +1155,8 @@ } @override - DartType getKnownType(CoreTypes coreTypes) => coreTypes.intType; + DartType getKnownType(CommonElements commonElements) => + commonElements.intType; @override bool get isPotential { @@ -1216,9 +1227,9 @@ } @override - DartType getKnownType(CoreTypes coreTypes) { - DartType trueType = trueExp.getKnownType(coreTypes); - DartType falseType = falseExp.getKnownType(coreTypes); + DartType getKnownType(CommonElements commonElements) { + DartType trueType = trueExp.getKnownType(commonElements); + DartType falseType = falseExp.getKnownType(commonElements); if (trueType == falseType) { return trueType; } @@ -1397,7 +1408,8 @@ } @override - DartType getKnownType(CoreTypes coreTypes) => coreTypes.boolType; + DartType getKnownType(CommonElements commonElements) => + commonElements.boolType; } /// A `const int.fromEnvironment` constant. @@ -1462,7 +1474,8 @@ } @override - DartType getKnownType(CoreTypes coreTypes) => coreTypes.intType; + DartType getKnownType(CommonElements commonElements) => + commonElements.intType; } /// A `const String.fromEnvironment` constant. @@ -1523,7 +1536,8 @@ } @override - DartType getKnownType(CoreTypes coreTypes) => coreTypes.stringType; + DartType getKnownType(CommonElements commonElements) => + commonElements.stringType; } /// A constant expression referenced with a deferred prefix.
diff --git a/pkg/compiler/lib/src/constants/values.dart b/pkg/compiler/lib/src/constants/values.dart index cba4e69..5be89fc 100644 --- a/pkg/compiler/lib/src/constants/values.dart +++ b/pkg/compiler/lib/src/constants/values.dart
@@ -82,7 +82,7 @@ bool get isNegativeInfinity => false; // TODO(johnniwinther): Replace with a 'type' getter. - DartType getType(CoreTypes types); + DartType getType(CommonElements types); List<ConstantValue> getDependencies(); @@ -131,7 +131,7 @@ return new DartString.literal(element.name); } - DartType getType(CoreTypes types) => element.type; + DartType getType(CommonElements types) => element.type; int get hashCode => (17 * element.hashCode) & 0x7fffffff; @@ -189,7 +189,7 @@ get primitiveValue => null; - DartType getType(CoreTypes types) => types.nullType; + DartType getType(CommonElements types) => types.nullType; // The magic constant has no meaning. It is just a random value. int get hashCode => 785965825; @@ -261,7 +261,7 @@ bool get isOne => primitiveValue == 1; - DartType getType(CoreTypes types) => types.intType; + DartType getType(CommonElements types) => types.intType; // We have to override the equality operator so that ints and doubles are // treated as separate constants. @@ -322,7 +322,7 @@ bool get isNegativeInfinity => primitiveValue == -double.INFINITY; - DartType getType(CoreTypes types) => types.doubleType; + DartType getType(CommonElements types) => types.doubleType; bool operator ==(var other) { if (other is! DoubleConstantValue) return false; @@ -359,7 +359,7 @@ bool get isBool => true; - DartType getType(CoreTypes types) => types.boolType; + DartType getType(CommonElements types) => types.boolType; BoolConstantValue negate(); @@ -427,7 +427,7 @@ bool get isString => true; - DartType getType(CoreTypes types) => types.stringType; + DartType getType(CommonElements types) => types.stringType; bool operator ==(var other) { if (identical(this, other)) return true; @@ -458,7 +458,7 @@ bool get isObject => true; - DartType getType(CoreTypes types) => type; + DartType getType(CommonElements types) => type; void _unparseTypeArguments(StringBuffer sb) { if (!type.treatAsRaw) { @@ -656,7 +656,7 @@ return visitor.visitInterceptor(this, arg); } - DartType getType(CoreTypes types) => const DynamicType(); + DartType getType(CommonElements types) => const DynamicType(); ConstantValueKind get kind => ConstantValueKind.INTERCEPTOR; @@ -689,7 +689,7 @@ return visitor.visitSynthetic(this, arg); } - DartType getType(CoreTypes types) => const DynamicType(); + DartType getType(CommonElements types) => const DynamicType(); ConstantValueKind get kind => ConstantValueKind.SYNTHETIC; @@ -793,7 +793,7 @@ accept(ConstantValueVisitor visitor, arg) => visitor.visitDeferred(this, arg); - DartType getType(CoreTypes types) => referenced.getType(types); + DartType getType(CommonElements types) => referenced.getType(types); ConstantValueKind get kind => ConstantValueKind.DEFERRED; @@ -819,7 +819,7 @@ List<ConstantValue> getDependencies() => const <ConstantValue>[]; @override - DartType getType(CoreTypes types) => const DynamicType(); + DartType getType(CommonElements types) => const DynamicType(); ConstantValueKind get kind => ConstantValueKind.NON_CONSTANT;
diff --git a/pkg/compiler/lib/src/core_types.dart b/pkg/compiler/lib/src/core_types.dart index aff5fd9..6f70cbb 100644 --- a/pkg/compiler/lib/src/core_types.dart +++ b/pkg/compiler/lib/src/core_types.dart
@@ -14,8 +14,8 @@ LibraryElement, Element; -/// The core classes in Dart. -abstract class CoreClasses { +/// The common elements and types in Dart. +abstract class CommonElements { /// The `Object` class defined in 'dart:core'. ClassElement get objectClass; @@ -61,15 +61,12 @@ /// The `Iterable` class defined in 'dart:core'; ClassElement get iterableClass; - /// The `Future` class defined in 'async'; + /// The `Future` class defined in 'async';. ClassElement get futureClass; /// The `Stream` class defined in 'async'; ClassElement get streamClass; -} -/// TODO(sigmund): delete CoreClasses and merge it here. -abstract class CommonElements extends CoreClasses { /// The dart:core library. LibraryElement get coreLibrary; @@ -136,10 +133,7 @@ /// The 'filled' constructor of `List`. ConstructorElement get filledListConstructor; -} -/// The core types in Dart. -abstract class CoreTypes { /// The `Object` type defined in 'dart:core'. InterfaceType get objectType; @@ -194,9 +188,6 @@ /// If no type argument is provided, the canonical raw type is returned. InterfaceType iterableType([DartType elementType]); - /// The `Future` class declaration. - ClassElement get futureClass; - /// Returns an instance of the `Future` type defined in 'dart:async' with /// [elementType] as its type argument. ///
diff --git a/pkg/compiler/lib/src/dart_types.dart b/pkg/compiler/lib/src/dart_types.dart index 688b43e..b151ed9 100644 --- a/pkg/compiler/lib/src/dart_types.dart +++ b/pkg/compiler/lib/src/dart_types.dart
@@ -17,7 +17,6 @@ enum TypeKind { FUNCTION, INTERFACE, - STATEMENT, TYPEDEF, TYPE_VARIABLE, MALFORMED_TYPE, @@ -262,23 +261,6 @@ get containsMethodTypeVariableType => true; } -/// Internal type representing the result of analyzing a statement. -class StatementType extends DartType { - Element get element => null; - - TypeKind get kind => TypeKind.STATEMENT; - - String get name => 'statement'; - - const StatementType(); - - DartType subst(List<DartType> arguments, List<DartType> parameters) => this; - - accept(DartTypeVisitor visitor, var argument) { - return visitor.visitStatementType(this, argument); - } -} - class VoidType extends DartType { const VoidType(); @@ -952,8 +934,6 @@ R visitMalformedType(MalformedType type, A argument) => null; - R visitStatementType(StatementType type, A argument) => null; - R visitInterfaceType(InterfaceType type, A argument) => null; R visitTypedefType(TypedefType type, A argument) => null; @@ -981,10 +961,6 @@ R visitMalformedType(MalformedType type, A argument) => visitType(type, argument); - @override - R visitStatementType(StatementType type, A argument) => - visitType(type, argument); - R visitGenericType(GenericType type, A argument) => visitType(type, argument); @override @@ -1008,7 +984,7 @@ AbstractTypeRelation(this.resolution); - CoreTypes get coreTypes => resolution.coreTypes; + CommonElements get commonElements => resolution.commonElements; bool visitType(DartType t, DartType s) { throw 'internal error: unknown type kind ${t.kind}'; @@ -1057,7 +1033,7 @@ } } - if (s == coreTypes.functionType && t.element.callType != null) { + if (s == commonElements.functionType && t.element.callType != null) { return true; } else if (s is FunctionType) { FunctionType callType = t.callType; @@ -1068,7 +1044,7 @@ } bool visitFunctionType(FunctionType t, DartType s) { - if (s == coreTypes.functionType) { + if (s == commonElements.functionType) { return true; } if (s is! FunctionType) return false; @@ -1198,7 +1174,7 @@ MoreSpecificVisitor(Resolution resolution) : super(resolution); bool isMoreSpecific(DartType t, DartType s) { - if (identical(t, s) || s.treatAsDynamic || t == coreTypes.nullType) { + if (identical(t, s) || s.treatAsDynamic || t == commonElements.nullType) { return true; } if (t.isVoid || s.isVoid) { @@ -1207,7 +1183,7 @@ if (t.treatAsDynamic) { return false; } - if (s == coreTypes.objectType) { + if (s == commonElements.objectType) { return true; } t.computeUnaliased(resolution); @@ -1286,7 +1262,7 @@ /// Basic interface for the Dart type system. abstract class DartTypes { /// The types defined in 'dart:core'. - CoreTypes get coreTypes; + CommonElements get commonElements; /// Returns `true` if [t] is a subtype of [s]. bool isSubtype(DartType t, DartType s); @@ -1302,7 +1278,7 @@ final SubtypeVisitor subtypeVisitor; final PotentialSubtypeVisitor potentialSubtypeVisitor; - CoreTypes get coreTypes => resolution.coreTypes; + CommonElements get commonElements => resolution.commonElements; DiagnosticReporter get reporter => resolution.reporter; @@ -1334,11 +1310,11 @@ /// return. DartType flatten(DartType type) { if (type is InterfaceType) { - if (type.element == coreTypes.futureClass) { + if (type.element == commonElements.futureClass) { // T = Future<S> return flatten(type.typeArguments.first); } - InterfaceType futureType = type.asInstanceOf(coreTypes.futureClass); + InterfaceType futureType = type.asInstanceOf(commonElements.futureClass); if (futureType != null) { // T << Future<S> return futureType.typeArguments.single; @@ -1551,17 +1527,6 @@ // [b] is a malformed or statement type => a > b. return 1; } - if (a.kind == TypeKind.STATEMENT) { - if (b.kind == TypeKind.STATEMENT) { - return 0; - } else { - // [b] is a malformed type => a > b. - return 1; - } - } else if (b.kind == TypeKind.STATEMENT) { - // [a] is a malformed type => a < b. - return -1; - } assert(a.isMalformed); assert(b.isMalformed); // TODO(johnniwinther): Can we do this better? @@ -1641,7 +1606,7 @@ /// [a] and [b]. DartType computeLeastUpperBoundFunctionTypes(FunctionType a, FunctionType b) { if (a.parameterTypes.length != b.parameterTypes.length) { - return coreTypes.functionType; + return commonElements.functionType; } DartType returnType = computeLeastUpperBound(a.returnType, b.returnType); List<DartType> parameterTypes = @@ -1718,10 +1683,10 @@ } if (a.isFunctionType) { - a = coreTypes.functionType; + a = commonElements.functionType; } if (b.isFunctionType) { - b = coreTypes.functionType; + b = commonElements.functionType; } if (a.isInterfaceType && b.isInterfaceType) { @@ -1763,7 +1728,7 @@ TypeVariableType variable = type; type = variable.element.bound; if (type == originalType) { - type = resolution.coreTypes.objectType; + type = resolution.commonElements.objectType; } } if (type.isMalformed) { @@ -1807,7 +1772,7 @@ return null; } if (type.isFunctionType) { - type = resolution.coreTypes.functionType; + type = resolution.commonElements.functionType; } assert(invariant(NO_LOCATION_SPANNABLE, type.isInterfaceType, message: "unexpected type kind ${type.kind}."));
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart index 49e1668..838a783 100644 --- a/pkg/compiler/lib/src/deferred_load.dart +++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -797,7 +797,7 @@ metadata.ensureResolved(compiler.resolution); ConstantValue value = compiler.constants.getConstantValue(metadata.constant); - Element element = value.getType(compiler.coreTypes).element; + Element element = value.getType(compiler.commonElements).element; if (element == deferredLibraryClass) { reporter.reportErrorMessage( import, MessageKind.DEFERRED_OLD_SYNTAX); @@ -1033,7 +1033,7 @@ metadata.ensureResolved(compiler.resolution); ConstantValue value = compiler.constants.getConstantValue(metadata.constant); - Element element = value.getType(compiler.coreTypes).element; + Element element = value.getType(compiler.commonElements).element; if (element == compiler.commonElements.deferredLibraryClass) { ConstructedConstantValue constant = value; StringConstantValue s = constant.fields.values.single;
diff --git a/pkg/compiler/lib/src/elements/common.dart b/pkg/compiler/lib/src/elements/common.dart index 83eb3ea..3be91d3 100644 --- a/pkg/compiler/lib/src/elements/common.dart +++ b/pkg/compiler/lib/src/elements/common.dart
@@ -7,7 +7,7 @@ library elements.common; import '../common/names.dart' show Identifiers, Names, Uris; -import '../core_types.dart' show CoreClasses; +import '../core_types.dart' show CommonElements; import '../dart_types.dart' show DartType, InterfaceType, FunctionType; import '../util/util.dart' show Link; import 'elements.dart'; @@ -439,8 +439,9 @@ } @override - bool implementsFunction(CoreClasses coreClasses) { - return asInstanceOf(coreClasses.functionClass) != null || callType != null; + bool implementsFunction(CommonElements commonElements) { + return asInstanceOf(commonElements.functionClass) != null || + callType != null; } @override
diff --git a/pkg/compiler/lib/src/elements/elements.dart b/pkg/compiler/lib/src/elements/elements.dart index 95acc7b..ded810b 100644 --- a/pkg/compiler/lib/src/elements/elements.dart +++ b/pkg/compiler/lib/src/elements/elements.dart
@@ -9,7 +9,7 @@ import '../compiler.dart' show Compiler; import '../constants/constructors.dart'; import '../constants/expressions.dart'; -import '../core_types.dart' show CoreClasses, CommonElements; +import '../core_types.dart' show CommonElements; import '../dart_types.dart'; import '../ordered_typeset.dart' show OrderedTypeSet; import '../resolution/scope.dart' show Scope; @@ -807,7 +807,7 @@ closedWorld.backendClasses.isNative(cls) && closedWorld.isSubtypeOf( cls, closedWorld.commonElements.typedDataClass) && - closedWorld.isSubtypeOf(cls, closedWorld.coreClasses.listClass) && + closedWorld.isSubtypeOf(cls, closedWorld.commonElements.listClass) && constructor.name == ''; } @@ -1544,7 +1544,7 @@ /// Returns `true` if this class implements [Function] either by directly /// implementing the interface or by providing a [call] method. - bool implementsFunction(CoreClasses coreClasses); + bool implementsFunction(CommonElements commonElements); /// Returns `true` if this class extends [cls] directly or indirectly. ///
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart index 30c5aef..3af5382 100644 --- a/pkg/compiler/lib/src/enqueue.dart +++ b/pkg/compiler/lib/src/enqueue.dart
@@ -8,8 +8,7 @@ import 'cache_strategy.dart'; import 'common/backend_api.dart' show Backend; -import 'common/names.dart' show Identifiers; -import 'common/resolution.dart' show Resolution, ResolutionWorkItem; +import 'common/resolution.dart' show Resolution; import 'common/tasks.dart' show CompilerTask; import 'common/work.dart' show WorkItem; import 'common.dart'; @@ -19,7 +18,6 @@ import 'elements/elements.dart' show AnalyzableElement, - AstElement, ClassElement, ConstructorElement, Element, @@ -70,6 +68,7 @@ } abstract class Enqueuer { + // TODO(johnniwinther): Rename to `worldBuilder`. WorldBuilder get universe; native.NativeEnqueuer get nativeEnqueuer; void forgetEntity(Entity entity, Compiler compiler); @@ -137,13 +136,14 @@ final EnqueuerStrategy strategy; final Set<ClassEntity> _recentClasses = new Setlet<ClassEntity>(); final ResolutionWorldBuilderImpl _universe; + final WorkItemBuilder _workItemBuilder; bool queueIsClosed = false; WorldImpactVisitor _impactVisitor; /// All declaration elements that have been processed by the resolver. - final Set<Entity> _processedElements = new Set<Entity>(); + final Set<Entity> _processedEntities = new Set<Entity>(); final Queue<WorkItem> _queue = new Queue<WorkItem>(); @@ -164,14 +164,13 @@ this._resolution = resolution, this.nativeEnqueuer = backend.nativeResolutionEnqueuer(), _universe = new ResolutionWorldBuilderImpl( - backend, resolution, cacheStrategy, const TypeMaskStrategy()) { + backend, resolution, cacheStrategy, const OpenWorldStrategy()), + _workItemBuilder = new ResolutionWorkItemBuilder(resolution) { _impactVisitor = new EnqueuerImplImpactVisitor(this); } ResolutionWorldBuilder get universe => _universe; - OpenWorld get _openWorld => universe.openWorld; - bool get queueIsEmpty => _queue.isEmpty; DiagnosticReporter get _reporter => _resolution.reporter; @@ -300,7 +299,7 @@ break; case TypeUseKind.TYPE_LITERAL: if (type.isTypedef) { - universe.openWorld.registerTypedef(type.element); + universe.registerTypedef(type.element); } break; } @@ -330,9 +329,9 @@ while (_queue.isNotEmpty) { // TODO(johnniwinther): Find an optimal process order. WorkItem work = _queue.removeLast(); - if (!_processedElements.contains(work.element)) { + if (!_processedEntities.contains(work.element)) { strategy.processWorkItem(f, work); - _processedElements.add(work.element); + _processedEntities.add(work.element); } } List recents = _recentClasses.toList(growable: false); @@ -344,13 +343,13 @@ } void logSummary(log(message)) { - log('Resolved ${_processedElements.length} elements.'); + log('Resolved ${_processedEntities.length} elements.'); nativeEnqueuer.logSummary(log); } String toString() => 'Enqueuer($name)'; - Iterable<Entity> get processedEntities => _processedElements; + Iterable<Entity> get processedEntities => _processedEntities; ImpactUseCase get impactUse => IMPACT_USE; @@ -358,37 +357,32 @@ /// Returns `true` if [element] has been processed by the resolution enqueuer. // TODO(johnniwinther): Move this to the [OpenWorld]/[ResolutionWorldBuilder]. - bool hasBeenProcessed(Element element) { + bool hasBeenProcessed(MemberElement element) { assert(invariant(element, element == element.analyzableElement.declaration, message: "Unexpected element $element")); - return _processedElements.contains(element); + return _processedEntities.contains(element); } - /// Registers [element] as processed by the resolution enqueuer. Used only for + /// Registers [entity] as processed by the resolution enqueuer. Used only for /// testing. - void registerProcessedElementInternal(AstElement element) { - _processedElements.add(element); + void registerProcessedElementInternal(Entity entity) { + _processedEntities.add(entity); } - /// Adds [element] to the work list if it has not already been processed. - /// - /// Invariant: [element] must be a declaration element. - void _addToWorkList(Element element) { - assert(invariant(element, element.isDeclaration)); - if (element.isMalformed) return; + /// Create a [WorkItem] for [entity] and add it to the work list if it has not + /// already been processed. + void _addToWorkList(MemberEntity entity) { + if (hasBeenProcessed(entity)) return; + WorkItem workItem = _workItemBuilder.createWorkItem(entity); + if (workItem == null) return; - assert(invariant(element, element is AnalyzableElement, - message: 'Element $element is not analyzable.')); - if (hasBeenProcessed(element)) return; if (queueIsClosed) { throw new SpannableAssertionFailure( - element, "Resolution work list is closed. Trying to add $element."); + entity, "Resolution work list is closed. Trying to add $entity."); } - applyImpact(backend.registerUsedElement(element, forResolution: true)); - _openWorld.registerUsedElement(element); - - ResolutionWorkItem workItem = _resolution.createWorkItem(element); + applyImpact(backend.registerUsedElement(entity, forResolution: true)); + _universe.registerUsedElement(entity); _queue.add(workItem); } @@ -430,7 +424,7 @@ void forgetEntity(Entity entity, Compiler compiler) { _universe.forgetEntity(entity, compiler); - _processedElements.remove(entity); + _processedEntities.remove(entity); } } @@ -531,3 +525,26 @@ _DeferredAction(this.element, this.action); } + +/// Interface for creating work items for enqueued member entities. +abstract class WorkItemBuilder { + WorkItem createWorkItem(MemberEntity entity); +} + +/// Builder that creates work item necessary for the resolution of a +/// [MemberElement]. +class ResolutionWorkItemBuilder extends WorkItemBuilder { + final Resolution _resolution; + + ResolutionWorkItemBuilder(this._resolution); + + @override + WorkItem createWorkItem(MemberElement element) { + assert(invariant(element, element.isDeclaration)); + if (element.isMalformed) return null; + + assert(invariant(element, element is AnalyzableElement, + message: 'Element $element is not analyzable.')); + return _resolution.createWorkItem(element); + } +}
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart index ef9fbfa..f9773c4 100644 --- a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart +++ b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
@@ -891,7 +891,7 @@ // TODO(kasperl): We should be able to tell that the type of a literal // symbol is always a non-null exact symbol implementation -- not just // any non-null subtype of the symbol interface. - return types.nonNullSubtype(closedWorld.coreClasses.symbolClass); + return types.nonNullSubtype(closedWorld.commonElements.symbolClass); } @override @@ -1042,7 +1042,7 @@ } } else { // Narrow the elements to a non-null type. - DartType objectType = closedWorld.coreTypes.objectType; + DartType objectType = closedWorld.commonElements.objectType; if (Elements.isLocal(receiverElement)) { narrow(receiverElement, objectType, node); }
diff --git a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart index b60f5d6..1001ce2a 100644 --- a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart +++ b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
@@ -9,7 +9,7 @@ import '../common/names.dart' show Identifiers, Selectors; import '../compiler.dart' show Compiler; import '../constants/values.dart' show ConstantValue, IntConstantValue; -import '../core_types.dart' show CoreClasses, CoreTypes; +import '../core_types.dart' show CommonElements; import '../dart_types.dart' show DartType; import '../elements/elements.dart'; import '../js_backend/backend_helpers.dart'; @@ -47,9 +47,7 @@ InferrerEngine( this.compiler, this.closedWorld, this.closedWorldRefiner, this.types); - CoreClasses get coreClasses => compiler.coreClasses; - - CoreTypes get coreTypes => compiler.coreTypes; + CommonElements get commonElements => closedWorld.commonElements; /** * Records the default type of parameter [parameter]. @@ -234,19 +232,20 @@ for (var type in typesReturned) { T mappedType; if (type == native.SpecialType.JsObject) { - mappedType = types.nonNullExact(coreClasses.objectClass); - } else if (type == coreTypes.stringType) { + mappedType = types.nonNullExact(commonElements.objectClass); + } else if (type == commonElements.stringType) { mappedType = types.stringType; - } else if (type == coreTypes.intType) { + } else if (type == commonElements.intType) { mappedType = types.intType; - } else if (type == coreTypes.numType || type == coreTypes.doubleType) { + } else if (type == commonElements.numType || + type == commonElements.doubleType) { // Note: the backend double class is specifically for non-integer // doubles, and a native behavior returning 'double' does not guarantee // a non-integer return type, so we return the number type for those. mappedType = types.numType; - } else if (type == coreTypes.boolType) { + } else if (type == commonElements.boolType) { mappedType = types.boolType; - } else if (type == coreTypes.nullType) { + } else if (type == commonElements.nullType) { mappedType = types.nullType; } else if (type.isVoid) { mappedType = types.nullType; @@ -1416,7 +1415,7 @@ ClassElement cls = outermostElement.enclosingClass.declaration; MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_); if (!Selectors.noSuchMethod_.signatureApplies(element)) { - element = compiler.coreClasses.objectClass + element = compiler.commonElements.objectClass .lookupMember(Identifiers.noSuchMethod_); } return handleStaticSend(node, selector, mask, element, arguments);
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart index 332e256..3b7884e 100644 --- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart +++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -273,7 +273,7 @@ {bool isNullable: true}) { if (annotation.treatAsDynamic) return type; if (annotation.isVoid) return nullType; - if (annotation.element == closedWorld.coreClasses.objectClass && + if (annotation.element == closedWorld.commonElements.objectClass && isNullable) { return type; } @@ -285,7 +285,7 @@ return type; } else { assert(annotation.isInterfaceType); - otherType = annotation.element == closedWorld.coreClasses.objectClass + otherType = annotation.element == closedWorld.commonElements.objectClass ? dynamicType.type.nonNullable() : new TypeMask.nonNullSubtype(annotation.element, closedWorld); }
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart index fe066c7..2ef3e2a 100644 --- a/pkg/compiler/lib/src/js_backend/backend.dart +++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -25,7 +25,7 @@ import '../constants/constant_system.dart'; import '../constants/expressions.dart'; import '../constants/values.dart'; -import '../core_types.dart' show CommonElements, CoreClasses, CoreTypes; +import '../core_types.dart' show CommonElements; import '../dart_types.dart'; import '../deferred_load.dart' show DeferredLoadTask; import '../dump_info.dart' show DumpInfoTask; @@ -324,9 +324,8 @@ /** * The generated code as a js AST for compiled methods. */ - Map<Element, jsAst.Expression> get generatedCode { - return codegenEnqueuer.generatedCode; - } + final Map<Element, jsAst.Expression> generatedCode = + <Element, jsAst.Expression>{}; FunctionInlineCache inlineCache = new FunctionInlineCache(); @@ -541,6 +540,7 @@ PatchResolverTask patchResolverTask; bool enabledNoSuchMethod = false; + bool _noSuchMethodEnabledForCodegen = false; SourceInformationStrategy sourceInformationStrategy; @@ -607,10 +607,6 @@ CommonElements get commonElements => compiler.commonElements; - CoreClasses get coreClasses => compiler.coreClasses; - - CoreTypes get coreTypes => compiler.coreTypes; - Resolution get resolution => compiler.resolution; /// Returns constant environment for the JavaScript interpretation of the @@ -682,7 +678,7 @@ compiler.commonElements.isSymbolConstructor(element) || helpers.isSymbolValidatedConstructor(element) || element == helpers.syncCompleterConstructor || - element == coreClasses.symbolClass || + element == commonElements.symbolClass || element == helpers.objectNoSuchMethod) { // TODO(johnniwinther): These are valid but we could be more precise. return true; @@ -697,10 +693,10 @@ element.library == helpers.isolateHelperLibrary) { // TODO(johnniwinther): We should be more precise about these. return true; - } else if (element == coreClasses.listClass || + } else if (element == commonElements.listClass || element == helpers.mapLiteralClass || - element == coreClasses.functionClass || - element == coreClasses.stringClass) { + element == commonElements.functionClass || + element == commonElements.stringClass) { // TODO(johnniwinther): Avoid these. return true; } else if (element == helpers.genericNoSuchMethod || @@ -978,7 +974,7 @@ ClassElement interceptorClass) { if (interceptorClass == null) return; interceptorClass.ensureResolved(resolution); - coreClasses.objectClass.forEachMember((_, Element member) { + commonElements.objectClass.forEachMember((_, Element member) { if (member.isGenerativeConstructor) return; Element interceptorMember = interceptorClass.lookupMember(member.name); // Interceptors must override all Object methods due to calling convention @@ -1002,7 +998,7 @@ } if (member.isSynthesized) return; // All methods on [Object] are shadowed by [Interceptor]. - if (classElement == coreClasses.objectClass) return; + if (classElement == commonElements.objectClass) return; Set<Element> set = interceptedElements.putIfAbsent( member.name, () => new Set<Element>()); set.add(member); @@ -1025,7 +1021,7 @@ cls.ensureResolved(resolution); cls.forEachMember((ClassElement classElement, Element member) { // All methods on [Object] are shadowed by [Interceptor]. - if (classElement == coreClasses.objectClass) return; + if (classElement == commonElements.objectClass) return; Set<Element> set = interceptedElements.putIfAbsent( member.name, () => new Set<Element>()); set.add(member); @@ -1075,7 +1071,7 @@ void computeImpactForCompileTimeConstantInternal(ConstantValue constant, WorldImpactBuilder impactBuilder, bool isForResolution) { - DartType type = constant.getType(compiler.coreTypes); + DartType type = constant.getType(compiler.commonElements); computeImpactForInstantiatedConstantType(type, impactBuilder); if (constant.isFunction) { @@ -1104,7 +1100,7 @@ void computeImpactForInstantiatedConstantType( DartType type, WorldImpactBuilder impactBuilder) { DartType instantiatedType = - type.isFunctionType ? coreTypes.functionType : type; + type.isFunctionType ? commonElements.functionType : type; if (type is InterfaceType) { impactBuilder .registerTypeUse(new TypeUse.instantiation(instantiatedType)); @@ -1144,19 +1140,19 @@ // Register any helper that will be needed by the backend. if (forResolution) { - if (cls == coreClasses.intClass || - cls == coreClasses.doubleClass || - cls == coreClasses.numClass) { + if (cls == commonElements.intClass || + cls == commonElements.doubleClass || + cls == commonElements.numClass) { impactTransformer.registerBackendImpact( impactBuilder, impacts.numClasses); - } else if (cls == coreClasses.listClass || - cls == coreClasses.stringClass) { + } else if (cls == commonElements.listClass || + cls == commonElements.stringClass) { impactTransformer.registerBackendImpact( impactBuilder, impacts.listOrStringClasses); - } else if (cls == coreClasses.functionClass) { + } else if (cls == commonElements.functionClass) { impactTransformer.registerBackendImpact( impactBuilder, impacts.functionClass); - } else if (cls == coreClasses.mapClass) { + } else if (cls == commonElements.mapClass) { impactTransformer.registerBackendImpact( impactBuilder, impacts.mapClass); // For map literals, the dependency between the implementation class @@ -1177,10 +1173,10 @@ impactTransformer.registerBackendImpact( impactBuilder, impacts.closureClass); } - if (cls == coreClasses.stringClass || cls == helpers.jsStringClass) { + if (cls == commonElements.stringClass || cls == helpers.jsStringClass) { addInterceptors(helpers.jsStringClass, impactBuilder, forResolution: forResolution); - } else if (cls == coreClasses.listClass || + } else if (cls == commonElements.listClass || cls == helpers.jsArrayClass || cls == helpers.jsFixedArrayClass || cls == helpers.jsExtendableArrayClass || @@ -1199,7 +1195,7 @@ impactTransformer.registerBackendImpact( impactBuilder, impacts.listClasses); } - } else if (cls == coreClasses.intClass || cls == helpers.jsIntClass) { + } else if (cls == commonElements.intClass || cls == helpers.jsIntClass) { addInterceptors(helpers.jsIntClass, impactBuilder, forResolution: forResolution); addInterceptors(helpers.jsPositiveIntClass, impactBuilder, @@ -1210,18 +1206,19 @@ forResolution: forResolution); addInterceptors(helpers.jsNumberClass, impactBuilder, forResolution: forResolution); - } else if (cls == coreClasses.doubleClass || cls == helpers.jsDoubleClass) { + } else if (cls == commonElements.doubleClass || + cls == helpers.jsDoubleClass) { addInterceptors(helpers.jsDoubleClass, impactBuilder, forResolution: forResolution); addInterceptors(helpers.jsNumberClass, impactBuilder, forResolution: forResolution); - } else if (cls == coreClasses.boolClass || cls == helpers.jsBoolClass) { + } else if (cls == commonElements.boolClass || cls == helpers.jsBoolClass) { addInterceptors(helpers.jsBoolClass, impactBuilder, forResolution: forResolution); - } else if (cls == coreClasses.nullClass || cls == helpers.jsNullClass) { + } else if (cls == commonElements.nullClass || cls == helpers.jsNullClass) { addInterceptors(helpers.jsNullClass, impactBuilder, forResolution: forResolution); - } else if (cls == coreClasses.numClass || cls == helpers.jsNumberClass) { + } else if (cls == commonElements.numClass || cls == helpers.jsNumberClass) { addInterceptors(helpers.jsIntClass, impactBuilder, forResolution: forResolution); addInterceptors(helpers.jsPositiveIntClass, impactBuilder, @@ -1306,6 +1303,11 @@ noSuchMethodRegistry.onTypeInferenceComplete(); } + /// Called to register that an instantiated generic class has a call method. + /// Any backend specific [WorldImpact] of this is returned. + /// + /// Note: The [callMethod] is registered even thought it doesn't reference + /// the type variables. WorldImpact registerCallMethodWithFreeTypeVariables(Element callMethod, {bool forResolution}) { if (forResolution || methodNeedsRti(callMethod)) { @@ -1388,7 +1390,7 @@ return null; } - WorldImpact enableNoSuchMethod() { + WorldImpact computeNoSuchMethodImpact() { return impactTransformer.createImpactFor(impacts.noSuchMethodSupport); } @@ -1527,7 +1529,7 @@ // Native classes inherit from Interceptor. return isNative(element) ? helpers.jsInterceptorClass - : coreClasses.objectClass; + : commonElements.objectClass; } /** @@ -1641,23 +1643,23 @@ if (nativeCheckOnly) return null; return 'voidTypeCheck'; } else if (element == helpers.jsStringClass || - element == coreClasses.stringClass) { + element == commonElements.stringClass) { if (nativeCheckOnly) return null; return typeCast ? 'stringTypeCast' : 'stringTypeCheck'; } else if (element == helpers.jsDoubleClass || - element == coreClasses.doubleClass) { + element == commonElements.doubleClass) { if (nativeCheckOnly) return null; return typeCast ? 'doubleTypeCast' : 'doubleTypeCheck'; } else if (element == helpers.jsNumberClass || - element == coreClasses.numClass) { + element == commonElements.numClass) { if (nativeCheckOnly) return null; return typeCast ? 'numTypeCast' : 'numTypeCheck'; } else if (element == helpers.jsBoolClass || - element == coreClasses.boolClass) { + element == commonElements.boolClass) { if (nativeCheckOnly) return null; return typeCast ? 'boolTypeCast' : 'boolTypeCheck'; } else if (element == helpers.jsIntClass || - element == coreClasses.intClass || + element == commonElements.intClass || element == helpers.jsUInt32Class || element == helpers.jsUInt31Class || element == helpers.jsPositiveIntClass) { @@ -1681,7 +1683,7 @@ } else { return typeCast ? 'stringSuperTypeCast' : 'stringSuperTypeCheck'; } - } else if ((element == coreClasses.listClass || + } else if ((element == commonElements.listClass || element == helpers.jsArrayClass) && type.treatAsRaw) { if (nativeCheckOnly) return null; @@ -1734,11 +1736,11 @@ */ bool hasDirectCheckFor(DartType type) { Element element = type.element; - return element == coreClasses.stringClass || - element == coreClasses.boolClass || - element == coreClasses.numClass || - element == coreClasses.intClass || - element == coreClasses.doubleClass || + return element == commonElements.stringClass || + element == commonElements.boolClass || + element == commonElements.numClass || + element == commonElements.intClass || + element == commonElements.doubleClass || element == helpers.jsArrayClass || element == helpers.jsMutableArrayClass || element == helpers.jsExtendableArrayClass || @@ -1756,7 +1758,7 @@ return _closedWorld.hasOnlySubclasses(classElement); } - WorldImpact registerUsedElement(Element element, {bool forResolution}) { + WorldImpact registerUsedElement(MemberElement element, {bool forResolution}) { WorldImpactBuilderImpl worldImpact = new WorldImpactBuilderImpl(); if (element == helpers.disableTreeShakingMarker) { isTreeShakingDisabled = true; @@ -1787,16 +1789,15 @@ customElementsAnalysis.registerStaticUse(element, forResolution: forResolution); - if (forResolution) { - if (element.isFunction && element.isInstanceMember) { - MemberElement function = element; - ClassElement cls = function.enclosingClass; - if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) { - worldImpact.addImpact(registerCallMethodWithFreeTypeVariables( - function, - forResolution: true)); - } + if (element.isFunction && element.isInstanceMember) { + MemberElement function = element; + ClassElement cls = function.enclosingClass; + if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) { + worldImpact.addImpact(registerCallMethodWithFreeTypeVariables(function, + forResolution: forResolution)); } + } + if (forResolution) { // Enable isolate support if we start using something from the isolate // library, or timers for the async library. We exclude constant fields, // which are ending here because their initializing expression is @@ -1831,6 +1832,10 @@ } else if (compiler.commonElements.isFunctionApplyMethod(element)) { hasFunctionApplySupport = true; } + } else { + // TODO(sigmund): add other missing dependencies (internals, selectors + // enqueued after allocations). + compiler.dumpInfoTask.registerDependency(element); } return worldImpact; } @@ -1914,20 +1919,20 @@ helpers.onLibrariesLoaded(loadedLibraries); implementationClasses = <ClassElement, ClassElement>{}; - implementationClasses[coreClasses.intClass] = helpers.jsIntClass; - implementationClasses[coreClasses.boolClass] = helpers.jsBoolClass; - implementationClasses[coreClasses.numClass] = helpers.jsNumberClass; - implementationClasses[coreClasses.doubleClass] = helpers.jsDoubleClass; - implementationClasses[coreClasses.stringClass] = helpers.jsStringClass; - implementationClasses[coreClasses.listClass] = helpers.jsArrayClass; - implementationClasses[coreClasses.nullClass] = helpers.jsNullClass; + implementationClasses[commonElements.intClass] = helpers.jsIntClass; + implementationClasses[commonElements.boolClass] = helpers.jsBoolClass; + implementationClasses[commonElements.numClass] = helpers.jsNumberClass; + implementationClasses[commonElements.doubleClass] = helpers.jsDoubleClass; + implementationClasses[commonElements.stringClass] = helpers.jsStringClass; + implementationClasses[commonElements.listClass] = helpers.jsArrayClass; + implementationClasses[commonElements.nullClass] = helpers.jsNullClass; // These methods are overwritten with generated versions. inlineCache.markAsNonInlinable(helpers.getInterceptorMethod, insideLoop: true); specialOperatorEqClasses - ..add(coreClasses.objectClass) + ..add(commonElements.objectClass) ..add(helpers.jsInterceptorClass) ..add(helpers.jsNullClass); @@ -2016,7 +2021,7 @@ ConstantValue value = compiler.constants.getConstantValue(metadata.constant); if (value == null) continue; - DartType type = value.getType(compiler.coreTypes); + DartType type = value.getType(compiler.commonElements); if (metaTargetsUsed.contains(type.element)) return true; } return false; @@ -2131,7 +2136,7 @@ for (LibraryElement lib in compiler.libraryLoader.libraries) { if (lib.isInternalLibrary) continue; lib.forEachLocalMember((Element member) { - if (!member.isClass && + if (!(member.isClass || member.isTypedef) && resolution.hasBeenProcessed(member) && referencedFromMirrorSystem(member)) { reflectableMembers.add(member); @@ -2237,22 +2242,31 @@ enqueuer.applyImpact( typeVariableHandler.flush(forResolution: enqueuer.isResolutionQueue)); - if (!enqueuer.queueIsEmpty) return false; - - for (ClassElement cls in recentClasses) { - Element element = cls.lookupLocalMember(Identifiers.noSuchMethod_); - if (element != null && element.isInstanceMember && element.isFunction) { - registerNoSuchMethod(element); + if (enqueuer.isResolutionQueue) { + for (ClassElement cls in recentClasses) { + Element element = cls.lookupLocalMember(Identifiers.noSuchMethod_); + if (element != null && element.isInstanceMember && element.isFunction) { + registerNoSuchMethod(element); + } } } noSuchMethodRegistry.onQueueEmpty(); - if (!enabledNoSuchMethod && - (noSuchMethodRegistry.hasThrowingNoSuchMethod || - noSuchMethodRegistry.hasComplexNoSuchMethod)) { - enqueuer.applyImpact(enableNoSuchMethod()); - enabledNoSuchMethod = true; + if (enqueuer.isResolutionQueue) { + if (!enabledNoSuchMethod && + (noSuchMethodRegistry.hasThrowingNoSuchMethod || + noSuchMethodRegistry.hasComplexNoSuchMethod)) { + enqueuer.applyImpact(computeNoSuchMethodImpact()); + enabledNoSuchMethod = true; + } + } else { + if (enabledNoSuchMethod && !_noSuchMethodEnabledForCodegen) { + enqueuer.applyImpact(computeNoSuchMethodImpact()); + _noSuchMethodEnabledForCodegen = true; + } } + if (!enqueuer.queueIsEmpty) return false; + if (compiler.options.useKernel && compiler.mainApp != null) { kernelTask.buildKernelIr(); } @@ -2483,6 +2497,12 @@ constants.forgetElement(element); constantCompilerTask.dartConstantCompiler.forgetElement(element); aliasedSuperMembers.remove(element); + generatedCode.remove(element); + if (element is MemberElement) { + for (Element closure in element.nestedClosures) { + generatedCode.remove(closure); + } + } } @override @@ -2743,7 +2763,7 @@ case Feature.FIELD_WITHOUT_INITIALIZER: case Feature.LOCAL_WITHOUT_INITIALIZER: transformed.registerTypeUse( - new TypeUse.instantiation(backend.coreTypes.nullType)); + new TypeUse.instantiation(backend.commonElements.nullType)); registerBackendImpact(transformed, impacts.nullLiteral); break; case Feature.LAZY_FIELD: @@ -2833,7 +2853,7 @@ if (hasTypeLiteral) { transformed.registerTypeUse( - new TypeUse.instantiation(backend.compiler.coreTypes.typeType)); + new TypeUse.instantiation(backend.compiler.commonElements.typeType)); registerBackendImpact(transformed, impacts.typeLiteral); } @@ -3228,7 +3248,8 @@ ClassElement get syncStarIterableImplementation => helpers.syncStarIterable; ClassElement get asyncFutureImplementation => helpers.futureImplementation; ClassElement get asyncStarStreamImplementation => helpers.controllerStream; - ClassElement get functionImplementation => helpers.coreClasses.functionClass; + ClassElement get functionImplementation => + helpers.commonElements.functionClass; ClassElement get indexableImplementation => helpers.jsIndexableClass; ClassElement get mutableIndexableImplementation => helpers.jsMutableIndexableClass; @@ -3239,7 +3260,7 @@ bool isDefaultEqualityImplementation(Element element) { assert(element.name == '=='); ClassElement classElement = element.enclosingClass; - return classElement == helpers.coreClasses.objectClass || + return classElement == helpers.commonElements.objectClass || classElement == helpers.jsInterceptorClass || classElement == helpers.jsNullClass; }
diff --git a/pkg/compiler/lib/src/js_backend/backend_helpers.dart b/pkg/compiler/lib/src/js_backend/backend_helpers.dart index ee8d696..6967ca8 100644 --- a/pkg/compiler/lib/src/js_backend/backend_helpers.dart +++ b/pkg/compiler/lib/src/js_backend/backend_helpers.dart
@@ -8,7 +8,7 @@ import '../common/names.dart' show Identifiers, Uris; import '../common/resolution.dart' show Resolution; import '../compiler.dart' show Compiler; -import '../core_types.dart' show CoreClasses; +import '../core_types.dart' show CommonElements; import '../elements/elements.dart' show AbstractFieldElement, @@ -16,7 +16,6 @@ ConstructorElement, Element, EnumClassElement, - FieldElement, FunctionElement, LibraryElement, MemberElement, @@ -62,7 +61,7 @@ Resolution get resolution => backend.resolution; - CoreClasses get coreClasses => compiler.coreClasses; + CommonElements get commonElements => compiler.commonElements; DiagnosticReporter get reporter => compiler.reporter; @@ -393,7 +392,7 @@ jsStringOperatorAdd = compiler.lookupElementIn(jsStringClass, '+'); jsStringToString = compiler.lookupElementIn(jsStringClass, 'toString'); - objectEquals = compiler.lookupElementIn(coreClasses.objectClass, '=='); + objectEquals = compiler.lookupElementIn(commonElements.objectClass, '=='); } ConstructorElement _mapLiteralConstructor; @@ -811,8 +810,8 @@ MethodElement get objectNoSuchMethod { if (_objectNoSuchMethod == null) { - _objectNoSuchMethod = - coreClasses.objectClass.lookupLocalMember(Identifiers.noSuchMethod_); + _objectNoSuchMethod = commonElements.objectClass + .lookupLocalMember(Identifiers.noSuchMethod_); } return _objectNoSuchMethod; }
diff --git a/pkg/compiler/lib/src/js_backend/backend_impact.dart b/pkg/compiler/lib/src/js_backend/backend_impact.dart index cbd3752..2a3244c 100644 --- a/pkg/compiler/lib/src/js_backend/backend_impact.dart +++ b/pkg/compiler/lib/src/js_backend/backend_impact.dart
@@ -579,7 +579,7 @@ // The backend will use a literal list to initialize the entries // of the map. globalClasses: [ - helpers.coreClasses.listClass, + helpers.commonElements.listClass, helpers.mapLiteralClass ]); } @@ -673,7 +673,7 @@ BackendImpact get runtimeTypeSupport { return _runtimeTypeSupport ??= new BackendImpact( - globalClasses: [helpers.coreClasses.listClass], + globalClasses: [helpers.commonElements.listClass], globalUses: [helpers.setRuntimeTypeInfo, helpers.getRuntimeTypeInfo], otherImpacts: [getRuntimeTypeArgument, computeSignature]); } @@ -684,7 +684,7 @@ return _deferredLoading ??= new BackendImpact(globalUses: [helpers.checkDeferredIsLoaded], // Also register the types of the arguments passed to this method. - globalClasses: [helpers.coreClasses.stringClass]); + globalClasses: [helpers.commonElements.stringClass]); } BackendImpact _noSuchMethodSupport;
diff --git a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart index 08174df..ee445b3 100644 --- a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart +++ b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
@@ -8,7 +8,7 @@ import '../constant_system_dart.dart'; import '../constants/constant_system.dart'; import '../constants/values.dart'; -import '../core_types.dart' show CoreTypes; +import '../core_types.dart' show CommonElements; import '../dart_types.dart'; import '../elements/elements.dart' show ClassElement, FieldElement; import '../tree/dartstring.dart' show DartString, LiteralDartString; @@ -334,7 +334,8 @@ // integer type check is Math.floor, which will return true only // for real integers, and our double type check is 'typeof number' // which will return true for both integers and doubles. - if (s == types.coreTypes.intType && t == types.coreTypes.doubleType) { + if (s == types.commonElements.intType && + t == types.commonElements.doubleType) { return true; } return types.isSubtype(s, t); @@ -343,7 +344,7 @@ MapConstantValue createMap(Compiler compiler, InterfaceType sourceType, List<ConstantValue> keys, List<ConstantValue> values) { JavaScriptBackend backend = compiler.backend; - CoreTypes coreTypes = compiler.coreTypes; + CommonElements commonElements = compiler.commonElements; bool onlyStringKeys = true; ConstantValue protoValue = null; @@ -364,9 +365,9 @@ bool hasProtoKey = (protoValue != null); DartType keysType; if (sourceType.treatAsRaw) { - keysType = coreTypes.listType(); + keysType = commonElements.listType(); } else { - keysType = coreTypes.listType(sourceType.typeArguments.first); + keysType = commonElements.listType(sourceType.typeArguments.first); } ListConstantValue keysList = new ListConstantValue(keysType, keys); String className = onlyStringKeys
diff --git a/pkg/compiler/lib/src/js_backend/enqueuer.dart b/pkg/compiler/lib/src/js_backend/enqueuer.dart index da79b0e..55fda27 100644 --- a/pkg/compiler/lib/src/js_backend/enqueuer.dart +++ b/pkg/compiler/lib/src/js_backend/enqueuer.dart
@@ -9,49 +9,33 @@ import '../cache_strategy.dart' show CacheStrategy; import '../common/backend_api.dart' show Backend; import '../common/codegen.dart' show CodegenWorkItem; -import '../common/names.dart' show Identifiers; import '../common/tasks.dart' show CompilerTask; import '../common/work.dart' show WorkItem; import '../common.dart'; import '../compiler.dart' show Compiler; import '../dart_types.dart' show DartType, InterfaceType; -import '../dump_info.dart'; -import '../elements/elements.dart' - show - ClassElement, - Element, - Entity, - FunctionElement, - MemberElement, - MethodElement, - TypedElement; +import '../elements/elements.dart' show Entity, MemberElement, TypedElement; import '../elements/entities.dart'; import '../enqueue.dart'; -import '../js/js.dart' as js; import '../native/native.dart' as native; import '../options.dart'; import '../types/types.dart' show TypeMaskStrategy; -import '../universe/selector.dart' show Selector; import '../universe/world_builder.dart'; import '../universe/use.dart' show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind; import '../universe/world_impact.dart' show ImpactUseCase, WorldImpact, WorldImpactVisitor; +import '../util/enumset.dart'; import '../util/util.dart' show Setlet; -import '../world.dart'; /// [Enqueuer] which is specific to code generation. class CodegenEnqueuer extends EnqueuerImpl { final String name; final EnqueuerStrategy strategy; - final Map<String, Set<Element>> _instanceMembersByName = - new Map<String, Set<Element>>(); - final Map<String, Set<Element>> _instanceFunctionsByName = - new Map<String, Set<Element>>(); - final Set<ClassElement> _processedClasses = new Set<ClassElement>(); - Set<ClassElement> _recentClasses = new Setlet<ClassElement>(); - final CodegenWorldBuilderImpl _universe = - new CodegenWorldBuilderImpl(const TypeMaskStrategy()); + + Set<ClassEntity> _recentClasses = new Setlet<ClassEntity>(); + final CodegenWorldBuilderImpl _universe; + final WorkItemBuilder _workItemBuilder; bool queueIsClosed = false; final CompilerTask task; @@ -62,73 +46,60 @@ WorldImpactVisitor _impactVisitor; final Queue<WorkItem> _queue = new Queue<WorkItem>(); - final Map<Element, js.Expression> generatedCode = <Element, js.Expression>{}; - final Set<Element> newlyEnqueuedElements; + /// All declaration elements that have been processed by codegen. + final Set<Entity> _processedEntities = new Set<Entity>(); + + final Set<Entity> newlyEnqueuedElements; final Set<DynamicUse> newlySeenSelectors; - bool _enabledNoSuchMethod = false; - static const ImpactUseCase IMPACT_USE = const ImpactUseCase('CodegenEnqueuer'); CodegenEnqueuer(this.task, CacheStrategy cacheStrategy, Backend backend, - this._options, this.strategy) - : newlyEnqueuedElements = cacheStrategy.newSet(), + CompilerOptions options, this.strategy) + : _universe = + new CodegenWorldBuilderImpl(backend, const TypeMaskStrategy()), + _workItemBuilder = new CodegenWorkItemBuilder(backend, options), + newlyEnqueuedElements = cacheStrategy.newSet(), newlySeenSelectors = cacheStrategy.newSet(), nativeEnqueuer = backend.nativeCodegenEnqueuer(), this._backend = backend, + this._options = options, this.name = 'codegen enqueuer' { _impactVisitor = new EnqueuerImplImpactVisitor(this); } CodegenWorldBuilder get universe => _universe; - // TODO(johnniwinther): Remove these hacks: - ClosedWorld get _world => - _backend.compiler.resolverWorld.closedWorldForTesting; - DumpInfoTask get _dumpInfoTask => _backend.compiler.dumpInfoTask; - bool get queueIsEmpty => _queue.isEmpty; /// Returns [:true:] if this enqueuer is the resolution enqueuer. bool get isResolutionQueue => false; - /** - * Documentation wanted -- johnniwinther - * - * Invariant: [element] must be a declaration element. - */ - void _addToWorkList(Element element) { - assert(invariant(element, element.isDeclaration)); - // Don't generate code for foreign elements. - if (_backend.isForeign(element)) return; + /// Create a [WorkItem] for [entity] and add it to the work list if it has not + /// already been processed. + void _addToWorkList(MemberEntity entity) { + if (_processedEntities.contains(entity)) return; - // Codegen inlines field initializers. It only needs to generate - // code for checked setters. - if (element.isField && element.isInstanceMember) { - if (!_options.enableTypeAssertions || - element.enclosingElement.isClosure) { - return; - } - } + WorkItem workItem = _workItemBuilder.createWorkItem(entity); + if (workItem == null) return; - if (_options.hasIncrementalSupport && !isProcessed(element)) { - newlyEnqueuedElements.add(element); + if (_options.hasIncrementalSupport) { + newlyEnqueuedElements.add(entity); } if (queueIsClosed) { throw new SpannableAssertionFailure( - element, "Codegen work list is closed. Trying to add $element"); + entity, "Codegen work list is closed. Trying to add $entity"); } - _queue.add(new CodegenWorkItem(_backend, element)); - // TODO(sigmund): add other missing dependencies (internals, selectors - // enqueued after allocations). - _dumpInfoTask.registerDependency(element); + + applyImpact(_backend.registerUsedElement(entity, forResolution: false)); + _queue.add(workItem); } - void applyImpact(WorldImpact worldImpact, {Element impactSource}) { + void applyImpact(WorldImpact worldImpact, {var impactSource}) { if (worldImpact.isEmpty) return; impactStrategy.visitImpact( impactSource, worldImpact, _impactVisitor, impactUse); @@ -137,22 +108,12 @@ void _registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false, bool nativeUsage: false}) { task.measure(() { - ClassElement cls = type.element; - bool isNative = _backend.isNative(cls); - _universe.registerTypeInstantiation(type, - isNative: isNative, - byMirrors: mirrorUsage, onImplemented: (ClassElement cls) { - applyImpact( - _backend.registerImplementedClass(cls, forResolution: false)); - }); + _universe.registerTypeInstantiation(type, _applyClassUse, + byMirrors: mirrorUsage); if (nativeUsage) { nativeEnqueuer.onInstantiatedType(type); } _backend.registerInstantiatedType(type); - // TODO(johnniwinther): Share this reasoning with [Universe]. - if (!cls.isAbstract || isNative || mirrorUsage) { - _processInstantiatedClass(cls); - } }); } @@ -160,225 +121,65 @@ return strategy.checkEnqueuerConsistency(this); } - void checkClass(ClassElement cls) { - cls.implementation.forEachMember(processInstantiatedClassMember); - } - - void processInstantiatedClassMember(ClassElement cls, Element member) { - assert(invariant(member, member.isDeclaration)); - if (isProcessed(member)) return; - if (!member.isInstanceMember) return; - String memberName = member.name; - - if (member.isField) { - // The obvious thing to test here would be "member.isNative", - // however, that only works after metadata has been parsed/analyzed, - // and that may not have happened yet. - // So instead we use the enclosing class, which we know have had - // its metadata parsed and analyzed. - // Note: this assumes that there are no non-native fields on native - // classes, which may not be the case when a native class is subclassed. - if (_backend.isNative(cls)) { - if (_universe.hasInvokedGetter(member, _world) || - _universe.hasInvocation(member, _world)) { - _addToWorkList(member); - return; - } else if (universe.hasInvokedSetter(member, _world)) { - _addToWorkList(member); - return; - } - // Native fields need to go into instanceMembersByName as they - // are virtual instantiation points and escape points. - } else { - // All field initializers must be resolved as they could - // have an observable side-effect (and cannot be tree-shaken - // away). - _addToWorkList(member); - return; - } - } else if (member.isFunction) { - FunctionElement function = member; - if (function.name == Identifiers.noSuchMethod_) { - _registerNoSuchMethod(function); - } - if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) { - _registerCallMethodWithFreeTypeVariables(function); - } - // If there is a property access with the same name as a method we - // need to emit the method. - if (_universe.hasInvokedGetter(function, _world)) { - _registerClosurizedMember(function); - _addToWorkList(function); - return; - } - _registerInstanceMethod(function); - if (_universe.hasInvocation(function, _world)) { - _addToWorkList(function); - return; - } - } else if (member.isGetter) { - FunctionElement getter = member; - if (_universe.hasInvokedGetter(getter, _world)) { - _addToWorkList(getter); - return; - } - // We don't know what selectors the returned closure accepts. If - // the set contains any selector we have to assume that it matches. - if (_universe.hasInvocation(getter, _world)) { - _addToWorkList(getter); - return; - } - } else if (member.isSetter) { - FunctionElement setter = member; - if (_universe.hasInvokedSetter(setter, _world)) { - _addToWorkList(setter); - return; - } - } - - // The element is not yet used. Add it to the list of instance - // members to still be processed. - _instanceMembersByName - .putIfAbsent(memberName, () => new Set<Element>()) - .add(member); - } - - // Store the member in [instanceFunctionsByName] to catch - // getters on the function. - void _registerInstanceMethod(MethodElement element) { - _instanceFunctionsByName - .putIfAbsent(element.name, () => new Set<Element>()) - .add(element); - } - - void _processInstantiatedClass(ClassElement cls) { - task.measure(() { - if (_processedClasses.contains(cls)) return; - - void processClass(ClassElement superclass) { - if (_processedClasses.contains(superclass)) return; - // TODO(johnniwinther): Re-insert this invariant when unittests don't - // fail. There is already a similar invariant on the members. - /*assert(invariant(superclass, - superclass.isClosure || - _compiler.enqueuer.resolution.isClassProcessed(superclass), - message: "Class $superclass has not been " - "processed in resolution.")); - */ - - _processedClasses.add(superclass); - _recentClasses.add(superclass); - superclass.implementation.forEachMember(processInstantiatedClassMember); - // We only tell the backend once that [superclass] was instantiated, so - // any additional dependencies must be treated as global - // dependencies. - applyImpact(_backend.registerInstantiatedClass(superclass, - forResolution: false)); - } - - ClassElement superclass = cls; - while (superclass != null) { - processClass(superclass); - superclass = superclass.superclass; + void checkClass(ClassEntity cls) { + _universe.processClassMembers(cls, (MemberEntity member, useSet) { + if (useSet.isNotEmpty) { + _backend.compiler.reporter.internalError(member, + 'Unenqueued use of $member: ${useSet.iterable(MemberUse.values)}'); } }); } + /// Callback for applying the use of a [cls]. + void _applyClassUse(ClassEntity cls, EnumSet<ClassUse> useSet) { + if (useSet.contains(ClassUse.INSTANTIATED)) { + _recentClasses.add(cls); + _universe.processClassMembers(cls, _applyMemberUse); + // We only tell the backend once that [cls] was instantiated, so + // any additional dependencies must be treated as global + // dependencies. + applyImpact( + _backend.registerInstantiatedClass(cls, forResolution: false)); + } + if (useSet.contains(ClassUse.IMPLEMENTED)) { + applyImpact(_backend.registerImplementedClass(cls, forResolution: false)); + } + } + + /// Callback for applying the use of a [member]. + void _applyMemberUse(Entity member, EnumSet<MemberUse> useSet) { + if (useSet.contains(MemberUse.NORMAL)) { + _addToWorkList(member); + } + if (useSet.contains(MemberUse.CLOSURIZE_INSTANCE)) { + _registerClosurizedMember(member); + } + if (useSet.contains(MemberUse.CLOSURIZE_STATIC)) { + applyImpact(_backend.registerGetOfStaticFunction()); + } + } + void processDynamicUse(DynamicUse dynamicUse) { task.measure(() { - if (_universe.registerDynamicUse(dynamicUse)) { - _handleUnseenSelector(dynamicUse); + if (_universe.registerDynamicUse(dynamicUse, _applyMemberUse)) { + if (_options.hasIncrementalSupport) { + newlySeenSelectors.add(dynamicUse); + } } }); } - void _processSet( - Map<String, Set<Element>> map, String memberName, bool f(Element e)) { - Set<Element> members = map[memberName]; - if (members == null) return; - // [f] might add elements to [: map[memberName] :] during the loop below - // so we create a new list for [: map[memberName] :] and prepend the - // [remaining] members after the loop. - map[memberName] = new Set<Element>(); - Set<Element> remaining = new Set<Element>(); - for (Element member in members) { - if (!f(member)) remaining.add(member); - } - map[memberName].addAll(remaining); - } - - void _processInstanceMembers(String n, bool f(Element e)) { - _processSet(_instanceMembersByName, n, f); - } - - void _processInstanceFunctions(String n, bool f(Element e)) { - _processSet(_instanceFunctionsByName, n, f); - } - - void _handleUnseenSelector(DynamicUse dynamicUse) { - if (_options.hasIncrementalSupport) { - newlySeenSelectors.add(dynamicUse); - } - Selector selector = dynamicUse.selector; - String methodName = selector.name; - _processInstanceMembers(methodName, (Element member) { - if (dynamicUse.appliesUnnamed(member, _world)) { - if (member.isFunction && selector.isGetter) { - _registerClosurizedMember(member); - } - _addToWorkList(member); - return true; - } - return false; - }); - if (selector.isGetter) { - _processInstanceFunctions(methodName, (Element member) { - if (dynamicUse.appliesUnnamed(member, _world)) { - _registerClosurizedMember(member); - return true; - } - return false; - }); - } - } - void processStaticUse(StaticUse staticUse) { - Element element = staticUse.element; - assert(invariant(element, element.isDeclaration, - message: "Element ${element} is not the declaration.")); - _universe.registerStaticUse(staticUse); - applyImpact(_backend.registerUsedElement(element, forResolution: false)); - bool addElement = true; + _universe.registerStaticUse(staticUse, _applyMemberUse); switch (staticUse.kind) { - case StaticUseKind.STATIC_TEAR_OFF: - applyImpact(_backend.registerGetOfStaticFunction()); - break; - case StaticUseKind.FIELD_GET: - case StaticUseKind.FIELD_SET: - case StaticUseKind.CLOSURE: - // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and - // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue. - // Also [CLOSURE] contains [LocalFunctionElement] which we cannot - // enqueue. - addElement = false; - break; - case StaticUseKind.SUPER_FIELD_SET: - case StaticUseKind.SUPER_TEAR_OFF: - case StaticUseKind.GENERAL: - case StaticUseKind.DIRECT_USE: - break; case StaticUseKind.CONSTRUCTOR_INVOKE: case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: case StaticUseKind.REDIRECTION: processTypeUse(new TypeUse.instantiation(staticUse.type)); break; - case StaticUseKind.DIRECT_INVOKE: - _registerInstanceMethod(staticUse.element); + default: break; } - if (addElement) { - _addToWorkList(element); - } } void processTypeUse(TypeUse typeUse) { @@ -416,11 +217,6 @@ assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); } - void _registerCallMethodWithFreeTypeVariables(Element element) { - applyImpact(_backend.registerCallMethodWithFreeTypeVariables(element, - forResolution: false)); - } - void _registerClosurizedMember(TypedElement element) { assert(element.isInstanceMember); if (element.type.containsTypeVariables) { @@ -435,10 +231,11 @@ while (_queue.isNotEmpty) { // TODO(johnniwinther): Find an optimal process order. WorkItem work = _queue.removeLast(); - if (!isProcessed(work.element)) { + if (!_processedEntities.contains(work.element)) { strategy.processWorkItem(f, work); // TODO(johnniwinther): Register the processed element here. This // is currently a side-effect of calling `work.run`. + _processedEntities.add(work.element); } } List recents = _recentClasses.toList(growable: false); @@ -453,12 +250,12 @@ /// the [recentClasses] have been processed and may be cleared. If [false] is /// returned, [_onQueueEmpty] will be called once the queue is empty again (or /// still empty) and [recentClasses] will be a superset of the current value. - bool _onQueueEmpty(Iterable<ClassElement> recentClasses) { + bool _onQueueEmpty(Iterable<ClassEntity> recentClasses) { return _backend.onQueueEmpty(this, recentClasses); } void logSummary(log(message)) { - log('Compiled ${generatedCode.length} methods.'); + log('Compiled ${_processedEntities.length} methods.'); nativeEnqueuer.logSummary(log); } @@ -466,40 +263,41 @@ ImpactUseCase get impactUse => IMPACT_USE; - bool isProcessed(Element member) => - member.isAbstract || generatedCode.containsKey(member); - - void _registerNoSuchMethod(Element element) { - if (!_enabledNoSuchMethod && _backend.enabledNoSuchMethod) { - applyImpact(_backend.enableNoSuchMethod()); - _enabledNoSuchMethod = true; - } - } - - void forgetEntity(Element element, Compiler compiler) { - _universe.forgetElement(element, compiler); - _processedClasses.remove(element); - _instanceMembersByName[element.name]?.remove(element); - _instanceFunctionsByName[element.name]?.remove(element); - generatedCode.remove(element); - if (element is MemberElement) { - for (Element closure in element.nestedClosures) { - generatedCode.remove(closure); - removeFromSet(_instanceMembersByName, closure); - removeFromSet(_instanceFunctionsByName, closure); - } - } + void forgetEntity(Entity entity, Compiler compiler) { + _universe.forgetElement(entity, compiler); + _processedEntities.remove(entity); } @override - Iterable<Entity> get processedEntities => generatedCode.keys; + Iterable<Entity> get processedEntities => _processedEntities; @override - Iterable<ClassEntity> get processedClasses => _processedClasses; + Iterable<ClassEntity> get processedClasses => _universe.processedClasses; } -void removeFromSet(Map<String, Set<Element>> map, Element element) { - Set<Element> set = map[element.name]; - if (set == null) return; - set.remove(element); +/// Builder that creates the work item necessary for the code generation of a +/// [MemberElement]. +class CodegenWorkItemBuilder extends WorkItemBuilder { + Backend _backend; + CompilerOptions _options; + + CodegenWorkItemBuilder(this._backend, this._options); + + @override + WorkItem createWorkItem(MemberElement element) { + assert(invariant(element, element.isDeclaration)); + // Don't generate code for foreign elements. + if (_backend.isForeign(element)) return null; + if (element.isAbstract) return null; + + // Codegen inlines field initializers. It only needs to generate + // code for checked setters. + if (element.isField && element.isInstanceMember) { + if (!_options.enableTypeAssertions || + element.enclosingElement.isClosure) { + return null; + } + } + return new CodegenWorkItem(_backend, element); + } }
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart index c03056a..717cbc6 100644 --- a/pkg/compiler/lib/src/js_backend/namer.dart +++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -13,7 +13,7 @@ import '../common/names.dart' show Identifiers, Selectors; import '../compiler.dart' show Compiler; import '../constants/values.dart'; -import '../core_types.dart' show CoreClasses; +import '../core_types.dart' show CommonElements; import '../dart_types.dart'; import '../diagnostics/invariant.dart' show DEBUG_MODE; import '../elements/elements.dart'; @@ -475,7 +475,7 @@ DiagnosticReporter get reporter => backend.reporter; - CoreClasses get coreClasses => closedWorld.coreClasses; + CommonElements get commonElements => closedWorld.commonElements; String get deferredTypesName => 'deferredTypes'; String get isolateName => 'Isolate'; @@ -550,11 +550,11 @@ case JsGetName.IS_INDEXABLE_FIELD_NAME: return operatorIs(helpers.jsIndexingBehaviorInterface); case JsGetName.NULL_CLASS_TYPE_NAME: - return runtimeTypeName(coreClasses.nullClass); + return runtimeTypeName(commonElements.nullClass); case JsGetName.OBJECT_CLASS_TYPE_NAME: - return runtimeTypeName(coreClasses.objectClass); + return runtimeTypeName(commonElements.objectClass); case JsGetName.FUNCTION_CLASS_TYPE_NAME: - return runtimeTypeName(coreClasses.functionClass); + return runtimeTypeName(commonElements.functionClass); default: reporter.reportErrorMessage(node, MessageKind.GENERIC, {'text': 'Error: Namer has no name for "$name".'}); @@ -1253,7 +1253,7 @@ String suffixForGetInterceptor(Iterable<ClassEntity> classes) { String abbreviate(ClassElement cls) { - if (cls == coreClasses.objectClass) return "o"; + if (cls == commonElements.objectClass) return "o"; if (cls == helpers.jsStringClass) return "s"; if (cls == helpers.jsArrayClass) return "a"; if (cls == helpers.jsDoubleClass) return "d";
diff --git a/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart b/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart index a318872..00b9ac7 100644 --- a/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart +++ b/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
@@ -187,7 +187,7 @@ bool isDefaultNoSuchMethodImplementation(FunctionElement element) { ClassElement classElement = element.enclosingClass; - return classElement == _compiler.coreClasses.objectClass || + return classElement == _compiler.commonElements.objectClass || classElement == _backend.helpers.jsInterceptorClass || classElement == _backend.helpers.jsNullClass; }
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart index e404cdd..dcf964b 100644 --- a/pkg/compiler/lib/src/js_backend/runtime_types.dart +++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -263,7 +263,7 @@ // TODO(karlklose): make this dependency visible from code. if (backend.helpers.jsArrayClass != null) { registerRtiDependency( - backend.helpers.jsArrayClass, compiler.coreClasses.listClass); + backend.helpers.jsArrayClass, compiler.commonElements.listClass); } // Compute the set of all classes and methods that need runtime type // information. @@ -911,11 +911,6 @@ return unaliasedType.accept(this, null); } } - - visitStatementType(StatementType type, _) { - reporter.internalError( - NO_LOCATION_SPANNABLE, 'Unexpected type: $type (${type.kind}).'); - } } class TypeCheckMapping implements TypeChecks {
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart index 1affdaf..c1b7824 100644 --- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart +++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -15,7 +15,7 @@ import '../../common/names.dart' show Names; import '../../compiler.dart' show Compiler; import '../../constants/values.dart'; -import '../../core_types.dart' show CoreClasses; +import '../../core_types.dart' show CommonElements; import '../../dart_types.dart' show DartType; import '../../deferred_load.dart' show OutputUnit; import '../../elements/elements.dart' @@ -127,7 +127,7 @@ ConstantEmitter constantEmitter; NativeEmitter get nativeEmitter => task.nativeEmitter; TypeTestRegistry get typeTestRegistry => task.typeTestRegistry; - CoreClasses get coreClasses => compiler.coreClasses; + CommonElements get commonElements => compiler.commonElements; // The full code that is written to each hunk part-file. Map<OutputUnit, CodeOutput> outputBuffers = new Map<OutputUnit, CodeOutput>(); @@ -367,7 +367,7 @@ switch (builtin) { case JsBuiltin.dartObjectConstructor: return jsAst.js - .expressionTemplateYielding(typeAccess(coreClasses.objectClass)); + .expressionTemplateYielding(typeAccess(commonElements.objectClass)); case JsBuiltin.isCheckPropertyToJsConstructorName: int isPrefixLength = namer.operatorIsPrefix.length; @@ -440,13 +440,13 @@ /// In minified mode we want to keep the name for the most common core types. bool _isNativeTypeNeedingReflectionName(Element element) { if (!element.isClass) return false; - return (element == coreClasses.intClass || - element == coreClasses.doubleClass || - element == coreClasses.numClass || - element == coreClasses.stringClass || - element == coreClasses.boolClass || - element == coreClasses.nullClass || - element == coreClasses.listClass); + return (element == commonElements.intClass || + element == commonElements.doubleClass || + element == commonElements.numClass || + element == commonElements.stringClass || + element == commonElements.boolClass || + element == commonElements.nullClass || + element == commonElements.listClass); } /// Returns the "reflection name" of an [Element] or [Selector]. @@ -1237,8 +1237,8 @@ // We can be pretty sure that the objectClass is initialized, since // typedefs are only emitted with reflection, which requires lots of // classes. - assert(coreClasses.objectClass != null); - builder.superName = namer.className(coreClasses.objectClass); + assert(commonElements.objectClass != null); + builder.superName = namer.className(commonElements.objectClass); jsAst.Node declaration = builder.toObjectInitializer(); jsAst.Name mangledName = namer.globalPropertyName(typedef); String reflectionName = getReflectionName(typedef, mangledName);
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart index 9bdf146..ad1ef5b 100644 --- a/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart +++ b/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
@@ -162,7 +162,7 @@ } // Startup code that loops over the method names and puts handlers on the // Object class to catch noSuchMethod invocations. - ClassElement objectClass = compiler.coreClasses.objectClass; + ClassElement objectClass = compiler.commonElements.objectClass; jsAst.Expression createInvocationMirror = backend.emitter .staticFunctionAccess(backend.helpers.createInvocationMirror); if (useDiffEncoding) {
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart index 68c2451..24a66e9 100644 --- a/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart +++ b/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
@@ -129,13 +129,13 @@ 'enabledJsInterop': backend.jsInteropAnalysis.enabledJsInterop, 'jsInteropBoostrap': backend.jsInteropAnalysis.buildJsInteropBootstrap(), 'isInterceptorClass': namer.operatorIs(backend.helpers.jsInterceptorClass), - 'isObject': namer.operatorIs(compiler.coreClasses.objectClass), + 'isObject': namer.operatorIs(compiler.commonElements.objectClass), 'specProperty': js.string(namer.nativeSpecProperty), 'trivialNsmHandlers': emitter.buildTrivialNsmHandlers(), 'hasRetainedMetadata': backend.hasRetainedMetadata, 'types': typesAccess, - 'objectClassName': - js.quoteName(namer.runtimeTypeName(compiler.coreClasses.objectClass)), + 'objectClassName': js + .quoteName(namer.runtimeTypeName(compiler.commonElements.objectClass)), 'needsStructuredMemberInfo': emitter.needsStructuredMemberInfo, 'usesMangledNames': compiler.commonElements.mirrorsLibrary != null || backend.hasFunctionApplySupport,
diff --git a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart index 9a7d2cc..a6255d3 100644 --- a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart +++ b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
@@ -162,7 +162,8 @@ }''', [ interceptorFor(helpers.jsJavaScriptFunctionClass), - backend.emitter.constructorAccess(compiler.coreClasses.objectClass), + backend.emitter + .constructorAccess(compiler.commonElements.objectClass), backend.emitter .staticFunctionAccess(helpers.getNativeInterceptorMethod) ])); @@ -171,7 +172,8 @@ if (compiler.codegenWorld.directlyInstantiatedClasses .contains(jsUnknown)) { statements.add(js.statement('if (!(receiver instanceof #)) return #;', [ - backend.emitter.constructorAccess(compiler.coreClasses.objectClass), + backend.emitter + .constructorAccess(compiler.commonElements.objectClass), interceptorFor(jsUnknown) ])); }
diff --git a/pkg/compiler/lib/src/js_emitter/js_emitter.dart b/pkg/compiler/lib/src/js_emitter/js_emitter.dart index 5d715a3..fb87380 100644 --- a/pkg/compiler/lib/src/js_emitter/js_emitter.dart +++ b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
@@ -15,7 +15,7 @@ import '../common/tasks.dart' show CompilerTask; import '../compiler.dart' show Compiler; import '../constants/values.dart'; -import '../core_types.dart' show CoreClasses; +import '../core_types.dart' show CommonElements; import '../dart_types.dart' show DartType,
diff --git a/pkg/compiler/lib/src/js_emitter/lazy_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/lazy_emitter/emitter.dart index 3714a08..a38de70 100644 --- a/pkg/compiler/lib/src/js_emitter/lazy_emitter/emitter.dart +++ b/pkg/compiler/lib/src/js_emitter/lazy_emitter/emitter.dart
@@ -144,7 +144,7 @@ switch (builtin) { case JsBuiltin.dartObjectConstructor: return js.js.expressionTemplateYielding( - typeAccess(_compiler.coreClasses.objectClass)); + typeAccess(_compiler.commonElements.objectClass)); case JsBuiltin.isCheckPropertyToJsConstructorName: int isPrefixLength = namer.operatorIsPrefix.length;
diff --git a/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart index 53f12e3..8cb0eb1 100644 --- a/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart +++ b/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart
@@ -22,7 +22,7 @@ import '../../compiler.dart' show Compiler; import '../../constants/values.dart' show ConstantValue, FunctionConstantValue; -import '../../core_types.dart' show CoreClasses; +import '../../core_types.dart' show CommonElements; import '../../elements/elements.dart' show ClassElement, FunctionElement; import '../../js/js.dart' as js; import '../../js_backend/js_backend.dart' @@ -342,17 +342,17 @@ js.Property emitMangledGlobalNames() { List<js.Property> names = <js.Property>[]; - CoreClasses coreClasses = compiler.coreClasses; + CommonElements commonElements = compiler.commonElements; // We want to keep the original names for the most common core classes when // calling toString on them. List<ClassElement> nativeClassesNeedingUnmangledName = [ - coreClasses.intClass, - coreClasses.doubleClass, - coreClasses.numClass, - coreClasses.stringClass, - coreClasses.boolClass, - coreClasses.nullClass, - coreClasses.listClass + commonElements.intClass, + commonElements.doubleClass, + commonElements.numClass, + commonElements.stringClass, + commonElements.boolClass, + commonElements.nullClass, + commonElements.listClass ]; nativeClassesNeedingUnmangledName.forEach((element) { names.add(new js.Property(
diff --git a/pkg/compiler/lib/src/js_emitter/native_emitter.dart b/pkg/compiler/lib/src/js_emitter/native_emitter.dart index 2e5f457..1f39802 100644 --- a/pkg/compiler/lib/src/js_emitter/native_emitter.dart +++ b/pkg/compiler/lib/src/js_emitter/native_emitter.dart
@@ -83,7 +83,7 @@ Class jsInterceptorClass = null; void walk(Class cls) { - if (cls.element == compiler.coreClasses.objectClass) { + if (cls.element == compiler.commonElements.objectClass) { objectClass = cls; return; }
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart index 5389c2c..8c66d00 100644 --- a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart +++ b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
@@ -45,7 +45,7 @@ BackendHelpers get helpers => backend.helpers; - CoreClasses get coreClasses => compiler.coreClasses; + CommonElements get commonElements => compiler.commonElements; Collector(this.compiler, this.namer, this.closedWorld, this.rtiNeededClasses, this.emitter); @@ -73,7 +73,7 @@ Set<ClassElement> unneededClasses = new Set<ClassElement>(); // The [Bool] class is not marked as abstract, but has a factory // constructor that always throws. We never need to emit it. - unneededClasses.add(coreClasses.boolClass); + unneededClasses.add(commonElements.boolClass); // Go over specialized interceptors and then constants to know which // interceptors are needed. @@ -89,7 +89,7 @@ // Add unneeded interceptors to the [unneededClasses] set. for (ClassElement interceptor in backend.interceptedClasses) { if (!needed.contains(interceptor) && - interceptor != coreClasses.objectClass) { + interceptor != commonElements.objectClass) { unneededClasses.add(interceptor); } } @@ -220,22 +220,22 @@ // TODO(18175, floitsch): remove once issue 18175 is fixed. if (neededClasses.contains(helpers.jsIntClass)) { - neededClasses.add(coreClasses.intClass); + neededClasses.add(commonElements.intClass); } if (neededClasses.contains(helpers.jsDoubleClass)) { - neededClasses.add(coreClasses.doubleClass); + neededClasses.add(commonElements.doubleClass); } if (neededClasses.contains(helpers.jsNumberClass)) { - neededClasses.add(coreClasses.numClass); + neededClasses.add(commonElements.numClass); } if (neededClasses.contains(helpers.jsStringClass)) { - neededClasses.add(coreClasses.stringClass); + neededClasses.add(commonElements.stringClass); } if (neededClasses.contains(helpers.jsBoolClass)) { - neededClasses.add(coreClasses.boolClass); + neededClasses.add(commonElements.boolClass); } if (neededClasses.contains(helpers.jsArrayClass)) { - neededClasses.add(coreClasses.listClass); + neededClasses.add(commonElements.listClass); } // 4. Finally, sort the classes.
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart index fd18152..be27411 100644 --- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart +++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -10,7 +10,7 @@ import '../../compiler.dart' show Compiler; import '../../constants/values.dart' show ConstantValue, InterceptorConstantValue; -import '../../core_types.dart' show CoreClasses; +import '../../core_types.dart' show CommonElements; import '../../dart_types.dart' show DartType, FunctionType, TypedefType; import '../../deferred_load.dart' show DeferredLoadTask, OutputUnit; import '../../elements/elements.dart' @@ -327,11 +327,11 @@ } void _addJsInteropStubs(LibrariesMap librariesMap) { - if (_classes.containsKey(_compiler.coreClasses.objectClass)) { + if (_classes.containsKey(_compiler.commonElements.objectClass)) { var toStringInvocation = namer.invocationName(Selectors.toString_); // TODO(jacobr): register toString as used so that it is always accessible // from JavaScript. - _classes[_compiler.coreClasses.objectClass].callStubs.add( + _classes[_compiler.commonElements.objectClass].callStubs.add( _buildStubMethod(new StringBackedName("toString"), js.js('function() { return this.#(this) }', toStringInvocation))); } @@ -396,13 +396,13 @@ functionType = returnType; } else if (returnType.treatAsDynamic || _compiler.types.isSubtype( - returnType, backend.coreTypes.functionType)) { + returnType, backend.commonElements.functionType)) { if (returnType.isTypedef) { TypedefType typedef = returnType; // TODO(jacobr): can we just use typdef.unaliased instead? functionType = typedef.element.functionSignature.type; } else { - // Other misc function type such as coreTypes.Function. + // Other misc function type such as commonElements.Function. // Allow any number of arguments. isFunctionLike = true; }
diff --git a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart index 7cffc44..c6365ae 100644 --- a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart +++ b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
@@ -35,7 +35,7 @@ JavaScriptBackend get backend => compiler.backend; TypeTestRegistry get typeTestRegistry => emitterTask.typeTestRegistry; - CoreClasses get coreClasses => compiler.coreClasses; + CommonElements get commonElements => compiler.commonElements; Set<ClassElement> get checkedClasses => typeTestRegistry.checkedClasses; @@ -193,7 +193,7 @@ bool supertypesNeedSubstitutions = false; if (superclass != null && - superclass != coreClasses.objectClass && + superclass != commonElements.objectClass && !haveSameTypeVariables(cls, superclass)) { // We cannot inherit the generated substitutions, because the type // variable layout for this class is different. Instead we generate @@ -238,7 +238,7 @@ // A class that defines a `call` method implicitly implements // [Function] and needs checks for all typedefs that are used in is-checks. - if (checkedClasses.contains(coreClasses.functionClass) || + if (checkedClasses.contains(commonElements.functionClass) || checkedFunctionTypes.isNotEmpty) { Element call = cls.lookupLocalMember(Identifiers.call); if (call == null) { @@ -249,9 +249,9 @@ FunctionElement callFunction = call; // A superclass might already implement the Function interface. In such // a case, we can avoid emiting the is test here. - if (!cls.superclass.implementsFunction(coreClasses)) { - _generateInterfacesIsTests(coreClasses.functionClass, generateIsTest, - generateSubstitution, generated); + if (!cls.superclass.implementsFunction(commonElements)) { + _generateInterfacesIsTests(commonElements.functionClass, + generateIsTest, generateSubstitution, generated); } FunctionType callType = callFunction.computeType(compiler.resolution); generateFunctionTypeSignature(callFunction, callType);
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart index bac4f1e..617fea3 100644 --- a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart +++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
@@ -146,7 +146,7 @@ switch (builtin) { case JsBuiltin.dartObjectConstructor: return js.js.expressionTemplateYielding( - typeAccess(_compiler.coreClasses.objectClass)); + typeAccess(_compiler.commonElements.objectClass)); case JsBuiltin.isCheckPropertyToJsConstructorName: int isPrefixLength = namer.operatorIsPrefix.length;
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart index 57e10a2..9f67aa9 100644 --- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart +++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -1140,17 +1140,17 @@ js.Property emitMangledGlobalNames() { List<js.Property> names = <js.Property>[]; - CoreClasses coreClasses = compiler.coreClasses; + CommonElements commonElements = compiler.commonElements; // We want to keep the original names for the most common core classes when // calling toString on them. List<ClassElement> nativeClassesNeedingUnmangledName = [ - coreClasses.intClass, - coreClasses.doubleClass, - coreClasses.numClass, - coreClasses.stringClass, - coreClasses.boolClass, - coreClasses.nullClass, - coreClasses.listClass + commonElements.intClass, + commonElements.doubleClass, + commonElements.numClass, + commonElements.stringClass, + commonElements.boolClass, + commonElements.nullClass, + commonElements.listClass ]; // TODO(floitsch): this should probably be on a per-fragment basis. nativeClassesNeedingUnmangledName.forEach((element) {
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 index 046fa6f..8a1bb2a 100644 --- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart +++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -33,7 +33,7 @@ import '../../common.dart'; import '../../compiler.dart' show Compiler; import '../../constants/values.dart' show ConstantValue, FunctionConstantValue; -import '../../core_types.dart' show CoreClasses; +import '../../core_types.dart' show CommonElements; import '../../elements/elements.dart' show ClassElement, FunctionElement; import '../../hash/sha1.dart' show Hasher; import '../../io/code_output.dart';
diff --git a/pkg/compiler/lib/src/kernel/kernel.dart b/pkg/compiler/lib/src/kernel/kernel.dart index 155f2a0..964854a 100644 --- a/pkg/compiler/lib/src/kernel/kernel.dart +++ b/pkg/compiler/lib/src/kernel/kernel.dart
@@ -348,9 +348,6 @@ case TypeKind.INTERFACE: return interfaceTypeToIr(type); - case TypeKind.STATEMENT: - throw "Internal error: statement type: $type."; - case TypeKind.TYPEDEF: type.computeUnaliased(compiler.resolution); return typeToIr(type.unaliased);
diff --git a/pkg/compiler/lib/src/mirrors_used.dart b/pkg/compiler/lib/src/mirrors_used.dart index 79dac05..3c20fc9 100644 --- a/pkg/compiler/lib/src/mirrors_used.dart +++ b/pkg/compiler/lib/src/mirrors_used.dart
@@ -251,7 +251,7 @@ metadata.ensureResolved(compiler.resolution); ConstantValue value = compiler.constants.getConstantValue(metadata.constant); - Element element = value.getType(compiler.coreTypes).element; + Element element = value.getType(compiler.commonElements).element; if (element == compiler.commonElements.mirrorsUsedClass) { result.add(buildUsage(value)); } @@ -415,7 +415,7 @@ /// Find the first non-implementation interface of constant. DartType apiTypeOf(ConstantValue constant) { - DartType type = constant.getType(compiler.coreTypes); + DartType type = constant.getType(compiler.commonElements); LibraryElement library = type.element.library; if (type.isInterfaceType && library.isInternalLibrary) { InterfaceType interface = type;
diff --git a/pkg/compiler/lib/src/native/behavior.dart b/pkg/compiler/lib/src/native/behavior.dart index e34145a..63ae4e3 100644 --- a/pkg/compiler/lib/src/native/behavior.dart +++ b/pkg/compiler/lib/src/native/behavior.dart
@@ -8,7 +8,7 @@ import '../compiler.dart' show Compiler; import '../constants/expressions.dart'; import '../constants/values.dart'; -import '../core_types.dart' show CoreTypes; +import '../core_types.dart' show CommonElements; import '../dart_types.dart'; import '../elements/elements.dart'; import '../js/js.dart' as js; @@ -498,8 +498,12 @@ } /// Compute the [NativeBehavior] for a [Send] node calling the 'JS' function. - static NativeBehavior ofJsCallSend(Send jsCall, DiagnosticReporter reporter, - ParsingContext parsing, CoreTypes coreTypes, ForeignResolver resolver) { + static NativeBehavior ofJsCallSend( + Send jsCall, + DiagnosticReporter reporter, + ParsingContext parsing, + CommonElements commonElements, + ForeignResolver resolver) { var argNodes = jsCall.arguments; if (argNodes.isEmpty || argNodes.tail.isEmpty) { reporter.reportErrorMessage(jsCall, MessageKind.WRONG_ARGUMENT_FOR_JS); @@ -524,7 +528,7 @@ String codeString = codeArgument.dartString.slowToString(); return ofJsCall(specString, codeString, _typeLookup(specArgument, resolver), - specArgument, reporter, coreTypes); + specArgument, reporter, commonElements); } /// Compute the [NativeBehavior] for a call to the 'JS' function with the @@ -535,7 +539,7 @@ TypeLookup lookupType, Spannable spannable, DiagnosticReporter reporter, - CoreTypes coreTypes) { + CommonElements commonElements) { // The first argument of a JS-call is a string encoding various attributes // of the code. // @@ -576,8 +580,8 @@ lookupType: lookupType, typesReturned: behavior.typesReturned, typesInstantiated: behavior.typesInstantiated, - objectType: coreTypes.objectType, - nullType: coreTypes.nullType); + objectType: commonElements.objectType, + nullType: commonElements.nullType); if (!sideEffectsAreEncodedInSpecString) { new SideEffectsVisitor(behavior.sideEffects) @@ -597,7 +601,7 @@ String specString, TypeLookup lookupType, DiagnosticReporter reporter, - CoreTypes coreTypes, + CommonElements commonElements, {List<String> validTags}) { void setSideEffects(SideEffects newEffects) { behavior.sideEffects.setTo(newEffects); @@ -609,14 +613,14 @@ setSideEffects: setSideEffects, typesReturned: behavior.typesReturned, typesInstantiated: behavior.typesInstantiated, - objectType: coreTypes.objectType, - nullType: coreTypes.nullType); + objectType: commonElements.objectType, + nullType: commonElements.nullType); } static NativeBehavior ofJsBuiltinCallSend( Send jsBuiltinCall, DiagnosticReporter reporter, - CoreTypes coreTypes, + CommonElements commonElements, ForeignResolver resolver) { NativeBehavior behavior = new NativeBehavior(); behavior.sideEffects.setTo(new SideEffects()); @@ -650,7 +654,7 @@ String specString = specLiteral.dartString.slowToString(); return ofJsBuiltinCall(specString, _typeLookup(jsBuiltinCall, resolver), - jsBuiltinCall, reporter, coreTypes); + jsBuiltinCall, reporter, commonElements); } static NativeBehavior ofJsBuiltinCall( @@ -658,18 +662,18 @@ TypeLookup lookupType, Spannable spannable, DiagnosticReporter reporter, - CoreTypes coreTypes) { + CommonElements commonElements) { NativeBehavior behavior = new NativeBehavior(); behavior.sideEffects.setTo(new SideEffects()); _fillNativeBehaviorOfBuiltinOrEmbeddedGlobal( - behavior, spannable, specString, lookupType, reporter, coreTypes); + behavior, spannable, specString, lookupType, reporter, commonElements); return behavior; } static NativeBehavior ofJsEmbeddedGlobalCallSend( Send jsEmbeddedGlobalCall, DiagnosticReporter reporter, - CoreTypes coreTypes, + CommonElements commonElements, ForeignResolver resolver) { NativeBehavior behavior = new NativeBehavior(); // TODO(sra): Allow the use site to override these defaults. @@ -717,7 +721,7 @@ _typeLookup(jsEmbeddedGlobalCall, resolver), jsEmbeddedGlobalCall, reporter, - coreTypes); + commonElements); } static NativeBehavior ofJsEmbeddedGlobalCall( @@ -725,7 +729,7 @@ TypeLookup lookupType, Spannable spannable, DiagnosticReporter reporter, - CoreTypes coreTypes) { + CommonElements commonElements) { NativeBehavior behavior = new NativeBehavior(); // TODO(sra): Allow the use site to override these defaults. // Embedded globals are usually pre-computed data structures or JavaScript @@ -733,7 +737,7 @@ behavior.sideEffects.setTo(new SideEffects.empty()); behavior.throwBehavior = NativeThrowBehavior.NEVER; _fillNativeBehaviorOfBuiltinOrEmbeddedGlobal( - behavior, spannable, specString, lookupType, reporter, coreTypes, + behavior, spannable, specString, lookupType, reporter, commonElements, validTags: ['returns', 'creates']); return behavior; } @@ -784,7 +788,7 @@ : const DynamicType()); if (!type.returnType.isVoid) { // Declared types are nullable. - behavior.typesReturned.add(compiler.coreTypes.nullType); + behavior.typesReturned.add(compiler.commonElements.nullType); } behavior._capture(type, compiler.resolution, isInterop: isJsInterop, compiler: compiler); @@ -839,7 +843,7 @@ ? type : const DynamicType()); // Declared types are nullable. - behavior.typesReturned.add(resolution.coreTypes.nullType); + behavior.typesReturned.add(resolution.commonElements.nullType); behavior._capture(type, resolution, isInterop: isJsInterop, compiler: compiler); behavior._overrideWithAnnotations(
diff --git a/pkg/compiler/lib/src/native/enqueue.dart b/pkg/compiler/lib/src/native/enqueue.dart index bd37b4c..e5405ba 100644 --- a/pkg/compiler/lib/src/native/enqueue.dart +++ b/pkg/compiler/lib/src/native/enqueue.dart
@@ -9,7 +9,7 @@ import '../common/resolution.dart' show Resolution; import '../compiler.dart' show Compiler; import '../constants/values.dart'; -import '../core_types.dart' show CoreTypes; +import '../core_types.dart' show CommonElements; import '../dart_types.dart'; import '../elements/elements.dart'; import '../elements/modelx.dart' show FunctionElementX; @@ -97,7 +97,7 @@ Resolution get resolution => compiler.resolution; DiagnosticReporter get reporter => compiler.reporter; - CoreTypes get coreTypes => compiler.coreTypes; + CommonElements get commonElements => compiler.commonElements; void onInstantiatedType(InterfaceType type) { if (_unusedClasses.remove(type.element)) { @@ -439,23 +439,23 @@ for (var type in behavior.typesInstantiated) { if (type is SpecialType) { if (type == SpecialType.JsObject) { - registerInstantiation(compiler.coreTypes.objectType); + registerInstantiation(compiler.commonElements.objectType); } continue; } if (type is InterfaceType) { - if (type == coreTypes.intType) { + if (type == commonElements.intType) { registerInstantiation(type); - } else if (type == coreTypes.doubleType) { + } else if (type == commonElements.doubleType) { registerInstantiation(type); - } else if (type == coreTypes.numType) { - registerInstantiation(coreTypes.doubleType); - registerInstantiation(coreTypes.intType); - } else if (type == coreTypes.stringType) { + } else if (type == commonElements.numType) { + registerInstantiation(commonElements.doubleType); + registerInstantiation(commonElements.intType); + } else if (type == commonElements.stringType) { registerInstantiation(type); - } else if (type == coreTypes.nullType) { + } else if (type == commonElements.nullType) { registerInstantiation(type); - } else if (type == coreTypes.boolType) { + } else if (type == commonElements.boolType) { registerInstantiation(type); } else if (compiler.types.isSubtype( type, backend.backendClasses.listImplementation.rawType)) { @@ -564,8 +564,8 @@ * */ NativeBehavior resolveJsCall(Send node, ForeignResolver resolver) { - return NativeBehavior.ofJsCallSend( - node, reporter, compiler.parsingContext, compiler.coreTypes, resolver); + return NativeBehavior.ofJsCallSend(node, reporter, compiler.parsingContext, + compiler.commonElements, resolver); } /** @@ -580,7 +580,7 @@ NativeBehavior resolveJsEmbeddedGlobalCall( Send node, ForeignResolver resolver) { return NativeBehavior.ofJsEmbeddedGlobalCallSend( - node, reporter, compiler.coreTypes, resolver); + node, reporter, compiler.commonElements, resolver); } /** @@ -594,7 +594,7 @@ */ NativeBehavior resolveJsBuiltinCall(Send node, ForeignResolver resolver) { return NativeBehavior.ofJsBuiltinCallSend( - node, reporter, compiler.coreTypes, resolver); + node, reporter, compiler.commonElements, resolver); } }
diff --git a/pkg/compiler/lib/src/patch_parser.dart b/pkg/compiler/lib/src/patch_parser.dart index 3050c0d..82c20b0 100644 --- a/pkg/compiler/lib/src/patch_parser.dart +++ b/pkg/compiler/lib/src/patch_parser.dart
@@ -428,7 +428,7 @@ void validate(Compiler compiler, Element element, MetadataAnnotation annotation, ConstantValue constant) { - DartType annotationType = constant.getType(compiler.coreTypes); + DartType annotationType = constant.getType(compiler.commonElements); if (annotationType.element != compiler.commonElements.nativeAnnotationClass) { DiagnosticReporter reporter = compiler.reporter; @@ -461,7 +461,7 @@ void validate(Compiler compiler, Element element, MetadataAnnotation annotation, ConstantValue constant) { JavaScriptBackend backend = compiler.backend; - if (constant.getType(compiler.coreTypes).element != + if (constant.getType(compiler.commonElements).element != backend.helpers.jsAnnotationClass) { compiler.reporter .internalError(annotation, 'Invalid @JS(...) annotation.'); @@ -497,7 +497,7 @@ @override void validate(Compiler compiler, Element element, MetadataAnnotation annotation, ConstantValue constant) { - DartType annotationType = constant.getType(compiler.coreTypes); + DartType annotationType = constant.getType(compiler.commonElements); if (annotationType.element != compiler.commonElements.patchAnnotationClass) { DiagnosticReporter reporter = compiler.reporter;
diff --git a/pkg/compiler/lib/src/resolution/class_hierarchy.dart b/pkg/compiler/lib/src/resolution/class_hierarchy.dart index b9fae97..7f2a57a 100644 --- a/pkg/compiler/lib/src/resolution/class_hierarchy.dart +++ b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
@@ -6,7 +6,7 @@ import '../common.dart'; import '../common/resolution.dart' show Resolution; -import '../core_types.dart' show CoreClasses, CoreTypes; +import '../core_types.dart' show CommonElements; import '../dart_types.dart'; import '../elements/elements.dart'; import '../elements/modelx.dart' @@ -39,9 +39,9 @@ scope = Scope.buildEnclosingScope(element), super(resolution, registry); - CoreTypes get coreTypes => resolution.coreTypes; + CommonElements get commonElements => resolution.commonElements; - DartType get objectType => coreTypes.objectType; + DartType get objectType => commonElements.objectType; void resolveTypeVariableBounds(NodeList node) { if (node == null) return; @@ -243,7 +243,7 @@ } EnumCreator creator = - new EnumCreator(reporter, resolution.coreTypes, element); + new EnumCreator(reporter, resolution.commonElements, element); creator.createMembers(); return enumType; } @@ -535,10 +535,10 @@ final DartType supertype = cls.supertype; if (supertype != null) { cls.allSupertypesAndSelf = new OrderedTypeSetBuilder(cls, - reporter: reporter, objectType: coreTypes.objectType) + reporter: reporter, objectType: commonElements.objectType) .createOrderedTypeSet(supertype, cls.interfaces); } else { - assert(cls == resolution.coreClasses.objectClass); + assert(cls == resolution.commonElements.objectClass); cls.allSupertypesAndSelf = new OrderedTypeSet.singleton(cls.computeType(resolution)); } @@ -549,12 +549,12 @@ return !identical(lib, resolution.commonElements.coreLibrary) && !resolution.target.isTargetSpecificLibrary(lib) && (type.isDynamic || - type == coreTypes.boolType || - type == coreTypes.numType || - type == coreTypes.intType || - type == coreTypes.doubleType || - type == coreTypes.stringType || - type == coreTypes.nullType); + type == commonElements.boolType || + type == commonElements.numType || + type == commonElements.intType || + type == commonElements.doubleType || + type == commonElements.stringType || + type == commonElements.nullType); } } @@ -567,7 +567,7 @@ this.classElement = cls, super(resolution); - CoreClasses get coreClasses => resolution.coreClasses; + CommonElements get commonElements => resolution.commonElements; void loadSupertype(ClassElement element, Node from) { if (!element.isResolved) { @@ -586,8 +586,8 @@ void visitClassNode(ClassNode node) { if (node.superclass == null) { - if (classElement != coreClasses.objectClass) { - loadSupertype(coreClasses.objectClass, node); + if (classElement != commonElements.objectClass) { + loadSupertype(commonElements.objectClass, node); } } else { node.superclass.accept(this); @@ -596,7 +596,7 @@ } void visitEnum(Enum node) { - loadSupertype(coreClasses.objectClass, node); + loadSupertype(commonElements.objectClass, node); } void visitMixinApplication(MixinApplication node) {
diff --git a/pkg/compiler/lib/src/resolution/class_members.dart b/pkg/compiler/lib/src/resolution/class_members.dart index 3039130..07bf004 100644 --- a/pkg/compiler/lib/src/resolution/class_members.dart +++ b/pkg/compiler/lib/src/resolution/class_members.dart
@@ -310,7 +310,7 @@ void checkImplementsFunctionWithCall() { assert(!cls.isAbstract); - ClassElement functionClass = resolution.coreClasses.functionClass; + ClassElement functionClass = resolution.commonElements.functionClass; functionClass.ensureResolved(resolution); if (cls.asInstanceOf(functionClass) == null) return; if (cls.lookupMember(Identifiers.call) != null) return;
diff --git a/pkg/compiler/lib/src/resolution/enum_creator.dart b/pkg/compiler/lib/src/resolution/enum_creator.dart index 2d07373..6b94c22 100644 --- a/pkg/compiler/lib/src/resolution/enum_creator.dart +++ b/pkg/compiler/lib/src/resolution/enum_creator.dart
@@ -5,7 +5,7 @@ library dart2js.resolution.enum_creator; import '../common.dart'; -import '../core_types.dart' show CoreTypes; +import '../core_types.dart' show CommonElements; import '../dart_types.dart'; import '../elements/elements.dart'; import '../elements/modelx.dart'; @@ -199,18 +199,18 @@ // removed. class EnumCreator { final DiagnosticReporter reporter; - final CoreTypes coreTypes; + final CommonElements commonElements; final EnumClassElementX enumClass; - EnumCreator(this.reporter, this.coreTypes, this.enumClass); + EnumCreator(this.reporter, this.commonElements, this.enumClass); void createMembers() { Enum node = enumClass.node; InterfaceType enumType = enumClass.thisType; AstBuilder builder = new AstBuilder(enumClass.position.charOffset); - InterfaceType intType = coreTypes.intType; - InterfaceType stringType = coreTypes.stringType; + InterfaceType intType = commonElements.intType; + InterfaceType stringType = commonElements.stringType; EnumFieldElementX addInstanceMember(String name, InterfaceType type) { Identifier identifier = builder.identifier(name); @@ -281,7 +281,7 @@ VariableList valuesVariableList = new VariableList(builder.modifiers(isStatic: true, isConst: true)); - valuesVariableList.type = coreTypes.listType(enumType); + valuesVariableList.type = commonElements.listType(enumType); Identifier valuesIdentifier = builder.identifier('values'); // TODO(johnniwinther): Add type argument.
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart index 0c0998a..85b4902 100644 --- a/pkg/compiler/lib/src/resolution/members.dart +++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -171,8 +171,7 @@ : ConstantState.NON_CONSTANT, super(resolution, registry); - CoreClasses get coreClasses => resolution.coreClasses; - CoreTypes get coreTypes => resolution.coreTypes; + CommonElements get commonElements => resolution.commonElements; ConstantEnvironment get constants => resolution.constants; ResolverTask get resolver => resolution.resolver; CompilerOptions get options => resolution.options; @@ -337,7 +336,7 @@ if (Elements.isUnresolved(element) && name == 'dynamic') { // TODO(johnniwinther): Remove this hack when we can return more complex // objects than [Element] from this method. - element = coreClasses.typeClass; + element = commonElements.typeClass; // Set the type to be `dynamic` to mark that this is a type literal. registry.setType(node, const DynamicType()); } @@ -1197,14 +1196,14 @@ bool isValidConstant; ConstantExpression expressionConstant = expressionResult.constant; DartType knownExpressionType = - expressionConstant.getKnownType(coreTypes); + expressionConstant.getKnownType(commonElements); switch (operator.kind) { case UnaryOperatorKind.COMPLEMENT: - isValidConstant = knownExpressionType == coreTypes.intType; + isValidConstant = knownExpressionType == commonElements.intType; break; case UnaryOperatorKind.NEGATE: - isValidConstant = knownExpressionType == coreTypes.intType || - knownExpressionType == coreTypes.doubleType; + isValidConstant = knownExpressionType == commonElements.intType || + knownExpressionType == commonElements.doubleType; break; case UnaryOperatorKind.NOT: reporter.internalError( @@ -1237,7 +1236,8 @@ if (result.isConstant) { ConstantExpression expressionConstant = result.constant; - if (expressionConstant.getKnownType(coreTypes) == coreTypes.boolType) { + if (expressionConstant.getKnownType(commonElements) == + commonElements.boolType) { // TODO(johnniwinther): Handle potentially invalid constant expressions. ConstantExpression constant = new UnaryConstantExpression(operator, expressionConstant); @@ -1262,8 +1262,10 @@ if (leftResult.isConstant && rightResult.isConstant) { ConstantExpression leftConstant = leftResult.constant; ConstantExpression rightConstant = rightResult.constant; - if (leftConstant.getKnownType(coreTypes) == coreTypes.boolType && - rightConstant.getKnownType(coreTypes) == coreTypes.boolType) { + if (leftConstant.getKnownType(commonElements) == + commonElements.boolType && + rightConstant.getKnownType(commonElements) == + commonElements.boolType) { // TODO(johnniwinther): Handle potentially invalid constant expressions. ConstantExpression constant = new BinaryConstantExpression( leftConstant, BinaryOperator.LOGICAL_AND, rightConstant); @@ -1286,8 +1288,10 @@ if (leftResult.isConstant && rightResult.isConstant) { ConstantExpression leftConstant = leftResult.constant; ConstantExpression rightConstant = rightResult.constant; - if (leftConstant.getKnownType(coreTypes) == coreTypes.boolType && - rightConstant.getKnownType(coreTypes) == coreTypes.boolType) { + if (leftConstant.getKnownType(commonElements) == + commonElements.boolType && + rightConstant.getKnownType(commonElements) == + commonElements.boolType) { // TODO(johnniwinther): Handle potentially invalid constant expressions. ConstantExpression constant = new BinaryConstantExpression( leftConstant, BinaryOperator.LOGICAL_OR, rightConstant); @@ -1368,29 +1372,29 @@ bool isValidConstant; ConstantExpression leftConstant = leftResult.constant; ConstantExpression rightConstant = rightResult.constant; - DartType knownLeftType = leftConstant.getKnownType(coreTypes); - DartType knownRightType = rightConstant.getKnownType(coreTypes); + DartType knownLeftType = leftConstant.getKnownType(commonElements); + DartType knownRightType = rightConstant.getKnownType(commonElements); switch (operator.kind) { case BinaryOperatorKind.EQ: case BinaryOperatorKind.NOT_EQ: - isValidConstant = (knownLeftType == coreTypes.intType || - knownLeftType == coreTypes.doubleType || - knownLeftType == coreTypes.stringType || - knownLeftType == coreTypes.boolType || - knownLeftType == coreTypes.nullType) && - (knownRightType == coreTypes.intType || - knownRightType == coreTypes.doubleType || - knownRightType == coreTypes.stringType || - knownRightType == coreTypes.boolType || - knownRightType == coreTypes.nullType); + isValidConstant = (knownLeftType == commonElements.intType || + knownLeftType == commonElements.doubleType || + knownLeftType == commonElements.stringType || + knownLeftType == commonElements.boolType || + knownLeftType == commonElements.nullType) && + (knownRightType == commonElements.intType || + knownRightType == commonElements.doubleType || + knownRightType == commonElements.stringType || + knownRightType == commonElements.boolType || + knownRightType == commonElements.nullType); break; case BinaryOperatorKind.ADD: - isValidConstant = (knownLeftType == coreTypes.intType || - knownLeftType == coreTypes.doubleType || - knownLeftType == coreTypes.stringType) && - (knownRightType == coreTypes.intType || - knownRightType == coreTypes.doubleType || - knownRightType == coreTypes.stringType); + isValidConstant = (knownLeftType == commonElements.intType || + knownLeftType == commonElements.doubleType || + knownLeftType == commonElements.stringType) && + (knownRightType == commonElements.intType || + knownRightType == commonElements.doubleType || + knownRightType == commonElements.stringType); break; case BinaryOperatorKind.SUB: case BinaryOperatorKind.MUL: @@ -1401,18 +1405,18 @@ case BinaryOperatorKind.GT: case BinaryOperatorKind.LTEQ: case BinaryOperatorKind.LT: - isValidConstant = (knownLeftType == coreTypes.intType || - knownLeftType == coreTypes.doubleType) && - (knownRightType == coreTypes.intType || - knownRightType == coreTypes.doubleType); + isValidConstant = (knownLeftType == commonElements.intType || + knownLeftType == commonElements.doubleType) && + (knownRightType == commonElements.intType || + knownRightType == commonElements.doubleType); break; case BinaryOperatorKind.SHL: case BinaryOperatorKind.SHR: case BinaryOperatorKind.AND: case BinaryOperatorKind.OR: case BinaryOperatorKind.XOR: - isValidConstant = knownLeftType == coreTypes.intType && - knownRightType == coreTypes.intType; + isValidConstant = knownLeftType == commonElements.intType && + knownRightType == commonElements.intType; break; case BinaryOperatorKind.INDEX: isValidConstant = false; @@ -2065,10 +2069,10 @@ ConstantExpression constant = new TypeConstantExpression( // TODO(johnniwinther): Use [type] when evaluation of constants is done // directly on the constant expressions. - node.isCall ? coreTypes.typeType : type); + node.isCall ? commonElements.typeType : type); AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant); return handleConstantTypeLiteralAccess(node, const PublicName('dynamic'), - coreClasses.typeClass, type, semantics); + commonElements.typeClass, type, semantics); } /// Handle update to a type literal of the type 'dynamic'. Like `dynamic++` or @@ -2079,7 +2083,7 @@ new TypeConstantExpression(const DynamicType()); AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant); return handleConstantTypeLiteralUpdate(node, const PublicName('dynamic'), - coreClasses.typeClass, type, semantics); + commonElements.typeClass, type, semantics); } /// Handle access to a type literal of a class. Like `C` or @@ -3590,9 +3594,9 @@ reporter.reportErrorMessage(node, MessageKind.INVALID_YIELD); } if (currentAsyncMarker.isAsync) { - coreClasses.streamClass.ensureResolved(resolution); + commonElements.streamClass.ensureResolved(resolution); } else { - coreClasses.iterableClass.ensureResolved(resolution); + commonElements.iterableClass.ensureResolved(resolution); } } visit(node.expression); @@ -3727,7 +3731,7 @@ if (!currentAsyncMarker.isAsync) { reporter.reportErrorMessage(node, MessageKind.INVALID_AWAIT); } - coreClasses.futureClass.ensureResolved(resolution); + commonElements.futureClass.ensureResolved(resolution); } visit(node.expression); return const NoneResult(); @@ -3909,7 +3913,7 @@ .compileNode(argumentNode, registry.mapping); ConstantValue name = resolution.constants.getConstantValue(constant); if (!name.isString) { - DartType type = name.getType(coreTypes); + DartType type = name.getType(commonElements); reporter.reportErrorMessage( argumentNode, MessageKind.STRING_EXPECTED, {'type': type}); } else { @@ -3983,7 +3987,7 @@ !resolution.mirrorUsageAnalyzerTask .hasMirrorUsage(enclosingElement)) { reporter.reportHintMessage(node.newToken, MessageKind.NON_CONST_BLOAT, - {'name': coreClasses.symbolClass.name}); + {'name': commonElements.symbolClass.name}); } registry.registerNewStructure( node, @@ -4002,9 +4006,9 @@ ObjectConstantValue objectConstant = key; DartType keyType = objectConstant.type; ClassElement cls = keyType.element; - if (cls == coreClasses.stringClass) continue; + if (cls == commonElements.stringClass) continue; Element equals = cls.lookupMember('=='); - if (equals.enclosingClass != coreClasses.objectClass) { + if (equals.enclosingClass != commonElements.objectClass) { reporter.reportErrorMessage(spannable, MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS, {'type': keyType}); } @@ -4113,9 +4117,9 @@ arguments.nodes.head, MessageKind.TYPE_VARIABLE_IN_CONSTANT); isValidAsConstant = false; } - listType = coreTypes.listType(typeArgument); + listType = commonElements.listType(typeArgument); } else { - listType = coreTypes.listType(); + listType = commonElements.listType(); } registry.registerLiteralList(node, listType, isConstant: node.isConst, isEmpty: node.elements.isEmpty); @@ -4411,9 +4415,9 @@ } DartType mapType; if (valueTypeArgument != null) { - mapType = coreTypes.mapType(keyTypeArgument, valueTypeArgument); + mapType = commonElements.mapType(keyTypeArgument, valueTypeArgument); } else { - mapType = coreTypes.mapType(); + mapType = commonElements.mapType(); } if (node.isConst && mapType.containsTypeVariables) { reporter.reportErrorMessage( @@ -4465,12 +4469,12 @@ } DartType typeOfConstant(ConstantValue constant) { - if (constant.isInt) return coreTypes.intType; - if (constant.isBool) return coreTypes.boolType; - if (constant.isDouble) return coreTypes.doubleType; - if (constant.isString) return coreTypes.stringType; - if (constant.isNull) return coreTypes.nullType; - if (constant.isFunction) return coreTypes.functionType; + if (constant.isInt) return commonElements.intType; + if (constant.isBool) return commonElements.boolType; + if (constant.isDouble) return commonElements.doubleType; + if (constant.isString) return commonElements.stringType; + if (constant.isNull) return commonElements.nullType; + if (constant.isFunction) return commonElements.functionType; assert(constant.isObject); ObjectConstantValue objectConstant = constant; return objectConstant.type; @@ -4479,7 +4483,7 @@ bool overridesEquals(DartType type) { ClassElement cls = type.element; Element equals = cls.lookupMember('=='); - return equals.enclosingClass != coreClasses.objectClass; + return equals.enclosingClass != commonElements.objectClass; } void checkCaseExpressions(SwitchStatement node) { @@ -4504,7 +4508,8 @@ message: 'No constant computed for $node')); ConstantValue value = resolution.constants.getConstantValue(constant); - DartType caseType = value.getType(coreTypes); //typeOfConstant(value); + DartType caseType = + value.getType(commonElements); //typeOfConstant(value); if (firstCaseType == null) { firstCase = caseMatch; @@ -4512,12 +4517,12 @@ // We only report the bad type on the first class element. All others // get a "type differs" error. - if (caseType == coreTypes.doubleType) { + if (caseType == commonElements.doubleType) { reporter.reportErrorMessage( node, MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS, {'type': "double"}); - } else if (caseType == coreTypes.functionType) { + } else if (caseType == commonElements.functionType) { reporter.reportErrorMessage( node, MessageKind.SWITCH_CASE_FORBIDDEN, {'type': "Function"}); } else if (value.isObject && overridesEquals(caseType)) { @@ -4740,7 +4745,7 @@ Node stackTraceVariable = stackTraceDefinition.definitions.nodes.head; VariableElementX stackTraceElement = registry.getDefinition(stackTraceVariable); - InterfaceType stackTraceType = coreTypes.stackTraceType; + InterfaceType stackTraceType = commonElements.stackTraceType; stackTraceElement.variables.type = stackTraceType; } return const NoneResult();
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart index 923952c..e4d8f21 100644 --- a/pkg/compiler/lib/src/resolution/resolution.dart +++ b/pkg/compiler/lib/src/resolution/resolution.dart
@@ -19,7 +19,7 @@ ConstructedConstantExpression, ErroneousConstantExpression; import '../constants/values.dart' show ConstantValue; -import '../core_types.dart' show CoreClasses, CoreTypes, CommonElements; +import '../core_types.dart' show CommonElements; import '../dart_types.dart'; import '../elements/elements.dart'; import '../elements/modelx.dart' @@ -72,13 +72,11 @@ DiagnosticReporter get reporter => resolution.reporter; Target get target => resolution.target; - CoreTypes get coreTypes => resolution.coreTypes; - CoreClasses get coreClasses => resolution.coreClasses; CommonElements get commonElements => resolution.commonElements; ParsingContext get parsingContext => resolution.parsingContext; CompilerOptions get options => resolution.options; ResolutionEnqueuer get enqueuer => resolution.enqueuer; - OpenWorld get world => enqueuer.universe.openWorld; + OpenWorld get world => enqueuer.universe; ResolutionImpact resolve(Element element) { return measure(() { @@ -146,7 +144,7 @@ static void processAsyncMarker(Resolution resolution, BaseFunctionElementX element, ResolutionRegistry registry) { DiagnosticReporter reporter = resolution.reporter; - CoreClasses coreClasses = resolution.coreClasses; + CommonElements commonElements = resolution.commonElements; FunctionExpression functionExpression = element.node; AsyncModifier asyncModifier = functionExpression.asyncModifier; if (asyncModifier != null) { @@ -189,15 +187,15 @@ switch (element.asyncMarker) { case AsyncMarker.ASYNC: registry.registerFeature(Feature.ASYNC); - coreClasses.futureClass.ensureResolved(resolution); + commonElements.futureClass.ensureResolved(resolution); break; case AsyncMarker.ASYNC_STAR: registry.registerFeature(Feature.ASYNC_STAR); - coreClasses.streamClass.ensureResolved(resolution); + commonElements.streamClass.ensureResolved(resolution); break; case AsyncMarker.SYNC_STAR: registry.registerFeature(Feature.SYNC_STAR); - coreClasses.iterableClass.ensureResolved(resolution); + commonElements.iterableClass.ensureResolved(resolution); break; } } @@ -539,7 +537,8 @@ from, MessageKind.CYCLIC_CLASS_HIERARCHY, {'className': cls.name}); cls.supertypeLoadState = STATE_DONE; cls.hasIncompleteHierarchy = true; - cls.allSupertypesAndSelf = coreClasses.objectClass.allSupertypesAndSelf + cls.allSupertypesAndSelf = commonElements + .objectClass.allSupertypesAndSelf .extendClass(cls.computeType(resolution)); cls.supertype = cls.allSupertypes.head; assert(invariant(from, cls.supertype != null,
diff --git a/pkg/compiler/lib/src/resolution/signatures.dart b/pkg/compiler/lib/src/resolution/signatures.dart index faa927c..0dd1363 100644 --- a/pkg/compiler/lib/src/resolution/signatures.dart +++ b/pkg/compiler/lib/src/resolution/signatures.dart
@@ -389,13 +389,13 @@ returnType = visitor.resolveReturnType(returnNode); break; case AsyncMarker.SYNC_STAR: - returnType = resolution.coreTypes.iterableType(); + returnType = resolution.commonElements.iterableType(); break; case AsyncMarker.ASYNC: - returnType = resolution.coreTypes.futureType(); + returnType = resolution.commonElements.futureType(); break; case AsyncMarker.ASYNC_STAR: - returnType = resolution.coreTypes.streamType(); + returnType = resolution.commonElements.streamType(); break; } }
diff --git a/pkg/compiler/lib/src/serialization/equivalence.dart b/pkg/compiler/lib/src/serialization/equivalence.dart index c9f03f2..81aefc9 100644 --- a/pkg/compiler/lib/src/serialization/equivalence.dart +++ b/pkg/compiler/lib/src/serialization/equivalence.dart
@@ -629,11 +629,6 @@ bool visitMalformedType(MalformedType type, MalformedType other) => true; @override - bool visitStatementType(StatementType type, StatementType other) { - throw new UnsupportedError("Unsupported type: $type"); - } - - @override bool visitTypeVariableType(TypeVariableType type, TypeVariableType other) { return strategy.testElements( type, other, 'element', type.element, other.element) &&
diff --git a/pkg/compiler/lib/src/serialization/type_serialization.dart b/pkg/compiler/lib/src/serialization/type_serialization.dart index 96f659e..29c28f0 100644 --- a/pkg/compiler/lib/src/serialization/type_serialization.dart +++ b/pkg/compiler/lib/src/serialization/type_serialization.dart
@@ -87,8 +87,6 @@ case TypeKind.TYPEDEF: return new TypedefType(decoder.getElement(Key.ELEMENT), decoder.getTypes(Key.TYPE_ARGUMENTS, isOptional: true)); - case TypeKind.STATEMENT: - throw new UnsupportedError("Unexpected type kind '${typeKind}."); case TypeKind.MALFORMED_TYPE: // TODO(johnniwinther): Do we need the 'userProvidedBadType' or maybe // just a toString of it?
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart index 25f7fe8..296aa81 100644 --- a/pkg/compiler/lib/src/ssa/builder.dart +++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -15,7 +15,7 @@ import '../constants/constant_system.dart'; import '../constants/expressions.dart'; import '../constants/values.dart'; -import '../core_types.dart' show CoreClasses; +import '../core_types.dart' show CommonElements; import '../dart_types.dart'; import '../diagnostics/messages.dart' show Message, MessageTemplate; import '../dump_info.dart' show InfoReporter; @@ -229,7 +229,7 @@ DiagnosticReporter get reporter => compiler.reporter; - CoreClasses get coreClasses => compiler.coreClasses; + CommonElements get commonElements => closedWorld.commonElements; Element get targetElement => target; @@ -453,7 +453,7 @@ // Don't inline operator== methods if the parameter can be null. if (element.name == '==') { - if (element.enclosingClass != coreClasses.objectClass && + if (element.enclosingClass != commonElements.objectClass && providedArguments[1].canBeNull()) { return false; } @@ -1558,7 +1558,7 @@ HInstruction value = pop(); if (typeBuilder.checkOrTrustTypes) { return typeBuilder.potentiallyCheckOrTrustType( - value, compiler.coreTypes.boolType, + value, compiler.commonElements.boolType, kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); } HInstruction result = new HBoolify(value, commonMasks.boolType); @@ -3048,7 +3048,8 @@ ClassElement cls = currentNonClosureClass; MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_); if (!Selectors.noSuchMethod_.signatureApplies(element)) { - element = coreClasses.objectClass.lookupMember(Identifiers.noSuchMethod_); + element = + commonElements.objectClass.lookupMember(Identifiers.noSuchMethod_); } if (backend.hasInvokeOnSupport && !element.enclosingClass.isObject) { // Register the call as dynamic if [noSuchMethod] on the super @@ -3504,7 +3505,7 @@ // not know about the type argument. Therefore we special case // this constructor to have the setRuntimeTypeInfo called where // the 'new' is done. - if (backend.classNeedsRti(coreClasses.listClass) && + if (backend.classNeedsRti(commonElements.listClass) && (isFixedListConstructorCall || isGrowableListConstructorCall || isJSArrayTypedConstructor)) { @@ -5155,7 +5156,7 @@ // case. return type.isDynamic || type.isObject || - (type is InterfaceType && type.element == coreClasses.futureClass); + (type is InterfaceType && type.element == commonElements.futureClass); } visitReturn(ast.Return node) { @@ -5207,8 +5208,8 @@ visit(node.expression); HInstruction awaited = pop(); // TODO(herhut): Improve this type. - push(new HAwait( - awaited, new TypeMask.subclass(coreClasses.objectClass, closedWorld))); + push(new HAwait(awaited, + new TypeMask.subclass(commonElements.objectClass, closedWorld))); } visitTypeAnnotation(ast.TypeAnnotation node) { @@ -5372,8 +5373,8 @@ TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node); pushInvokeDynamic(node, selector, mask, [streamIterator]); HInstruction future = pop(); - push(new HAwait( - future, new TypeMask.subclass(coreClasses.objectClass, closedWorld))); + push(new HAwait(future, + new TypeMask.subclass(commonElements.objectClass, closedWorld))); return popBoolified(); } @@ -5408,8 +5409,8 @@ node, buildInitializer, buildCondition, buildUpdate, buildBody); }, () { pushInvokeDynamic(node, Selectors.cancel, null, [streamIterator]); - push(new HAwait( - pop(), new TypeMask.subclass(coreClasses.objectClass, closedWorld))); + push(new HAwait(pop(), + new TypeMask.subclass(commonElements.objectClass, closedWorld))); pop(); }); }
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart index 7c92668..1fc734f 100644 --- a/pkg/compiler/lib/src/ssa/builder_kernel.dart +++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -215,7 +215,7 @@ HInstruction value = pop(); if (typeBuilder.checkOrTrustTypes) { return typeBuilder.potentiallyCheckOrTrustType( - value, compiler.coreTypes.boolType, + value, compiler.commonElements.boolType, kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); } HInstruction result = new HBoolify(value, commonMasks.boolType); @@ -223,6 +223,26 @@ return result; } + void _addClassTypeVariablesIfNeeded(ir.Member constructor) { + var enclosing = constructor.enclosingClass; + if (backend.classNeedsRti(astAdapter.getElement(enclosing))) { + ClassElement clsElement = + astAdapter.getElement(constructor).enclosingElement; + enclosing.typeParameters.forEach((ir.TypeParameter typeParameter) { + var typeParamElement = astAdapter.getElement(typeParameter); + HParameterValue param = + addParameter(typeParamElement, commonMasks.nonNullType); + // This is a little bit wacky (and n^2) until we make the localsHandler + // take Kernel DartTypes instead of just the AST DartTypes. + var typeVariableType = clsElement + .typeVariables + .firstWhere((TypeVariableType i) => i.name == typeParameter.name); + localsHandler.directLocals[ + localsHandler.getTypeVariableAsLocal(typeVariableType)] = param; + }); + } + } + /// Builds generative constructors. /// /// Generative constructors are built in two stages. @@ -233,6 +253,7 @@ /// constructor bodies for all constructors in the hierarchy. void buildConstructor(ir.Constructor constructor) { openFunction(); + _addClassTypeVariablesIfNeeded(constructor); // Collect field values for the current class. // TODO(het): Does kernel always put field initializers in the constructor @@ -399,6 +420,11 @@ /// Procedures. void buildFunctionNode(ir.FunctionNode functionNode) { openFunction(); + if (functionNode.parent is ir.Procedure && + (functionNode.parent as ir.Procedure).kind == + ir.ProcedureKind.Factory) { + _addClassTypeVariablesIfNeeded(functionNode.parent); + } functionNode.body.accept(this); closeFunction(); } @@ -1942,49 +1968,82 @@ } HInstruction buildIsNode( - ir.Node node, ir.DartType dart_type, HInstruction expression) { - // TODO(sra): Convert the type testing logic here to use ir.DartType. - DartType type = astAdapter.getDartType(dart_type); - - type = localsHandler.substInContext(type).unaliased; - - if (type is MethodTypeVariableType) { - return graph.addConstantBool(true, closedWorld); + ir.Node node, ir.DartType type, HInstruction expression) { + // Note: The call to "unalias" this type like in the original SSA builder is + // unnecessary in kernel because Kernel has no notion of typedef. + // TODO(efortuna): Add test for this. + DartType typeValue = + localsHandler.substInContext(astAdapter.getDartType(type)); + if (type is ir.InvalidType) { + generateTypeError(node, (typeValue.element as ErroneousElement).message); + return new HIs.compound( + typeValue, expression, pop(), commonMasks.boolType); } - if (type is MalformedType) { - ErroneousElement element = type.element; - generateTypeError(node, element.message); - return new HIs.compound(type, expression, pop(), commonMasks.boolType); - } - - if (type.isFunctionType) { - List arguments = <HInstruction>[buildFunctionType(type), expression]; - _pushDynamicInvocation(node, commonMasks.boolType, arguments, + if (type is ir.FunctionType) { + List arguments = [buildFunctionType(typeValue), expression]; + _pushDynamicInvocation(node, null, arguments, selector: new Selector.call( - new PrivateName('_isTest', astAdapter.jsHelperLibrary), + new PrivateName('_isTest', backend.helpers.jsHelperLibrary), CallStructure.ONE_ARG)); - return new HIs.compound(type, expression, pop(), commonMasks.boolType); + return new HIs.compound( + typeValue, expression, pop(), commonMasks.boolType); } - if (type.isTypeVariable) { + if (type is ir.TypeParameterType) { HInstruction runtimeType = - typeBuilder.addTypeVariableReference(type, sourceElement); + typeBuilder.addTypeVariableReference(typeValue, sourceElement); _pushStaticInvocation(astAdapter.checkSubtypeOfRuntimeType, <HInstruction>[expression, runtimeType], commonMasks.boolType); - return new HIs.variable(type, expression, pop(), commonMasks.boolType); + return new HIs.variable( + typeValue, expression, pop(), commonMasks.boolType); } - // TODO(sra): Type with type parameters. - - if (backend.hasDirectCheckFor(type)) { - return new HIs.direct(type, expression, commonMasks.boolType); + if (_isInterfaceWithNoDynamicTypes(type)) { + HInstruction representations = typeBuilder + .buildTypeArgumentRepresentations(typeValue, sourceElement); + add(representations); + ClassElement element = typeValue.element; + js.Name operator = backend.namer.operatorIs(element); + HInstruction isFieldName = + graph.addConstantStringFromName(operator, closedWorld); + HInstruction asFieldName = closedWorld.hasAnyStrictSubtype(element) + ? graph.addConstantStringFromName( + backend.namer.substitutionName(element), closedWorld) + : graph.addConstantNull(closedWorld); + List<HInstruction> inputs = <HInstruction>[ + expression, + isFieldName, + representations, + asFieldName + ]; + _pushStaticInvocation( + astAdapter.checkSubtype, inputs, commonMasks.boolType); + return new HIs.compound( + typeValue, expression, pop(), commonMasks.boolType); } + if (backend.hasDirectCheckFor(typeValue)) { + return new HIs.direct(typeValue, expression, commonMasks.boolType); + } // The interceptor is not always needed. It is removed by optimization // when the receiver type or tested type permit. - HInterceptor interceptor = _interceptorFor(expression); - return new HIs.raw(type, expression, interceptor, commonMasks.boolType); + return new HIs.raw(typeValue, expression, _interceptorFor(expression), + commonMasks.boolType); + } + + bool _isInterfaceWithNoDynamicTypes(ir.DartType type) { + bool isMethodTypeVariableType(ir.DartType typeArgType) { + return (typeArgType is ir.TypeParameterType && + typeArgType.parameter.parent is ir.FunctionNode); + } + + return type is ir.InterfaceType && + (type as ir.InterfaceType).typeArguments.any( + (ir.DartType typeArgType) => + typeArgType is! ir.DynamicType && + typeArgType is! ir.InvalidType && + !isMethodTypeVariableType(type)); } @override
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart index bf90d8e..67bcd30 100644 --- a/pkg/compiler/lib/src/ssa/codegen.dart +++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -2866,7 +2866,7 @@ // TODO(5022): We currently generate $isFunction checks for // function types. registry.registerTypeUse( - new TypeUse.isCheck(compiler.coreTypes.functionType)); + new TypeUse.isCheck(compiler.commonElements.functionType)); } registry.registerTypeUse(new TypeUse.isCheck(type));
diff --git a/pkg/compiler/lib/src/ssa/graph_builder.dart b/pkg/compiler/lib/src/ssa/graph_builder.dart index 35566b8..d659977 100644 --- a/pkg/compiler/lib/src/ssa/graph_builder.dart +++ b/pkg/compiler/lib/src/ssa/graph_builder.dart
@@ -308,10 +308,6 @@ visitDynamicType(const DynamicType(), builder); } - void visitStatementType(StatementType type, GraphBuilder builder) { - throw 'not implemented visitStatementType($type)'; - } - void visitInterfaceType(InterfaceType type, GraphBuilder builder) { List<HInstruction> inputs = <HInstruction>[]; for (DartType typeArgument in type.typeArguments) {
diff --git a/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart b/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart index 00e92f8..0859c3c 100644 --- a/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart +++ b/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
@@ -63,6 +63,9 @@ for (LocalFunctionElement localFunction in kernel.localFunctions.keys) { _nodeToElement[kernel.localFunctions[localFunction]] = localFunction; } + for (TypeVariableElement typeVariable in kernel.typeParameters.keys) { + _nodeToElement[kernel.typeParameters[typeVariable]] = typeVariable; + } _typeConverter = new DartTypeConverter(this); } @@ -436,7 +439,8 @@ TypeMaskFactory.inferredReturnTypeForElement( _backend.helpers.createRuntimeType, _globalInferenceResults); - ir.Class get objectClass => kernel.classes[_compiler.coreClasses.objectClass]; + ir.Class get objectClass => + kernel.classes[_compiler.commonElements.objectClass]; ir.Procedure get currentIsolate => kernel.functions[_backend.helpers.currentIsolate]; @@ -492,14 +496,14 @@ ast.Node node = getNodeOrNull(list); if (node != null) return elements.getType(node); assertNodeIsSynthetic(list); - return _compiler.coreTypes.listType(getDartType(list.typeArgument)); + return _compiler.commonElements.listType(getDartType(list.typeArgument)); } DartType getDartTypeOfMapLiteral(ir.MapLiteral literal) { ast.Node node = getNodeOrNull(literal); if (node != null) return elements.getType(node); assertNodeIsSynthetic(literal); - return _compiler.coreTypes + return _compiler.commonElements .mapType(getDartType(literal.keyType), getDartType(literal.valueType)); } @@ -632,7 +636,7 @@ _typeLookup(resolveAsRaw: true), CURRENT_ELEMENT_SPANNABLE, reporter, - _compiler.coreTypes); + _compiler.commonElements); } /// Computes the [native.NativeBehavior] for a call to the [JS_BUILTIN] function. @@ -660,7 +664,7 @@ _typeLookup(resolveAsRaw: true), CURRENT_ELEMENT_SPANNABLE, reporter, - _compiler.coreTypes); + _compiler.commonElements); } /// Computes the [native.NativeBehavior] for a call to the [JS_EMBEDDED_GLOBAL] @@ -695,7 +699,7 @@ _typeLookup(resolveAsRaw: true), CURRENT_ELEMENT_SPANNABLE, reporter, - _compiler.coreTypes); + _compiler.commonElements); } /// Returns `true` is [node] has a `@Native(...)` annotation.
diff --git a/pkg/compiler/lib/src/ssa/kernel_impact.dart b/pkg/compiler/lib/src/ssa/kernel_impact.dart index 155c10e..4476850 100644 --- a/pkg/compiler/lib/src/ssa/kernel_impact.dart +++ b/pkg/compiler/lib/src/ssa/kernel_impact.dart
@@ -222,7 +222,7 @@ DartType elementType = checkType(literal.typeArgument); impactBuilder.registerListLiteral(new ListLiteralUse( - compiler.coreTypes.listType(elementType), + compiler.commonElements.listType(elementType), isConstant: literal.isConst, isEmpty: literal.expressions.isEmpty)); } @@ -233,7 +233,7 @@ DartType keyType = checkType(literal.keyType); DartType valueType = checkType(literal.valueType); impactBuilder.registerMapLiteral(new MapLiteralUse( - compiler.coreTypes.mapType(keyType, valueType), + compiler.commonElements.mapType(keyType, valueType), isConstant: literal.isConst, isEmpty: literal.entries.isEmpty)); }
diff --git a/pkg/compiler/lib/src/ssa/types.dart b/pkg/compiler/lib/src/ssa/types.dart index fdab037..21be147 100644 --- a/pkg/compiler/lib/src/ssa/types.dart +++ b/pkg/compiler/lib/src/ssa/types.dart
@@ -3,7 +3,7 @@ // BSD-style license that can be found in the LICENSE file. import '../compiler.dart' show Compiler; -import '../core_types.dart' show CoreClasses; +import '../core_types.dart' show CommonElements; import '../elements/elements.dart'; import '../native/native.dart' as native; import '../tree/tree.dart' as ast; @@ -36,17 +36,18 @@ var typesReturned = nativeBehavior.typesReturned; if (typesReturned.isEmpty) return commonMasks.dynamicType; - CoreClasses coreClasses = closedWorld.coreClasses; + CommonElements commonElements = closedWorld.commonElements; // [type] is either an instance of [DartType] or special objects // like [native.SpecialType.JsObject]. TypeMask fromNativeType(dynamic type) { if (type == native.SpecialType.JsObject) { - return new TypeMask.nonNullExact(coreClasses.objectClass, closedWorld); + return new TypeMask.nonNullExact( + commonElements.objectClass, closedWorld); } if (type.isVoid) return commonMasks.nullType; - if (type.element == coreClasses.nullClass) return commonMasks.nullType; + if (type.element == commonElements.nullClass) return commonMasks.nullType; if (type.treatAsDynamic) return commonMasks.dynamicType; return new TypeMask.nonNullSubtype(type.element, closedWorld); }
diff --git a/pkg/compiler/lib/src/typechecker.dart b/pkg/compiler/lib/src/typechecker.dart index 3149368..94a88bb 100644 --- a/pkg/compiler/lib/src/typechecker.dart +++ b/pkg/compiler/lib/src/typechecker.dart
@@ -112,7 +112,7 @@ } } return compiler.types.isAssignable( - computeType(compiler.resolution), compiler.coreTypes.functionType); + computeType(compiler.resolution), compiler.commonElements.functionType); } } @@ -229,7 +229,8 @@ String get name => type.name; - DartType computeType(Resolution resolution) => resolution.coreTypes.typeType; + DartType computeType(Resolution resolution) => + resolution.commonElements.typeType; String toString() => 'TypeLiteralAccess($type)'; } @@ -297,16 +298,16 @@ /// The immediately enclosing field, method or constructor being analyzed. ExecutableElement executableContext; - CoreTypes get coreTypes => compiler.coreTypes; + CommonElements get commonElements => compiler.commonElements; DiagnosticReporter get reporter => compiler.reporter; Resolution get resolution => compiler.resolution; - InterfaceType get intType => coreTypes.intType; - InterfaceType get doubleType => coreTypes.doubleType; - InterfaceType get boolType => coreTypes.boolType; - InterfaceType get stringType => coreTypes.stringType; + InterfaceType get intType => commonElements.intType; + InterfaceType get doubleType => commonElements.doubleType; + InterfaceType get boolType => commonElements.boolType; + InterfaceType get stringType => commonElements.stringType; DartType thisType; DartType superType; @@ -429,7 +430,8 @@ /// If [inInitializer] is true, assignment should be interpreted as write to /// a field and not to a setter. - DartType analyze(Node node, {bool inInitializer: false}) { + DartType analyze(Node node, + {bool inInitializer: false, bool mustHaveType: true}) { if (node == null) { final String error = 'Unexpected node: null'; if (lastSeenNode != null) { @@ -444,12 +446,18 @@ analyzingInitializer = inInitializer; DartType result = node.accept(this); analyzingInitializer = previouslyInitializer; - if (result == null) { + if (result == null && mustHaveType) { reporter.internalError(node, 'Type is null.'); } return result; } + void analyzeUntyped(Node node, {bool inInitializer: false}) { + if (node != null) { + analyze(node, inInitializer: inInitializer, mustHaveType: false); + } + } + void checkTypePromotion(Node node, TypePromotion typePromotion, {bool checkAccesses: false}) { VariableElement variable = typePromotion.variable; @@ -529,7 +537,8 @@ } /// Analyze [node] in the context of the known types shown in [context]. - DartType analyzeInPromotedContext(Node context, Node node) { + DartType analyzeInPromotedContext(Node context, Node node, + {bool mustHaveType: true}) { Link<TypePromotion> knownForNode = const Link<TypePromotion>(); for (TypePromotion typePromotion in getShownTypePromotionsFor(context)) { typePromotion = typePromotion.copy(); @@ -538,7 +547,7 @@ registerKnownTypePromotion(typePromotion); } - final DartType type = analyze(node); + final DartType type = analyze(node, mustHaveType: mustHaveType); while (!knownForNode.isEmpty) { unregisterKnownTypePromotion(knownForNode.head); @@ -582,14 +591,13 @@ return type; } - DartType visitAssert(Assert node) { + visitAssert(Assert node) { analyze(node.condition); if (node.hasMessage) analyze(node.message); - return const StatementType(); } - DartType visitBlock(Block node) { - return analyze(node.statements); + visitBlock(Block node) { + analyzeUntyped(node.statements); } DartType visitCascade(Cascade node) { @@ -603,35 +611,32 @@ return type; } - DartType visitDoWhile(DoWhile node) { - analyze(node.body); + visitDoWhile(DoWhile node) { + analyzeUntyped(node.body); checkCondition(node.condition); - return const StatementType(); } - DartType visitExpressionStatement(ExpressionStatement node) { + visitExpressionStatement(ExpressionStatement node) { Expression expression = node.expression; analyze(expression); - return const StatementType(); } /** Dart Programming Language Specification: 11.5.1 For Loop */ - DartType visitFor(For node) { + visitFor(For node) { if (node.initializer != null) { - analyze(node.initializer); + analyzeUntyped(node.initializer); } if (node.condition != null) { checkCondition(node.condition); } if (node.update != null) { - analyze(node.update); + analyzeUntyped(node.update); } - return analyze(node.body); + analyzeUntyped(node.body); } - DartType visitFunctionDeclaration(FunctionDeclaration node) { + visitFunctionDeclaration(FunctionDeclaration node) { analyze(node.function); - return const StatementType(); } DartType visitFunctionExpression(FunctionExpression node) { @@ -653,7 +658,7 @@ } }); if (node.initializers != null) { - analyze(node.initializers, inInitializer: true); + analyzeUntyped(node.initializers, inInitializer: true); } } else { FunctionType functionType = element.computeType(resolution); @@ -667,7 +672,7 @@ executableContext = element; currentAsyncMarker = element.asyncMarker; - analyze(node.body); + analyzeUntyped(node.body); executableContext = previousExecutableContext; expectedReturnType = previousReturnType; @@ -691,16 +696,15 @@ } } - DartType visitIf(If node) { + visitIf(If node) { Expression condition = node.condition.expression; Statement thenPart = node.thenPart; checkCondition(node.condition); - analyzeInPromotedContext(condition, thenPart); + analyzeInPromotedContext(condition, thenPart, mustHaveType: false); if (node.elsePart != null) { - analyze(node.elsePart); + analyzeUntyped(node.elsePart); } - return const StatementType(); } void checkPrivateAccess(Node node, Element element, String name) { @@ -748,7 +752,7 @@ // This is an access the implicit 'call' method of a function type. return new FunctionCallAccess(receiverElement, unaliasedBound); } - if (types.isSubtype(interface, coreTypes.functionType)) { + if (types.isSubtype(interface, commonElements.functionType)) { // This is an access of the special 'call' method implicitly defined // on 'Function'. This method can be called with any arguments, which // we ensure by giving it the type 'dynamic'. @@ -1598,7 +1602,7 @@ } DartType visitLiteralSymbol(LiteralSymbol node) { - return coreTypes.symbolType; + return commonElements.symbolType; } DartType computeConstructorType( @@ -1651,27 +1655,25 @@ return listType; } - DartType visitNodeList(NodeList node) { + visitNodeList(NodeList node) { for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { - analyze(link.head, inInitializer: analyzingInitializer); + analyzeUntyped(link.head, inInitializer: analyzingInitializer); } - return const StatementType(); } - DartType visitRedirectingFactoryBody(RedirectingFactoryBody node) { + visitRedirectingFactoryBody(RedirectingFactoryBody node) { // TODO(lrn): Typecheck the body. It must refer to the constructor // of a subtype. - return const StatementType(); } - DartType visitRethrow(Rethrow node) { - return const StatementType(); + visitRethrow(Rethrow node) { + // Nothing to do here. } /** Dart Programming Language Specification: 11.10 Return */ - DartType visitReturn(Return node) { + visitReturn(Return node) { if (identical(node.beginToken.stringValue, 'native')) { - return const StatementType(); + return; } final Node expression = node.expression; @@ -1685,7 +1687,8 @@ // The resolver already emitted an error for this expression. } else { if (currentAsyncMarker == AsyncMarker.ASYNC) { - expressionType = coreTypes.futureType(types.flatten(expressionType)); + expressionType = + commonElements.futureType(types.flatten(expressionType)); } if (expectedReturnType.isVoid && !types.isAssignable(expressionType, const VoidType())) { @@ -1705,7 +1708,6 @@ reportTypeWarning( node, MessageKind.RETURN_NOTHING, {'returnType': expectedReturnType}); } - return const StatementType(); } DartType visitThrow(Throw node) { @@ -1727,22 +1729,21 @@ DartType resultType = analyze(node.expression); if (!node.hasStar) { if (currentAsyncMarker.isAsync) { - resultType = coreTypes.streamType(resultType); + resultType = commonElements.streamType(resultType); } else { - resultType = coreTypes.iterableType(resultType); + resultType = commonElements.iterableType(resultType); } } else { if (currentAsyncMarker.isAsync) { // The static type of expression must be assignable to Stream. - checkAssignable(node, resultType, coreTypes.streamType()); + checkAssignable(node, resultType, commonElements.streamType()); } else { // The static type of expression must be assignable to Iterable. - checkAssignable(node, resultType, coreTypes.iterableType()); + checkAssignable(node, resultType, commonElements.iterableType()); } } // The static type of the result must be assignable to the declared type. checkAssignable(node, resultType, expectedReturnType); - return const StatementType(); } DartType visitTypeAnnotation(TypeAnnotation node) { @@ -1766,7 +1767,7 @@ checkAssignable(spannable, expressionType, declaredType); } - DartType visitVariableDefinitions(VariableDefinitions node) { + visitVariableDefinitions(VariableDefinitions node) { DartType type = analyzeVariableTypeAnnotation(node); for (Link<Node> link = node.definitions.nodes; !link.isEmpty; @@ -1791,13 +1792,11 @@ // } } } - return const StatementType(); } - DartType visitWhile(While node) { + visitWhile(While node) { checkCondition(node.condition); - analyze(node.body); - return const StatementType(); + analyzeUntyped(node.body); } DartType visitParenthesizedExpression(ParenthesizedExpression node) { @@ -1832,15 +1831,15 @@ } visitEmptyStatement(EmptyStatement node) { - return const StatementType(); + // Nothing to do here. } visitBreakStatement(BreakStatement node) { - return const StatementType(); + // Nothing to do here. } visitContinueStatement(ContinueStatement node) { - return const StatementType(); + // Nothing to do here. } DartType computeForInElementType(ForIn node) { @@ -1857,7 +1856,7 @@ DartType elementType = computeForInElementType(node); DartType expressionType = analyze(node.expression); if (resolution.target.supportsAsyncAwait) { - DartType streamOfDynamic = coreTypes.streamType(); + DartType streamOfDynamic = commonElements.streamType(); if (!types.isAssignable(expressionType, streamOfDynamic)) { reportMessage(node.expression, MessageKind.NOT_ASSIGNABLE, {'fromType': expressionType, 'toType': streamOfDynamic}, @@ -1885,8 +1884,7 @@ } } } - analyze(node.body); - return const StatementType(); + analyzeUntyped(node.body); } visitSyncForIn(SyncForIn node) { @@ -1908,12 +1906,11 @@ }, isHint: true); } - analyze(node.body); - return const StatementType(); + analyzeUntyped(node.body); } visitLabeledStatement(LabeledStatement node) { - return analyze(node.statement); + analyzeUntyped(node.statement); } visitLiteralMap(LiteralMap node) { @@ -1963,7 +1960,7 @@ checkAssignable(caseMatch, expressionType, caseType); } - analyze(switchCase); + analyzeUntyped(switchCase); } if (!hasDefaultCase && expressionType.isEnumType) { @@ -2006,28 +2003,25 @@ } }); } - - return const StatementType(); } visitSwitchCase(SwitchCase node) { - return analyze(node.statements); + analyzeUntyped(node.statements); } visitTryStatement(TryStatement node) { // TODO(johnniwinther): Use reachability information of try-block, // catch-blocks and finally-block to compute the whether the try statement // is returning. - analyze(node.tryBlock); + analyzeUntyped(node.tryBlock); for (CatchBlock catchBlock in node.catchBlocks) { - analyze(catchBlock); + analyzeUntyped(catchBlock); } - analyzeWithDefault(node.finallyBlock, null); - return const StatementType(); + analyzeUntyped(node.finallyBlock); } visitCatchBlock(CatchBlock node) { - return analyze(node.block); + analyzeUntyped(node.block); } visitTypedef(Typedef node) {
diff --git a/pkg/compiler/lib/src/types/flat_type_mask.dart b/pkg/compiler/lib/src/types/flat_type_mask.dart index b93b1e6..80a4734 100644 --- a/pkg/compiler/lib/src/types/flat_type_mask.dart +++ b/pkg/compiler/lib/src/types/flat_type_mask.dart
@@ -113,22 +113,22 @@ // not track correctly the list of truly instantiated classes. BackendClasses backendClasses = closedWorld.backendClasses; if (containsOnlyString(closedWorld)) { - return cls == closedWorld.coreClasses.stringClass || + return cls == closedWorld.commonElements.stringClass || cls == backendClasses.stringImplementation; } if (containsOnlyBool(closedWorld)) { - return cls == closedWorld.coreClasses.boolClass || + return cls == closedWorld.commonElements.boolClass || cls == backendClasses.boolImplementation; } if (containsOnlyInt(closedWorld)) { - return cls == closedWorld.coreClasses.intClass || + return cls == closedWorld.commonElements.intClass || cls == backendClasses.intImplementation || cls == backendClasses.positiveIntImplementation || cls == backendClasses.uint32Implementation || cls == backendClasses.uint31Implementation; } if (containsOnlyDouble(closedWorld)) { - return cls == closedWorld.coreClasses.doubleClass || + return cls == closedWorld.commonElements.doubleClass || cls == backendClasses.doubleImplementation; } return false; @@ -158,7 +158,8 @@ // TODO(herhut): Add check whether flatOther.base is superclass of // all subclasses of this.base. if (flatOther.isSubclass) { - if (isSubtype) return (otherBase == closedWorld.coreClasses.objectClass); + if (isSubtype) + return (otherBase == closedWorld.commonElements.objectClass); return closedWorld.isSubclassOf(base, otherBase); } assert(flatOther.isSubtype); @@ -172,7 +173,7 @@ bool containsOnlyInt(ClosedWorld closedWorld) { BackendClasses backendClasses = closedWorld.backendClasses; - return base == closedWorld.coreClasses.intClass || + return base == closedWorld.commonElements.intClass || base == backendClasses.intImplementation || base == backendClasses.positiveIntImplementation || base == backendClasses.uint31Implementation || @@ -181,7 +182,7 @@ bool containsOnlyDouble(ClosedWorld closedWorld) { BackendClasses backendClasses = closedWorld.backendClasses; - return base == closedWorld.coreClasses.doubleClass || + return base == closedWorld.commonElements.doubleClass || base == backendClasses.doubleImplementation; } @@ -189,19 +190,19 @@ BackendClasses backendClasses = closedWorld.backendClasses; return containsOnlyInt(closedWorld) || containsOnlyDouble(closedWorld) || - base == closedWorld.coreClasses.numClass || + base == closedWorld.commonElements.numClass || base == backendClasses.numImplementation; } bool containsOnlyBool(ClosedWorld closedWorld) { BackendClasses backendClasses = closedWorld.backendClasses; - return base == closedWorld.coreClasses.boolClass || + return base == closedWorld.commonElements.boolClass || base == backendClasses.boolImplementation; } bool containsOnlyString(ClosedWorld closedWorld) { BackendClasses backendClasses = closedWorld.backendClasses; - return base == closedWorld.coreClasses.stringClass || + return base == closedWorld.commonElements.stringClass || base == backendClasses.stringImplementation; } @@ -237,7 +238,7 @@ */ bool containsAll(ClosedWorld closedWorld) { if (isEmptyOrNull || isExact) return false; - return identical(base, closedWorld.coreClasses.objectClass); + return identical(base, closedWorld.commonElements.objectClass); } TypeMask union(TypeMask other, ClosedWorld closedWorld) { @@ -292,7 +293,7 @@ assert(TypeMask.assertIsNormalized(other, closedWorld)); int combined; if ((isExact && other.isExact) || - base == closedWorld.coreClasses.objectClass) { + base == closedWorld.commonElements.objectClass) { // Since the other mask is a subclass of this mask, we need the // resulting union to be a subclass too. If either one of the // masks are nullable the result should be nullable too.
diff --git a/pkg/compiler/lib/src/types/masks.dart b/pkg/compiler/lib/src/types/masks.dart index f44446a..a713dc8 100644 --- a/pkg/compiler/lib/src/types/masks.dart +++ b/pkg/compiler/lib/src/types/masks.dart
@@ -69,11 +69,11 @@ TypeMask _unmodifiableArrayType; TypeMask _interceptorType; - TypeMask get dynamicType => _dynamicType ??= - new TypeMask.subclass(closedWorld.coreClasses.objectClass, closedWorld); + TypeMask get dynamicType => _dynamicType ??= new TypeMask.subclass( + closedWorld.commonElements.objectClass, closedWorld); TypeMask get nonNullType => _nonNullType ??= new TypeMask.nonNullSubclass( - closedWorld.coreClasses.objectClass, closedWorld); + closedWorld.commonElements.objectClass, closedWorld); TypeMask get intType => _intType ??= new TypeMask.nonNullSubclass( backendClasses.intImplementation, closedWorld);
diff --git a/pkg/compiler/lib/src/types/type_mask.dart b/pkg/compiler/lib/src/types/type_mask.dart index c91fac6..e985433 100644 --- a/pkg/compiler/lib/src/types/type_mask.dart +++ b/pkg/compiler/lib/src/types/type_mask.dart
@@ -25,7 +25,7 @@ bool needsNoSuchMethodHandling(Selector selector, ClosedWorld world) { if (isAll) { TypeMask mask = - new TypeMask.subclass(world.coreClasses.objectClass, world); + new TypeMask.subclass(world.commonElements.objectClass, world); return mask.needsNoSuchMethodHandling(selector, world); } for (TypeMask mask in _masks) {
diff --git a/pkg/compiler/lib/src/types/union_type_mask.dart b/pkg/compiler/lib/src/types/union_type_mask.dart index eada935..3c7dfcc 100644 --- a/pkg/compiler/lib/src/types/union_type_mask.dart +++ b/pkg/compiler/lib/src/types/union_type_mask.dart
@@ -219,13 +219,13 @@ // Ensure the cheap test fails. assert(!disjointMasks.any((mask) => mask.containsMask(other, closedWorld))); // If we cover object, we should never get here. - assert(!contains(closedWorld.coreClasses.objectClass, closedWorld)); + assert(!contains(closedWorld.commonElements.objectClass, closedWorld)); // Likewise, nullness should be covered. assert(isNullable || !other.isNullable); // The fast test is precise for exact types. if (other.isExact) return false; // We cannot contain object. - if (other.contains(closedWorld.coreClasses.objectClass, closedWorld)) { + if (other.contains(closedWorld.commonElements.objectClass, closedWorld)) { return false; } FlatTypeMask flat = TypeMask.nonForwardingMask(other);
diff --git a/pkg/compiler/lib/src/universe/function_set.dart b/pkg/compiler/lib/src/universe/function_set.dart index 0fb0018..b99e1fe 100644 --- a/pkg/compiler/lib/src/universe/function_set.dart +++ b/pkg/compiler/lib/src/universe/function_set.dart
@@ -13,13 +13,8 @@ import 'selector.dart' show Selector; import 'world_builder.dart' show ReceiverConstraint; -// TODO(kasperl): This actually holds getters and setters just fine -// too and stricly they aren't functions. Maybe this needs a better -// name -- something like ElementSet seems a bit too generic. -class FunctionSet { - final ClosedWorld closedWorld; +class FunctionSetBuilder { final Map<String, FunctionSetNode> nodes = new Map<String, FunctionSetNode>(); - FunctionSet(this.closedWorld); FunctionSetNode newNode(String name) => new FunctionSetNode(name); @@ -41,6 +36,20 @@ } } + FunctionSet close(ClosedWorld closedWorld) { + return new FunctionSet(closedWorld, nodes); + } +} + +// TODO(kasperl): This actually holds getters and setters just fine +// too and stricly they aren't functions. Maybe this needs a better +// name -- something like ElementSet seems a bit too generic. +class FunctionSet { + final ClosedWorld closedWorld; + final Map<String, FunctionSetNode> nodes; + + FunctionSet(this.closedWorld, this.nodes); + bool contains(Element element) { assert(element.isInstanceMember); assert(!element.isAbstract); @@ -74,7 +83,7 @@ : new SelectorMask( selector, new TypeMask.subclass( - closedWorld.coreClasses.objectClass, closedWorld)); + closedWorld.commonElements.objectClass, closedWorld)); } /// Returns the set of functions that can be the target of a call to @@ -279,8 +288,8 @@ @override TypeMask computeMask(ClosedWorld closedWorld) { - assert( - closedWorld.hasAnyStrictSubclass(closedWorld.coreClasses.objectClass)); + assert(closedWorld + .hasAnyStrictSubclass(closedWorld.commonElements.objectClass)); if (_mask != null) return _mask; return _mask = new TypeMask.unionOf( functions.expand((element) {
diff --git a/pkg/compiler/lib/src/universe/world_builder.dart b/pkg/compiler/lib/src/universe/world_builder.dart index cd676bd..05cae63 100644 --- a/pkg/compiler/lib/src/universe/world_builder.dart +++ b/pkg/compiler/lib/src/universe/world_builder.dart
@@ -12,13 +12,15 @@ import '../common/names.dart' show Identifiers; import '../common/resolution.dart' show Resolution; import '../compiler.dart' show Compiler; +import '../core_types.dart'; import '../dart_types.dart'; import '../elements/elements.dart'; import '../elements/entities.dart'; -import '../universe/class_set.dart' show Instantiation; +import '../universe/class_set.dart'; +import '../universe/function_set.dart' show FunctionSetBuilder; import '../util/enumset.dart'; import '../util/util.dart'; -import '../world.dart' show World, ClosedWorld, OpenWorld, WorldImpl; +import '../world.dart' show World, ClosedWorld, ClosedWorldImpl, OpenWorld; import 'selector.dart' show Selector; import 'use.dart' show DynamicUse, DynamicUseKind, StaticUse, StaticUseKind; @@ -109,6 +111,39 @@ UniverseSelectorConstraints createSelectorConstraints(Selector selector); } +class OpenWorldStrategy implements SelectorConstraintsStrategy { + const OpenWorldStrategy(); + + OpenWorldConstraints createSelectorConstraints(Selector selector) { + return new OpenWorldConstraints(); + } +} + +class OpenWorldConstraints extends UniverseSelectorConstraints { + bool isAll = false; + + @override + bool applies(Element element, Selector selector, World world) => isAll; + + @override + bool needsNoSuchMethodHandling(Selector selector, World world) => isAll; + + @override + bool addReceiverConstraint(ReceiverConstraint constraint) { + if (isAll) return false; + isAll = true; + return true; + } + + String toString() { + if (isAll) { + return '<all>'; + } else { + return '<none>'; + } + } +} + /// The [WorldBuilder] is an auxiliary class used in the process of computing /// the [ClosedWorld]. // TODO(johnniwinther): Move common implementation to a [WorldBuilderBase] when @@ -133,7 +168,7 @@ Iterable<DartType> get instantiatedTypes; } -abstract class ResolutionWorldBuilder implements WorldBuilder { +abstract class ResolutionWorldBuilder implements WorldBuilder, OpenWorld { /// Set of (live) local functions (closures) whose signatures reference type /// variables. /// @@ -169,10 +204,6 @@ /// Returns `true` if [member] is invoked as a setter. bool hasInvokedSetter(Element member); - /// The [OpenWorld] being created by this world builder. - // TODO(johnniwinther): Merge this with [ResolutionWorldBuilder]. - OpenWorld get openWorld; - /// The closed world computed by this world builder. /// /// This is only available after the world builder has been closed. @@ -430,30 +461,49 @@ /// and classes. bool useInstantiationMap = false; - WorldImpl _openWorld; - final Backend _backend; final Resolution _resolution; + bool _closed = false; + ClosedWorld _closedWorldCache; + FunctionSetBuilder _allFunctions; + + final Set<TypedefElement> _allTypedefs = new Set<TypedefElement>(); + + final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses = + new Map<ClassElement, Set<MixinApplicationElement>>(); + + // We keep track of subtype and subclass relationships in four + // distinct sets to make class hierarchy analysis faster. + final Map<ClassElement, ClassHierarchyNode> _classHierarchyNodes = + <ClassElement, ClassHierarchyNode>{}; + final Map<ClassElement, ClassSet> _classSets = <ClassElement, ClassSet>{}; + + final Set<Element> alreadyPopulated; + + final CacheStrategy cacheStrategy; + + bool get isClosed => _closed; ResolutionWorldBuilderImpl(Backend backend, Resolution resolution, CacheStrategy cacheStrategy, this.selectorConstraintsStrategy) : this._backend = backend, - this._resolution = resolution { - _openWorld = new WorldImpl(this, backend, resolution.coreClasses, - resolution.coreTypes, cacheStrategy); + this._resolution = resolution, + this.cacheStrategy = cacheStrategy, + alreadyPopulated = cacheStrategy.newSet() { + _allFunctions = new FunctionSetBuilder(); } Iterable<ClassElement> get processedClasses => _processedClasses.keys .where((cls) => _processedClasses[cls].isInstantiated); - OpenWorld get openWorld => _openWorld; + CommonElements get commonElements => _resolution.commonElements; ClosedWorld get closedWorldForTesting { - if (!_openWorld.isClosed) { + if (!_closed) { throw new SpannableAssertionFailure( NO_LOCATION_SPANNABLE, "The world builder has not yet been closed."); } - return _openWorld; + return _closedWorldCache; } /// All directly instantiated classes, that is, classes with a generative @@ -538,15 +588,11 @@ // TODO(johnniwinther): Use [_instantiationInfo] to compute this information // instead. if (_implementedClasses.add(cls)) { - void onImplemented(ClassElement cls) { - _ClassUsage usage = _getClassUsage(cls); - classUsed(usage.cls, usage.implement()); - } - - onImplemented(cls); + classUsed(cls, _getClassUsage(cls).implement()); cls.allSupertypes.forEach((InterfaceType supertype) { if (_implementedClasses.add(supertype.element)) { - onImplemented(supertype.element); + classUsed( + supertype.element, _getClassUsage(supertype.element).implement()); } }); } @@ -563,7 +609,7 @@ for (Selector selector in selectors.keys) { if (selector.appliesUnnamed(member)) { SelectorConstraints masks = selectors[selector]; - if (masks.applies(member, selector, _openWorld)) { + if (masks.applies(member, selector, this)) { return true; } } @@ -632,45 +678,33 @@ DynamicUse dynamicUse, MemberUsedCallback memberUsed) { Selector selector = dynamicUse.selector; String methodName = selector.name; + + void _process(Map<String, Set<_MemberUsage>> memberMap, + EnumSet<MemberUse> action(_MemberUsage usage)) { + _processSet(memberMap, methodName, (_MemberUsage usage) { + if (dynamicUse.appliesUnnamed(usage.entity, this)) { + memberUsed(usage.entity, action(usage)); + return true; + } + return false; + }); + } + switch (dynamicUse.kind) { case DynamicUseKind.INVOKE: if (_registerNewSelector(dynamicUse, _invokedNames)) { - _processInstanceMembers(methodName, (_MemberUsage usage) { - if (dynamicUse.appliesUnnamed(usage.entity, _openWorld)) { - memberUsed(usage.entity, usage.invoke()); - return true; - } - return false; - }); + _process(_instanceMembersByName, (m) => m.invoke()); } break; case DynamicUseKind.GET: if (_registerNewSelector(dynamicUse, _invokedGetters)) { - _processInstanceMembers(methodName, (_MemberUsage usage) { - if (dynamicUse.appliesUnnamed(usage.entity, _openWorld)) { - memberUsed(usage.entity, usage.read()); - return true; - } - return false; - }); - _processInstanceFunctions(methodName, (_MemberUsage usage) { - if (dynamicUse.appliesUnnamed(usage.entity, _openWorld)) { - memberUsed(usage.entity, usage.read()); - return true; - } - return false; - }); + _process(_instanceMembersByName, (m) => m.read()); + _process(_instanceFunctionsByName, (m) => m.read()); } break; case DynamicUseKind.SET: if (_registerNewSelector(dynamicUse, _invokedSetters)) { - _processInstanceMembers(methodName, (_MemberUsage usage) { - if (dynamicUse.appliesUnnamed(usage.entity, _openWorld)) { - memberUsed(usage.entity, usage.write()); - return true; - } - return false; - }); + _process(_instanceMembersByName, (m) => m.write()); } break; } @@ -827,7 +861,7 @@ }); } - /// Call [updateUsage] on all [MemberUsage]s in the set in [map] for + /// Call [updateUsage] on all [_MemberUsage]s in the set in [map] for /// [memberName]. If [updateUsage] returns `true` the usage is removed from /// the set. void _processSet(Map<String, Set<_MemberUsage>> map, String memberName, @@ -845,22 +879,12 @@ map[memberName].addAll(remaining); } - void _processInstanceMembers(String name, bool updateUsage(_MemberUsage e)) { - _processSet(_instanceMembersByName, name, updateUsage); - } - - void _processInstanceFunctions( - String name, bool updateUsage(_MemberUsage e)) { - _processSet(_instanceFunctionsByName, name, updateUsage); - } - void _processInstantiatedClassMember( ClassElement cls, MemberElement member, MemberUsedCallback memberUsed) { assert(invariant(member, member.isDeclaration)); if (!member.isInstanceMember) return; String memberName = member.name; member.computeType(_resolution); - EnumSet<MemberUse> useSet = new EnumSet<MemberUse>(); // The obvious thing to test here would be "member.isNative", // however, that only works after metadata has been parsed/analyzed, // and that may not have happened yet. @@ -868,12 +892,13 @@ // its metadata parsed and analyzed. // Note: this assumes that there are no non-native fields on native // classes, which may not be the case when a native class is subclassed. - bool isNative = _backend.isNative(cls); - _MemberUsage usage = _instanceMemberUsage.putIfAbsent(member, () { + _instanceMemberUsage.putIfAbsent(member, () { + bool isNative = _backend.isNative(cls); _MemberUsage usage = new _MemberUsage(member, isNative: isNative); + EnumSet<MemberUse> useSet = new EnumSet<MemberUse>(); useSet.addAll(usage.appliedUse); if (member.isField && isNative) { - _openWorld.registerUsedElement(member); + registerUsedElement(member); } if (member.isFunction && member.name == Identifiers.call && @@ -910,6 +935,168 @@ return usage; }); } + + /// Returns an iterable over all mixin applications that mixin [cls]. + Iterable<MixinApplicationElement> allMixinUsesOf(ClassElement cls) { + Iterable<MixinApplicationElement> uses = _mixinUses[cls]; + return uses != null ? uses : const <MixinApplicationElement>[]; + } + + /// Called to add [cls] to the set of known classes. + /// + /// This ensures that class hierarchy queries can be performed on [cls] and + /// classes that extend or implement it. + void registerClass(ClassElement cls) => _registerClass(cls); + + void _registerClass(ClassElement cls, {bool isDirectlyInstantiated: false}) { + _ensureClassSet(cls); + if (isDirectlyInstantiated) { + _updateClassHierarchyNodeForClass(cls, directlyInstantiated: true); + } + } + + void registerTypedef(TypedefElement typdef) { + _allTypedefs.add(typdef); + } + + ClassHierarchyNode _ensureClassHierarchyNode(ClassElement cls) { + cls = cls.declaration; + return _classHierarchyNodes.putIfAbsent(cls, () { + ClassHierarchyNode parentNode; + if (cls.superclass != null) { + parentNode = _ensureClassHierarchyNode(cls.superclass); + } + return new ClassHierarchyNode(parentNode, cls); + }); + } + + ClassSet _ensureClassSet(ClassElement cls) { + cls = cls.declaration; + return _classSets.putIfAbsent(cls, () { + ClassHierarchyNode node = _ensureClassHierarchyNode(cls); + ClassSet classSet = new ClassSet(node); + + for (InterfaceType type in cls.allSupertypes) { + // TODO(johnniwinther): Optimization: Avoid adding [cls] to + // superclasses. + ClassSet subtypeSet = _ensureClassSet(type.element); + subtypeSet.addSubtype(node); + } + if (cls.isMixinApplication) { + // TODO(johnniwinther): Store this in the [ClassSet]. + MixinApplicationElement mixinApplication = cls; + if (mixinApplication.mixin != null) { + // If [mixinApplication] is malformed [mixin] is `null`. + registerMixinUse(mixinApplication, mixinApplication.mixin); + } + } + + return classSet; + }); + } + + void _updateSuperClassHierarchyNodeForClass(ClassHierarchyNode node) { + // Ensure that classes implicitly implementing `Function` are in its + // subtype set. + ClassElement cls = node.cls; + if (cls != commonElements.functionClass && + cls.implementsFunction(commonElements)) { + ClassSet subtypeSet = _ensureClassSet(commonElements.functionClass); + subtypeSet.addSubtype(node); + } + if (!node.isInstantiated && node.parentNode != null) { + _updateSuperClassHierarchyNodeForClass(node.parentNode); + } + } + + void _updateClassHierarchyNodeForClass(ClassElement cls, + {bool directlyInstantiated: false, bool abstractlyInstantiated: false}) { + ClassHierarchyNode node = _ensureClassHierarchyNode(cls); + _updateSuperClassHierarchyNodeForClass(node); + if (directlyInstantiated) { + node.isDirectlyInstantiated = true; + } + if (abstractlyInstantiated) { + node.isAbstractlyInstantiated = true; + } + } + + ClosedWorld closeWorld(DiagnosticReporter reporter) { + Map<ClassElement, Set<ClassElement>> typesImplementedBySubclasses = + new Map<ClassElement, Set<ClassElement>>(); + + /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated` + /// properties of the [ClassHierarchyNode] for [cls]. + + void addSubtypes(ClassElement cls, InstantiationInfo info) { + if (!info.hasInstantiation) { + return; + } + if (cacheStrategy.hasIncrementalSupport && !alreadyPopulated.add(cls)) { + return; + } + assert(cls.isDeclaration); + if (!cls.isResolved) { + reporter.internalError(cls, 'Class "${cls.name}" is not resolved.'); + } + + _updateClassHierarchyNodeForClass(cls, + directlyInstantiated: info.isDirectlyInstantiated, + abstractlyInstantiated: info.isAbstractlyInstantiated); + + // Walk through the superclasses, and record the types + // implemented by that type on the superclasses. + ClassElement superclass = cls.superclass; + while (superclass != null) { + Set<Element> typesImplementedBySubclassesOfCls = + typesImplementedBySubclasses.putIfAbsent( + superclass, () => new Set<ClassElement>()); + for (DartType current in cls.allSupertypes) { + typesImplementedBySubclassesOfCls.add(current.element); + } + superclass = superclass.superclass; + } + } + + // Use the [:seenClasses:] set to include non-instantiated + // classes: if the superclass of these classes require RTI, then + // they also need RTI, so that a constructor passes the type + // variables to the super constructor. + forEachInstantiatedClass(addSubtypes); + + _closed = true; + return _closedWorldCache = new ClosedWorldImpl( + backend: _backend, + commonElements: commonElements, + resolverWorld: this, + functionSetBuilder: _allFunctions, + allTypedefs: _allTypedefs, + mixinUses: _mixinUses, + typesImplementedBySubclasses: typesImplementedBySubclasses, + classHierarchyNodes: _classHierarchyNodes, + classSets: _classSets); + } + + void registerMixinUse( + MixinApplicationElement mixinApplication, ClassElement mixin) { + // TODO(johnniwinther): Add map restricted to live classes. + // We don't support patch classes as mixin. + assert(mixin.isDeclaration); + Set<MixinApplicationElement> users = + _mixinUses.putIfAbsent(mixin, () => new Set<MixinApplicationElement>()); + users.add(mixinApplication); + } + + void registerUsedElement(MemberElement element) { + if (element.isInstanceMember && !element.isAbstract) { + _allFunctions.add(element); + } + } + + ClosedWorld get closedWorldCache { + assert(isClosed); + return _closedWorldCache; + } } /// World builder specific to codegen. @@ -946,6 +1133,8 @@ } class CodegenWorldBuilderImpl implements CodegenWorldBuilder { + final Backend _backend; + /// The set of all directly instantiated classes, that is, classes with a /// generative constructor that has been called directly and not only through /// a super-call. @@ -986,11 +1175,39 @@ final Map<String, Map<Selector, SelectorConstraints>> _invokedSetters = <String, Map<Selector, SelectorConstraints>>{}; + final Map<ClassElement, _ClassUsage> _processedClasses = + <ClassElement, _ClassUsage>{}; + + /// Map of registered usage of static members of live classes. + final Map<Entity, _StaticMemberUsage> _staticMemberUsage = + <Entity, _StaticMemberUsage>{}; + + /// Map of registered usage of instance members of live classes. + final Map<MemberEntity, _MemberUsage> _instanceMemberUsage = + <MemberEntity, _MemberUsage>{}; + + /// Map containing instance members of live classes that are not yet live + /// themselves. + final Map<String, Set<_MemberUsage>> _instanceMembersByName = + <String, Set<_MemberUsage>>{}; + + /// Map containing instance methods of live classes that are not yet + /// closurized. + final Map<String, Set<_MemberUsage>> _instanceFunctionsByName = + <String, Set<_MemberUsage>>{}; + final Set<DartType> isChecks = new Set<DartType>(); final SelectorConstraintsStrategy selectorConstraintsStrategy; - CodegenWorldBuilderImpl(this.selectorConstraintsStrategy); + CodegenWorldBuilderImpl(this._backend, this.selectorConstraintsStrategy); + + // TODO(johnniwinther): Remove this hack: + ClosedWorld get _world => + _backend.compiler.resolverWorld.closedWorldForTesting; + + Iterable<ClassElement> get processedClasses => _processedClasses.keys + .where((cls) => _processedClasses[cls].isInstantiated); /// All directly instantiated classes, that is, classes with a generative /// constructor that has been called directly and not only through a @@ -1013,12 +1230,12 @@ // TODO(johnniwinther): Fully enforce the separation between exact, through // subclass and through subtype instantiated types/classes. // TODO(johnniwinther): Support unknown type arguments for generic types. - void registerTypeInstantiation(InterfaceType type, - {bool byMirrors: false, - bool isNative: false, - void onImplemented(ClassElement cls)}) { - _instantiatedTypes.add(type); + void registerTypeInstantiation( + InterfaceType type, ClassUsedCallback classUsed, + {bool byMirrors: false}) { ClassElement cls = type.element; + bool isNative = _backend.isNative(cls); + _instantiatedTypes.add(type); if (!cls.isAbstract // We can't use the closed-world assumption with native abstract // classes; a native abstract class may have non-abstract subclasses @@ -1032,15 +1249,17 @@ || byMirrors) { _directlyInstantiatedClasses.add(cls); + _processInstantiatedClass(cls, classUsed); } // TODO(johnniwinther): Replace this by separate more specific mappings that // include the type arguments. if (_implementedClasses.add(cls)) { - onImplemented(cls); + classUsed(cls, _getClassUsage(cls).implement()); cls.allSupertypes.forEach((InterfaceType supertype) { if (_implementedClasses.add(supertype.element)) { - onImplemented(supertype.element); + classUsed( + supertype.element, _getClassUsage(supertype.element).implement()); } }); } @@ -1073,15 +1292,44 @@ return _hasMatchingSelector(_invokedSetters[member.name], member, world); } - bool registerDynamicUse(DynamicUse dynamicUse) { + bool registerDynamicUse( + DynamicUse dynamicUse, MemberUsedCallback memberUsed) { + Selector selector = dynamicUse.selector; + String methodName = selector.name; + + void _process(Map<String, Set<_MemberUsage>> memberMap, + EnumSet<MemberUse> action(_MemberUsage usage)) { + _processSet(memberMap, methodName, (_MemberUsage usage) { + if (dynamicUse.appliesUnnamed(usage.entity, _world)) { + memberUsed(usage.entity, action(usage)); + return true; + } + return false; + }); + } + switch (dynamicUse.kind) { case DynamicUseKind.INVOKE: - return _registerNewSelector(dynamicUse, _invokedNames); + if (_registerNewSelector(dynamicUse, _invokedNames)) { + _process(_instanceMembersByName, (m) => m.invoke()); + return true; + } + break; case DynamicUseKind.GET: - return _registerNewSelector(dynamicUse, _invokedGetters); + if (_registerNewSelector(dynamicUse, _invokedGetters)) { + _process(_instanceMembersByName, (m) => m.read()); + _process(_instanceFunctionsByName, (m) => m.read()); + return true; + } + break; case DynamicUseKind.SET: - return _registerNewSelector(dynamicUse, _invokedSetters); + if (_registerNewSelector(dynamicUse, _invokedSetters)) { + _process(_instanceMembersByName, (m) => m.write()); + return true; + } + break; } + return false; } bool _registerNewSelector(DynamicUse dynamicUse, @@ -1140,7 +1388,7 @@ return type; } - void registerStaticUse(StaticUse staticUse) { + void _registerStaticUse(StaticUse staticUse) { Element element = staticUse.element; if (Elements.isStaticOrTopLevel(element) && element.isField) { allReferencedStaticFields.add(element); @@ -1166,13 +1414,156 @@ } } + void registerStaticUse(StaticUse staticUse, MemberUsedCallback memberUsed) { + Element element = staticUse.element; + assert(invariant(element, element.isDeclaration, + message: "Element ${element} is not the declaration.")); + _registerStaticUse(staticUse); + _StaticMemberUsage usage = _staticMemberUsage.putIfAbsent(element, () { + if ((element.isStatic || element.isTopLevel) && element.isFunction) { + return new _StaticFunctionUsage(element); + } else { + return new _GeneralStaticMemberUsage(element); + } + }); + EnumSet<MemberUse> useSet = new EnumSet<MemberUse>(); + switch (staticUse.kind) { + case StaticUseKind.STATIC_TEAR_OFF: + useSet.addAll(usage.tearOff()); + break; + case StaticUseKind.FIELD_GET: + case StaticUseKind.FIELD_SET: + case StaticUseKind.CLOSURE: + // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and + // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue. + // Also [CLOSURE] contains [LocalFunctionElement] which we cannot + // enqueue. + break; + case StaticUseKind.SUPER_FIELD_SET: + case StaticUseKind.SUPER_TEAR_OFF: + case StaticUseKind.GENERAL: + case StaticUseKind.DIRECT_USE: + useSet.addAll(usage.normalUse()); + break; + case StaticUseKind.CONSTRUCTOR_INVOKE: + case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: + case StaticUseKind.REDIRECTION: + useSet.addAll(usage.normalUse()); + break; + case StaticUseKind.DIRECT_INVOKE: + _MemberUsage instanceUsage = + _getMemberUsage(staticUse.element, memberUsed); + memberUsed(instanceUsage.entity, instanceUsage.invoke()); + _instanceMembersByName[instanceUsage.entity.name] + ?.remove(instanceUsage); + useSet.addAll(usage.normalUse()); + break; + } + memberUsed(usage.entity, useSet); + } + void forgetElement(Element element, Compiler compiler) { + _processedClasses.remove(element); _directlyInstantiatedClasses.remove(element); if (element is ClassElement) { assert(invariant(element, element.thisType.isRaw, message: 'Generic classes not supported (${element.thisType}).')); _instantiatedTypes..remove(element.rawType)..remove(element.thisType); } + removeFromSet(_instanceMembersByName, element); + removeFromSet(_instanceFunctionsByName, element); + if (element is MemberElement) { + for (Element closure in element.nestedClosures) { + removeFromSet(_instanceMembersByName, closure); + removeFromSet(_instanceFunctionsByName, closure); + } + } + } + + void processClassMembers(ClassElement cls, MemberUsedCallback memberUsed) { + cls.implementation.forEachMember((_, MemberElement member) { + assert(invariant(member, member.isDeclaration)); + if (!member.isInstanceMember) return; + _getMemberUsage(member, memberUsed); + }); + } + + _MemberUsage _getMemberUsage( + MemberElement member, MemberUsedCallback memberUsed) { + assert(invariant(member, member.isDeclaration)); + return _instanceMemberUsage.putIfAbsent(member, () { + String memberName = member.name; + ClassElement cls = member.enclosingClass; + bool isNative = _backend.isNative(cls); + _MemberUsage usage = new _MemberUsage(member, isNative: isNative); + EnumSet<MemberUse> useSet = new EnumSet<MemberUse>(); + useSet.addAll(usage.appliedUse); + if (hasInvokedGetter(member, _world)) { + useSet.addAll(usage.read()); + } + if (hasInvokedSetter(member, _world)) { + useSet.addAll(usage.write()); + } + if (hasInvocation(member, _world)) { + useSet.addAll(usage.invoke()); + } + + if (usage.pendingUse.contains(MemberUse.CLOSURIZE_INSTANCE)) { + // Store the member in [instanceFunctionsByName] to catch + // getters on the function. + _instanceFunctionsByName + .putIfAbsent(usage.entity.name, () => new Set<_MemberUsage>()) + .add(usage); + } + if (usage.pendingUse.contains(MemberUse.NORMAL)) { + // The element is not yet used. Add it to the list of instance + // members to still be processed. + _instanceMembersByName + .putIfAbsent(memberName, () => new Set<_MemberUsage>()) + .add(usage); + } + memberUsed(member, useSet); + return usage; + }); + } + + void _processSet(Map<String, Set<_MemberUsage>> map, String memberName, + bool f(_MemberUsage e)) { + Set<_MemberUsage> members = map[memberName]; + if (members == null) return; + // [f] might add elements to [: map[memberName] :] during the loop below + // so we create a new list for [: map[memberName] :] and prepend the + // [remaining] members after the loop. + map[memberName] = new Set<_MemberUsage>(); + Set<_MemberUsage> remaining = new Set<_MemberUsage>(); + for (_MemberUsage member in members) { + if (!f(member)) remaining.add(member); + } + map[memberName].addAll(remaining); + } + + /// Return the canonical [_ClassUsage] for [cls]. + _ClassUsage _getClassUsage(ClassElement cls) { + return _processedClasses.putIfAbsent(cls, () => new _ClassUsage(cls)); + } + + void _processInstantiatedClass( + ClassElement cls, ClassUsedCallback classUsed) { + // Registers [superclass] as instantiated. Returns `true` if it wasn't + // already instantiated and we therefore have to process its superclass as + // well. + bool processClass(ClassElement superclass) { + _ClassUsage usage = _getClassUsage(superclass); + if (!usage.isInstantiated) { + classUsed(usage.cls, usage.instantiate()); + return true; + } + return false; + } + + while (cls != null && processClass(cls)) { + cls = cls.superclass; + } } } @@ -1548,3 +1939,10 @@ @override EnumSet<MemberUse> get _originalUse => MemberUses.ALL_STATIC; } + +void removeFromSet(Map<String, Set<_MemberUsage>> map, Element element) { + Set<_MemberUsage> set = map[element.name]; + if (set == null) return; + set.removeAll( + set.where((_MemberUsage usage) => usage.entity == element).toList()); +}
diff --git a/pkg/compiler/lib/src/use_unused_api.dart b/pkg/compiler/lib/src/use_unused_api.dart index da1cbdf..cff74c4 100644 --- a/pkg/compiler/lib/src/use_unused_api.dart +++ b/pkg/compiler/lib/src/use_unused_api.dart
@@ -247,15 +247,15 @@ usedByTests() { // TODO(ahe): We should try to avoid including API used only for tests. In // most cases, such API can be moved to a test library. - WorldImpl world = null; + ClosedWorldImpl closedWorld = null; type_graph_inferrer.TypeGraphInferrer typeGraphInferrer = null; source_file_provider.SourceFileProvider sourceFileProvider = null; sourceFileProvider.getSourceFile(null); - world.hasAnyUserDefinedGetter(null, null); - world.subclassesOf(null); - world.getClassHierarchyNode(null); - world.getClassSet(null); - world.haveAnyCommonSubtypes(null, null); + closedWorld.hasAnyUserDefinedGetter(null, null); + closedWorld.subclassesOf(null); + closedWorld.getClassHierarchyNode(null); + closedWorld.getClassSet(null); + closedWorld.haveAnyCommonSubtypes(null, null); typeGraphInferrer.getCallersOf(null); dart_types.Types.sorted(null); new dart_types.Types(null).copy(null);
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart index 76b2bc3..490390d 100644 --- a/pkg/compiler/lib/src/world.dart +++ b/pkg/compiler/lib/src/world.dart
@@ -4,18 +4,18 @@ library dart2js.world; -import 'cache_strategy.dart'; -import 'closure.dart' show SynthesizedCallMethodElementX; +import 'closure.dart' show ClosureClassElement, SynthesizedCallMethodElementX; import 'common/backend_api.dart' show BackendClasses; import 'common.dart'; import 'constants/constant_system.dart'; -import 'core_types.dart' show CoreTypes, CoreClasses, CommonElements; +import 'core_types.dart' show CommonElements; import 'dart_types.dart'; import 'elements/elements.dart' show ClassElement, Element, FunctionElement, + MemberElement, MixinApplicationElement, TypedefElement, FieldElement; @@ -23,11 +23,10 @@ import 'ordered_typeset.dart'; import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask; import 'universe/class_set.dart'; -import 'universe/function_set.dart' show FunctionSet; +import 'universe/function_set.dart' show FunctionSet, FunctionSetBuilder; import 'universe/selector.dart' show Selector; import 'universe/side_effects.dart' show SideEffects; -import 'universe/world_builder.dart' - show InstantiationInfo, ResolutionWorldBuilder; +import 'universe/world_builder.dart' show ResolutionWorldBuilder; import 'util/util.dart' show Link; /// Common superinterface for [OpenWorld] and [ClosedWorld]. @@ -45,11 +44,6 @@ /// Access to core classes used by the backend. BackendClasses get backendClasses; - /// Access to core classes used in the Dart language. - CoreClasses get coreClasses; - - CoreTypes get coreTypes; - CommonElements get commonElements; CommonMasks get commonMasks; @@ -341,7 +335,7 @@ /// classes that extend or implement it. void registerClass(ClassElement cls); - void registerUsedElement(Element element); + void registerUsedElement(MemberElement element); void registerTypedef(TypedefElement typedef); ClosedWorld closeWorld(DiagnosticReporter reporter); @@ -350,13 +344,76 @@ Iterable<MixinApplicationElement> allMixinUsesOf(ClassElement cls); } -class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { - bool _closed = false; +/// Enum values defining subset of classes included in queries. +enum ClassQuery { + /// Only the class itself is included. + EXACT, - TypeMask getCachedMask(ClassElement base, int flags, TypeMask createMask()) { - Map<ClassElement, TypeMask> cachedMasks = - _canonicalizedTypeMasks[flags] ??= <ClassElement, TypeMask>{}; - return cachedMasks.putIfAbsent(base, createMask); + /// The class and all subclasses (transitively) are included. + SUBCLASS, + + /// The class and all classes that implement or subclass it (transitively) + /// are included. + SUBTYPE, +} + +class ClosedWorldImpl implements ClosedWorld, ClosedWorldRefiner { + final JavaScriptBackend _backend; + BackendClasses get backendClasses => _backend.backendClasses; + FunctionSet _allFunctions; + + final Iterable<TypedefElement> _allTypedefs; + + final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses; + Map<ClassElement, List<MixinApplicationElement>> _liveMixinUses; + + final Map<ClassElement, Set<ClassElement>> _typesImplementedBySubclasses; + + // We keep track of subtype and subclass relationships in four + // distinct sets to make class hierarchy analysis faster. + final Map<ClassElement, ClassHierarchyNode> _classHierarchyNodes; + final Map<ClassElement, ClassSet> _classSets; + + final Map<ClassElement, Map<ClassElement, bool>> _subtypeCoveredByCache = + <ClassElement, Map<ClassElement, bool>>{}; + + final Set<Element> functionsCalledInLoop = new Set<Element>(); + final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>(); + + final Set<Element> sideEffectsFreeElements = new Set<Element>(); + + final Set<Element> elementsThatCannotThrow = new Set<Element>(); + + final Set<Element> functionsThatMightBePassedToApply = + new Set<FunctionElement>(); + + CommonMasks _commonMasks; + + final CommonElements commonElements; + + final ResolutionWorldBuilder _resolverWorld; + + bool get isClosed => true; + + ClosedWorldImpl( + {JavaScriptBackend backend, + this.commonElements, + ResolutionWorldBuilder resolverWorld, + FunctionSetBuilder functionSetBuilder, + Iterable<TypedefElement> allTypedefs, + Map<ClassElement, Set<MixinApplicationElement>> mixinUses, + Map<ClassElement, Set<ClassElement>> typesImplementedBySubclasses, + Map<ClassElement, ClassHierarchyNode> classHierarchyNodes, + Map<ClassElement, ClassSet> classSets}) + : this._backend = backend, + this._resolverWorld = resolverWorld, + this._allTypedefs = allTypedefs, + this._mixinUses = mixinUses, + this._typesImplementedBySubclasses = typesImplementedBySubclasses, + this._classHierarchyNodes = classHierarchyNodes, + this._classSets = classSets { + _commonMasks = new CommonMasks(this); + _allFunctions = functionSetBuilder.close(this); } /// Cache of [FlatTypeMask]s grouped by the 8 possible values of the @@ -364,6 +421,21 @@ final List<Map<ClassElement, TypeMask>> _canonicalizedTypeMasks = new List<Map<ClassElement, TypeMask>>.filled(8, null); + FunctionSet get allFunctions => _allFunctions; + + CommonMasks get commonMasks { + assert(isClosed); + return _commonMasks; + } + + ConstantSystem get constantSystem => _backend.constantSystem; + + TypeMask getCachedMask(ClassElement base, int flags, TypeMask createMask()) { + Map<ClassElement, TypeMask> cachedMasks = + _canonicalizedTypeMasks[flags] ??= <ClassElement, TypeMask>{}; + return cachedMasks.putIfAbsent(base, createMask); + } + bool checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) { return invariant(cls, cls.isDeclaration, message: '$cls must be the declaration.') && @@ -384,10 +456,10 @@ assert(checkInvariants(x)); assert(checkInvariants(y, mustBeInstantiated: false)); - if (y == coreClasses.objectClass) return true; - if (x == coreClasses.objectClass) return false; + if (y == commonElements.objectClass) return true; + if (x == commonElements.objectClass) return false; if (x.asInstanceOf(y) != null) return true; - if (y != coreClasses.functionClass) return false; + if (y != commonElements.functionClass) return false; return x.callType != null; } @@ -397,8 +469,8 @@ assert(checkInvariants(x)); assert(checkInvariants(y)); - if (y == coreClasses.objectClass) return true; - if (x == coreClasses.objectClass) return false; + if (y == commonElements.objectClass) return true; + if (x == commonElements.objectClass) return false; while (x != null && x.hierarchyDepth >= y.hierarchyDepth) { if (x == y) return true; x = x.superclass; @@ -447,7 +519,7 @@ /// Returns `true` if [cls] is implemented by an instantiated class. bool isImplemented(ClassElement cls) { assert(isClosed); - return resolverWorld.isImplemented(cls); + return _resolverWorld.isImplemented(cls); } /// Returns an iterable over the directly instantiated classes that extend @@ -595,7 +667,7 @@ bool hasOnlySubclasses(ClassElement cls) { assert(isClosed); // TODO(johnniwinther): move this to ClassSet? - if (cls == coreClasses.objectClass) return true; + if (cls == commonElements.objectClass) return true; ClassSet classSet = _classSets[cls.declaration]; if (classSet == null) { // Vacuously true. @@ -652,7 +724,7 @@ List<ClassElement> commonSupertypes = <ClassElement>[]; OUTER: for (Link<DartType> link = typeSet[depth]; - link.head.element != coreClasses.objectClass; + link.head.element != commonElements.objectClass; link = link.tail) { ClassElement cls = link.head.element; for (Link<OrderedTypeSet> link = otherTypeSets; @@ -664,16 +736,10 @@ } commonSupertypes.add(cls); } - commonSupertypes.add(coreClasses.objectClass); + commonSupertypes.add(commonElements.objectClass); return commonSupertypes; } - /// Returns an iterable over all mixin applications that mixin [cls]. - Iterable<MixinApplicationElement> allMixinUsesOf(ClassElement cls) { - Iterable<MixinApplicationElement> uses = _mixinUses[cls]; - return uses != null ? uses : const <MixinApplicationElement>[]; - } - /// Returns an iterable over the live mixin applications that mixin [cls]. Iterable<MixinApplicationElement> mixinUsesOf(ClassElement cls) { assert(isClosed); @@ -758,7 +824,9 @@ bool hasAnySubclassThatImplements( ClassElement superclass, ClassElement type) { assert(isClosed); - Set<ClassElement> subclasses = typesImplementedBySubclassesOf(superclass); + + Set<ClassElement> subclasses = + _typesImplementedBySubclasses[superclass.declaration]; if (subclasses == null) return false; return subclasses.contains(type); } @@ -846,96 +914,6 @@ } } - final JavaScriptBackend _backend; - BackendClasses get backendClasses => _backend.backendClasses; - FunctionSet _allFunctions; - final Set<Element> functionsCalledInLoop = new Set<Element>(); - final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>(); - - final Set<TypedefElement> _allTypedefs = new Set<TypedefElement>(); - - final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses = - new Map<ClassElement, Set<MixinApplicationElement>>(); - Map<ClassElement, List<MixinApplicationElement>> _liveMixinUses; - - final Map<ClassElement, Set<ClassElement>> _typesImplementedBySubclasses = - new Map<ClassElement, Set<ClassElement>>(); - - // We keep track of subtype and subclass relationships in four - // distinct sets to make class hierarchy analysis faster. - final Map<ClassElement, ClassHierarchyNode> _classHierarchyNodes = - <ClassElement, ClassHierarchyNode>{}; - final Map<ClassElement, ClassSet> _classSets = <ClassElement, ClassSet>{}; - - final Map<ClassElement, Map<ClassElement, bool>> _subtypeCoveredByCache = - <ClassElement, Map<ClassElement, bool>>{}; - - final Set<Element> sideEffectsFreeElements = new Set<Element>(); - - final Set<Element> elementsThatCannotThrow = new Set<Element>(); - - final Set<Element> functionsThatMightBePassedToApply = - new Set<FunctionElement>(); - - final Set<Element> alreadyPopulated; - - CommonMasks _commonMasks; - - final CommonElements commonElements; - - final CoreTypes coreTypes; - - final CacheStrategy cacheStrategy; - - final ResolutionWorldBuilder resolverWorld; - - bool get isClosed => _closed; - - Set<ClassElement> typesImplementedBySubclassesOf(ClassElement cls) { - return _typesImplementedBySubclasses[cls.declaration]; - } - - WorldImpl(this.resolverWorld, this._backend, this.commonElements, - this.coreTypes, CacheStrategy cacheStrategy) - : this.cacheStrategy = cacheStrategy, - alreadyPopulated = cacheStrategy.newSet() { - _allFunctions = new FunctionSet(this); - } - - FunctionSet get allFunctions => _allFunctions; - - CommonMasks get commonMasks { - assert(isClosed); - return _commonMasks; - } - - CoreClasses get coreClasses => commonElements; - - ConstantSystem get constantSystem => _backend.constantSystem; - - /// Called to add [cls] to the set of known classes. - /// - /// This ensures that class hierarchy queries can be performed on [cls] and - /// classes that extend or implement it. - void registerClass(ClassElement cls) => _registerClass(cls); - - void registerClosureClass(ClassElement cls) { - _registerClass(cls, isDirectlyInstantiated: true); - } - - void _registerClass(ClassElement cls, {bool isDirectlyInstantiated: false}) { - _ensureClassSet(cls); - if (isDirectlyInstantiated) { - _updateClassHierarchyNodeForClass(cls, directlyInstantiated: true); - } - } - - void registerTypedef(TypedefElement typdef) { - _allTypedefs.add(typdef); - } - - Iterable<TypedefElement> get allTypedefs => _allTypedefs; - /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies /// of known classes. /// @@ -945,17 +923,6 @@ return _classHierarchyNodes[cls.declaration]; } - ClassHierarchyNode _ensureClassHierarchyNode(ClassElement cls) { - cls = cls.declaration; - return _classHierarchyNodes.putIfAbsent(cls, () { - ClassHierarchyNode parentNode; - if (cls.superclass != null) { - parentNode = _ensureClassHierarchyNode(cls.superclass); - } - return new ClassHierarchyNode(parentNode, cls); - }); - } - /// Returns [ClassSet] for [cls] used to model the extends and implements /// relations of known classes. /// @@ -965,38 +932,26 @@ return _classSets[cls.declaration]; } - ClassSet _ensureClassSet(ClassElement cls) { - cls = cls.declaration; - return _classSets.putIfAbsent(cls, () { - ClassHierarchyNode node = _ensureClassHierarchyNode(cls); - ClassSet classSet = new ClassSet(node); - - for (InterfaceType type in cls.allSupertypes) { - // TODO(johnniwinther): Optimization: Avoid adding [cls] to - // superclasses. - ClassSet subtypeSet = _ensureClassSet(type.element); - subtypeSet.addSubtype(node); - } - if (cls.isMixinApplication) { - // TODO(johnniwinther): Store this in the [ClassSet]. - MixinApplicationElement mixinApplication = cls; - if (mixinApplication.mixin != null) { - // If [mixinApplication] is malformed [mixin] is `null`. - registerMixinUse(mixinApplication, mixinApplication.mixin); - } - } - - return classSet; - }); + void registerClosureClass(ClosureClassElement cls) { + ClassHierarchyNode parentNode = getClassHierarchyNode(cls.superclass); + ClassHierarchyNode node = + _classHierarchyNodes[cls] = new ClassHierarchyNode(parentNode, cls); + for (InterfaceType type in cls.allSupertypes) { + ClassSet subtypeSet = getClassSet(type.element); + subtypeSet.addSubtype(node); + } + _classSets[cls] = new ClassSet(node); + _updateSuperClassHierarchyNodeForClass(node); + node.isDirectlyInstantiated = true; } void _updateSuperClassHierarchyNodeForClass(ClassHierarchyNode node) { // Ensure that classes implicitly implementing `Function` are in its // subtype set. ClassElement cls = node.cls; - if (cls != coreClasses.functionClass && - cls.implementsFunction(coreClasses)) { - ClassSet subtypeSet = _ensureClassSet(coreClasses.functionClass); + if (cls != commonElements.functionClass && + cls.implementsFunction(commonElements)) { + ClassSet subtypeSet = getClassSet(commonElements.functionClass); subtypeSet.addSubtype(node); } if (!node.isInstantiated && node.parentNode != null) { @@ -1004,62 +959,7 @@ } } - void _updateClassHierarchyNodeForClass(ClassElement cls, - {bool directlyInstantiated: false, bool abstractlyInstantiated: false}) { - ClassHierarchyNode node = _ensureClassHierarchyNode(cls); - _updateSuperClassHierarchyNodeForClass(node); - if (directlyInstantiated) { - node.isDirectlyInstantiated = true; - } - if (abstractlyInstantiated) { - node.isAbstractlyInstantiated = true; - } - } - - ClosedWorld closeWorld(DiagnosticReporter reporter) { - /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated` - /// properties of the [ClassHierarchyNode] for [cls]. - - void addSubtypes(ClassElement cls, InstantiationInfo info) { - if (!info.hasInstantiation) { - return; - } - if (cacheStrategy.hasIncrementalSupport && !alreadyPopulated.add(cls)) { - return; - } - assert(cls.isDeclaration); - if (!cls.isResolved) { - reporter.internalError(cls, 'Class "${cls.name}" is not resolved.'); - } - - _updateClassHierarchyNodeForClass(cls, - directlyInstantiated: info.isDirectlyInstantiated, - abstractlyInstantiated: info.isAbstractlyInstantiated); - - // Walk through the superclasses, and record the types - // implemented by that type on the superclasses. - ClassElement superclass = cls.superclass; - while (superclass != null) { - Set<Element> typesImplementedBySubclassesOfCls = - _typesImplementedBySubclasses.putIfAbsent( - superclass, () => new Set<ClassElement>()); - for (DartType current in cls.allSupertypes) { - typesImplementedBySubclassesOfCls.add(current.element); - } - superclass = superclass.superclass; - } - } - - // Use the [:seenClasses:] set to include non-instantiated - // classes: if the superclass of these classes require RTI, then - // they also need RTI, so that a constructor passes the type - // variables to the super constructor. - resolverWorld.forEachInstantiatedClass(addSubtypes); - - _closed = true; - _commonMasks = new CommonMasks(this); - return this; - } + Iterable<TypedefElement> get allTypedefs => _allTypedefs; @override String dump([ClassElement cls]) { @@ -1069,31 +969,15 @@ } else { sb.write("Instantiated classes in the closed world:\n"); } - getClassHierarchyNode(coreClasses.objectClass) + getClassHierarchyNode(commonElements.objectClass) .printOn(sb, ' ', instantiatedOnly: cls == null, withRespectTo: cls); return sb.toString(); } - void registerMixinUse( - MixinApplicationElement mixinApplication, ClassElement mixin) { - // TODO(johnniwinther): Add map restricted to live classes. - // We don't support patch classes as mixin. - assert(mixin.isDeclaration); - Set<MixinApplicationElement> users = - _mixinUses.putIfAbsent(mixin, () => new Set<MixinApplicationElement>()); - users.add(mixinApplication); - } - bool hasAnyUserDefinedGetter(Selector selector, TypeMask mask) { return allFunctions.filter(selector, mask).any((each) => each.isGetter); } - void registerUsedElement(Element element) { - if (element.isInstanceMember && !element.isAbstract) { - allFunctions.add(element); - } - } - FieldElement locateSingleField(Selector selector, TypeMask mask) { Element result = locateSingleElement(selector, mask); return (result != null && result.isField) ? result : null; @@ -1137,8 +1021,8 @@ return true; } if (element.isInstanceMember) { - return !resolverWorld.hasInvokedSetter(element) && - !resolverWorld.fieldSetters.contains(element); + return !_resolverWorld.hasInvokedSetter(element) && + !_resolverWorld.fieldSetters.contains(element); } return false; } @@ -1226,16 +1110,3 @@ return getMightBePassedToApply(element); } } - -/// Enum values defining subset of classes included in queries. -enum ClassQuery { - /// Only the class itself is included. - EXACT, - - /// The class and all subclasses (transitively) are included. - SUBCLASS, - - /// The class and all classes that implement or subclass it (transitively) - /// are included. - SUBTYPE, -}
diff --git a/pkg/dev_compiler/lib/js/amd/dart_sdk.js b/pkg/dev_compiler/lib/js/amd/dart_sdk.js index 2a94c9f..bc1747a 100644 --- a/pkg/dev_compiler/lib/js/amd/dart_sdk.js +++ b/pkg/dev_compiler/lib/js/amd/dart_sdk.js
@@ -59506,10 +59506,10 @@ return html$.Blob._check(html$.Blob._create_2(blobParts, bag)); } static _create_1(parts) { - return new window.Blob(parts); + return new self.Blob(parts); } static _create_2(parts, bag) { - return new window.Blob(parts, bag); + return new self.Blob(parts, bag); } static _create_bag() { return {};
diff --git a/pkg/dev_compiler/lib/js/common/dart_sdk.js b/pkg/dev_compiler/lib/js/common/dart_sdk.js index f2826b9..9e510b1 100644 --- a/pkg/dev_compiler/lib/js/common/dart_sdk.js +++ b/pkg/dev_compiler/lib/js/common/dart_sdk.js
@@ -59506,10 +59506,10 @@ return html$.Blob._check(html$.Blob._create_2(blobParts, bag)); } static _create_1(parts) { - return new window.Blob(parts); + return new self.Blob(parts); } static _create_2(parts, bag) { - return new window.Blob(parts, bag); + return new self.Blob(parts, bag); } static _create_bag() { return {};
diff --git a/pkg/dev_compiler/lib/js/es6/dart_sdk.js b/pkg/dev_compiler/lib/js/es6/dart_sdk.js index 993d4b0..89e4810 100644 --- a/pkg/dev_compiler/lib/js/es6/dart_sdk.js +++ b/pkg/dev_compiler/lib/js/es6/dart_sdk.js
@@ -59504,10 +59504,10 @@ return html.Blob._check(html.Blob._create_2(blobParts, bag)); } static _create_1(parts) { - return new window.Blob(parts); + return new self.Blob(parts); } static _create_2(parts, bag) { - return new window.Blob(parts, bag); + return new self.Blob(parts, bag); } static _create_bag() { return {};
diff --git a/pkg/dev_compiler/lib/js/legacy/dart_sdk.js b/pkg/dev_compiler/lib/js/legacy/dart_sdk.js index d960ce5..e0639d0 100644 --- a/pkg/dev_compiler/lib/js/legacy/dart_sdk.js +++ b/pkg/dev_compiler/lib/js/legacy/dart_sdk.js
@@ -59507,10 +59507,10 @@ return html$.Blob._check(html$.Blob._create_2(blobParts, bag)); } static _create_1(parts) { - return new window.Blob(parts); + return new self.Blob(parts); } static _create_2(parts, bag) { - return new window.Blob(parts, bag); + return new self.Blob(parts, bag); } static _create_bag() { return {};
diff --git a/pkg/dev_compiler/test/browser/language_tests.js b/pkg/dev_compiler/test/browser/language_tests.js index 56f7196..593b3a0 100644 --- a/pkg/dev_compiler/test/browser/language_tests.js +++ b/pkg/dev_compiler/test/browser/language_tests.js
@@ -425,7 +425,6 @@ 'async_spawnuri_test': async_unittest, 'async_test': async_unittest, 'audiocontext_test': is.chrome('<=54') ? fail : pass, // was sdk#27578, needs triage - 'blob_constructor_test': 'fail', // was sdk#27578, needs triage 'canvas_test': ['unittest'], 'canvasrenderingcontext2d_test': ['unittest'], 'cross_domain_iframe_test': async_unittest,
diff --git a/pkg/dev_compiler/tool/input_sdk/lib/html/dart2js/html_dart2js.dart b/pkg/dev_compiler/tool/input_sdk/lib/html/dart2js/html_dart2js.dart index d24f6da..9798bbe 100644 --- a/pkg/dev_compiler/tool/input_sdk/lib/html/dart2js/html_dart2js.dart +++ b/pkg/dev_compiler/tool/input_sdk/lib/html/dart2js/html_dart2js.dart
@@ -1214,8 +1214,8 @@ return _create_2(blobParts, bag); } - static _create_1(parts) => JS('Blob', 'new window.Blob(#)', parts); - static _create_2(parts, bag) => JS('Blob', 'new window.Blob(#, #)', parts, bag); + static _create_1(parts) => JS('Blob', 'new self.Blob(#)', parts); + static _create_2(parts, bag) => JS('Blob', 'new self.Blob(#, #)', parts, bag); static _create_bag() => JS('var', '{}'); static _bag_set(bag, key, value) { JS('void', '#[#] = #', bag, key, value); }
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn index 8556ba2..6008aec 100644 --- a/runtime/BUILD.gn +++ b/runtime/BUILD.gn
@@ -129,11 +129,13 @@ } else if (dart_target_arch == "ia32") { defines += [ "TARGET_ARCH_IA32" ] } else if (dart_target_arch == "dbc" || dart_target_arch == "simdbc" || - dart_target_arch == "simdbc64") { + dart_target_arch == "simdbc64" || + dart_target_arch == "armsimdbc" || + dart_target_arch == "armsimdbc64") { defines += [ "TARGET_ARCH_DBC" ] defines += [ "USING_SIMULATOR" ] } else { - print("Invalid |dart_target_arch|") + print("Invalid $dart_target_arch") assert(false) } }
diff --git a/runtime/bin/file_android.cc b/runtime/bin/file_android.cc index afe0966..985fbf8 100644 --- a/runtime/bin/file_android.cc +++ b/runtime/bin/file_android.cc
@@ -17,8 +17,8 @@ #include <unistd.h> // NOLINT #include "bin/builtin.h" +#include "bin/fdutils.h" #include "bin/log.h" - #include "platform/signal_blocker.h" #include "platform/utils.h" @@ -227,7 +227,8 @@ bool File::Exists(const char* name) { struct stat st; if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { - return S_ISREG(st.st_mode); + // Everything but a directory and a link is a file to Dart. + return !S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode); } else { return false; } @@ -239,7 +240,22 @@ if (fd < 0) { return false; } - return (close(fd) == 0); + // File.create returns a File, so we shouldn't be giving the illusion that the + // call has created a file or that a file already exists if there is already + // an entity at the same path that is a directory or a link. + bool is_file = true; + struct stat st; + if (NO_RETRY_EXPECTED(fstat(fd, &st)) == 0) { + if (S_ISDIR(st.st_mode)) { + errno = EISDIR; + is_file = false; + } else if (S_ISLNK(st.st_mode)) { + errno = ENOENT; + is_file = false; + } + } + FDUtils::SaveErrorAndClose(fd); + return is_file; }
diff --git a/runtime/bin/file_fuchsia.cc b/runtime/bin/file_fuchsia.cc index ff08043..ceea0c3 100644 --- a/runtime/bin/file_fuchsia.cc +++ b/runtime/bin/file_fuchsia.cc
@@ -208,9 +208,10 @@ bool File::Exists(const char* name) { - struct stat st; - if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { - return S_ISREG(st.st_mode); + struct stat64 st; + if (NO_RETRY_EXPECTED(stat64(name, &st)) == 0) { + // Everything but a directory and a link is a file to Dart. + return !S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode); } else { return false; } @@ -218,11 +219,27 @@ bool File::Create(const char* name) { - int fd = NO_RETRY_EXPECTED(open(name, O_RDONLY | O_CREAT | O_CLOEXEC, 0666)); + int fd = + NO_RETRY_EXPECTED(open64(name, O_RDONLY | O_CREAT | O_CLOEXEC, 0666)); if (fd < 0) { return false; } - return (close(fd) == 0); + // File.create returns a File, so we shouldn't be giving the illusion that the + // call has created a file or that a file already exists if there is already + // an entity at the same path that is a directory or a link. + bool is_file = true; + struct stat64 st; + if (NO_RETRY_EXPECTED(fstat64(fd, &st)) == 0) { + if (S_ISDIR(st.st_mode)) { + errno = EISDIR; + is_file = false; + } else if (S_ISLNK(st.st_mode)) { + errno = ENOENT; + is_file = false; + } + } + FDUtils::SaveErrorAndClose(fd); + return is_file; }
diff --git a/runtime/bin/file_linux.cc b/runtime/bin/file_linux.cc index 9a6dc41..6664c67 100644 --- a/runtime/bin/file_linux.cc +++ b/runtime/bin/file_linux.cc
@@ -17,6 +17,7 @@ #include <unistd.h> // NOLINT #include "bin/builtin.h" +#include "bin/fdutils.h" #include "bin/log.h" #include "platform/signal_blocker.h" #include "platform/utils.h" @@ -227,7 +228,8 @@ bool File::Exists(const char* name) { struct stat64 st; if (TEMP_FAILURE_RETRY(stat64(name, &st)) == 0) { - return S_ISREG(st.st_mode); + // Everything but a directory and a link is a file to Dart. + return !S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode); } else { return false; } @@ -240,7 +242,22 @@ if (fd < 0) { return false; } - return (TEMP_FAILURE_RETRY(close(fd)) == 0); + // File.create returns a File, so we shouldn't be giving the illusion that the + // call has created a file or that a file already exists if there is already + // an entity at the same path that is a directory or a link. + bool is_file = true; + struct stat64 st; + if (TEMP_FAILURE_RETRY(fstat64(fd, &st)) == 0) { + if (S_ISDIR(st.st_mode)) { + errno = EISDIR; + is_file = false; + } else if (S_ISLNK(st.st_mode)) { + errno = ENOENT; + is_file = false; + } + } + FDUtils::SaveErrorAndClose(fd); + return is_file; }
diff --git a/runtime/bin/file_macos.cc b/runtime/bin/file_macos.cc index 2b32bc1..d1259f7 100644 --- a/runtime/bin/file_macos.cc +++ b/runtime/bin/file_macos.cc
@@ -230,7 +230,8 @@ bool File::Exists(const char* name) { struct stat st; if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { - return S_ISREG(st.st_mode); + // Everything but a directory and a link is a file to Dart. + return !S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode); } else { return false; } @@ -242,7 +243,22 @@ if (fd < 0) { return false; } - return (close(fd) == 0); + // File.create returns a File, so we shouldn't be giving the illusion that the + // call has created a file or that a file already exists if there is already + // an entity at the same path that is a directory or a link. + bool is_file = true; + struct stat st; + if (NO_RETRY_EXPECTED(fstat(fd, &st)) == 0) { + if (S_ISDIR(st.st_mode)) { + errno = EISDIR; + is_file = false; + } else if (S_ISLNK(st.st_mode)) { + errno = ENOENT; + is_file = false; + } + } + FDUtils::SaveErrorAndClose(fd); + return is_file; }
diff --git a/runtime/bin/process.h b/runtime/bin/process.h index 48cf21b..f877b8d 100644 --- a/runtime/bin/process.h +++ b/runtime/bin/process.h
@@ -5,11 +5,16 @@ #ifndef RUNTIME_BIN_PROCESS_H_ #define RUNTIME_BIN_PROCESS_H_ +#include <errno.h> + #include "bin/builtin.h" #include "bin/io_buffer.h" #include "bin/lockers.h" #include "bin/thread.h" #include "platform/globals.h" +#if !defined(TARGET_OS_WINDOWS) +#include "platform/signal_blocker.h" +#endif #include "platform/utils.h" namespace dart { @@ -203,24 +208,30 @@ public: explicit BufferListNode(intptr_t size) { data_ = new uint8_t[size]; - if (data_ == NULL) FATAL("Allocation failed"); + // We check for a failed allocation below in Allocate() next_ = NULL; } ~BufferListNode() { delete[] data_; } + bool Valid() const { return data_ != NULL; } + + uint8_t* data() const { return data_; } + BufferListNode* next() const { return next_; } + void set_next(BufferListNode* n) { next_ = n; } + + private: uint8_t* data_; BufferListNode* next_; - private: DISALLOW_IMPLICIT_CONSTRUCTORS(BufferListNode); }; public: BufferListBase() : head_(NULL), tail_(NULL), data_size_(0), free_size_(0) {} ~BufferListBase() { - ASSERT(head_ == NULL); - ASSERT(tail_ == NULL); + Free(); + DEBUG_ASSERT(IsEmpty()); } // Returns the collected data as a Uint8List. If an error occours an @@ -234,9 +245,9 @@ return result; } for (BufferListNode* current = head_; current != NULL; - current = current->next_) { + current = current->next()) { intptr_t to_copy = dart::Utils::Minimum(data_size_, kBufferSize); - memmove(buffer + buffer_position, current->data_, to_copy); + memmove(buffer + buffer_position, current->data(), to_copy); buffer_position += to_copy; data_size_ -= to_copy; } @@ -245,26 +256,36 @@ return result; } +#if defined(DEBUG) + bool IsEmpty() const { return (head_ == NULL) && (tail_ == NULL); } +#endif + protected: - void Allocate() { + bool Allocate() { ASSERT(free_size_ == 0); BufferListNode* node = new BufferListNode(kBufferSize); + if ((node == NULL) || !node->Valid()) { + // Failed to allocate a buffer for the node. + delete node; + return false; + } if (head_ == NULL) { head_ = node; tail_ = node; } else { - ASSERT(tail_->next_ == NULL); - tail_->next_ = node; + ASSERT(tail_->next() == NULL); + tail_->set_next(node); tail_ = node; } free_size_ = kBufferSize; + return true; } void Free() { BufferListNode* current = head_; while (current != NULL) { BufferListNode* tmp = current; - current = current->next_; + current = current->next(); delete tmp; } head_ = NULL; @@ -275,9 +296,19 @@ // Returns the address of the first byte in the free space. uint8_t* FreeSpaceAddress() { - return tail_->data_ + (kBufferSize - free_size_); + return tail_->data() + (kBufferSize - free_size_); } + intptr_t data_size() const { return data_size_; } + void set_data_size(intptr_t size) { data_size_ = size; } + + intptr_t free_size() const { return free_size_; } + void set_free_size(intptr_t size) { free_size_ = size; } + + BufferListNode* head() const { return head_; } + BufferListNode* tail() const { return tail_; } + + private: // Linked list for data collected. BufferListNode* head_; BufferListNode* tail_; @@ -288,10 +319,49 @@ // Number of free bytes in the last node in the list. intptr_t free_size_; - private: DISALLOW_COPY_AND_ASSIGN(BufferListBase); }; +#if defined(TARGET_OS_ANDROID) || defined(TARGET_OS_FUCHSIA) || \ + defined(TARGET_OS_LINUX) || defined(TARGET_OS_MACOS) +class BufferList : public BufferListBase { + public: + BufferList() {} + + bool Read(int fd, intptr_t available) { + // Read all available bytes. + while (available > 0) { + if (free_size() == 0) { + if (!Allocate()) { + errno = ENOMEM; + return false; + } + } + ASSERT(free_size() > 0); + ASSERT(free_size() <= kBufferSize); + intptr_t block_size = dart::Utils::Minimum(free_size(), available); +#if defined(TARGET_OS_FUCHSIA) + intptr_t bytes = NO_RETRY_EXPECTED( + read(fd, reinterpret_cast<void*>(FreeSpaceAddress()), block_size)); +#else + intptr_t bytes = TEMP_FAILURE_RETRY( + read(fd, reinterpret_cast<void*>(FreeSpaceAddress()), block_size)); +#endif // defined(TARGET_OS_FUCHSIA) + if (bytes < 0) { + return false; + } + set_data_size(data_size() + bytes); + set_free_size(free_size() - bytes); + available -= bytes; + } + return true; + } + + private: + DISALLOW_COPY_AND_ASSIGN(BufferList); +}; +#endif // defined(TARGET_OS_ANDROID) ... + } // namespace bin } // namespace dart
diff --git a/runtime/bin/process_android.cc b/runtime/bin/process_android.cc index b49515f..550f680 100644 --- a/runtime/bin/process_android.cc +++ b/runtime/bin/process_android.cc
@@ -768,36 +768,6 @@ } -class BufferList : public BufferListBase { - public: - BufferList() {} - - bool Read(int fd, intptr_t available) { - // Read all available bytes. - while (available > 0) { - if (free_size_ == 0) { - Allocate(); - } - ASSERT(free_size_ > 0); - ASSERT(free_size_ <= kBufferSize); - intptr_t block_size = dart::Utils::Minimum(free_size_, available); - intptr_t bytes = TEMP_FAILURE_RETRY( - read(fd, reinterpret_cast<void*>(FreeSpaceAddress()), block_size)); - if (bytes < 0) { - return false; - } - data_size_ += bytes; - free_size_ -= bytes; - available -= bytes; - } - return true; - } - - private: - DISALLOW_COPY_AND_ASSIGN(BufferList); -}; - - static bool CloseProcessBuffers(struct pollfd fds[3]) { int e = errno; VOID_TEMP_FAILURE_RETRY(close(fds[0].fd)); @@ -881,6 +851,8 @@ // All handles closed and all data read. result->set_stdout_data(out_data.GetData()); result->set_stderr_data(err_data.GetData()); + DEBUG_ASSERT(out_data.IsEmpty()); + DEBUG_ASSERT(err_data.IsEmpty()); // Calculate the exit code. intptr_t exit_code = exit_code_data.ints[0];
diff --git a/runtime/bin/process_fuchsia.cc b/runtime/bin/process_fuchsia.cc index 9eb4d74..88b115a 100644 --- a/runtime/bin/process_fuchsia.cc +++ b/runtime/bin/process_fuchsia.cc
@@ -441,36 +441,6 @@ } -class BufferList : public BufferListBase { - public: - BufferList() {} - - bool Read(int fd, intptr_t available) { - // Read all available bytes. - while (available > 0) { - if (free_size_ == 0) { - Allocate(); - } - ASSERT(free_size_ > 0); - ASSERT(free_size_ <= kBufferSize); - intptr_t block_size = dart::Utils::Minimum(free_size_, available); - intptr_t bytes = NO_RETRY_EXPECTED( - read(fd, reinterpret_cast<void*>(FreeSpaceAddress()), block_size)); - if (bytes < 0) { - return false; - } - data_size_ += bytes; - free_size_ -= bytes; - available -= bytes; - } - return true; - } - - private: - DISALLOW_COPY_AND_ASSIGN(BufferList); -}; - - bool Process::Wait(intptr_t pid, intptr_t in, intptr_t out, @@ -570,6 +540,8 @@ // All handles closed and all data read. result->set_stdout_data(out_data.GetData()); result->set_stderr_data(err_data.GetData()); + DEBUG_ASSERT(out_data.IsEmpty()); + DEBUG_ASSERT(err_data.IsEmpty()); // Calculate the exit code. intptr_t exit_code = exit_code_data.ints[0];
diff --git a/runtime/bin/process_linux.cc b/runtime/bin/process_linux.cc index 22dc683..c8a2f7b 100644 --- a/runtime/bin/process_linux.cc +++ b/runtime/bin/process_linux.cc
@@ -768,36 +768,6 @@ } -class BufferList : public BufferListBase { - public: - BufferList() {} - - bool Read(int fd, intptr_t available) { - // Read all available bytes. - while (available > 0) { - if (free_size_ == 0) { - Allocate(); - } - ASSERT(free_size_ > 0); - ASSERT(free_size_ <= kBufferSize); - intptr_t block_size = dart::Utils::Minimum(free_size_, available); - intptr_t bytes = TEMP_FAILURE_RETRY( - read(fd, reinterpret_cast<void*>(FreeSpaceAddress()), block_size)); - if (bytes < 0) { - return false; - } - data_size_ += bytes; - free_size_ -= bytes; - available -= bytes; - } - return true; - } - - private: - DISALLOW_COPY_AND_ASSIGN(BufferList); -}; - - static bool CloseProcessBuffers(struct pollfd fds[3]) { int e = errno; VOID_TEMP_FAILURE_RETRY(close(fds[0].fd)); @@ -881,6 +851,8 @@ // All handles closed and all data read. result->set_stdout_data(out_data.GetData()); result->set_stderr_data(err_data.GetData()); + DEBUG_ASSERT(out_data.IsEmpty()); + DEBUG_ASSERT(err_data.IsEmpty()); // Calculate the exit code. intptr_t exit_code = exit_code_data.ints[0];
diff --git a/runtime/bin/process_macos.cc b/runtime/bin/process_macos.cc index 584968e..30035c5 100644 --- a/runtime/bin/process_macos.cc +++ b/runtime/bin/process_macos.cc
@@ -784,36 +784,6 @@ } -class BufferList : public BufferListBase { - public: - BufferList() {} - - bool Read(int fd, intptr_t available) { - // Read all available bytes. - while (available > 0) { - if (free_size_ == 0) { - Allocate(); - } - ASSERT(free_size_ > 0); - ASSERT(free_size_ <= kBufferSize); - size_t block_size = dart::Utils::Minimum(free_size_, available); - ssize_t bytes = TEMP_FAILURE_RETRY( - read(fd, reinterpret_cast<void*>(FreeSpaceAddress()), block_size)); - if (bytes < 0) { - return false; - } - data_size_ += bytes; - free_size_ -= bytes; - available -= bytes; - } - return true; - } - - private: - DISALLOW_COPY_AND_ASSIGN(BufferList); -}; - - static bool CloseProcessBuffers(struct pollfd fds[3]) { int e = errno; VOID_TEMP_FAILURE_RETRY(close(fds[0].fd)); @@ -903,6 +873,8 @@ // All handles closed and all data read. result->set_stdout_data(out_data.GetData()); result->set_stderr_data(err_data.GetData()); + DEBUG_ASSERT(out_data.IsEmpty()); + DEBUG_ASSERT(err_data.IsEmpty()); // Calculate the exit code. intptr_t exit_code = exit_code_data.ints[0];
diff --git a/runtime/bin/process_win.cc b/runtime/bin/process_win.cc index a2d93a4..c0cb06b 100644 --- a/runtime/bin/process_win.cc +++ b/runtime/bin/process_win.cc
@@ -714,32 +714,35 @@ // overlapped read. void DataIsRead(intptr_t size) { ASSERT(read_pending_ == true); - data_size_ += size; - free_size_ -= size; - ASSERT(free_size_ >= 0); + set_data_size(data_size() + size); + set_free_size(free_size() - size); + ASSERT(free_size() >= 0); read_pending_ = false; } // The access to the read buffer for overlapped read. - void GetReadBuffer(uint8_t** buffer, intptr_t* size) { + bool GetReadBuffer(uint8_t** buffer, intptr_t* size) { ASSERT(!read_pending_); - if (free_size_ == 0) { - Allocate(); + if (free_size() == 0) { + if (!Allocate()) { + return false; + } } - ASSERT(free_size_ > 0); - ASSERT(free_size_ <= kBufferSize); + ASSERT(free_size() > 0); + ASSERT(free_size() <= kBufferSize); *buffer = FreeSpaceAddress(); - *size = free_size_; + *size = free_size(); read_pending_ = true; + return true; } - intptr_t GetDataSize() { return data_size_; } + intptr_t GetDataSize() { return data_size(); } uint8_t* GetFirstDataBuffer() { - ASSERT(head_ != NULL); - ASSERT(head_ == tail_); - ASSERT(data_size_ <= kBufferSize); - return head_->data_; + ASSERT(head() != NULL); + ASSERT(head() == tail()); + ASSERT(data_size() <= kBufferSize); + return head()->data(); } void FreeDataBuffer() { Free(); } @@ -776,7 +779,9 @@ ClearOverlapped(); uint8_t* buffer; intptr_t buffer_size; - buffer_.GetReadBuffer(&buffer, &buffer_size); + if (!buffer_.GetReadBuffer(&buffer, &buffer_size)) { + return false; + } BOOL ok = ReadFile(handle_, buffer, buffer_size, NULL, &overlapped_); if (!ok) { return (GetLastError() == ERROR_IO_PENDING); @@ -793,6 +798,10 @@ void FreeDataBuffer() { return buffer_.FreeDataBuffer(); } +#if defined(DEBUG) + bool IsEmpty() const { return buffer_.IsEmpty(); } +#endif + void Close() { CloseHandle(handle_); CloseHandle(event_); @@ -882,6 +891,8 @@ // All handles closed and all data read. result->set_stdout_data(oh[0].GetData()); result->set_stderr_data(oh[1].GetData()); + DEBUG_ASSERT(oh[0].IsEmpty()); + DEBUG_ASSERT(oh[1].IsEmpty()); // Calculate the exit code. ASSERT(oh[2].GetDataSize() == 8);
diff --git a/runtime/lib/function.cc b/runtime/lib/function.cc index 2abdde71..5b2343f 100644 --- a/runtime/lib/function.cc +++ b/runtime/lib/function.cc
@@ -69,17 +69,7 @@ const Closure& receiver = Closure::CheckedHandle(zone, arguments->NativeArgAt(0)); const Function& func = Function::Handle(receiver.function()); - // Hash together name, class name and signature. - const Class& cls = Class::Handle(func.Owner()); - intptr_t result = String::Handle(func.name()).Hash(); - result += String::Handle(func.Signature()).Hash(); - result += String::Handle(cls.Name()).Hash(); - // Finalize hash value like for strings so that it fits into a smi. - result += result << 3; - result ^= result >> 11; - result += result << 15; - result &= ((static_cast<intptr_t>(1) << String::kHashBits) - 1); - return Smi::New(result); + return func.GetClosureHashCode(); }
diff --git a/runtime/lib/typed_data.dart b/runtime/lib/typed_data.dart deleted file mode 100644 index 0875fbc..0000000 --- a/runtime/lib/typed_data.dart +++ /dev/null
@@ -1,4258 +0,0 @@ -// Copyright (c) 2013, 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. - -// Unlike the other SDK libraries, this file is not a patch that is applied to -// dart:typed_data. Instead, it completely replaces the implementation from the -// SDK. -library dart.typed_data; - -import "dart:_internal"; -import "dart:collection" show ListBase; -import 'dart:math' show Random; - -/** - * A typed view of a sequence of bytes. - */ -abstract class TypedData { - /** - * Returns the number of bytes in the representation of each element in this - * list. - */ - int get elementSizeInBytes; - - /** - * Returns the offset in bytes into the underlying byte buffer of this view. - */ - int get offsetInBytes; - - /** - * Returns the length of this view, in bytes. - */ - int get lengthInBytes; - - /** - * Returns the byte buffer associated with this object. - */ - ByteBuffer get buffer; -} - - -/** - * Describes endianness to be used when accessing or updating a - * sequence of bytes. - */ -class Endianness { - const Endianness._(this._littleEndian); - - static const Endianness BIG_ENDIAN = const Endianness._(false); - static const Endianness LITTLE_ENDIAN = const Endianness._(true); - static final Endianness HOST_ENDIAN = - (new ByteData.view(new Uint16List.fromList([1]).buffer)).getInt8(0) == 1 ? - LITTLE_ENDIAN : BIG_ENDIAN; - - final bool _littleEndian; -} - - -/** - * A fixed-length, random-access sequence of bytes that also provides random - * and unaligned access to the fixed-width integers and floating point - * numbers represented by those bytes. - * - * `ByteData` may be used to pack and unpack data from external sources - * (such as networks or files systems), and to process large quantities - * of numerical data more efficiently than would be possible - * with ordinary [List] implementations. - * `ByteData` can save space, by eliminating the need for object headers, - * and time, by eliminating the need for data copies. - * Finally, `ByteData` may be used to intentionally reinterpret the bytes - * representing one arithmetic type as another. - * For example this code fragment determine what 32-bit signed integer - * is represented by the bytes of a 32-bit floating point number: - * - * var buffer = new Uint8List(8).buffer; - * var bdata = new ByteData.view(buffer); - * bdata.setFloat32(0, 3.04); - * int huh = bdata.getInt32(0); - */ -class ByteData implements TypedData { - /** - * Creates a [ByteData] of the specified length (in elements), all of - * whose bytes are initially zero. - */ - factory ByteData(int length) { - var list = new Uint8List(length); - return new _ByteDataView(list, 0, length); - } - - // Called directly from C code. - factory ByteData._view(TypedData typedData, int offsetInBytes, int length) { - return new _ByteDataView(typedData, offsetInBytes, length); - } - - /** - * Creates an [ByteData] _view_ of the specified region in [buffer]. - * - * Changes in the [ByteData] will be visible in the byte - * buffer and vice versa. - * If the [offsetInBytes] index of the region is not specified, - * it defaults to zero (the first byte in the byte buffer). - * If the length is not specified, it defaults to `null`, - * which indicates that the view extends to the end of the byte buffer. - * - * Throws [RangeError] if [offsetInBytes] or [length] are negative, or - * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than - * the length of [buffer]. - */ - factory ByteData.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { - return buffer.asByteData(offsetInBytes, length); - } - - /** - * Returns the (possibly negative) integer represented by the byte at the - * specified [byteOffset] in this object, in two's complement binary - * representation. - * - * The return value will be between -128 and 127, inclusive. - * - * Throws [RangeError] if [byteOffset] is negative, or - * greater than or equal to the length of this object. - */ - int getInt8(int byteOffset); - - /** - * Sets the byte at the specified [byteOffset] in this object to the - * two's complement binary representation of the specified [value], which - * must fit in a single byte. - * - * In other words, [value] must be between -128 and 127, inclusive. - * - * Throws [RangeError] if [byteOffset] is negative, or - * greater than or equal to the length of this object. - */ - void setInt8(int byteOffset, int value); - - /** - * Returns the positive integer represented by the byte at the specified - * [byteOffset] in this object, in unsigned binary form. - * - * The return value will be between 0 and 255, inclusive. - * - * Throws [RangeError] if [byteOffset] is negative, or - * greater than or equal to the length of this object. - */ - int getUint8(int byteOffset); - - /** - * Sets the byte at the specified [byteOffset] in this object to the - * unsigned binary representation of the specified [value], which must fit - * in a single byte. - * - * In other words, [value] must be between 0 and 255, inclusive. - * - * Throws [RangeError] if [byteOffset] is negative, - * or greater than or equal to the length of this object. - */ - void setUint8(int byteOffset, int value); - - /** - * Returns the (possibly negative) integer represented by the two bytes at - * the specified [byteOffset] in this object, in two's complement binary - * form. - * - * The return value will be between 2<sup>15</sup> and 2<sup>15</sup> - 1, - * inclusive. - * - * Throws [RangeError] if [byteOffset] is negative, or - * `byteOffset + 2` is greater than the length of this object. - */ - int getInt16(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]); - - /** - * Sets the two bytes starting at the specified [byteOffset] in this - * object to the two's complement binary representation of the specified - * [value], which must fit in two bytes. - * - * In other words, [value] must lie - * between 2<sup>15</sup> and 2<sup>15</sup> - 1, inclusive. - * - * Throws [RangeError] if [byteOffset] is negative, or - * `byteOffset + 2` is greater than the length of this object. - */ - void setInt16(int byteOffset, - int value, - [Endianness endian = Endianness.BIG_ENDIAN]); - - /** - * Returns the positive integer represented by the two bytes starting - * at the specified [byteOffset] in this object, in unsigned binary - * form. - * - * The return value will be between 0 and 2<sup>16</sup> - 1, inclusive. - * - * Throws [RangeError] if [byteOffset] is negative, or - * `byteOffset + 2` is greater than the length of this object. - */ - int getUint16(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]); - - /** - * Sets the two bytes starting at the specified [byteOffset] in this object - * to the unsigned binary representation of the specified [value], - * which must fit in two bytes. - * - * In other words, [value] must be between - * 0 and 2<sup>16</sup> - 1, inclusive. - * - * Throws [RangeError] if [byteOffset] is negative, or - * `byteOffset + 2` is greater than the length of this object. - */ - void setUint16(int byteOffset, - int value, - [Endianness endian = Endianness.BIG_ENDIAN]); - - /** - * Returns the (possibly negative) integer represented by the four bytes at - * the specified [byteOffset] in this object, in two's complement binary - * form. - * - * The return value will be between 2<sup>31</sup> and 2<sup>31</sup> - 1, - * inclusive. - * - * Throws [RangeError] if [byteOffset] is negative, or - * `byteOffset + 4` is greater than the length of this object. - */ - int getInt32(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]); - - /** - * Sets the four bytes starting at the specified [byteOffset] in this - * object to the two's complement binary representation of the specified - * [value], which must fit in four bytes. - * - * In other words, [value] must lie - * between 2<sup>31</sup> and 2<sup>31</sup> - 1, inclusive. - * - * Throws [RangeError] if [byteOffset] is negative, or - * `byteOffset + 4` is greater than the length of this object. - */ - void setInt32(int byteOffset, - int value, - [Endianness endian = Endianness.BIG_ENDIAN]); - - /** - * Returns the positive integer represented by the four bytes starting - * at the specified [byteOffset] in this object, in unsigned binary - * form. - * - * The return value will be between 0 and 2<sup>32</sup> - 1, inclusive. - * - * Throws [RangeError] if [byteOffset] is negative, or - * `byteOffset + 4` is greater than the length of this object. - */ - int getUint32(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]); - - /** - * Sets the four bytes starting at the specified [byteOffset] in this object - * to the unsigned binary representation of the specified [value], - * which must fit in four bytes. - * - * In other words, [value] must be between - * 0 and 2<sup>32</sup> - 1, inclusive. - * - * Throws [RangeError] if [byteOffset] is negative, or - * `byteOffset + 4` is greater than the length of this object. - */ - void setUint32(int byteOffset, - int value, - [Endianness endian = Endianness.BIG_ENDIAN]); - - /** - * Returns the (possibly negative) integer represented by the eight bytes at - * the specified [byteOffset] in this object, in two's complement binary - * form. - * - * The return value will be between 2<sup>63</sup> and 2<sup>63</sup> - 1, - * inclusive. - * - * Throws [RangeError] if [byteOffset] is negative, or - * `byteOffset + 8` is greater than the length of this object. - */ - int getInt64(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]); - - /** - * Sets the eight bytes starting at the specified [byteOffset] in this - * object to the two's complement binary representation of the specified - * [value], which must fit in eight bytes. - * - * In other words, [value] must lie - * between 2<sup>63</sup> and 2<sup>63</sup> - 1, inclusive. - * - * Throws [RangeError] if [byteOffset] is negative, or - * `byteOffset + 8` is greater than the length of this object. - */ - void setInt64(int byteOffset, - int value, - [Endianness endian = Endianness.BIG_ENDIAN]); - - /** - * Returns the positive integer represented by the eight bytes starting - * at the specified [byteOffset] in this object, in unsigned binary - * form. - * - * The return value will be between 0 and 2<sup>64</sup> - 1, inclusive. - * - * Throws [RangeError] if [byteOffset] is negative, or - * `byteOffset + 8` is greater than the length of this object. - */ - int getUint64(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]); - - /** - * Sets the eight bytes starting at the specified [byteOffset] in this object - * to the unsigned binary representation of the specified [value], - * which must fit in eight bytes. - * - * In other words, [value] must be between - * 0 and 2<sup>64</sup> - 1, inclusive. - * - * Throws [RangeError] if [byteOffset] is negative, or - * `byteOffset + 8` is greater than the length of this object. - */ - void setUint64(int byteOffset, - int value, - [Endianness endian = Endianness.BIG_ENDIAN]); - - /** - * Returns the floating point number represented by the four bytes at - * the specified [byteOffset] in this object, in IEEE 754 - * single-precision binary floating-point format (binary32). - * - * Throws [RangeError] if [byteOffset] is negative, or - * `byteOffset + 4` is greater than the length of this object. - */ - double getFloat32(int byteOffset, - [Endianness endian = Endianness.BIG_ENDIAN]); - - /** - * Sets the four bytes starting at the specified [byteOffset] in this - * object to the IEEE 754 single-precision binary floating-point - * (binary32) representation of the specified [value]. - * - * **Note that this method can lose precision.** The input [value] is - * a 64-bit floating point value, which will be converted to 32-bit - * floating point value by IEEE 754 rounding rules before it is stored. - * If [value] cannot be represented exactly as a binary32, it will be - * converted to the nearest binary32 value. If two binary32 values are - * equally close, the one whose least significant bit is zero will be used. - * Note that finite (but large) values can be converted to infinity, and - * small non-zero values can be converted to zero. - * - * Throws [RangeError] if [byteOffset] is negative, or - * `byteOffset + 4` is greater than the length of this object. - */ - void setFloat32(int byteOffset, - double value, - [Endianness endian = Endianness.BIG_ENDIAN]); - - /** - * Returns the floating point number represented by the eight bytes at - * the specified [byteOffset] in this object, in IEEE 754 - * double-precision binary floating-point format (binary64). - * - * Throws [RangeError] if [byteOffset] is negative, or - * `byteOffset + 8` is greater than the length of this object. - */ - double getFloat64(int byteOffset, - [Endianness endian = Endianness.BIG_ENDIAN]); - - /** - * Sets the eight bytes starting at the specified [byteOffset] in this - * object to the IEEE 754 double-precision binary floating-point - * (binary64) representation of the specified [value]. - * - * Throws [RangeError] if [byteOffset] is negative, or - * `byteOffset + 8` is greater than the length of this object. - */ - void setFloat64(int byteOffset, - double value, - [Endianness endian = Endianness.BIG_ENDIAN]); -} - - -// Based class for _TypedList that provides common methods for implementing -// the collection and list interfaces. -// This class does not extend ListBase<T> since that would add type arguments -// to instances of _TypeListBase. Instead the subclasses use type specific -// mixins (like _IntListMixin, _DoubleListMixin) to implement ListBase<T>. -abstract class _TypedListBase { - - // Method(s) implementing the Collection interface. - bool contains(element) { - var len = this.length; - for (var i = 0; i < len; ++i) { - if (this[i] == element) return true; - } - return false; - } - - void forEach(void f(element)) { - var len = this.length; - for (var i = 0; i < len; i++) { - f(this[i]); - } - } - - String join([String separator = ""]) { - StringBuffer buffer = new StringBuffer(); - buffer.writeAll(this, separator); - return buffer.toString(); - } - - dynamic reduce(dynamic combine(value, element)) { - var len = this.length; - if (len == 0) throw IterableElementError.noElement(); - var i = 0; - var value = this[0]; - for (var i = 1; i < len; ++i) { - value = combine(value, this[i]); - } - return value; - } - - dynamic fold(dynamic initialValue, - dynamic combine(dynamic initialValue, element)) { - var len = this.length; - for (var i = 0; i < len; ++i) { - initialValue = combine(initialValue, this[i]); - } - return initialValue; - } - - Iterable map(f(element)) => new MappedIterable(this, f); - - Iterable expand(Iterable f(element)) => new ExpandIterable(this, f); - - bool every(bool f(element)) { - var len = this.length; - for (var i = 0; i < len; ++i) { - if (!f(this[i])) return false; - } - return true; - } - - bool any(bool f(element)) { - var len = this.length; - for (var i = 0; i < len; ++i) { - if (f(this[i])) return true; - } - return false; - } - - dynamic firstWhere(bool test(element), {orElse()}) { - var len = this.length; - for (var i = 0; i < len; ++i) { - var element = this[i]; - if (test(element)) return element; - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - dynamic lastWhere(bool test(element), {orElse()}) { - var result = null; - var len = this.length; - for (var i = len - 1; i >= 0; --i) { - var element = this[i]; - if (test(element)) { - return element; - } - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - dynamic singleWhere(bool test(element)) { - var result = null; - bool foundMatching = false; - var len = this.length; - for (var i = 0; i < len; ++i) { - var element = this[i]; - if (test(element)) { - if (foundMatching) { - throw IterableElementError.tooMany(); - } - result = element; - foundMatching = true; - } - } - if (foundMatching) return result; - throw IterableElementError.noElement(); - } - - dynamic elementAt(int index) { - return this[index]; - } - - bool get isEmpty { - return this.length == 0; - } - - bool get isNotEmpty => !isEmpty; - - // Method(s) implementing the List interface. - - set length(newLength) { - throw new UnsupportedError( - "Cannot resize a fixed-length list"); - } - - void add(value) { - throw new UnsupportedError( - "Cannot add to a fixed-length list"); - } - - void addAll(Iterable value) { - throw new UnsupportedError( - "Cannot add to a fixed-length list"); - } - - void insert(int index, value) { - throw new UnsupportedError( - "Cannot insert into a fixed-length list"); - } - - void insertAll(int index, Iterable values) { - throw new UnsupportedError( - "Cannot insert into a fixed-length list"); - } - - void sort([int compare(a, b)]) { - if (compare == null) compare = Comparable.compare; - Sort.sort(this, compare); - } - - void shuffle([Random random]) { - if (random == null) random = new Random(); - var i = this.length; - while (i > 1) { - int pos = random.nextInt(i); - i -= 1; - var tmp = this[i]; - this[i] = this[pos]; - this[pos] = tmp; - } - } - - int indexOf(element, [int start = 0]) { - return Lists.indexOf(this, element, start, this.length); - } - - int lastIndexOf(element, [int start = null]) { - if (start == null) start = this.length - 1; - return Lists.lastIndexOf(this, element, start); - } - - void clear() { - throw new UnsupportedError( - "Cannot remove from a fixed-length list"); - } - - int removeLast() { - throw new UnsupportedError( - "Cannot remove from a fixed-length list"); - } - - bool remove(Object element) { - throw new UnsupportedError( - "Cannot remove from a fixed-length list"); - } - - bool removeAt(int index) { - throw new UnsupportedError( - "Cannot remove from a fixed-length list"); - } - - void removeWhere(bool test(element)) { - throw new UnsupportedError( - "Cannot remove from a fixed-length list"); - } - - void retainWhere(bool test(element)) { - throw new UnsupportedError( - "Cannot remove from a fixed-length list"); - } - - dynamic get first { - if (length > 0) return this[0]; - throw IterableElementError.noElement(); - } - - dynamic get last { - if (length > 0) return this[length - 1]; - throw IterableElementError.noElement(); - } - - dynamic get single { - if (length == 1) return this[0]; - if (length == 0) throw IterableElementError.noElement(); - throw IterableElementError.tooMany(); - } - - void removeRange(int start, int end) { - throw new UnsupportedError( - "Cannot remove from a fixed-length list"); - } - - void replaceRange(int start, int end, Iterable iterable) { - throw new UnsupportedError( - "Cannot remove from a fixed-length list"); - } - - List toList({bool growable: true}) { - return new List.from(this, growable: growable); - } - - Set toSet() { - return new Set.from(this); - } - - List sublist(int start, [int end]) { - end = RangeError.checkValidRange(start, end, this.length); - var length = end - start; - List result = _createList(length); - result.setRange(0, length, this, start); - return result; - } - - void setRange(int start, int end, Iterable from, [int skipCount = 0]) { - // Check ranges. - if (0 > start || start > end || end > length) { - RangeError.checkValidRange(start, end, length); // Always throws. - assert(false); - } - if (skipCount < 0) { - throw new ArgumentError(skipCount); - } - - final count = end - start; - if ((from.length - skipCount) < count) { - throw IterableElementError.tooFew(); - } - - if (from is _TypedListBase) { - if (this.elementSizeInBytes == from.elementSizeInBytes) { - if ((count < 10) && (from.buffer != this.buffer)) { - Lists.copy(from, skipCount, this, start, count); - return; - } else if (this.buffer._data._setRange( - start * elementSizeInBytes + this.offsetInBytes, - count * elementSizeInBytes, - from.buffer._data, - skipCount * elementSizeInBytes + from.offsetInBytes, - ClassID.getID(this), ClassID.getID(from))) { - return; - } - } else if (from.buffer == this.buffer) { - // Different element sizes, but same buffer means that we need - // an intermediate structure. - // TODO(srdjan): Optimize to skip copying if the range does not overlap. - final temp_buffer = new List(count); - for (var i = 0; i < count; i++) { - temp_buffer[i] = from[skipCount + i]; - } - for (var i = start; i < end; i++) { - this[i] = temp_buffer[i - start]; - } - return; - } - } - - if (count == 0) return; - List otherList; - int otherStart; - if (from is List) { - otherList = from; - otherStart = skipCount; - } else { - otherList = from.skip(skipCount).toList(growable: false); - otherStart = 0; - } - if (otherStart + count > otherList.length) { - throw IterableElementError.tooFew(); - } - Lists.copy(otherList, otherStart, this, start, count); - } - - void setAll(int index, Iterable iterable) { - final end = iterable.length + index; - setRange(index, end, iterable); - } - - void fillRange(int start, int end, [fillValue]) { - RangeError.checkValidRange(start, end, this.length); - for (var i = start; i < end; ++i) { - this[i] = fillValue; - } - } - - - // Method(s) implementing Object interface. - - String toString() => ListBase.listToString(this); - - - // Internal utility methods. - - // Returns true if operation succeeds. - // 'fromCid' and 'toCid' may be cid-s of the views and therefore may not - // match the cids of 'this' and 'from'. - // Uses toCid and fromCid to decide if clamping is necessary. - // Element size of toCid and fromCid must match (test at caller). - bool _setRange(int startInBytes, int lengthInBytes, - _TypedListBase from, int startFromInBytes, - int toCid, int fromCid) - native "TypedData_setRange"; -} - - -class _IntListMixin { - Iterable<int> where(bool f(int element)) => new WhereIterable<int>(this, f); - - Iterable<int> take(int n) => new SubListIterable<int>(this, 0, n); - - Iterable<int> takeWhile(bool test(int element)) => - new TakeWhileIterable<int>(this, test); - - Iterable<int> skip(int n) => new SubListIterable<int>(this, n, null); - - Iterable<int> skipWhile(bool test(element)) => - new SkipWhileIterable<int>(this, test); - - Iterable<int> get reversed => new ReversedListIterable<int>(this); - - Map<int, int> asMap() => new ListMapView<int>(this); - - Iterable<int> getRange(int start, [int end]) { - RangeError.checkValidRange(start, end, this.length); - return new SubListIterable<int>(this, start, end); - } - - Iterator<int> get iterator => new _TypedListIterator<int>(this); - - List<int> toList({bool growable: true}) { - return new List<int>.from(this, growable: growable); - } - - Set<int> toSet() { - return new Set<int>.from(this); - } -} - - -class _DoubleListMixin { - Iterable<double> where(bool f(int element)) => - new WhereIterable<double>(this, f); - - Iterable<double> take(int n) => new SubListIterable<double>(this, 0, n); - - Iterable<double> takeWhile(bool test(int element)) => - new TakeWhileIterable<double>(this, test); - - Iterable<double> skip(int n) => new SubListIterable<double>(this, n, null); - - Iterable<double> skipWhile(bool test(element)) => - new SkipWhileIterable<double>(this, test); - - Iterable<double> get reversed => new ReversedListIterable<double>(this); - - Map<int, double> asMap() => new ListMapView<double>(this); - - Iterable<double> getRange(int start, [int end]) { - RangeError.checkValidRange(start, end, this.length); - return new SubListIterable<double>(this, start, end); - } - - Iterator<double> get iterator => new _TypedListIterator<double>(this); - - List<double> toList({bool growable: true}) { - return new List<double>.from(this, growable: growable); - } - - Set<double> toSet() { - return new Set<double>.from(this); - } -} - - -class _Float32x4ListMixin { - Iterable<Float32x4> where(bool f(int element)) => - new WhereIterable<Float32x4>(this, f); - - Iterable<Float32x4> take(int n) => new SubListIterable<Float32x4>(this, 0, n); - - Iterable<Float32x4> takeWhile(bool test(int element)) => - new TakeWhileIterable<Float32x4>(this, test); - - Iterable<Float32x4> skip(int n) => - new SubListIterable<Float32x4>(this, n, null); - - Iterable<Float32x4> skipWhile(bool test(element)) => - new SkipWhileIterable<Float32x4>(this, test); - - Iterable<Float32x4> get reversed => new ReversedListIterable<Float32x4>(this); - - Map<int, Float32x4> asMap() => new ListMapView<Float32x4>(this); - - Iterable<Float32x4> getRange(int start, [int end]) { - RangeError.checkValidRange(start, end, this.length); - return new SubListIterable<Float32x4>(this, start, end); - } - - Iterator<Float32x4> get iterator => new _TypedListIterator<Float32x4>(this); - - List<Float32x4> toList({bool growable: true}) { - return new List<Float32x4>.from(this, growable: growable); - } - - Set<Float32x4> toSet() { - return new Set<Float32x4>.from(this); - } -} - - -class _Int32x4ListMixin { - Iterable<Int32x4> where(bool f(int element)) => - new WhereIterable<Int32x4>(this, f); - - Iterable<Int32x4> take(int n) => new SubListIterable<Int32x4>(this, 0, n); - - Iterable<Int32x4> takeWhile(bool test(int element)) => - new TakeWhileIterable<Int32x4>(this, test); - - Iterable<Int32x4> skip(int n) => new SubListIterable<Int32x4>(this, n, null); - - Iterable<Int32x4> skipWhile(bool test(element)) => - new SkipWhileIterable<Int32x4>(this, test); - - Iterable<Int32x4> get reversed => new ReversedListIterable<Int32x4>(this); - - Map<int, Int32x4> asMap() => new ListMapView<Int32x4>(this); - - Iterable<Int32x4> getRange(int start, [int end]) { - RangeError.checkValidRange(start, end, this.length); - return new SubListIterable<Int32x4>(this, start, end); - } - - Iterator<Int32x4> get iterator => new _TypedListIterator<Int32x4>(this); - - List<Int32x4> toList({bool growable: true}) { - return new List<Int32x4>.from(this, growable: growable); - } - - Set<Int32x4> toSet() { - return new Set<Int32x4>.from(this); - } -} - - -class _Float64x2ListMixin { - Iterable<Float64x2> where(bool f(int element)) => - new WhereIterable<Float64x2>(this, f); - - Iterable<Float64x2> take(int n) => new SubListIterable<Float64x2>(this, 0, n); - - Iterable<Float64x2> takeWhile(bool test(int element)) => - new TakeWhileIterable<Float64x2>(this, test); - - Iterable<Float64x2> skip(int n) => - new SubListIterable<Float64x2>(this, n, null); - - Iterable<Float64x2> skipWhile(bool test(element)) => - new SkipWhileIterable<Float64x2>(this, test); - - Iterable<Float64x2> get reversed => new ReversedListIterable<Float64x2>(this); - - Map<int, Float64x2> asMap() => new ListMapView<Float64x2>(this); - - Iterable<Float64x2> getRange(int start, [int end]) { - RangeError.checkValidRange(start, end, this.length); - return new SubListIterable<Float64x2>(this, start, end); - } - - Iterator<Float64x2> get iterator => new _TypedListIterator<Float64x2>(this); - - List<Float64x2> toList({bool growable: true}) { - return new List<Float64x2>.from(this, growable: growable); - } - - Set<Float64x2> toSet() { - return new Set<Float64x2>.from(this); - } -} - - -class ByteBuffer { - final _TypedList _data; - - ByteBuffer(this._data); - - factory ByteBuffer._New(data) => new ByteBuffer(data); - - // Forward calls to _data. - int get lengthInBytes => _data.lengthInBytes; - int get hashCode => _data.hashCode; - bool operator==(Object other) => - (other is ByteBuffer) && identical(_data, other._data); - - ByteData asByteData([int offsetInBytes = 0, int length]) { - if (length == null) { - length = this.lengthInBytes - offsetInBytes; - } - return new _ByteDataView(this._data, offsetInBytes, length); - } - - Int8List asInt8List([int offsetInBytes = 0, int length]) { - if (length == null) { - length = this.lengthInBytes - offsetInBytes; - } - return new _Int8ArrayView(this, offsetInBytes, length); - } - - Uint8List asUint8List([int offsetInBytes = 0, int length]) { - if (length == null) { - length = this.lengthInBytes - offsetInBytes; - } - return new _Uint8ArrayView(this, offsetInBytes, length); - } - - Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int length]) { - if (length == null) { - length = this.lengthInBytes - offsetInBytes; - } - return new _Uint8ClampedArrayView(this, offsetInBytes, length); - } - - Int16List asInt16List([int offsetInBytes = 0, int length]) { - if (length == null) { - length = (this.lengthInBytes - offsetInBytes) ~/ - Int16List.BYTES_PER_ELEMENT; - } - return new _Int16ArrayView(this, offsetInBytes, length); - } - - Uint16List asUint16List([int offsetInBytes = 0, int length]) { - if (length == null) { - length = (this.lengthInBytes - offsetInBytes) ~/ - Uint16List.BYTES_PER_ELEMENT; - } - return new _Uint16ArrayView(this, offsetInBytes, length); - } - - Int32List asInt32List([int offsetInBytes = 0, int length]) { - if (length == null) { - length = (this.lengthInBytes - offsetInBytes) ~/ - Int32List.BYTES_PER_ELEMENT; - } - return new _Int32ArrayView(this, offsetInBytes, length); - } - - Uint32List asUint32List([int offsetInBytes = 0, int length]) { - if (length == null) { - length = (this.lengthInBytes - offsetInBytes) ~/ - Uint32List.BYTES_PER_ELEMENT; - } - return new _Uint32ArrayView(this, offsetInBytes, length); - } - - Int64List asInt64List([int offsetInBytes = 0, int length]) { - if (length == null) { - length = (this.lengthInBytes - offsetInBytes) ~/ - Int64List.BYTES_PER_ELEMENT; - } - return new _Int64ArrayView(this, offsetInBytes, length); - } - - Uint64List asUint64List([int offsetInBytes = 0, int length]) { - if (length == null) { - length = (this.lengthInBytes - offsetInBytes) ~/ - Uint64List.BYTES_PER_ELEMENT; - } - return new _Uint64ArrayView(this, offsetInBytes, length); - } - - Float32List asFloat32List([int offsetInBytes = 0, int length]) { - if (length == null) { - length = (this.lengthInBytes - offsetInBytes) ~/ - Float32List.BYTES_PER_ELEMENT; - } - return new _Float32ArrayView(this, offsetInBytes, length); - } - - Float64List asFloat64List([int offsetInBytes = 0, int length]) { - if (length == null) { - length = (this.lengthInBytes - offsetInBytes) ~/ - Float64List.BYTES_PER_ELEMENT; - } - return new _Float64ArrayView(this, offsetInBytes, length); - } - - Float32x4List asFloat32x4List([int offsetInBytes = 0, int length]) { - if (length == null) { - length = (this.lengthInBytes - offsetInBytes) ~/ - Float32x4List.BYTES_PER_ELEMENT; - } - return new _Float32x4ArrayView(this, offsetInBytes, length); - } - - Int32x4List asInt32x4List([int offsetInBytes = 0, int length]) { - if (length == null) { - length = (this.lengthInBytes - offsetInBytes) ~/ - Int32x4List.BYTES_PER_ELEMENT; - } - return new _Int32x4ArrayView(this, offsetInBytes, length); - } - - Float64x2List asFloat64x2List([int offsetInBytes = 0, int length]) { - if (length == null) { - length = (this.lengthInBytes - offsetInBytes) ~/ - Float64x2List.BYTES_PER_ELEMENT; - } - return new _Float64x2ArrayView(this, offsetInBytes, length); - } -} - - -abstract class _TypedList extends _TypedListBase { - // Default method implementing parts of the TypedData interface. - int get offsetInBytes { - return 0; - } - - int get lengthInBytes { - return length * elementSizeInBytes; - } - - ByteBuffer get buffer => new ByteBuffer(this); - - // Methods implementing the collection interface. - - int get length native "TypedData_length"; - - // Internal utility methods. - - int _getInt8(int offsetInBytes) native "TypedData_GetInt8"; - void _setInt8(int offsetInBytes, int value) native "TypedData_SetInt8"; - - int _getUint8(int offsetInBytes) native "TypedData_GetUint8"; - void _setUint8(int offsetInBytes, int value) native "TypedData_SetUint8"; - - int _getInt16(int offsetInBytes) native "TypedData_GetInt16"; - void _setInt16(int offsetInBytes, int value) native "TypedData_SetInt16"; - - int _getUint16(int offsetInBytes) native "TypedData_GetUint16"; - void _setUint16(int offsetInBytes, int value) native "TypedData_SetUint16"; - - int _getInt32(int offsetInBytes) native "TypedData_GetInt32"; - void _setInt32(int offsetInBytes, int value) native "TypedData_SetInt32"; - - int _getUint32(int offsetInBytes) native "TypedData_GetUint32"; - void _setUint32(int offsetInBytes, int value) native "TypedData_SetUint32"; - - int _getInt64(int offsetInBytes) native "TypedData_GetInt64"; - void _setInt64(int offsetInBytes, int value) native "TypedData_SetInt64"; - - int _getUint64(int offsetInBytes) native "TypedData_GetUint64"; - void _setUint64(int offsetInBytes, int value) native "TypedData_SetUint64"; - - double _getFloat32(int offsetInBytes) native "TypedData_GetFloat32"; - void _setFloat32(int offsetInBytes, double value) - native "TypedData_SetFloat32"; - - double _getFloat64(int offsetInBytes) native "TypedData_GetFloat64"; - void _setFloat64(int offsetInBytes, double value) - native "TypedData_SetFloat64"; - - Float32x4 _getFloat32x4(int offsetInBytes) native "TypedData_GetFloat32x4"; - void _setFloat32x4(int offsetInBytes, Float32x4 value) - native "TypedData_SetFloat32x4"; - - Int32x4 _getInt32x4(int offsetInBytes) native "TypedData_GetInt32x4"; - void _setInt32x4(int offsetInBytes, Int32x4 value) - native "TypedData_SetInt32x4"; - - Float64x2 _getFloat64x2(int offsetInBytes) native "TypedData_GetFloat64x2"; - void _setFloat64x2(int offsetInBytes, Float64x2 value) - native "TypedData_SetFloat64x2"; - - /** - * Stores the [CodeUnits] as UTF-16 units into this TypedData at - * positions [start]..[end] (uint16 indices). - */ - void _setCodeUnits(CodeUnits units, - int byteStart, int length, int skipCount) { - assert(byteStart + length * Uint16List.BYTES_PER_ELEMENT <= lengthInBytes); - String string = CodeUnits.stringOf(units); - int sliceEnd = skipCount + length; - RangeError.checkValidRange(skipCount, sliceEnd, - string.length, - "skipCount", "skipCount + length"); - for (int i = 0; i < length; i++) { - _setUint16(byteStart + i * Uint16List.BYTES_PER_ELEMENT, - string.codeUnitAt(skipCount + i)); - } - } -} - - -class Int8List extends _TypedList with _IntListMixin implements List<int>, TypedData { - // Factory constructors. - - factory Int8List(int length) native "TypedData_Int8Array_new"; - - factory Int8List.fromList(List<int> elements) { - return new Int8List(elements.length) - ..setRange(0, elements.length, elements); - } - - factory Int8List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { - return buffer.asInt8List(offsetInBytes, length); - } - - // Method(s) implementing List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getInt8(index); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setInt8(index, _toInt8(value)); - } - - static const int BYTES_PER_ELEMENT = 1; - - // Method(s) implementing TypedData interface. - - int get elementSizeInBytes { - return Int8List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Int8List _createList(int length) { - return new Int8List(length); - } -} - - -class Uint8List extends _TypedList with _IntListMixin implements List<int>, TypedData { - // Factory constructors. - - factory Uint8List(int length) native "TypedData_Uint8Array_new"; - - factory Uint8List.fromList(List<int> elements) { - return new Uint8List(elements.length) - ..setRange(0, elements.length, elements); - } - - factory Uint8List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { - return buffer.asUint8List(offsetInBytes, length); - } - - // Methods implementing List interface. - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getUint8(index); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setUint8(index, _toUint8(value)); - } - - static const int BYTES_PER_ELEMENT = 1; - - // Methods implementing TypedData interface. - int get elementSizeInBytes { - return Uint8List.BYTES_PER_ELEMENT; - } - - // Internal utility methods. - - Uint8List _createList(int length) { - return new Uint8List(length); - } -} - - -class Uint8ClampedList extends _TypedList with _IntListMixin implements List<int>, TypedData { - // Factory constructors. - - factory Uint8ClampedList(int length) native "TypedData_Uint8ClampedArray_new"; - - factory Uint8ClampedList.fromList(List<int> elements) { - return new Uint8ClampedList(elements.length) - ..setRange(0, elements.length, elements); - } - - factory Uint8ClampedList.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { - return buffer.asUint8ClampedList(offsetInBytes, length); - } - - // Methods implementing List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getUint8(index); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setUint8(index, _toClampedUint8(value)); - } - - static const int BYTES_PER_ELEMENT = 1; - - // Methods implementing TypedData interface. - int get elementSizeInBytes { - return Uint8List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Uint8ClampedList _createList(int length) { - return new Uint8ClampedList(length); - } -} - - -class Int16List extends _TypedList with _IntListMixin implements List<int>, TypedData { - // Factory constructors. - - factory Int16List(int length) native "TypedData_Int16Array_new"; - - factory Int16List.fromList(List<int> elements) { - return new Int16List(elements.length) - ..setRange(0, elements.length, elements); - } - - factory Int16List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { - return buffer.asInt16List(offsetInBytes, length); - } - - // Method(s) implementing List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedInt16(index); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedInt16(index, _toInt16(value)); - } - - void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { - if (iterable is CodeUnits) { - end = RangeError.checkValidRange(start, end, this.length); - int length = end - start; - int byteStart = this.offsetInBytes + start * Int16List.BYTES_PER_ELEMENT; - _setCodeUnits(iterable, byteStart, length, skipCount); - } else { - super.setRange(start, end, iterable, skipCount); - } - } - - // Method(s) implementing TypedData interface. - static const int BYTES_PER_ELEMENT = 2; - - int get elementSizeInBytes { - return Int16List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Int16List _createList(int length) { - return new Int16List(length); - } - - int _getIndexedInt16(int index) { - return _getInt16(index * Int16List.BYTES_PER_ELEMENT); - } - - void _setIndexedInt16(int index, int value) { - _setInt16(index * Int16List.BYTES_PER_ELEMENT, value); - } -} - - -class Uint16List extends _TypedList with _IntListMixin implements List<int>, TypedData { - // Factory constructors. - - factory Uint16List(int length) native "TypedData_Uint16Array_new"; - - factory Uint16List.fromList(List<int> elements) { - return new Uint16List(elements.length) - ..setRange(0, elements.length, elements); - } - - factory Uint16List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { - return buffer.asUint16List(offsetInBytes, length); - } - - // Method(s) implementing the List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedUint16(index); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedUint16(index, _toUint16(value)); - } - - void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { - if (iterable is CodeUnits) { - end = RangeError.checkValidRange(start, end, this.length); - int length = end - start; - int byteStart = this.offsetInBytes + start * Uint16List.BYTES_PER_ELEMENT; - _setCodeUnits(iterable, byteStart, length, skipCount); - } else { - super.setRange(start, end, iterable, skipCount); - } - } - - // Method(s) implementing the TypedData interface. - static const int BYTES_PER_ELEMENT = 2; - - int get elementSizeInBytes { - return Uint16List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Uint16List _createList(int length) { - return new Uint16List(length); - } - - int _getIndexedUint16(int index) { - return _getUint16(index * Uint16List.BYTES_PER_ELEMENT); - } - - void _setIndexedUint16(int index, int value) { - _setUint16(index * Uint16List.BYTES_PER_ELEMENT, value); - } -} - - -class Int32List extends _TypedList with _IntListMixin implements List<int>, TypedData { - // Factory constructors. - - factory Int32List(int length) native "TypedData_Int32Array_new"; - - factory Int32List.fromList(List<int> elements) { - return new Int32List(elements.length) - ..setRange(0, elements.length, elements); - } - - factory Int32List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { - return buffer.asInt32List(offsetInBytes, length); - } - - // Method(s) implementing the List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedInt32(index); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedInt32(index, _toInt32(value)); - } - - - // Method(s) implementing TypedData interface. - static const int BYTES_PER_ELEMENT = 4; - - int get elementSizeInBytes { - return Int32List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Int32List _createList(int length) { - return new Int32List(length); - } - - int _getIndexedInt32(int index) { - return _getInt32(index * Int32List.BYTES_PER_ELEMENT); - } - - void _setIndexedInt32(int index, int value) { - _setInt32(index * Int32List.BYTES_PER_ELEMENT, value); - } - -} - - -class Uint32List extends _TypedList with _IntListMixin implements List<int>, TypedData { - // Factory constructors. - - factory Uint32List(int length) native "TypedData_Uint32Array_new"; - - factory Uint32List.fromList(List<int> elements) { - return new Uint32List(elements.length) - ..setRange(0, elements.length, elements); - } - - factory Uint32List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { - return buffer.asUint32List(offsetInBytes, length); - } - - // Method(s) implementing the List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedUint32(index); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedUint32(index, _toUint32(value)); - } - - - // Method(s) implementing the TypedData interface. - static const int BYTES_PER_ELEMENT = 4; - - int get elementSizeInBytes { - return Uint32List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Uint32List _createList(int length) { - return new Uint32List(length); - } - - int _getIndexedUint32(int index) { - return _getUint32(index * Uint32List.BYTES_PER_ELEMENT); - } - - void _setIndexedUint32(int index, int value) { - _setUint32(index * Uint32List.BYTES_PER_ELEMENT, value); - } -} - - -class Int64List extends _TypedList with _IntListMixin implements List<int>, TypedData { - // Factory constructors. - - factory Int64List(int length) native "TypedData_Int64Array_new"; - - factory Int64List.fromList(List<int> elements) { - return new Int64List(elements.length) - ..setRange(0, elements.length, elements); - } - - factory Int64List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { - return buffer.asInt64List(offsetInBytes, length); - } - - // Method(s) implementing the List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedInt64(index); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedInt64(index, _toInt64(value)); - } - - - // Method(s) implementing the TypedData interface. - static const int BYTES_PER_ELEMENT = 8; - - int get elementSizeInBytes { - return Int64List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Int64List _createList(int length) { - return new Int64List(length); - } - - int _getIndexedInt64(int index) { - return _getInt64(index * Int64List.BYTES_PER_ELEMENT); - } - - void _setIndexedInt64(int index, int value) { - _setInt64(index * Int64List.BYTES_PER_ELEMENT, value); - } -} - - -class Uint64List extends _TypedList with _IntListMixin implements List<int>, TypedData { - // Factory constructors. - - factory Uint64List(int length) native "TypedData_Uint64Array_new"; - - factory Uint64List.fromList(List<int> elements) { - return new Uint64List(elements.length) - ..setRange(0, elements.length, elements); - } - - factory Uint64List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { - return buffer.asUint64List(offsetInBytes, length); - } - - // Method(s) implementing the List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedUint64(index); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedUint64(index, _toUint64(value)); - } - - - // Method(s) implementing the TypedData interface. - static const int BYTES_PER_ELEMENT = 8; - - int get elementSizeInBytes { - return Uint64List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Uint64List _createList(int length) { - return new Uint64List(length); - } - - int _getIndexedUint64(int index) { - return _getUint64(index * Uint64List.BYTES_PER_ELEMENT); - } - - void _setIndexedUint64(int index, int value) { - _setUint64(index * Uint64List.BYTES_PER_ELEMENT, value); - } -} - - -class Float32List extends _TypedList with _DoubleListMixin implements List<double>, TypedData { - // Factory constructors. - - factory Float32List(int length) native "TypedData_Float32Array_new"; - - factory Float32List.fromList(List<double> elements) { - return new Float32List(elements.length) - ..setRange(0, elements.length, elements); - } - - factory Float32List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { - return buffer.asFloat32List(offsetInBytes, length); - } - - // Method(s) implementing the List interface. - - double operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedFloat32(index); - } - - void operator[]=(int index, double value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedFloat32(index, value); - } - - - // Method(s) implementing the TypedData interface. - static const int BYTES_PER_ELEMENT = 4; - - int get elementSizeInBytes { - return Float32List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Float32List _createList(int length) { - return new Float32List(length); - } - - double _getIndexedFloat32(int index) { - return _getFloat32(index * Float32List.BYTES_PER_ELEMENT); - } - - void _setIndexedFloat32(int index, double value) { - _setFloat32(index * Float32List.BYTES_PER_ELEMENT, value); - } -} - - -class Float64List extends _TypedList with _DoubleListMixin implements List<double>, TypedData { - // Factory constructors. - - factory Float64List(int length) native "TypedData_Float64Array_new"; - - factory Float64List.fromList(List<double> elements) { - return new Float64List(elements.length) - ..setRange(0, elements.length, elements); - } - - factory Float64List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { - return buffer.asFloat64List(offsetInBytes, length); - } - - // Method(s) implementing the List interface. - - double operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedFloat64(index); - } - - void operator[]=(int index, double value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedFloat64(index, value); - } - - - // Method(s) implementing the TypedData interface. - static const int BYTES_PER_ELEMENT = 8; - - int get elementSizeInBytes { - return Float64List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Float64List _createList(int length) { - return new Float64List(length); - } - - double _getIndexedFloat64(int index) { - return _getFloat64(index * Float64List.BYTES_PER_ELEMENT); - } - - void _setIndexedFloat64(int index, double value) { - _setFloat64(index * Float64List.BYTES_PER_ELEMENT, value); - } -} - - -class Float32x4List extends _TypedList with _Float32x4ListMixin implements List<Float32x4>, TypedData { - // Factory constructors. - - factory Float32x4List(int length) native "TypedData_Float32x4Array_new"; - - factory Float32x4List.fromList(List<Float32x4> elements) { - return new Float32x4List(elements.length) - ..setRange(0, elements.length, elements); - } - - factory Float32x4List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { - return buffer.asFloat32x4List(offsetInBytes, length); - } - - Float32x4 operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedFloat32x4(index); - } - - void operator[]=(int index, Float32x4 value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedFloat32x4(index, value); - } - - - // Method(s) implementing the TypedData interface. - static const int BYTES_PER_ELEMENT = 16; - - int get elementSizeInBytes { - return Float32x4List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Float32x4List _createList(int length) { - return new Float32x4List(length); - } - - Float32x4 _getIndexedFloat32x4(int index) { - return _getFloat32x4(index * Float32x4List.BYTES_PER_ELEMENT); - } - - void _setIndexedFloat32x4(int index, Float32x4 value) { - _setFloat32x4(index * Float32x4List.BYTES_PER_ELEMENT, value); - } -} - - -class Int32x4List extends _TypedList with _Int32x4ListMixin implements List<Int32x4>, TypedData { - // Factory constructors. - - factory Int32x4List(int length) native "TypedData_Int32x4Array_new"; - - factory Int32x4List.fromList(List<Int32x4> elements) { - return new Int32x4List(elements.length) - ..setRange(0, elements.length, elements); - } - - factory Int32x4List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { - return buffer.asInt32x4List(offsetInBytes, length); - } - - Int32x4 operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedInt32x4(index); - } - - void operator[]=(int index, Int32x4 value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedInt32x4(index, value); - } - - - // Method(s) implementing the TypedData interface. - static const int BYTES_PER_ELEMENT = 16; - - int get elementSizeInBytes { - return Int32x4List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Int32x4List _createList(int length) { - return new Int32x4List(length); - } - - Int32x4 _getIndexedInt32x4(int index) { - return _getInt32x4(index * Int32x4List.BYTES_PER_ELEMENT); - } - - void _setIndexedInt32x4(int index, Int32x4 value) { - _setInt32x4(index * Int32x4List.BYTES_PER_ELEMENT, value); - } -} - - -class Float64x2List extends _TypedList with _Float64x2ListMixin implements List<Float64x2>, TypedData { - // Factory constructors. - - factory Float64x2List(int length) native "TypedData_Float64x2Array_new"; - - factory Float64x2List.fromList(List<Float64x2> elements) { - return new Float64x2List(elements.length) - ..setRange(0, elements.length, elements); - } - - factory Float64x2List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { - return buffer.asFloat64x2List(offsetInBytes, length); - } - - Float64x2 operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedFloat64x2(index); - } - - void operator[]=(int index, Float64x2 value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedFloat64x2(index, value); - } - - - // Method(s) implementing the TypedData interface. - static const int BYTES_PER_ELEMENT = 16; - - int get elementSizeInBytes { - return Float64x2List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Float64x2List _createList(int length) { - return new Float64x2List(length); - } - - Float64x2 _getIndexedFloat64x2(int index) { - return _getFloat64x2(index * Float64x2List.BYTES_PER_ELEMENT); - } - - void _setIndexedFloat64x2(int index, Float64x2 value) { - _setFloat64x2(index * Float64x2List.BYTES_PER_ELEMENT, value); - } -} - - -class _ExternalInt8Array extends _TypedList with _IntListMixin implements Int8List { - // Method(s) implementing the List interface. - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getInt8(index); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setInt8(index, value); - } - - - // Method(s) implementing the TypedData interface. - - int get elementSizeInBytes { - return Int8List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Int8List _createList(int length) { - return new Int8List(length); - } -} - - -class _ExternalUint8Array extends _TypedList with _IntListMixin implements Uint8List { - // Method(s) implementing the List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getUint8(index); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setUint8(index, _toUint8(value)); - } - - - // Method(s) implementing the TypedData interface. - - int get elementSizeInBytes { - return Uint8List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Uint8List _createList(int length) { - return new Uint8List(length); - } -} - - -class _ExternalUint8ClampedArray extends _TypedList with _IntListMixin implements Uint8ClampedList { - // Method(s) implementing the List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getUint8(index); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setUint8(index, _toClampedUint8(value)); - } - - - // Method(s) implementing the TypedData interface. - - int get elementSizeInBytes { - return Uint8List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Uint8ClampedList _createList(int length) { - return new Uint8ClampedList(length); - } -} - - -class _ExternalInt16Array extends _TypedList with _IntListMixin implements Int16List { - // Method(s) implementing the List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedInt16(index); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedInt16(index, _toInt16(value)); - } - - - // Method(s) implementing the TypedData interface. - - int get elementSizeInBytes { - return Int16List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Int16List _createList(int length) { - return new Int16List(length); - } - - int _getIndexedInt16(int index) { - return _getInt16(index * Int16List.BYTES_PER_ELEMENT); - } - - void _setIndexedInt16(int index, int value) { - _setInt16(index * Int16List.BYTES_PER_ELEMENT, value); - } -} - - -class _ExternalUint16Array extends _TypedList with _IntListMixin implements Uint16List { - // Method(s) implementing the List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedUint16(index); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedUint16(index, _toUint16(value)); - } - - - // Method(s) implementing the TypedData interface. - - int get elementSizeInBytes { - return Uint16List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Uint16List _createList(int length) { - return new Uint16List(length); - } - - int _getIndexedUint16(int index) { - return _getUint16(index * Uint16List.BYTES_PER_ELEMENT); - } - - void _setIndexedUint16(int index, int value) { - _setUint16(index * Uint16List.BYTES_PER_ELEMENT, value); - } -} - - -class _ExternalInt32Array extends _TypedList with _IntListMixin implements Int32List { - // Method(s) implementing the List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedInt32(index); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedInt32(index, _toInt32(value)); - } - - - // Method(s) implementing the TypedData interface. - - int get elementSizeInBytes { - return Int32List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Int32List _createList(int length) { - return new Int32List(length); - } - - int _getIndexedInt32(int index) { - return _getInt32(index * Int32List.BYTES_PER_ELEMENT); - } - - void _setIndexedInt32(int index, int value) { - _setInt32(index * Int32List.BYTES_PER_ELEMENT, value); - } -} - - -class _ExternalUint32Array extends _TypedList with _IntListMixin implements Uint32List { - // Method(s) implementing the List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedUint32(index); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedUint32(index, _toUint32(value)); - } - - - // Method(s) implementing the TypedData interface. - - int get elementSizeInBytes { - return Uint32List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Uint32List _createList(int length) { - return new Uint32List(length); - } - - int _getIndexedUint32(int index) { - return _getUint32(index * Uint32List.BYTES_PER_ELEMENT); - } - - void _setIndexedUint32(int index, int value) { - _setUint32(index * Uint32List.BYTES_PER_ELEMENT, value); - } -} - - -class _ExternalInt64Array extends _TypedList with _IntListMixin implements Int64List { - // Method(s) implementing the List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedInt64(index); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedInt64(index, _toInt64(value)); - } - - - // Method(s) implementing the TypedData interface. - - int get elementSizeInBytes { - return Int64List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Int64List _createList(int length) { - return new Int64List(length); - } - - int _getIndexedInt64(int index) { - return _getInt64(index * Int64List.BYTES_PER_ELEMENT); - } - - void _setIndexedInt64(int index, int value) { - _setInt64(index * Int64List.BYTES_PER_ELEMENT, value); - } -} - - -class _ExternalUint64Array extends _TypedList with _IntListMixin implements Uint64List { - // Method(s) implementing the List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedUint64(index); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedUint64(index, _toUint64(value)); - } - - - // Method(s) implementing the TypedData interface. - - int get elementSizeInBytes { - return Uint64List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Uint64List _createList(int length) { - return new Uint64List(length); - } - - int _getIndexedUint64(int index) { - return _getUint64(index * Uint64List.BYTES_PER_ELEMENT); - } - - void _setIndexedUint64(int index, int value) { - _setUint64(index * Uint64List.BYTES_PER_ELEMENT, value); - } -} - - -class _ExternalFloat32Array extends _TypedList with _DoubleListMixin implements Float32List { - // Method(s) implementing the List interface. - - double operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedFloat32(index); - } - - void operator[]=(int index, double value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedFloat32(index, value); - } - - - // Method(s) implementing the TypedData interface. - - int get elementSizeInBytes { - return Float32List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Float32List _createList(int length) { - return new Float32List(length); - } - - double _getIndexedFloat32(int index) { - return _getFloat32(index * Float32List.BYTES_PER_ELEMENT); - } - - void _setIndexedFloat32(int index, double value) { - _setFloat32(index * Float32List.BYTES_PER_ELEMENT, value); - } -} - - -class _ExternalFloat64Array extends _TypedList with _DoubleListMixin implements Float64List { - // Method(s) implementing the List interface. - - double operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedFloat64(index); - } - - void operator[]=(int index, double value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedFloat64(index, value); - } - - - // Method(s) implementing the TypedData interface. - - int get elementSizeInBytes { - return Float64List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Float64List _createList(int length) { - return new Float64List(length); - } - - double _getIndexedFloat64(int index) { - return _getFloat64(index * Float64List.BYTES_PER_ELEMENT); - } - - void _setIndexedFloat64(int index, double value) { - _setFloat64(index * Float64List.BYTES_PER_ELEMENT, value); - } -} - - -class _ExternalFloat32x4Array extends _TypedList with _Float32x4ListMixin implements Float32x4List { - // Method(s) implementing the List interface. - - Float32x4 operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedFloat32x4(index); - } - - void operator[]=(int index, Float32x4 value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedFloat32x4(index, value); - } - - - // Method(s) implementing the TypedData interface. - - int get elementSizeInBytes { - return Float32x4List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Float32x4List _createList(int length) { - return new Float32x4List(length); - } - - Float32x4 _getIndexedFloat32x4(int index) { - return _getFloat32x4(index * Float32x4List.BYTES_PER_ELEMENT); - } - - void _setIndexedFloat32x4(int index, Float32x4 value) { - _setFloat32x4(index * Float32x4List.BYTES_PER_ELEMENT, value); - } -} - - -class _ExternalInt32x4Array extends _TypedList with _Int32x4ListMixin implements Int32x4List { - // Method(s) implementing the List interface. - - Int32x4 operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedInt32x4(index); - } - - void operator[]=(int index, Int32x4 value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedInt32x4(index, value); - } - - - // Method(s) implementing the TypedData interface. - - int get elementSizeInBytes { - return Int32x4List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Int32x4List _createList(int length) { - return new Int32x4List(length); - } - - Int32x4 _getIndexedInt32x4(int index) { - return _getInt32x4(index * Int32x4List.BYTES_PER_ELEMENT); - } - - void _setIndexedInt32x4(int index, Int32x4 value) { - _setInt32x4(index * Int32x4List.BYTES_PER_ELEMENT, value); - } -} - - -class _ExternalFloat64x2Array extends _TypedList with _Float64x2ListMixin implements Float64x2List { - // Method(s) implementing the List interface. - - Float64x2 operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedFloat64x2(index); - } - - void operator[]=(int index, Float64x2 value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedFloat64x2(index, value); - } - - - // Method(s) implementing the TypedData interface. - - int get elementSizeInBytes { - return Float64x2List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Float64x2List _createList(int length) { - return new Float64x2List(length); - } - - Float64x2 _getIndexedFloat64x2(int index) { - return _getFloat64x2(index * Float64x2List.BYTES_PER_ELEMENT); - } - - void _setIndexedFloat64x2(int index, Float64x2 value) { - _setFloat64x2(index * Float64x2List.BYTES_PER_ELEMENT, value); - } -} - - -class Float32x4 { - factory Float32x4(double x, double y, double z, double w) - native "Float32x4_fromDoubles"; - factory Float32x4.splat(double v) native "Float32x4_splat"; - factory Float32x4.zero() native "Float32x4_zero"; - factory Float32x4.fromInt32x4Bits(Int32x4 x) - native "Float32x4_fromInt32x4Bits"; - factory Float32x4.fromFloat64x2(Float64x2 v) - native "Float32x4_fromFloat64x2"; - Float32x4 operator +(Float32x4 other) { - return _add(other); - } - Float32x4 _add(Float32x4 other) native "Float32x4_add"; - Float32x4 operator -() { - return _negate(); - } - Float32x4 _negate() native "Float32x4_negate"; - Float32x4 operator -(Float32x4 other) { - return _sub(other); - } - Float32x4 _sub(Float32x4 other) native "Float32x4_sub"; - Float32x4 operator *(Float32x4 other) { - return _mul(other); - } - Float32x4 _mul(Float32x4 other) native "Float32x4_mul"; - Float32x4 operator /(Float32x4 other) { - return _div(other); - } - Float32x4 _div(Float32x4 other) native "Float32x4_div"; - Int32x4 lessThan(Float32x4 other) { - return _cmplt(other); - } - Int32x4 _cmplt(Float32x4 other) native "Float32x4_cmplt"; - Int32x4 lessThanOrEqual(Float32x4 other) { - return _cmplte(other); - } - Int32x4 _cmplte(Float32x4 other) native "Float32x4_cmplte"; - Int32x4 greaterThan(Float32x4 other) { - return _cmpgt(other); - } - Int32x4 _cmpgt(Float32x4 other) native "Float32x4_cmpgt"; - Int32x4 greaterThanOrEqual(Float32x4 other) { - return _cmpgte(other); - } - Int32x4 _cmpgte(Float32x4 other) native "Float32x4_cmpgte"; - Int32x4 equal(Float32x4 other) { - return _cmpequal(other); - } - Int32x4 _cmpequal(Float32x4 other) - native "Float32x4_cmpequal"; - Int32x4 notEqual(Float32x4 other) { - return _cmpnequal(other); - } - Int32x4 _cmpnequal(Float32x4 other) - native "Float32x4_cmpnequal"; - Float32x4 scale(double s) { - return _scale(s); - } - Float32x4 _scale(double s) native "Float32x4_scale"; - Float32x4 abs() { - return _abs(); - } - Float32x4 _abs() native "Float32x4_abs"; - Float32x4 clamp(Float32x4 lowerLimit, Float32x4 upperLimit) { - return _clamp(lowerLimit, upperLimit); - } - Float32x4 _clamp(Float32x4 lowerLimit, Float32x4 upperLimit) - native "Float32x4_clamp"; - double get x native "Float32x4_getX"; - double get y native "Float32x4_getY"; - double get z native "Float32x4_getZ"; - double get w native "Float32x4_getW"; - int get signMask native "Float32x4_getSignMask"; - - Float32x4 shuffle(int mask) native "Float32x4_shuffle"; - Float32x4 shuffleMix(Float32x4 zw, int mask) native "Float32x4_shuffleMix"; - - Float32x4 withX(double x) native "Float32x4_setX"; - Float32x4 withY(double y) native "Float32x4_setY"; - Float32x4 withZ(double z) native "Float32x4_setZ"; - Float32x4 withW(double w) native "Float32x4_setW"; - Float32x4 min(Float32x4 other) { - return _min(other); - } - Float32x4 _min(Float32x4 other) native "Float32x4_min"; - Float32x4 max(Float32x4 other) { - return _max(other); - } - Float32x4 _max(Float32x4 other) native "Float32x4_max"; - Float32x4 sqrt() { - return _sqrt(); - } - Float32x4 _sqrt() native "Float32x4_sqrt"; - Float32x4 reciprocal() { - return _reciprocal(); - } - Float32x4 _reciprocal() native "Float32x4_reciprocal"; - Float32x4 reciprocalSqrt() { - return _reciprocalSqrt(); - } - Float32x4 _reciprocalSqrt() native "Float32x4_reciprocalSqrt"; - - /// Mask passed to [shuffle] or [shuffleMix]. - static const int XXXX = 0x0; - static const int XXXY = 0x40; - static const int XXXZ = 0x80; - static const int XXXW = 0xC0; - static const int XXYX = 0x10; - static const int XXYY = 0x50; - static const int XXYZ = 0x90; - static const int XXYW = 0xD0; - static const int XXZX = 0x20; - static const int XXZY = 0x60; - static const int XXZZ = 0xA0; - static const int XXZW = 0xE0; - static const int XXWX = 0x30; - static const int XXWY = 0x70; - static const int XXWZ = 0xB0; - static const int XXWW = 0xF0; - static const int XYXX = 0x4; - static const int XYXY = 0x44; - static const int XYXZ = 0x84; - static const int XYXW = 0xC4; - static const int XYYX = 0x14; - static const int XYYY = 0x54; - static const int XYYZ = 0x94; - static const int XYYW = 0xD4; - static const int XYZX = 0x24; - static const int XYZY = 0x64; - static const int XYZZ = 0xA4; - static const int XYZW = 0xE4; - static const int XYWX = 0x34; - static const int XYWY = 0x74; - static const int XYWZ = 0xB4; - static const int XYWW = 0xF4; - static const int XZXX = 0x8; - static const int XZXY = 0x48; - static const int XZXZ = 0x88; - static const int XZXW = 0xC8; - static const int XZYX = 0x18; - static const int XZYY = 0x58; - static const int XZYZ = 0x98; - static const int XZYW = 0xD8; - static const int XZZX = 0x28; - static const int XZZY = 0x68; - static const int XZZZ = 0xA8; - static const int XZZW = 0xE8; - static const int XZWX = 0x38; - static const int XZWY = 0x78; - static const int XZWZ = 0xB8; - static const int XZWW = 0xF8; - static const int XWXX = 0xC; - static const int XWXY = 0x4C; - static const int XWXZ = 0x8C; - static const int XWXW = 0xCC; - static const int XWYX = 0x1C; - static const int XWYY = 0x5C; - static const int XWYZ = 0x9C; - static const int XWYW = 0xDC; - static const int XWZX = 0x2C; - static const int XWZY = 0x6C; - static const int XWZZ = 0xAC; - static const int XWZW = 0xEC; - static const int XWWX = 0x3C; - static const int XWWY = 0x7C; - static const int XWWZ = 0xBC; - static const int XWWW = 0xFC; - static const int YXXX = 0x1; - static const int YXXY = 0x41; - static const int YXXZ = 0x81; - static const int YXXW = 0xC1; - static const int YXYX = 0x11; - static const int YXYY = 0x51; - static const int YXYZ = 0x91; - static const int YXYW = 0xD1; - static const int YXZX = 0x21; - static const int YXZY = 0x61; - static const int YXZZ = 0xA1; - static const int YXZW = 0xE1; - static const int YXWX = 0x31; - static const int YXWY = 0x71; - static const int YXWZ = 0xB1; - static const int YXWW = 0xF1; - static const int YYXX = 0x5; - static const int YYXY = 0x45; - static const int YYXZ = 0x85; - static const int YYXW = 0xC5; - static const int YYYX = 0x15; - static const int YYYY = 0x55; - static const int YYYZ = 0x95; - static const int YYYW = 0xD5; - static const int YYZX = 0x25; - static const int YYZY = 0x65; - static const int YYZZ = 0xA5; - static const int YYZW = 0xE5; - static const int YYWX = 0x35; - static const int YYWY = 0x75; - static const int YYWZ = 0xB5; - static const int YYWW = 0xF5; - static const int YZXX = 0x9; - static const int YZXY = 0x49; - static const int YZXZ = 0x89; - static const int YZXW = 0xC9; - static const int YZYX = 0x19; - static const int YZYY = 0x59; - static const int YZYZ = 0x99; - static const int YZYW = 0xD9; - static const int YZZX = 0x29; - static const int YZZY = 0x69; - static const int YZZZ = 0xA9; - static const int YZZW = 0xE9; - static const int YZWX = 0x39; - static const int YZWY = 0x79; - static const int YZWZ = 0xB9; - static const int YZWW = 0xF9; - static const int YWXX = 0xD; - static const int YWXY = 0x4D; - static const int YWXZ = 0x8D; - static const int YWXW = 0xCD; - static const int YWYX = 0x1D; - static const int YWYY = 0x5D; - static const int YWYZ = 0x9D; - static const int YWYW = 0xDD; - static const int YWZX = 0x2D; - static const int YWZY = 0x6D; - static const int YWZZ = 0xAD; - static const int YWZW = 0xED; - static const int YWWX = 0x3D; - static const int YWWY = 0x7D; - static const int YWWZ = 0xBD; - static const int YWWW = 0xFD; - static const int ZXXX = 0x2; - static const int ZXXY = 0x42; - static const int ZXXZ = 0x82; - static const int ZXXW = 0xC2; - static const int ZXYX = 0x12; - static const int ZXYY = 0x52; - static const int ZXYZ = 0x92; - static const int ZXYW = 0xD2; - static const int ZXZX = 0x22; - static const int ZXZY = 0x62; - static const int ZXZZ = 0xA2; - static const int ZXZW = 0xE2; - static const int ZXWX = 0x32; - static const int ZXWY = 0x72; - static const int ZXWZ = 0xB2; - static const int ZXWW = 0xF2; - static const int ZYXX = 0x6; - static const int ZYXY = 0x46; - static const int ZYXZ = 0x86; - static const int ZYXW = 0xC6; - static const int ZYYX = 0x16; - static const int ZYYY = 0x56; - static const int ZYYZ = 0x96; - static const int ZYYW = 0xD6; - static const int ZYZX = 0x26; - static const int ZYZY = 0x66; - static const int ZYZZ = 0xA6; - static const int ZYZW = 0xE6; - static const int ZYWX = 0x36; - static const int ZYWY = 0x76; - static const int ZYWZ = 0xB6; - static const int ZYWW = 0xF6; - static const int ZZXX = 0xA; - static const int ZZXY = 0x4A; - static const int ZZXZ = 0x8A; - static const int ZZXW = 0xCA; - static const int ZZYX = 0x1A; - static const int ZZYY = 0x5A; - static const int ZZYZ = 0x9A; - static const int ZZYW = 0xDA; - static const int ZZZX = 0x2A; - static const int ZZZY = 0x6A; - static const int ZZZZ = 0xAA; - static const int ZZZW = 0xEA; - static const int ZZWX = 0x3A; - static const int ZZWY = 0x7A; - static const int ZZWZ = 0xBA; - static const int ZZWW = 0xFA; - static const int ZWXX = 0xE; - static const int ZWXY = 0x4E; - static const int ZWXZ = 0x8E; - static const int ZWXW = 0xCE; - static const int ZWYX = 0x1E; - static const int ZWYY = 0x5E; - static const int ZWYZ = 0x9E; - static const int ZWYW = 0xDE; - static const int ZWZX = 0x2E; - static const int ZWZY = 0x6E; - static const int ZWZZ = 0xAE; - static const int ZWZW = 0xEE; - static const int ZWWX = 0x3E; - static const int ZWWY = 0x7E; - static const int ZWWZ = 0xBE; - static const int ZWWW = 0xFE; - static const int WXXX = 0x3; - static const int WXXY = 0x43; - static const int WXXZ = 0x83; - static const int WXXW = 0xC3; - static const int WXYX = 0x13; - static const int WXYY = 0x53; - static const int WXYZ = 0x93; - static const int WXYW = 0xD3; - static const int WXZX = 0x23; - static const int WXZY = 0x63; - static const int WXZZ = 0xA3; - static const int WXZW = 0xE3; - static const int WXWX = 0x33; - static const int WXWY = 0x73; - static const int WXWZ = 0xB3; - static const int WXWW = 0xF3; - static const int WYXX = 0x7; - static const int WYXY = 0x47; - static const int WYXZ = 0x87; - static const int WYXW = 0xC7; - static const int WYYX = 0x17; - static const int WYYY = 0x57; - static const int WYYZ = 0x97; - static const int WYYW = 0xD7; - static const int WYZX = 0x27; - static const int WYZY = 0x67; - static const int WYZZ = 0xA7; - static const int WYZW = 0xE7; - static const int WYWX = 0x37; - static const int WYWY = 0x77; - static const int WYWZ = 0xB7; - static const int WYWW = 0xF7; - static const int WZXX = 0xB; - static const int WZXY = 0x4B; - static const int WZXZ = 0x8B; - static const int WZXW = 0xCB; - static const int WZYX = 0x1B; - static const int WZYY = 0x5B; - static const int WZYZ = 0x9B; - static const int WZYW = 0xDB; - static const int WZZX = 0x2B; - static const int WZZY = 0x6B; - static const int WZZZ = 0xAB; - static const int WZZW = 0xEB; - static const int WZWX = 0x3B; - static const int WZWY = 0x7B; - static const int WZWZ = 0xBB; - static const int WZWW = 0xFB; - static const int WWXX = 0xF; - static const int WWXY = 0x4F; - static const int WWXZ = 0x8F; - static const int WWXW = 0xCF; - static const int WWYX = 0x1F; - static const int WWYY = 0x5F; - static const int WWYZ = 0x9F; - static const int WWYW = 0xDF; - static const int WWZX = 0x2F; - static const int WWZY = 0x6F; - static const int WWZZ = 0xAF; - static const int WWZW = 0xEF; - static const int WWWX = 0x3F; - static const int WWWY = 0x7F; - static const int WWWZ = 0xBF; - static const int WWWW = 0xFF; - -} - - -class Int32x4 { - factory Int32x4(int x, int y, int z, int w) - native "Int32x4_fromInts"; - factory Int32x4.bool(bool x, bool y, bool z, bool w) - native "Int32x4_fromBools"; - factory Int32x4.fromFloat32x4Bits(Float32x4 x) - native "Int32x4_fromFloat32x4Bits"; - Int32x4 operator |(Int32x4 other) { - return _or(other); - } - Int32x4 _or(Int32x4 other) native "Int32x4_or"; - Int32x4 operator &(Int32x4 other) { - return _and(other); - } - Int32x4 _and(Int32x4 other) native "Int32x4_and"; - Int32x4 operator ^(Int32x4 other) { - return _xor(other); - } - Int32x4 _xor(Int32x4 other) native "Int32x4_xor"; - Int32x4 operator +(Int32x4 other) { - return _add(other); - } - Int32x4 _add(Int32x4 other) native "Int32x4_add"; - Int32x4 operator -(Int32x4 other) { - return _sub(other); - } - Int32x4 _sub(Int32x4 other) native "Int32x4_sub"; - int get x native "Int32x4_getX"; - int get y native "Int32x4_getY"; - int get z native "Int32x4_getZ"; - int get w native "Int32x4_getW"; - int get signMask native "Int32x4_getSignMask"; - Int32x4 shuffle(int mask) native "Int32x4_shuffle"; - Int32x4 shuffleMix(Int32x4 zw, int mask) native "Int32x4_shuffleMix"; - Int32x4 withX(int x) native "Int32x4_setX"; - Int32x4 withY(int y) native "Int32x4_setY"; - Int32x4 withZ(int z) native "Int32x4_setZ"; - Int32x4 withW(int w) native "Int32x4_setW"; - bool get flagX native "Int32x4_getFlagX"; - bool get flagY native "Int32x4_getFlagY"; - bool get flagZ native "Int32x4_getFlagZ"; - bool get flagW native "Int32x4_getFlagW"; - Int32x4 withFlagX(bool x) native "Int32x4_setFlagX"; - Int32x4 withFlagY(bool y) native "Int32x4_setFlagY"; - Int32x4 withFlagZ(bool z) native "Int32x4_setFlagZ"; - Int32x4 withFlagW(bool w) native "Int32x4_setFlagW"; - Float32x4 select(Float32x4 trueValue, Float32x4 falseValue) { - return _select(trueValue, falseValue); - } - Float32x4 _select(Float32x4 trueValue, Float32x4 falseValue) - native "Int32x4_select"; - - /// Mask passed to [shuffle] or [shuffleMix]. - static const int XXXX = 0x0; - static const int XXXY = 0x40; - static const int XXXZ = 0x80; - static const int XXXW = 0xC0; - static const int XXYX = 0x10; - static const int XXYY = 0x50; - static const int XXYZ = 0x90; - static const int XXYW = 0xD0; - static const int XXZX = 0x20; - static const int XXZY = 0x60; - static const int XXZZ = 0xA0; - static const int XXZW = 0xE0; - static const int XXWX = 0x30; - static const int XXWY = 0x70; - static const int XXWZ = 0xB0; - static const int XXWW = 0xF0; - static const int XYXX = 0x4; - static const int XYXY = 0x44; - static const int XYXZ = 0x84; - static const int XYXW = 0xC4; - static const int XYYX = 0x14; - static const int XYYY = 0x54; - static const int XYYZ = 0x94; - static const int XYYW = 0xD4; - static const int XYZX = 0x24; - static const int XYZY = 0x64; - static const int XYZZ = 0xA4; - static const int XYZW = 0xE4; - static const int XYWX = 0x34; - static const int XYWY = 0x74; - static const int XYWZ = 0xB4; - static const int XYWW = 0xF4; - static const int XZXX = 0x8; - static const int XZXY = 0x48; - static const int XZXZ = 0x88; - static const int XZXW = 0xC8; - static const int XZYX = 0x18; - static const int XZYY = 0x58; - static const int XZYZ = 0x98; - static const int XZYW = 0xD8; - static const int XZZX = 0x28; - static const int XZZY = 0x68; - static const int XZZZ = 0xA8; - static const int XZZW = 0xE8; - static const int XZWX = 0x38; - static const int XZWY = 0x78; - static const int XZWZ = 0xB8; - static const int XZWW = 0xF8; - static const int XWXX = 0xC; - static const int XWXY = 0x4C; - static const int XWXZ = 0x8C; - static const int XWXW = 0xCC; - static const int XWYX = 0x1C; - static const int XWYY = 0x5C; - static const int XWYZ = 0x9C; - static const int XWYW = 0xDC; - static const int XWZX = 0x2C; - static const int XWZY = 0x6C; - static const int XWZZ = 0xAC; - static const int XWZW = 0xEC; - static const int XWWX = 0x3C; - static const int XWWY = 0x7C; - static const int XWWZ = 0xBC; - static const int XWWW = 0xFC; - static const int YXXX = 0x1; - static const int YXXY = 0x41; - static const int YXXZ = 0x81; - static const int YXXW = 0xC1; - static const int YXYX = 0x11; - static const int YXYY = 0x51; - static const int YXYZ = 0x91; - static const int YXYW = 0xD1; - static const int YXZX = 0x21; - static const int YXZY = 0x61; - static const int YXZZ = 0xA1; - static const int YXZW = 0xE1; - static const int YXWX = 0x31; - static const int YXWY = 0x71; - static const int YXWZ = 0xB1; - static const int YXWW = 0xF1; - static const int YYXX = 0x5; - static const int YYXY = 0x45; - static const int YYXZ = 0x85; - static const int YYXW = 0xC5; - static const int YYYX = 0x15; - static const int YYYY = 0x55; - static const int YYYZ = 0x95; - static const int YYYW = 0xD5; - static const int YYZX = 0x25; - static const int YYZY = 0x65; - static const int YYZZ = 0xA5; - static const int YYZW = 0xE5; - static const int YYWX = 0x35; - static const int YYWY = 0x75; - static const int YYWZ = 0xB5; - static const int YYWW = 0xF5; - static const int YZXX = 0x9; - static const int YZXY = 0x49; - static const int YZXZ = 0x89; - static const int YZXW = 0xC9; - static const int YZYX = 0x19; - static const int YZYY = 0x59; - static const int YZYZ = 0x99; - static const int YZYW = 0xD9; - static const int YZZX = 0x29; - static const int YZZY = 0x69; - static const int YZZZ = 0xA9; - static const int YZZW = 0xE9; - static const int YZWX = 0x39; - static const int YZWY = 0x79; - static const int YZWZ = 0xB9; - static const int YZWW = 0xF9; - static const int YWXX = 0xD; - static const int YWXY = 0x4D; - static const int YWXZ = 0x8D; - static const int YWXW = 0xCD; - static const int YWYX = 0x1D; - static const int YWYY = 0x5D; - static const int YWYZ = 0x9D; - static const int YWYW = 0xDD; - static const int YWZX = 0x2D; - static const int YWZY = 0x6D; - static const int YWZZ = 0xAD; - static const int YWZW = 0xED; - static const int YWWX = 0x3D; - static const int YWWY = 0x7D; - static const int YWWZ = 0xBD; - static const int YWWW = 0xFD; - static const int ZXXX = 0x2; - static const int ZXXY = 0x42; - static const int ZXXZ = 0x82; - static const int ZXXW = 0xC2; - static const int ZXYX = 0x12; - static const int ZXYY = 0x52; - static const int ZXYZ = 0x92; - static const int ZXYW = 0xD2; - static const int ZXZX = 0x22; - static const int ZXZY = 0x62; - static const int ZXZZ = 0xA2; - static const int ZXZW = 0xE2; - static const int ZXWX = 0x32; - static const int ZXWY = 0x72; - static const int ZXWZ = 0xB2; - static const int ZXWW = 0xF2; - static const int ZYXX = 0x6; - static const int ZYXY = 0x46; - static const int ZYXZ = 0x86; - static const int ZYXW = 0xC6; - static const int ZYYX = 0x16; - static const int ZYYY = 0x56; - static const int ZYYZ = 0x96; - static const int ZYYW = 0xD6; - static const int ZYZX = 0x26; - static const int ZYZY = 0x66; - static const int ZYZZ = 0xA6; - static const int ZYZW = 0xE6; - static const int ZYWX = 0x36; - static const int ZYWY = 0x76; - static const int ZYWZ = 0xB6; - static const int ZYWW = 0xF6; - static const int ZZXX = 0xA; - static const int ZZXY = 0x4A; - static const int ZZXZ = 0x8A; - static const int ZZXW = 0xCA; - static const int ZZYX = 0x1A; - static const int ZZYY = 0x5A; - static const int ZZYZ = 0x9A; - static const int ZZYW = 0xDA; - static const int ZZZX = 0x2A; - static const int ZZZY = 0x6A; - static const int ZZZZ = 0xAA; - static const int ZZZW = 0xEA; - static const int ZZWX = 0x3A; - static const int ZZWY = 0x7A; - static const int ZZWZ = 0xBA; - static const int ZZWW = 0xFA; - static const int ZWXX = 0xE; - static const int ZWXY = 0x4E; - static const int ZWXZ = 0x8E; - static const int ZWXW = 0xCE; - static const int ZWYX = 0x1E; - static const int ZWYY = 0x5E; - static const int ZWYZ = 0x9E; - static const int ZWYW = 0xDE; - static const int ZWZX = 0x2E; - static const int ZWZY = 0x6E; - static const int ZWZZ = 0xAE; - static const int ZWZW = 0xEE; - static const int ZWWX = 0x3E; - static const int ZWWY = 0x7E; - static const int ZWWZ = 0xBE; - static const int ZWWW = 0xFE; - static const int WXXX = 0x3; - static const int WXXY = 0x43; - static const int WXXZ = 0x83; - static const int WXXW = 0xC3; - static const int WXYX = 0x13; - static const int WXYY = 0x53; - static const int WXYZ = 0x93; - static const int WXYW = 0xD3; - static const int WXZX = 0x23; - static const int WXZY = 0x63; - static const int WXZZ = 0xA3; - static const int WXZW = 0xE3; - static const int WXWX = 0x33; - static const int WXWY = 0x73; - static const int WXWZ = 0xB3; - static const int WXWW = 0xF3; - static const int WYXX = 0x7; - static const int WYXY = 0x47; - static const int WYXZ = 0x87; - static const int WYXW = 0xC7; - static const int WYYX = 0x17; - static const int WYYY = 0x57; - static const int WYYZ = 0x97; - static const int WYYW = 0xD7; - static const int WYZX = 0x27; - static const int WYZY = 0x67; - static const int WYZZ = 0xA7; - static const int WYZW = 0xE7; - static const int WYWX = 0x37; - static const int WYWY = 0x77; - static const int WYWZ = 0xB7; - static const int WYWW = 0xF7; - static const int WZXX = 0xB; - static const int WZXY = 0x4B; - static const int WZXZ = 0x8B; - static const int WZXW = 0xCB; - static const int WZYX = 0x1B; - static const int WZYY = 0x5B; - static const int WZYZ = 0x9B; - static const int WZYW = 0xDB; - static const int WZZX = 0x2B; - static const int WZZY = 0x6B; - static const int WZZZ = 0xAB; - static const int WZZW = 0xEB; - static const int WZWX = 0x3B; - static const int WZWY = 0x7B; - static const int WZWZ = 0xBB; - static const int WZWW = 0xFB; - static const int WWXX = 0xF; - static const int WWXY = 0x4F; - static const int WWXZ = 0x8F; - static const int WWXW = 0xCF; - static const int WWYX = 0x1F; - static const int WWYY = 0x5F; - static const int WWYZ = 0x9F; - static const int WWYW = 0xDF; - static const int WWZX = 0x2F; - static const int WWZY = 0x6F; - static const int WWZZ = 0xAF; - static const int WWZW = 0xEF; - static const int WWWX = 0x3F; - static const int WWWY = 0x7F; - static const int WWWZ = 0xBF; - static const int WWWW = 0xFF; - -} - - -class Float64x2 { - factory Float64x2(double x, double y) native "Float64x2_fromDoubles"; - factory Float64x2.splat(double v) native "Float64x2_splat"; - factory Float64x2.zero() native "Float64x2_zero"; - factory Float64x2.fromFloat32x4(Float32x4 v) native "Float64x2_fromFloat32x4"; - - Float64x2 operator +(Float64x2 other) { - return _add(other); - } - Float64x2 _add(Float64x2 other) native "Float64x2_add"; - Float64x2 operator -() { - return _negate(); - } - Float64x2 _negate() native "Float64x2_negate"; - Float64x2 operator -(Float64x2 other) { - return _sub(other); - } - Float64x2 _sub(Float64x2 other) native "Float64x2_sub"; - Float64x2 operator *(Float64x2 other) { - return _mul(other); - } - Float64x2 _mul(Float64x2 other) native "Float64x2_mul"; - Float64x2 operator /(Float64x2 other) { - return _div(other); - } - Float64x2 _div(Float64x2 other) native "Float64x2_div"; - - - /// Returns a copy of [this] each lane being scaled by [s]. - Float64x2 scale(double s) native "Float64x2_scale"; - /// Returns the absolute value of this [Float64x2]. - Float64x2 abs() native "Float64x2_abs"; - - /// Clamps [this] to be in the range [lowerLimit]-[upperLimit]. - Float64x2 clamp(Float64x2 lowerLimit, - Float64x2 upperLimit) native "Float64x2_clamp"; - - /// Extracted x value. - double get x native "Float64x2_getX"; - /// Extracted y value. - double get y native "Float64x2_getY"; - - /// Extract the sign bits from each lane return them in the first 2 bits. - int get signMask native "Float64x2_getSignMask"; - - /// Returns a new [Float64x2] copied from [this] with a new x value. - Float64x2 withX(double x) native "Float64x2_setX"; - /// Returns a new [Float64x2] copied from [this] with a new y value. - Float64x2 withY(double y) native "Float64x2_setY"; - - /// Returns the lane-wise minimum value in [this] or [other]. - Float64x2 min(Float64x2 other) native "Float64x2_min"; - - /// Returns the lane-wise maximum value in [this] or [other]. - Float64x2 max(Float64x2 other) native "Float64x2_max"; - - /// Returns the lane-wise square root of [this]. - Float64x2 sqrt() native "Float64x2_sqrt"; -} - - - -class _TypedListIterator<E> implements Iterator<E> { - final List<E> _array; - final int _length; - int _position; - E _current; - - _TypedListIterator(List array) - : _array = array, _length = array.length, _position = -1 { - assert(array is _TypedList || array is _TypedListView); - } - - bool moveNext() { - int nextPosition = _position + 1; - if (nextPosition < _length) { - _current = _array[nextPosition]; - _position = nextPosition; - return true; - } - _position = _length; - _current = null; - return false; - } - - E get current => _current; -} - - -class _TypedListView extends _TypedListBase implements TypedData { - _TypedListView(ByteBuffer _buffer, int _offset, int _length) - : _typedData = _buffer._data, - offsetInBytes = _offset, - length = _length { - } - - // Method(s) implementing the TypedData interface. - - int get lengthInBytes { - return length * elementSizeInBytes; - } - - ByteBuffer get buffer { - return _typedData.buffer; - } - - final _TypedList _typedData; - final int offsetInBytes; - final int length; -} - - -class _Int8ArrayView extends _TypedListView with _IntListMixin implements Int8List { - // Constructor. - _Int8ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) - : super(buffer, _offsetInBytes, - _defaultIfNull(_length, - ((buffer.lengthInBytes - _offsetInBytes) ~/ - Int8List.BYTES_PER_ELEMENT))) { - _rangeCheck(buffer.lengthInBytes, - _offsetInBytes, - length * Int8List.BYTES_PER_ELEMENT); - } - - - // Method(s) implementing List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData._getInt8(offsetInBytes + - (index * Int8List.BYTES_PER_ELEMENT)); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setInt8(offsetInBytes + (index * Int8List.BYTES_PER_ELEMENT), - _toInt8(value)); - } - - - // Method(s) implementing TypedData interface. - - int get elementSizeInBytes { - return Int8List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Int8List _createList(int length) { - return new Int8List(length); - } -} - - -class _Uint8ArrayView extends _TypedListView with _IntListMixin implements Uint8List { - // Constructor. - _Uint8ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) - : super(buffer, _offsetInBytes, - _defaultIfNull(_length, - ((buffer.lengthInBytes - _offsetInBytes) ~/ - Uint8List.BYTES_PER_ELEMENT))) { - _rangeCheck(buffer.lengthInBytes, - _offsetInBytes, - length * Uint8List.BYTES_PER_ELEMENT); - } - - - // Method(s) implementing List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData._getUint8(offsetInBytes + - (index * Uint8List.BYTES_PER_ELEMENT)); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setUint8(offsetInBytes + (index * Uint8List.BYTES_PER_ELEMENT), - _toUint8(value)); - } - - - // Method(s) implementing TypedData interface. - - int get elementSizeInBytes { - return Uint8List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Uint8List _createList(int length) { - return new Uint8List(length); - } -} - - -class _Uint8ClampedArrayView extends _TypedListView with _IntListMixin implements Uint8ClampedList { - // Constructor. - _Uint8ClampedArrayView(ByteBuffer buffer, - [int _offsetInBytes = 0, int _length]) - : super(buffer, _offsetInBytes, - _defaultIfNull(_length, - ((buffer.lengthInBytes - _offsetInBytes) ~/ - Uint8List.BYTES_PER_ELEMENT))) { - _rangeCheck(buffer.lengthInBytes, - offsetInBytes, - length * Uint8List.BYTES_PER_ELEMENT); - } - - - // Method(s) implementing List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData._getUint8(offsetInBytes + - (index * Uint8List.BYTES_PER_ELEMENT)); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setUint8(offsetInBytes + (index * Uint8List.BYTES_PER_ELEMENT), - _toClampedUint8(value)); - } - - - // Method(s) implementing TypedData interface. - - int get elementSizeInBytes { - return Uint8List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Uint8ClampedList _createList(int length) { - return new Uint8ClampedList(length); - } -} - - -class _Int16ArrayView extends _TypedListView with _IntListMixin implements Int16List { - // Constructor. - _Int16ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) - : super(buffer, _offsetInBytes, - _defaultIfNull(_length, - ((buffer.lengthInBytes - _offsetInBytes) ~/ - Int16List.BYTES_PER_ELEMENT))) { - _rangeCheck(buffer.lengthInBytes, - offsetInBytes, - length * Int16List.BYTES_PER_ELEMENT); - _offsetAlignmentCheck(_offsetInBytes, Int16List.BYTES_PER_ELEMENT); - } - - - // Method(s) implementing List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData._getInt16(offsetInBytes + - (index * Int16List.BYTES_PER_ELEMENT)); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setInt16(offsetInBytes + (index * Int16List.BYTES_PER_ELEMENT), - _toInt16(value)); - } - - void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { - if (iterable is CodeUnits) { - end = RangeError.checkValidRange(start, end, this.length); - int length = end - start; - int byteStart = this.offsetInBytes + start * Int16List.BYTES_PER_ELEMENT; - _typedData._setCodeUnits(iterable, byteStart, length, skipCount); - } else { - super.setRange(start, end, iterable, skipCount); - } - } - - // Method(s) implementing TypedData interface. - - int get elementSizeInBytes { - return Int16List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Int16List _createList(int length) { - return new Int16List(length); - } -} - - -class _Uint16ArrayView extends _TypedListView with _IntListMixin implements Uint16List { - // Constructor. - _Uint16ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) - : super(buffer, _offsetInBytes, - _defaultIfNull(_length, - ((buffer.lengthInBytes - _offsetInBytes) ~/ - Uint16List.BYTES_PER_ELEMENT))) { - _rangeCheck(buffer.lengthInBytes, - offsetInBytes, - length * Uint16List.BYTES_PER_ELEMENT); - _offsetAlignmentCheck(_offsetInBytes, Uint16List.BYTES_PER_ELEMENT); - } - - - // Method(s) implementing List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData._getUint16(offsetInBytes + - (index * Uint16List.BYTES_PER_ELEMENT)); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setUint16(offsetInBytes + (index * Uint16List.BYTES_PER_ELEMENT), - _toUint16(value)); - } - - void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { - if (iterable is CodeUnits) { - end = RangeError.checkValidRange(start, end, this.length); - int length = end - start; - int byteStart = this.offsetInBytes + start * Uint16List.BYTES_PER_ELEMENT; - _typedData._setCodeUnits(iterable, byteStart, length, skipCount); - } else { - super.setRange(start, end, iterable, skipCount); - } - } - - // Method(s) implementing TypedData interface. - - int get elementSizeInBytes { - return Uint16List.BYTES_PER_ELEMENT; - } - - // Internal utility methods. - - Uint16List _createList(int length) { - return new Uint16List(length); - } -} - - -class _Int32ArrayView extends _TypedListView with _IntListMixin implements Int32List { - // Constructor. - _Int32ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) - : super(buffer, _offsetInBytes, - _defaultIfNull(_length, - ((buffer.lengthInBytes - _offsetInBytes) ~/ - Int32List.BYTES_PER_ELEMENT))) { - _rangeCheck(buffer.lengthInBytes, - offsetInBytes, - length * Int32List.BYTES_PER_ELEMENT); - _offsetAlignmentCheck(_offsetInBytes, Int32List.BYTES_PER_ELEMENT); - } - - - // Method(s) implementing List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData._getInt32(offsetInBytes + - (index * Int32List.BYTES_PER_ELEMENT)); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setInt32(offsetInBytes + (index * Int32List.BYTES_PER_ELEMENT), - _toInt32(value)); - } - - - // Method(s) implementing TypedData interface. - - int get elementSizeInBytes { - return Int32List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Int32List _createList(int length) { - return new Int32List(length); - } -} - - -class _Uint32ArrayView extends _TypedListView with _IntListMixin implements Uint32List { - // Constructor. - _Uint32ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) - : super(buffer, _offsetInBytes, - _defaultIfNull(_length, - ((buffer.lengthInBytes - _offsetInBytes) ~/ - Uint32List.BYTES_PER_ELEMENT))) { - _rangeCheck(buffer.lengthInBytes, - offsetInBytes, - length * Uint32List.BYTES_PER_ELEMENT); - _offsetAlignmentCheck(_offsetInBytes, Uint32List.BYTES_PER_ELEMENT); - } - - - // Method(s) implementing List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData._getUint32(offsetInBytes + - (index * Uint32List.BYTES_PER_ELEMENT)); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setUint32(offsetInBytes + (index * Uint32List.BYTES_PER_ELEMENT), - _toUint32(value)); - } - - - // Method(s) implementing TypedData interface. - - int get elementSizeInBytes { - return Uint32List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Uint32List _createList(int length) { - return new Uint32List(length); - } -} - - -class _Int64ArrayView extends _TypedListView with _IntListMixin implements Int64List { - // Constructor. - _Int64ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) - : super(buffer, _offsetInBytes, - _defaultIfNull(_length, - ((buffer.lengthInBytes - _offsetInBytes) ~/ - Int64List.BYTES_PER_ELEMENT))) { - _rangeCheck(buffer.lengthInBytes, - offsetInBytes, - length * Int64List.BYTES_PER_ELEMENT); - _offsetAlignmentCheck(_offsetInBytes, Int64List.BYTES_PER_ELEMENT); - } - - - // Method(s) implementing List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData._getInt64(offsetInBytes + - (index * Int64List.BYTES_PER_ELEMENT)); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setInt64(offsetInBytes + (index * Int64List.BYTES_PER_ELEMENT), - _toInt64(value)); - } - - - // Method(s) implementing TypedData interface. - - int get elementSizeInBytes { - return Int64List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Int64List _createList(int length) { - return new Int64List(length); - } -} - - -class _Uint64ArrayView extends _TypedListView with _IntListMixin implements Uint64List { - // Constructor. - _Uint64ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) - : super(buffer, _offsetInBytes, - _defaultIfNull(_length, - ((buffer.lengthInBytes - _offsetInBytes) ~/ - Uint64List.BYTES_PER_ELEMENT))) { - _rangeCheck(buffer.lengthInBytes, - offsetInBytes, - length * Uint64List.BYTES_PER_ELEMENT); - _offsetAlignmentCheck(_offsetInBytes, Uint64List.BYTES_PER_ELEMENT); - } - - - // Method(s) implementing List interface. - - int operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData._getUint64(offsetInBytes + - (index * Uint64List.BYTES_PER_ELEMENT)); - } - - void operator[]=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setUint64(offsetInBytes + (index * Uint64List.BYTES_PER_ELEMENT), - _toUint64(value)); - } - - - // Method(s) implementing TypedData interface. - - int get elementSizeInBytes { - return Uint64List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Uint64List _createList(int length) { - return new Uint64List(length); - } -} - - -class _Float32ArrayView extends _TypedListView with _DoubleListMixin implements Float32List { - // Constructor. - _Float32ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) - : super(buffer, _offsetInBytes, - _defaultIfNull(_length, - ((buffer.lengthInBytes - _offsetInBytes) ~/ - Float32List.BYTES_PER_ELEMENT))) { - _rangeCheck(buffer.lengthInBytes, - offsetInBytes, - length * Float32List.BYTES_PER_ELEMENT); - _offsetAlignmentCheck(_offsetInBytes, Float32List.BYTES_PER_ELEMENT); - } - - - // Method(s) implementing List interface. - - double operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData._getFloat32(offsetInBytes + - (index * Float32List.BYTES_PER_ELEMENT)); - } - - void operator[]=(int index, double value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setFloat32(offsetInBytes + - (index * Float32List.BYTES_PER_ELEMENT), value); - } - - - // Method(s) implementing TypedData interface. - - int get elementSizeInBytes { - return Float32List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Float32List _createList(int length) { - return new Float32List(length); - } -} - - -class _Float64ArrayView extends _TypedListView with _DoubleListMixin implements Float64List { - // Constructor. - _Float64ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) - : super(buffer, _offsetInBytes, - _defaultIfNull(_length, - ((buffer.lengthInBytes - _offsetInBytes) ~/ - Float64List.BYTES_PER_ELEMENT))) { - _rangeCheck(buffer.lengthInBytes, - offsetInBytes, - length * Float64List.BYTES_PER_ELEMENT); - _offsetAlignmentCheck(_offsetInBytes, Float64List.BYTES_PER_ELEMENT); - } - - - // Method(s) implementing List interface. - - double operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData._getFloat64(offsetInBytes + - (index * Float64List.BYTES_PER_ELEMENT)); - } - - void operator[]=(int index, double value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setFloat64(offsetInBytes + - (index * Float64List.BYTES_PER_ELEMENT), value); - } - - - // Method(s) implementing TypedData interface. - - int get elementSizeInBytes { - return Float64List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Float64List _createList(int length) { - return new Float64List(length); - } -} - - -class _Float32x4ArrayView extends _TypedListView with _Float32x4ListMixin implements Float32x4List { - // Constructor. - _Float32x4ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) - : super(buffer, _offsetInBytes, - _defaultIfNull(_length, - ((buffer.lengthInBytes - _offsetInBytes) ~/ - Float32x4List.BYTES_PER_ELEMENT))) { - _rangeCheck(buffer.lengthInBytes, - offsetInBytes, - length * Float32x4List.BYTES_PER_ELEMENT); - _offsetAlignmentCheck(_offsetInBytes, Float32x4List.BYTES_PER_ELEMENT); - } - - - // Method(s) implementing List interface. - - Float32x4 operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData._getFloat32x4(offsetInBytes + - (index * Float32x4List.BYTES_PER_ELEMENT)); - } - - void operator[]=(int index, Float32x4 value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setFloat32x4(offsetInBytes + - (index * Float32x4List.BYTES_PER_ELEMENT), value); - } - - - // Method(s) implementing TypedData interface. - - int get elementSizeInBytes { - return Float32x4List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Float32x4List _createList(int length) { - return new Float32x4List(length); - } -} - - -class _Int32x4ArrayView extends _TypedListView with _Int32x4ListMixin implements Int32x4List { - // Constructor. - _Int32x4ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) - : super(buffer, _offsetInBytes, - _defaultIfNull(_length, - ((buffer.lengthInBytes - _offsetInBytes) ~/ - Int32x4List.BYTES_PER_ELEMENT))) { - _rangeCheck(buffer.lengthInBytes, - offsetInBytes, - length * Int32x4List.BYTES_PER_ELEMENT); - _offsetAlignmentCheck(_offsetInBytes, Int32x4List.BYTES_PER_ELEMENT); - } - - - // Method(s) implementing List interface. - - Int32x4 operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData._getInt32x4(offsetInBytes + - (index * Int32x4List.BYTES_PER_ELEMENT)); - } - - void operator[]=(int index, Int32x4 value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setInt32x4(offsetInBytes + - (index * Int32x4List.BYTES_PER_ELEMENT), value); - } - - - // Method(s) implementing TypedData interface. - - int get elementSizeInBytes { - return Int32x4List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Int32x4List _createList(int length) { - return new Int32x4List(length); - } -} - - -class _Float64x2ArrayView extends _TypedListView with _Float64x2ListMixin implements Float64x2List { - // Constructor. - _Float64x2ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) - : super(buffer, _offsetInBytes, - _defaultIfNull(_length, - ((buffer.lengthInBytes - _offsetInBytes) ~/ - Float64x2List.BYTES_PER_ELEMENT))) { - _rangeCheck(buffer.lengthInBytes, - offsetInBytes, - length * Float64x2List.BYTES_PER_ELEMENT); - _offsetAlignmentCheck(_offsetInBytes, Float64x2List.BYTES_PER_ELEMENT); - } - - - // Method(s) implementing List interface. - - Float64x2 operator[](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData._getFloat64x2(offsetInBytes + - (index * Float64x2List.BYTES_PER_ELEMENT)); - } - - void operator[]=(int index, Float64x2 value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setFloat64x2(offsetInBytes + - (index * Float64x2List.BYTES_PER_ELEMENT), value); - } - - - // Method(s) implementing TypedData interface. - - int get elementSizeInBytes { - return Float64x2List.BYTES_PER_ELEMENT; - } - - - // Internal utility methods. - - Float64x2List _createList(int length) { - return new Float64x2List(length); - } -} - - -class _ByteDataView implements ByteData { - _ByteDataView(TypedData typedData, int _offsetInBytes, int _lengthInBytes) - : _typedData = typedData, - _offset = _offsetInBytes, - length = _lengthInBytes { - _rangeCheck(_typedData.lengthInBytes, _offset, length); - } - - - // Method(s) implementing TypedData interface. - - ByteBuffer get buffer { - return _typedData.buffer; - } - - int get lengthInBytes { - return length; - } - - int get offsetInBytes { - return _offset; - } - - int get elementSizeInBytes { - return 1; - } - - // Method(s) implementing ByteData interface. - - int getInt8(int byteOffset) { - if (byteOffset < 0 || byteOffset >= length) { - throw new RangeError.index(byteOffset, this, "byteOffset"); - } - return _typedData._getInt8(_offset + byteOffset); - } - void setInt8(int byteOffset, int value) { - if (byteOffset < 0 || byteOffset >= length) { - throw new RangeError.index(byteOffset, this, "byteOffset"); - } - _typedData._setInt8(_offset + byteOffset, value); - } - - int getUint8(int byteOffset) { - if (byteOffset < 0 || byteOffset >= length) { - throw new RangeError.index(byteOffset, this, "byteOffset"); - } - return _typedData._getUint8(_offset + byteOffset); - } - void setUint8(int byteOffset, int value) { - if (byteOffset < 0 || byteOffset >= length) { - throw new RangeError.index(byteOffset, this, "byteOffset"); - } - _typedData._setUint8(_offset + byteOffset, value); - } - - int getInt16(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) { - if (byteOffset < 0 || byteOffset + 1 >= length) { - throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset"); - } - var result = _typedData._getInt16(_offset + byteOffset); - if (identical(endian, Endianness.HOST_ENDIAN)) { - return result; - } - return _byteSwap16(result).toSigned(16); - } - void setInt16(int byteOffset, - int value, - [Endianness endian = Endianness.BIG_ENDIAN]) { - if (byteOffset < 0 || byteOffset + 1 >= length) { - throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset"); - } - _typedData._setInt16(_offset + byteOffset, - identical(endian, Endianness.HOST_ENDIAN) ? value : _byteSwap16(value)); - } - - int getUint16(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) { - if (byteOffset < 0 || byteOffset + 1 >= length) { - throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset"); - } - var result = _typedData._getUint16(_offset + byteOffset); - if (identical(endian, Endianness.HOST_ENDIAN)) { - return result; - } - return _byteSwap16(result); - } - void setUint16(int byteOffset, - int value, - [Endianness endian = Endianness.BIG_ENDIAN]) { - if (byteOffset < 0 || byteOffset + 1 >= length) { - throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset"); - } - _typedData._setUint16(_offset + byteOffset, - identical(endian, Endianness.HOST_ENDIAN) ? value : _byteSwap16(value)); - } - - int getInt32(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) { - if (byteOffset < 0 || byteOffset + 3 >= length) { - throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); - } - var result = _typedData._getInt32(_offset + byteOffset); - if (identical(endian, Endianness.HOST_ENDIAN)) { - return result; - } - return _byteSwap32(result).toSigned(32); - } - void setInt32(int byteOffset, - int value, - [Endianness endian = Endianness.BIG_ENDIAN]) { - if (byteOffset < 0 || byteOffset + 3 >= length) { - throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); - } - _typedData._setInt32(_offset + byteOffset, - identical(endian, Endianness.HOST_ENDIAN) ? value : _byteSwap32(value)); - } - - int getUint32(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) { - if (byteOffset < 0 || byteOffset + 3 >= length) { - throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); - } - var result = _typedData._getUint32(_offset + byteOffset); - if (identical(endian, Endianness.HOST_ENDIAN)) { - return result; - } - return _byteSwap32(result); - } - void setUint32(int byteOffset, - int value, - [Endianness endian = Endianness.BIG_ENDIAN]) { - if (byteOffset < 0 || byteOffset + 3 >= length) { - throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); - } - _typedData._setUint32(_offset + byteOffset, - identical(endian, Endianness.HOST_ENDIAN) ? value : _byteSwap32(value)); - } - - int getInt64(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) { - if (byteOffset < 0 || byteOffset + 7 >= length) { - throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset"); - } - var result = _typedData._getInt64(_offset + byteOffset); - if (identical(endian, Endianness.HOST_ENDIAN)) { - return result; - } - return _byteSwap64(result).toSigned(64); - } - void setInt64(int byteOffset, - int value, - [Endianness endian = Endianness.BIG_ENDIAN]) { - if (byteOffset < 0 || byteOffset + 7 >= length) { - throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset"); - } - _typedData._setInt64(_offset + byteOffset, - identical(endian, Endianness.HOST_ENDIAN) ? value : _byteSwap64(value)); - } - - int getUint64(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) { - if (byteOffset < 0 || byteOffset + 7 >= length) { - throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset"); - } - var result = _typedData._getUint64(_offset + byteOffset); - if (identical(endian, Endianness.HOST_ENDIAN)) { - return result; - } - return _byteSwap64(result); - } - void setUint64(int byteOffset, - int value, - [Endianness endian = Endianness.BIG_ENDIAN]) { - if (byteOffset < 0 || byteOffset + 7 >= length) { - throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset"); - } - _typedData._setUint64(_offset + byteOffset, - identical(endian, Endianness.HOST_ENDIAN) ? value : _byteSwap64(value)); - } - - double getFloat32(int byteOffset, - [Endianness endian = Endianness.BIG_ENDIAN]) { - if (byteOffset < 0 || byteOffset + 3 >= length) { - throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); - } - if (identical(endian, Endianness.HOST_ENDIAN)) { - return _typedData._getFloat32(_offset + byteOffset); - } - _convU32[0] = _byteSwap32(_typedData._getUint32(_offset + byteOffset)); - return _convF32[0]; - } - void setFloat32(int byteOffset, - double value, - [Endianness endian = Endianness.BIG_ENDIAN]) { - if (byteOffset < 0 || byteOffset + 3 >= length) { - throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); - } - if (identical(endian, Endianness.HOST_ENDIAN)) { - _typedData._setFloat32(_offset + byteOffset, value); - return; - } - _convF32[0] = value; - _typedData._setUint32(_offset + byteOffset, _byteSwap32(_convU32[0])); - } - - double getFloat64(int byteOffset, - [Endianness endian = Endianness.BIG_ENDIAN]) { - if (byteOffset < 0 || byteOffset + 7 >= length) { - throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset"); - } - if (identical(endian, Endianness.HOST_ENDIAN)) { - return _typedData._getFloat64(_offset + byteOffset); - } - _convU64[0] = _byteSwap64(_typedData._getUint64(_offset + byteOffset)); - return _convF64[0]; - } - void setFloat64(int byteOffset, - double value, - [Endianness endian = Endianness.BIG_ENDIAN]) { - if (byteOffset < 0 || byteOffset + 7 >= length) { - throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset"); - } - if (identical(endian, Endianness.HOST_ENDIAN)) { - _typedData._setFloat64(_offset + byteOffset, value); - return; - } - _convF64[0] = value; - _typedData._setUint64(_offset + byteOffset, _byteSwap64(_convU64[0])); - } - - Float32x4 getFloat32x4(int byteOffset, - [Endianness endian = Endianness.BIG_ENDIAN]) { - if (byteOffset < 0 || byteOffset + 3 >= length) { - throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); - } - // TODO(johnmccutchan) : Need to resolve this for endianity. - return _typedData._getFloat32x4(_offset + byteOffset); - } - void setFloat32x4(int byteOffset, - Float32x4 value, - [Endianness endian = Endianness.BIG_ENDIAN]) { - if (byteOffset < 0 || byteOffset + 3 >= length) { - throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); - } - // TODO(johnmccutchan) : Need to resolve this for endianity. - _typedData._setFloat32x4(_offset + byteOffset, value); - - } - - final TypedData _typedData; - final int _offset; - final int length; -} - -int _byteSwap16(int value) { - return ((value & 0xFF00) >> 8) | - ((value & 0x00FF) << 8); -} - -int _byteSwap32(int value) { - value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); - value = ((value & 0xFFFF0000) >> 16) | ((value & 0x0000FFFF) << 16); - return value; -} - -int _byteSwap64(int value) { - return (_byteSwap32(value) << 32) | _byteSwap32(value >> 32); -} - -final _convU32 = new Uint32List(2); -final _convU64 = new Uint64List.view(_convU32.buffer); -final _convF32 = new Float32List.view(_convU32.buffer); -final _convF64 = new Float64List.view(_convU32.buffer); - -// Top level utility methods. -int _toInt(int value, int mask) { - value &= mask; - if (value > (mask >> 1)) value -= mask + 1; - return value; -} - - -int _toInt8(int value) { - return _toInt(value, 0xFF); -} - - -int _toUint8(int value) { - return value & 0xFF; -} - - -int _toClampedUint8(int value) { - if (value < 0) return 0; - if (value > 0xFF) return 0xFF; - return value; -} - - -int _toInt16(int value) { - return _toInt(value, 0xFFFF); -} - - -int _toUint16(int value) { - return value & 0xFFFF; -} - - -int _toInt32(int value) { - return _toInt(value, 0xFFFFFFFF); -} - - -int _toUint32(int value) { - return value & 0xFFFFFFFF; -} - - -int _toInt64(int value) { - // Avoid bigint mask when possible. - return (ClassID.getID(value) == ClassID.cidBigint) ? - _toInt(value, 0xFFFFFFFFFFFFFFFF) : value; -} - - -int _toUint64(int value) { - // Avoid bigint mask when possible. - return (ClassID.getID(value) == ClassID.cidBigint) ? - _toInt(value, 0xFFFFFFFFFFFFFFFF) : value; -} - - -void _rangeCheck(int listLength, int start, int length) { - if (length < 0) { - throw new RangeError.value(length); - } - if (start < 0) { - throw new RangeError.value(start); - } - if (start + length > listLength) { - throw new RangeError.value(start + length); - } -} - - -void _offsetAlignmentCheck(int offset, int alignment) { - if ((offset % alignment) != 0) { - throw new RangeError('Offset ($offset) must be a multiple of ' - 'BYTES_PER_ELEMENT ($alignment)'); - } -} - - -int _defaultIfNull(object, value) { - if (object == null) { - return value; - } - return object; -}
diff --git a/runtime/lib/typed_data_patch.dart b/runtime/lib/typed_data_patch.dart new file mode 100644 index 0000000..6ad50f3 --- /dev/null +++ b/runtime/lib/typed_data_patch.dart
@@ -0,0 +1,3098 @@ +// Copyright (c) 2013, 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. + +import "dart:_internal"; +import "dart:collection" show ListBase; +import 'dart:math' show Random; + +@patch +class ByteData implements TypedData { + @patch + factory ByteData(int length) { + var list = new Uint8List(length); + return new _ByteDataView(list, 0, length); + } + + // Called directly from C code. + factory ByteData._view(TypedData typedData, int offsetInBytes, int length) { + return new _ByteDataView(typedData, offsetInBytes, length); + } +} + +// Based class for _TypedList that provides common methods for implementing +// the collection and list interfaces. +// This class does not extend ListBase<T> since that would add type arguments +// to instances of _TypeListBase. Instead the subclasses use type specific +// mixins (like _IntListMixin, _DoubleListMixin) to implement ListBase<T>. +abstract class _TypedListBase { + // Method(s) implementing the Collection interface. + bool contains(element) { + var len = this.length; + for (var i = 0; i < len; ++i) { + if (this[i] == element) return true; + } + return false; + } + + void forEach(void f(element)) { + var len = this.length; + for (var i = 0; i < len; i++) { + f(this[i]); + } + } + + String join([String separator = ""]) { + StringBuffer buffer = new StringBuffer(); + buffer.writeAll(this, separator); + return buffer.toString(); + } + + dynamic reduce(dynamic combine(value, element)) { + var len = this.length; + if (len == 0) throw IterableElementError.noElement(); + var i = 0; + var value = this[0]; + for (var i = 1; i < len; ++i) { + value = combine(value, this[i]); + } + return value; + } + + dynamic fold( + dynamic initialValue, dynamic combine(dynamic initialValue, element)) { + var len = this.length; + for (var i = 0; i < len; ++i) { + initialValue = combine(initialValue, this[i]); + } + return initialValue; + } + + Iterable map(f(element)) => new MappedIterable(this, f); + + Iterable expand(Iterable f(element)) => new ExpandIterable(this, f); + + bool every(bool f(element)) { + var len = this.length; + for (var i = 0; i < len; ++i) { + if (!f(this[i])) return false; + } + return true; + } + + bool any(bool f(element)) { + var len = this.length; + for (var i = 0; i < len; ++i) { + if (f(this[i])) return true; + } + return false; + } + + dynamic firstWhere(bool test(element), {orElse()}) { + var len = this.length; + for (var i = 0; i < len; ++i) { + var element = this[i]; + if (test(element)) return element; + } + if (orElse != null) return orElse(); + throw IterableElementError.noElement(); + } + + dynamic lastWhere(bool test(element), {orElse()}) { + var result = null; + var len = this.length; + for (var i = len - 1; i >= 0; --i) { + var element = this[i]; + if (test(element)) { + return element; + } + } + if (orElse != null) return orElse(); + throw IterableElementError.noElement(); + } + + dynamic singleWhere(bool test(element)) { + var result = null; + bool foundMatching = false; + var len = this.length; + for (var i = 0; i < len; ++i) { + var element = this[i]; + if (test(element)) { + if (foundMatching) { + throw IterableElementError.tooMany(); + } + result = element; + foundMatching = true; + } + } + if (foundMatching) return result; + throw IterableElementError.noElement(); + } + + dynamic elementAt(int index) { + return this[index]; + } + + bool get isEmpty { + return this.length == 0; + } + + bool get isNotEmpty => !isEmpty; + + // Method(s) implementing the List interface. + + set length(newLength) { + throw new UnsupportedError("Cannot resize a fixed-length list"); + } + + void add(value) { + throw new UnsupportedError("Cannot add to a fixed-length list"); + } + + void addAll(Iterable value) { + throw new UnsupportedError("Cannot add to a fixed-length list"); + } + + void insert(int index, value) { + throw new UnsupportedError("Cannot insert into a fixed-length list"); + } + + void insertAll(int index, Iterable values) { + throw new UnsupportedError("Cannot insert into a fixed-length list"); + } + + void sort([int compare(a, b)]) { + if (compare == null) compare = Comparable.compare; + Sort.sort(this, compare); + } + + void shuffle([Random random]) { + if (random == null) random = new Random(); + var i = this.length; + while (i > 1) { + int pos = random.nextInt(i); + i -= 1; + var tmp = this[i]; + this[i] = this[pos]; + this[pos] = tmp; + } + } + + int indexOf(element, [int start = 0]) { + return Lists.indexOf(this, element, start, this.length); + } + + int lastIndexOf(element, [int start = null]) { + if (start == null) start = this.length - 1; + return Lists.lastIndexOf(this, element, start); + } + + void clear() { + throw new UnsupportedError("Cannot remove from a fixed-length list"); + } + + int removeLast() { + throw new UnsupportedError("Cannot remove from a fixed-length list"); + } + + bool remove(Object element) { + throw new UnsupportedError("Cannot remove from a fixed-length list"); + } + + bool removeAt(int index) { + throw new UnsupportedError("Cannot remove from a fixed-length list"); + } + + void removeWhere(bool test(element)) { + throw new UnsupportedError("Cannot remove from a fixed-length list"); + } + + void retainWhere(bool test(element)) { + throw new UnsupportedError("Cannot remove from a fixed-length list"); + } + + dynamic get first { + if (length > 0) return this[0]; + throw IterableElementError.noElement(); + } + + dynamic get last { + if (length > 0) return this[length - 1]; + throw IterableElementError.noElement(); + } + + dynamic get single { + if (length == 1) return this[0]; + if (length == 0) throw IterableElementError.noElement(); + throw IterableElementError.tooMany(); + } + + void removeRange(int start, int end) { + throw new UnsupportedError("Cannot remove from a fixed-length list"); + } + + void replaceRange(int start, int end, Iterable iterable) { + throw new UnsupportedError("Cannot remove from a fixed-length list"); + } + + List toList({bool growable: true}) { + return new List.from(this, growable: growable); + } + + Set toSet() { + return new Set.from(this); + } + + List sublist(int start, [int end]) { + end = RangeError.checkValidRange(start, end, this.length); + var length = end - start; + List result = _createList(length); + result.setRange(0, length, this, start); + return result; + } + + void setRange(int start, int end, Iterable from, [int skipCount = 0]) { + // Check ranges. + if (0 > start || start > end || end > length) { + RangeError.checkValidRange(start, end, length); // Always throws. + assert(false); + } + if (skipCount < 0) { + throw new ArgumentError(skipCount); + } + + final count = end - start; + if ((from.length - skipCount) < count) { + throw IterableElementError.tooFew(); + } + + if (from is _TypedListBase) { + if (this.elementSizeInBytes == from.elementSizeInBytes) { + if ((count < 10) && (from.buffer != this.buffer)) { + Lists.copy(from, skipCount, this, start, count); + return; + } else if (this.buffer._data._setRange( + start * elementSizeInBytes + this.offsetInBytes, + count * elementSizeInBytes, + from.buffer._data, + skipCount * elementSizeInBytes + from.offsetInBytes, + ClassID.getID(this), + ClassID.getID(from))) { + return; + } + } else if (from.buffer == this.buffer) { + // Different element sizes, but same buffer means that we need + // an intermediate structure. + // TODO(srdjan): Optimize to skip copying if the range does not overlap. + final temp_buffer = new List(count); + for (var i = 0; i < count; i++) { + temp_buffer[i] = from[skipCount + i]; + } + for (var i = start; i < end; i++) { + this[i] = temp_buffer[i - start]; + } + return; + } + } + + if (count == 0) return; + List otherList; + int otherStart; + if (from is List) { + otherList = from; + otherStart = skipCount; + } else { + otherList = from.skip(skipCount).toList(growable: false); + otherStart = 0; + } + if (otherStart + count > otherList.length) { + throw IterableElementError.tooFew(); + } + Lists.copy(otherList, otherStart, this, start, count); + } + + void setAll(int index, Iterable iterable) { + final end = iterable.length + index; + setRange(index, end, iterable); + } + + void fillRange(int start, int end, [fillValue]) { + RangeError.checkValidRange(start, end, this.length); + for (var i = start; i < end; ++i) { + this[i] = fillValue; + } + } + + // Method(s) implementing Object interface. + String toString() => ListBase.listToString(this); + + // Internal utility methods. + + // Returns true if operation succeeds. + // 'fromCid' and 'toCid' may be cid-s of the views and therefore may not + // match the cids of 'this' and 'from'. + // Uses toCid and fromCid to decide if clamping is necessary. + // Element size of toCid and fromCid must match (test at caller). + bool _setRange(int startInBytes, int lengthInBytes, _TypedListBase from, + int startFromInBytes, int toCid, int fromCid) native "TypedData_setRange"; +} + +class _IntListMixin { + Iterable<int> where(bool f(int element)) => new WhereIterable<int>(this, f); + + Iterable<int> take(int n) => new SubListIterable<int>(this, 0, n); + + Iterable<int> takeWhile(bool test(int element)) => + new TakeWhileIterable<int>(this, test); + + Iterable<int> skip(int n) => new SubListIterable<int>(this, n, null); + + Iterable<int> skipWhile(bool test(element)) => + new SkipWhileIterable<int>(this, test); + + Iterable<int> get reversed => new ReversedListIterable<int>(this); + + Map<int, int> asMap() => new ListMapView<int>(this); + + Iterable<int> getRange(int start, [int end]) { + RangeError.checkValidRange(start, end, this.length); + return new SubListIterable<int>(this, start, end); + } + + Iterator<int> get iterator => new _TypedListIterator<int>(this); + + List<int> toList({bool growable: true}) { + return new List<int>.from(this, growable: growable); + } + + Set<int> toSet() { + return new Set<int>.from(this); + } +} + +class _DoubleListMixin { + Iterable<double> where(bool f(int element)) => + new WhereIterable<double>(this, f); + + Iterable<double> take(int n) => new SubListIterable<double>(this, 0, n); + + Iterable<double> takeWhile(bool test(int element)) => + new TakeWhileIterable<double>(this, test); + + Iterable<double> skip(int n) => new SubListIterable<double>(this, n, null); + + Iterable<double> skipWhile(bool test(element)) => + new SkipWhileIterable<double>(this, test); + + Iterable<double> get reversed => new ReversedListIterable<double>(this); + + Map<int, double> asMap() => new ListMapView<double>(this); + + Iterable<double> getRange(int start, [int end]) { + RangeError.checkValidRange(start, end, this.length); + return new SubListIterable<double>(this, start, end); + } + + Iterator<double> get iterator => new _TypedListIterator<double>(this); + + List<double> toList({bool growable: true}) { + return new List<double>.from(this, growable: growable); + } + + Set<double> toSet() { + return new Set<double>.from(this); + } +} + +class _Float32x4ListMixin { + Iterable<Float32x4> where(bool f(int element)) => + new WhereIterable<Float32x4>(this, f); + + Iterable<Float32x4> take(int n) => new SubListIterable<Float32x4>(this, 0, n); + + Iterable<Float32x4> takeWhile(bool test(int element)) => + new TakeWhileIterable<Float32x4>(this, test); + + Iterable<Float32x4> skip(int n) => + new SubListIterable<Float32x4>(this, n, null); + + Iterable<Float32x4> skipWhile(bool test(element)) => + new SkipWhileIterable<Float32x4>(this, test); + + Iterable<Float32x4> get reversed => new ReversedListIterable<Float32x4>(this); + + Map<int, Float32x4> asMap() => new ListMapView<Float32x4>(this); + + Iterable<Float32x4> getRange(int start, [int end]) { + RangeError.checkValidRange(start, end, this.length); + return new SubListIterable<Float32x4>(this, start, end); + } + + Iterator<Float32x4> get iterator => new _TypedListIterator<Float32x4>(this); + + List<Float32x4> toList({bool growable: true}) { + return new List<Float32x4>.from(this, growable: growable); + } + + Set<Float32x4> toSet() { + return new Set<Float32x4>.from(this); + } +} + +class _Int32x4ListMixin { + Iterable<Int32x4> where(bool f(int element)) => + new WhereIterable<Int32x4>(this, f); + + Iterable<Int32x4> take(int n) => new SubListIterable<Int32x4>(this, 0, n); + + Iterable<Int32x4> takeWhile(bool test(int element)) => + new TakeWhileIterable<Int32x4>(this, test); + + Iterable<Int32x4> skip(int n) => new SubListIterable<Int32x4>(this, n, null); + + Iterable<Int32x4> skipWhile(bool test(element)) => + new SkipWhileIterable<Int32x4>(this, test); + + Iterable<Int32x4> get reversed => new ReversedListIterable<Int32x4>(this); + + Map<int, Int32x4> asMap() => new ListMapView<Int32x4>(this); + + Iterable<Int32x4> getRange(int start, [int end]) { + RangeError.checkValidRange(start, end, this.length); + return new SubListIterable<Int32x4>(this, start, end); + } + + Iterator<Int32x4> get iterator => new _TypedListIterator<Int32x4>(this); + + List<Int32x4> toList({bool growable: true}) { + return new List<Int32x4>.from(this, growable: growable); + } + + Set<Int32x4> toSet() { + return new Set<Int32x4>.from(this); + } +} + +class _Float64x2ListMixin { + Iterable<Float64x2> where(bool f(int element)) => + new WhereIterable<Float64x2>(this, f); + + Iterable<Float64x2> take(int n) => new SubListIterable<Float64x2>(this, 0, n); + + Iterable<Float64x2> takeWhile(bool test(int element)) => + new TakeWhileIterable<Float64x2>(this, test); + + Iterable<Float64x2> skip(int n) => + new SubListIterable<Float64x2>(this, n, null); + + Iterable<Float64x2> skipWhile(bool test(element)) => + new SkipWhileIterable<Float64x2>(this, test); + + Iterable<Float64x2> get reversed => new ReversedListIterable<Float64x2>(this); + + Map<int, Float64x2> asMap() => new ListMapView<Float64x2>(this); + + Iterable<Float64x2> getRange(int start, [int end]) { + RangeError.checkValidRange(start, end, this.length); + return new SubListIterable<Float64x2>(this, start, end); + } + + Iterator<Float64x2> get iterator => new _TypedListIterator<Float64x2>(this); + + List<Float64x2> toList({bool growable: true}) { + return new List<Float64x2>.from(this, growable: growable); + } + + Set<Float64x2> toSet() { + return new Set<Float64x2>.from(this); + } +} + +class _ByteBuffer implements ByteBuffer { + final _TypedList _data; + + _ByteBuffer(this._data); + + factory _ByteBuffer._New(data) => new _ByteBuffer(data); + + // Forward calls to _data. + int get lengthInBytes => _data.lengthInBytes; + int get hashCode => _data.hashCode; + bool operator ==(Object other) => + (other is _ByteBuffer) && identical(_data, other._data); + + ByteData asByteData([int offsetInBytes = 0, int length]) { + if (length == null) { + length = this.lengthInBytes - offsetInBytes; + } + return new _ByteDataView(this._data, offsetInBytes, length); + } + + Int8List asInt8List([int offsetInBytes = 0, int length]) { + if (length == null) { + length = this.lengthInBytes - offsetInBytes; + } + return new _Int8ArrayView(this, offsetInBytes, length); + } + + Uint8List asUint8List([int offsetInBytes = 0, int length]) { + if (length == null) { + length = this.lengthInBytes - offsetInBytes; + } + return new _Uint8ArrayView(this, offsetInBytes, length); + } + + Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int length]) { + if (length == null) { + length = this.lengthInBytes - offsetInBytes; + } + return new _Uint8ClampedArrayView(this, offsetInBytes, length); + } + + Int16List asInt16List([int offsetInBytes = 0, int length]) { + if (length == null) { + length = + (this.lengthInBytes - offsetInBytes) ~/ Int16List.BYTES_PER_ELEMENT; + } + return new _Int16ArrayView(this, offsetInBytes, length); + } + + Uint16List asUint16List([int offsetInBytes = 0, int length]) { + if (length == null) { + length = + (this.lengthInBytes - offsetInBytes) ~/ Uint16List.BYTES_PER_ELEMENT; + } + return new _Uint16ArrayView(this, offsetInBytes, length); + } + + Int32List asInt32List([int offsetInBytes = 0, int length]) { + if (length == null) { + length = + (this.lengthInBytes - offsetInBytes) ~/ Int32List.BYTES_PER_ELEMENT; + } + return new _Int32ArrayView(this, offsetInBytes, length); + } + + Uint32List asUint32List([int offsetInBytes = 0, int length]) { + if (length == null) { + length = + (this.lengthInBytes - offsetInBytes) ~/ Uint32List.BYTES_PER_ELEMENT; + } + return new _Uint32ArrayView(this, offsetInBytes, length); + } + + Int64List asInt64List([int offsetInBytes = 0, int length]) { + if (length == null) { + length = + (this.lengthInBytes - offsetInBytes) ~/ Int64List.BYTES_PER_ELEMENT; + } + return new _Int64ArrayView(this, offsetInBytes, length); + } + + Uint64List asUint64List([int offsetInBytes = 0, int length]) { + if (length == null) { + length = + (this.lengthInBytes - offsetInBytes) ~/ Uint64List.BYTES_PER_ELEMENT; + } + return new _Uint64ArrayView(this, offsetInBytes, length); + } + + Float32List asFloat32List([int offsetInBytes = 0, int length]) { + if (length == null) { + length = + (this.lengthInBytes - offsetInBytes) ~/ Float32List.BYTES_PER_ELEMENT; + } + return new _Float32ArrayView(this, offsetInBytes, length); + } + + Float64List asFloat64List([int offsetInBytes = 0, int length]) { + if (length == null) { + length = + (this.lengthInBytes - offsetInBytes) ~/ Float64List.BYTES_PER_ELEMENT; + } + return new _Float64ArrayView(this, offsetInBytes, length); + } + + Float32x4List asFloat32x4List([int offsetInBytes = 0, int length]) { + if (length == null) { + length = (this.lengthInBytes - offsetInBytes) ~/ + Float32x4List.BYTES_PER_ELEMENT; + } + return new _Float32x4ArrayView(this, offsetInBytes, length); + } + + Int32x4List asInt32x4List([int offsetInBytes = 0, int length]) { + if (length == null) { + length = + (this.lengthInBytes - offsetInBytes) ~/ Int32x4List.BYTES_PER_ELEMENT; + } + return new _Int32x4ArrayView(this, offsetInBytes, length); + } + + Float64x2List asFloat64x2List([int offsetInBytes = 0, int length]) { + if (length == null) { + length = (this.lengthInBytes - offsetInBytes) ~/ + Float64x2List.BYTES_PER_ELEMENT; + } + return new _Float64x2ArrayView(this, offsetInBytes, length); + } +} + +abstract class _TypedList extends _TypedListBase { + // Default method implementing parts of the TypedData interface. + int get offsetInBytes { + return 0; + } + + int get lengthInBytes { + return length * elementSizeInBytes; + } + + _ByteBuffer get buffer => new _ByteBuffer(this); + + // Methods implementing the collection interface. + + int get length native "TypedData_length"; + + // Internal utility methods. + + int _getInt8(int offsetInBytes) native "TypedData_GetInt8"; + void _setInt8(int offsetInBytes, int value) native "TypedData_SetInt8"; + + int _getUint8(int offsetInBytes) native "TypedData_GetUint8"; + void _setUint8(int offsetInBytes, int value) native "TypedData_SetUint8"; + + int _getInt16(int offsetInBytes) native "TypedData_GetInt16"; + void _setInt16(int offsetInBytes, int value) native "TypedData_SetInt16"; + + int _getUint16(int offsetInBytes) native "TypedData_GetUint16"; + void _setUint16(int offsetInBytes, int value) native "TypedData_SetUint16"; + + int _getInt32(int offsetInBytes) native "TypedData_GetInt32"; + void _setInt32(int offsetInBytes, int value) native "TypedData_SetInt32"; + + int _getUint32(int offsetInBytes) native "TypedData_GetUint32"; + void _setUint32(int offsetInBytes, int value) native "TypedData_SetUint32"; + + int _getInt64(int offsetInBytes) native "TypedData_GetInt64"; + void _setInt64(int offsetInBytes, int value) native "TypedData_SetInt64"; + + int _getUint64(int offsetInBytes) native "TypedData_GetUint64"; + void _setUint64(int offsetInBytes, int value) native "TypedData_SetUint64"; + + double _getFloat32(int offsetInBytes) native "TypedData_GetFloat32"; + void _setFloat32(int offsetInBytes, double value) + native "TypedData_SetFloat32"; + + double _getFloat64(int offsetInBytes) native "TypedData_GetFloat64"; + void _setFloat64(int offsetInBytes, double value) + native "TypedData_SetFloat64"; + + Float32x4 _getFloat32x4(int offsetInBytes) native "TypedData_GetFloat32x4"; + void _setFloat32x4(int offsetInBytes, Float32x4 value) + native "TypedData_SetFloat32x4"; + + Int32x4 _getInt32x4(int offsetInBytes) native "TypedData_GetInt32x4"; + void _setInt32x4(int offsetInBytes, Int32x4 value) + native "TypedData_SetInt32x4"; + + Float64x2 _getFloat64x2(int offsetInBytes) native "TypedData_GetFloat64x2"; + void _setFloat64x2(int offsetInBytes, Float64x2 value) + native "TypedData_SetFloat64x2"; + + /** + * Stores the [CodeUnits] as UTF-16 units into this TypedData at + * positions [start]..[end] (uint16 indices). + */ + void _setCodeUnits( + CodeUnits units, int byteStart, int length, int skipCount) { + assert(byteStart + length * Uint16List.BYTES_PER_ELEMENT <= lengthInBytes); + String string = CodeUnits.stringOf(units); + int sliceEnd = skipCount + length; + RangeError.checkValidRange( + skipCount, sliceEnd, string.length, "skipCount", "skipCount + length"); + for (int i = 0; i < length; i++) { + _setUint16(byteStart + i * Uint16List.BYTES_PER_ELEMENT, + string.codeUnitAt(skipCount + i)); + } + } +} + +@patch +class Int8List { + @patch + factory Int8List(int length) native "TypedData_Int8Array_new"; + + @patch + factory Int8List.fromList(List<int> elements) { + return new Int8List(elements.length) + ..setRange(0, elements.length, elements); + } +} + +class _Int8List extends _TypedList with _IntListMixin implements Int8List { + Type get runtimeType => Int8List; + + // Method(s) implementing List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getInt8(index); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setInt8(index, _toInt8(value)); + } + + // Method(s) implementing TypedData interface. + int get elementSizeInBytes { + return Int8List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Int8List _createList(int length) { + return new Int8List(length); + } +} + +@patch +class Uint8List { + @patch + factory Uint8List(int length) native "TypedData_Uint8Array_new"; + + @patch + factory Uint8List.fromList(List<int> elements) { + return new Uint8List(elements.length) + ..setRange(0, elements.length, elements); + } +} + +class _Uint8List extends _TypedList with _IntListMixin implements Uint8List { + Type get runtimeType => Uint8List; + + // Methods implementing List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getUint8(index); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setUint8(index, _toUint8(value)); + } + + // Methods implementing TypedData interface. + int get elementSizeInBytes { + return Uint8List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Uint8List _createList(int length) { + return new Uint8List(length); + } +} + +@patch +class Uint8ClampedList { + @patch + factory Uint8ClampedList(int length) native "TypedData_Uint8ClampedArray_new"; + + @patch + factory Uint8ClampedList.fromList(List<int> elements) { + return new Uint8ClampedList(elements.length) + ..setRange(0, elements.length, elements); + } +} + +class _Uint8ClampedList extends _TypedList + with _IntListMixin + implements Uint8ClampedList { + Type get runtimeType => Uint8ClampedList; + + // Methods implementing List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getUint8(index); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setUint8(index, _toClampedUint8(value)); + } + + // Methods implementing TypedData interface. + int get elementSizeInBytes { + return Uint8List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Uint8ClampedList _createList(int length) { + return new Uint8ClampedList(length); + } +} + +@patch +class Int16List { + @patch + factory Int16List(int length) native "TypedData_Int16Array_new"; + + @patch + factory Int16List.fromList(List<int> elements) { + return new Int16List(elements.length) + ..setRange(0, elements.length, elements); + } +} + +class _Int16List extends _TypedList with _IntListMixin implements Int16List { + Type get runtimeType => Int16List; + + // Method(s) implementing List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedInt16(index); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedInt16(index, _toInt16(value)); + } + + void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { + if (iterable is CodeUnits) { + end = RangeError.checkValidRange(start, end, this.length); + int length = end - start; + int byteStart = this.offsetInBytes + start * Int16List.BYTES_PER_ELEMENT; + _setCodeUnits(iterable, byteStart, length, skipCount); + } else { + super.setRange(start, end, iterable, skipCount); + } + } + + // Method(s) implementing TypedData interface. + int get elementSizeInBytes { + return Int16List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Int16List _createList(int length) { + return new Int16List(length); + } + + int _getIndexedInt16(int index) { + return _getInt16(index * Int16List.BYTES_PER_ELEMENT); + } + + void _setIndexedInt16(int index, int value) { + _setInt16(index * Int16List.BYTES_PER_ELEMENT, value); + } +} + +@patch +class Uint16List { + @patch + factory Uint16List(int length) native "TypedData_Uint16Array_new"; + + @patch + factory Uint16List.fromList(List<int> elements) { + return new Uint16List(elements.length) + ..setRange(0, elements.length, elements); + } +} + +class _Uint16List extends _TypedList with _IntListMixin implements Uint16List { + Type get runtimeType => Uint16List; + + // Method(s) implementing the List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedUint16(index); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedUint16(index, _toUint16(value)); + } + + void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { + if (iterable is CodeUnits) { + end = RangeError.checkValidRange(start, end, this.length); + int length = end - start; + int byteStart = this.offsetInBytes + start * Uint16List.BYTES_PER_ELEMENT; + _setCodeUnits(iterable, byteStart, length, skipCount); + } else { + super.setRange(start, end, iterable, skipCount); + } + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Uint16List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Uint16List _createList(int length) { + return new Uint16List(length); + } + + int _getIndexedUint16(int index) { + return _getUint16(index * Uint16List.BYTES_PER_ELEMENT); + } + + void _setIndexedUint16(int index, int value) { + _setUint16(index * Uint16List.BYTES_PER_ELEMENT, value); + } +} + +@patch +class Int32List { + @patch + factory Int32List(int length) native "TypedData_Int32Array_new"; + + @patch + factory Int32List.fromList(List<int> elements) { + return new Int32List(elements.length) + ..setRange(0, elements.length, elements); + } +} + +class _Int32List extends _TypedList with _IntListMixin implements Int32List { + Type get runtimeType => Int32List; + + // Method(s) implementing the List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedInt32(index); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedInt32(index, _toInt32(value)); + } + + // Method(s) implementing TypedData interface. + int get elementSizeInBytes { + return Int32List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Int32List _createList(int length) { + return new Int32List(length); + } + + int _getIndexedInt32(int index) { + return _getInt32(index * Int32List.BYTES_PER_ELEMENT); + } + + void _setIndexedInt32(int index, int value) { + _setInt32(index * Int32List.BYTES_PER_ELEMENT, value); + } +} + +@patch +class Uint32List { + @patch + factory Uint32List(int length) native "TypedData_Uint32Array_new"; + + @patch + factory Uint32List.fromList(List<int> elements) { + return new Uint32List(elements.length) + ..setRange(0, elements.length, elements); + } +} + +class _Uint32List extends _TypedList with _IntListMixin implements Uint32List { + Type get runtimeType => Uint32List; + + // Method(s) implementing the List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedUint32(index); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedUint32(index, _toUint32(value)); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Uint32List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Uint32List _createList(int length) { + return new Uint32List(length); + } + + int _getIndexedUint32(int index) { + return _getUint32(index * Uint32List.BYTES_PER_ELEMENT); + } + + void _setIndexedUint32(int index, int value) { + _setUint32(index * Uint32List.BYTES_PER_ELEMENT, value); + } +} + +@patch +class Int64List { + @patch + factory Int64List(int length) native "TypedData_Int64Array_new"; + + @patch + factory Int64List.fromList(List<int> elements) { + return new Int64List(elements.length) + ..setRange(0, elements.length, elements); + } +} + +class _Int64List extends _TypedList with _IntListMixin implements Int64List { + Type get runtimeType => Int64List; + + // Method(s) implementing the List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedInt64(index); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedInt64(index, _toInt64(value)); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Int64List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Int64List _createList(int length) { + return new Int64List(length); + } + + int _getIndexedInt64(int index) { + return _getInt64(index * Int64List.BYTES_PER_ELEMENT); + } + + void _setIndexedInt64(int index, int value) { + _setInt64(index * Int64List.BYTES_PER_ELEMENT, value); + } +} + +@patch +class Uint64List { + @patch + factory Uint64List(int length) native "TypedData_Uint64Array_new"; + + @patch + factory Uint64List.fromList(List<int> elements) { + return new Uint64List(elements.length) + ..setRange(0, elements.length, elements); + } +} + +class _Uint64List extends _TypedList with _IntListMixin implements Uint64List { + Type get runtimeType => Uint64List; + + // Method(s) implementing the List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedUint64(index); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedUint64(index, _toUint64(value)); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Uint64List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Uint64List _createList(int length) { + return new Uint64List(length); + } + + int _getIndexedUint64(int index) { + return _getUint64(index * Uint64List.BYTES_PER_ELEMENT); + } + + void _setIndexedUint64(int index, int value) { + _setUint64(index * Uint64List.BYTES_PER_ELEMENT, value); + } +} + +@patch +class Float32List { + @patch + factory Float32List(int length) native "TypedData_Float32Array_new"; + + @patch + factory Float32List.fromList(List<double> elements) { + return new Float32List(elements.length) + ..setRange(0, elements.length, elements); + } +} + +class _Float32List extends _TypedList + with _DoubleListMixin + implements Float32List { + Type get runtimeType => Float32List; + + // Method(s) implementing the List interface. + double operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedFloat32(index); + } + + void operator []=(int index, double value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedFloat32(index, value); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Float32List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Float32List _createList(int length) { + return new Float32List(length); + } + + double _getIndexedFloat32(int index) { + return _getFloat32(index * Float32List.BYTES_PER_ELEMENT); + } + + void _setIndexedFloat32(int index, double value) { + _setFloat32(index * Float32List.BYTES_PER_ELEMENT, value); + } +} + +@patch +class Float64List { + @patch + factory Float64List(int length) native "TypedData_Float64Array_new"; + + @patch + factory Float64List.fromList(List<double> elements) { + return new Float64List(elements.length) + ..setRange(0, elements.length, elements); + } +} + +class _Float64List extends _TypedList + with _DoubleListMixin + implements Float64List { + Type get runtimeType => Float64List; + + // Method(s) implementing the List interface. + double operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedFloat64(index); + } + + void operator []=(int index, double value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedFloat64(index, value); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Float64List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Float64List _createList(int length) { + return new Float64List(length); + } + + double _getIndexedFloat64(int index) { + return _getFloat64(index * Float64List.BYTES_PER_ELEMENT); + } + + void _setIndexedFloat64(int index, double value) { + _setFloat64(index * Float64List.BYTES_PER_ELEMENT, value); + } +} + +@patch +class Float32x4List { + @patch + factory Float32x4List(int length) native "TypedData_Float32x4Array_new"; + + @patch + factory Float32x4List.fromList(List<Float32x4> elements) { + return new Float32x4List(elements.length) + ..setRange(0, elements.length, elements); + } +} + +class _Float32x4List extends _TypedList + with _Float32x4ListMixin + implements Float32x4List { + Type get runtimeType => Float32x4List; + + Float32x4 operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedFloat32x4(index); + } + + void operator []=(int index, Float32x4 value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedFloat32x4(index, value); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Float32x4List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Float32x4List _createList(int length) { + return new Float32x4List(length); + } + + Float32x4 _getIndexedFloat32x4(int index) { + return _getFloat32x4(index * Float32x4List.BYTES_PER_ELEMENT); + } + + void _setIndexedFloat32x4(int index, Float32x4 value) { + _setFloat32x4(index * Float32x4List.BYTES_PER_ELEMENT, value); + } +} + +@patch +class Int32x4List { + @patch + factory Int32x4List(int length) native "TypedData_Int32x4Array_new"; + + @patch + factory Int32x4List.fromList(List<Int32x4> elements) { + return new Int32x4List(elements.length) + ..setRange(0, elements.length, elements); + } +} + +class _Int32x4List extends _TypedList + with _Int32x4ListMixin + implements Int32x4List { + Type get runtimeType => Int32x4List; + + Int32x4 operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedInt32x4(index); + } + + void operator []=(int index, Int32x4 value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedInt32x4(index, value); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Int32x4List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Int32x4List _createList(int length) { + return new Int32x4List(length); + } + + Int32x4 _getIndexedInt32x4(int index) { + return _getInt32x4(index * Int32x4List.BYTES_PER_ELEMENT); + } + + void _setIndexedInt32x4(int index, Int32x4 value) { + _setInt32x4(index * Int32x4List.BYTES_PER_ELEMENT, value); + } +} + +@patch +class Float64x2List { + @patch + factory Float64x2List(int length) native "TypedData_Float64x2Array_new"; + + @patch + factory Float64x2List.fromList(List<Float64x2> elements) { + return new Float64x2List(elements.length) + ..setRange(0, elements.length, elements); + } +} + +class _Float64x2List extends _TypedList + with _Float64x2ListMixin + implements Float64x2List { + Type get runtimeType => Float64x2List; + + Float64x2 operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedFloat64x2(index); + } + + void operator []=(int index, Float64x2 value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedFloat64x2(index, value); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Float64x2List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Float64x2List _createList(int length) { + return new Float64x2List(length); + } + + Float64x2 _getIndexedFloat64x2(int index) { + return _getFloat64x2(index * Float64x2List.BYTES_PER_ELEMENT); + } + + void _setIndexedFloat64x2(int index, Float64x2 value) { + _setFloat64x2(index * Float64x2List.BYTES_PER_ELEMENT, value); + } +} + +class _ExternalInt8Array extends _TypedList + with _IntListMixin + implements Int8List { + // Method(s) implementing the List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getInt8(index); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setInt8(index, value); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Int8List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Int8List _createList(int length) { + return new Int8List(length); + } +} + +class _ExternalUint8Array extends _TypedList + with _IntListMixin + implements Uint8List { + // Method(s) implementing the List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getUint8(index); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setUint8(index, _toUint8(value)); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Uint8List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Uint8List _createList(int length) { + return new Uint8List(length); + } +} + +class _ExternalUint8ClampedArray extends _TypedList + with _IntListMixin + implements Uint8ClampedList { + // Method(s) implementing the List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getUint8(index); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setUint8(index, _toClampedUint8(value)); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Uint8List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Uint8ClampedList _createList(int length) { + return new Uint8ClampedList(length); + } +} + +class _ExternalInt16Array extends _TypedList + with _IntListMixin + implements Int16List { + // Method(s) implementing the List interface. + + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedInt16(index); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedInt16(index, _toInt16(value)); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Int16List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Int16List _createList(int length) { + return new Int16List(length); + } + + int _getIndexedInt16(int index) { + return _getInt16(index * Int16List.BYTES_PER_ELEMENT); + } + + void _setIndexedInt16(int index, int value) { + _setInt16(index * Int16List.BYTES_PER_ELEMENT, value); + } +} + +class _ExternalUint16Array extends _TypedList + with _IntListMixin + implements Uint16List { + // Method(s) implementing the List interface. + + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedUint16(index); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedUint16(index, _toUint16(value)); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Uint16List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Uint16List _createList(int length) { + return new Uint16List(length); + } + + int _getIndexedUint16(int index) { + return _getUint16(index * Uint16List.BYTES_PER_ELEMENT); + } + + void _setIndexedUint16(int index, int value) { + _setUint16(index * Uint16List.BYTES_PER_ELEMENT, value); + } +} + +class _ExternalInt32Array extends _TypedList + with _IntListMixin + implements Int32List { + // Method(s) implementing the List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedInt32(index); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedInt32(index, _toInt32(value)); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Int32List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Int32List _createList(int length) { + return new Int32List(length); + } + + int _getIndexedInt32(int index) { + return _getInt32(index * Int32List.BYTES_PER_ELEMENT); + } + + void _setIndexedInt32(int index, int value) { + _setInt32(index * Int32List.BYTES_PER_ELEMENT, value); + } +} + +class _ExternalUint32Array extends _TypedList + with _IntListMixin + implements Uint32List { + // Method(s) implementing the List interface. + + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedUint32(index); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedUint32(index, _toUint32(value)); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Uint32List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Uint32List _createList(int length) { + return new Uint32List(length); + } + + int _getIndexedUint32(int index) { + return _getUint32(index * Uint32List.BYTES_PER_ELEMENT); + } + + void _setIndexedUint32(int index, int value) { + _setUint32(index * Uint32List.BYTES_PER_ELEMENT, value); + } +} + +class _ExternalInt64Array extends _TypedList + with _IntListMixin + implements Int64List { + // Method(s) implementing the List interface. + + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedInt64(index); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedInt64(index, _toInt64(value)); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Int64List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Int64List _createList(int length) { + return new Int64List(length); + } + + int _getIndexedInt64(int index) { + return _getInt64(index * Int64List.BYTES_PER_ELEMENT); + } + + void _setIndexedInt64(int index, int value) { + _setInt64(index * Int64List.BYTES_PER_ELEMENT, value); + } +} + +class _ExternalUint64Array extends _TypedList + with _IntListMixin + implements Uint64List { + // Method(s) implementing the List interface. + + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedUint64(index); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedUint64(index, _toUint64(value)); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Uint64List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Uint64List _createList(int length) { + return new Uint64List(length); + } + + int _getIndexedUint64(int index) { + return _getUint64(index * Uint64List.BYTES_PER_ELEMENT); + } + + void _setIndexedUint64(int index, int value) { + _setUint64(index * Uint64List.BYTES_PER_ELEMENT, value); + } +} + +class _ExternalFloat32Array extends _TypedList + with _DoubleListMixin + implements Float32List { + // Method(s) implementing the List interface. + + double operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedFloat32(index); + } + + void operator []=(int index, double value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedFloat32(index, value); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Float32List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Float32List _createList(int length) { + return new Float32List(length); + } + + double _getIndexedFloat32(int index) { + return _getFloat32(index * Float32List.BYTES_PER_ELEMENT); + } + + void _setIndexedFloat32(int index, double value) { + _setFloat32(index * Float32List.BYTES_PER_ELEMENT, value); + } +} + +class _ExternalFloat64Array extends _TypedList + with _DoubleListMixin + implements Float64List { + // Method(s) implementing the List interface. + + double operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedFloat64(index); + } + + void operator []=(int index, double value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedFloat64(index, value); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Float64List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Float64List _createList(int length) { + return new Float64List(length); + } + + double _getIndexedFloat64(int index) { + return _getFloat64(index * Float64List.BYTES_PER_ELEMENT); + } + + void _setIndexedFloat64(int index, double value) { + _setFloat64(index * Float64List.BYTES_PER_ELEMENT, value); + } +} + +class _ExternalFloat32x4Array extends _TypedList + with _Float32x4ListMixin + implements Float32x4List { + // Method(s) implementing the List interface. + + Float32x4 operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedFloat32x4(index); + } + + void operator []=(int index, Float32x4 value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedFloat32x4(index, value); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Float32x4List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Float32x4List _createList(int length) { + return new Float32x4List(length); + } + + Float32x4 _getIndexedFloat32x4(int index) { + return _getFloat32x4(index * Float32x4List.BYTES_PER_ELEMENT); + } + + void _setIndexedFloat32x4(int index, Float32x4 value) { + _setFloat32x4(index * Float32x4List.BYTES_PER_ELEMENT, value); + } +} + +class _ExternalInt32x4Array extends _TypedList + with _Int32x4ListMixin + implements Int32x4List { + // Method(s) implementing the List interface. + + Int32x4 operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedInt32x4(index); + } + + void operator []=(int index, Int32x4 value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedInt32x4(index, value); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Int32x4List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Int32x4List _createList(int length) { + return new Int32x4List(length); + } + + Int32x4 _getIndexedInt32x4(int index) { + return _getInt32x4(index * Int32x4List.BYTES_PER_ELEMENT); + } + + void _setIndexedInt32x4(int index, Int32x4 value) { + _setInt32x4(index * Int32x4List.BYTES_PER_ELEMENT, value); + } +} + +class _ExternalFloat64x2Array extends _TypedList + with _Float64x2ListMixin + implements Float64x2List { + // Method(s) implementing the List interface. + Float64x2 operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _getIndexedFloat64x2(index); + } + + void operator []=(int index, Float64x2 value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _setIndexedFloat64x2(index, value); + } + + // Method(s) implementing the TypedData interface. + int get elementSizeInBytes { + return Float64x2List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Float64x2List _createList(int length) { + return new Float64x2List(length); + } + + Float64x2 _getIndexedFloat64x2(int index) { + return _getFloat64x2(index * Float64x2List.BYTES_PER_ELEMENT); + } + + void _setIndexedFloat64x2(int index, Float64x2 value) { + _setFloat64x2(index * Float64x2List.BYTES_PER_ELEMENT, value); + } +} + +@patch +class Float32x4 { + @patch + factory Float32x4(double x, double y, double z, double w) + native "Float32x4_fromDoubles"; + + @patch + factory Float32x4.splat(double v) native "Float32x4_splat"; + + @patch + factory Float32x4.zero() native "Float32x4_zero"; + + @patch + factory Float32x4.fromInt32x4Bits(Int32x4 x) + native "Float32x4_fromInt32x4Bits"; + + @patch + factory Float32x4.fromFloat64x2(Float64x2 v) native "Float32x4_fromFloat64x2"; +} + +class _Float32x4 implements Float32x4 { + Float32x4 operator +(Float32x4 other) native "Float32x4_add"; + Float32x4 operator -() native "Float32x4_negate"; + Float32x4 operator -(Float32x4 other) native "Float32x4_sub"; + Float32x4 operator *(Float32x4 other) native "Float32x4_mul"; + Float32x4 operator /(Float32x4 other) native "Float32x4_div"; + Int32x4 lessThan(Float32x4 other) native "Float32x4_cmplt"; + Int32x4 lessThanOrEqual(Float32x4 other) native "Float32x4_cmplte"; + Int32x4 greaterThan(Float32x4 other) native "Float32x4_cmpgt"; + Int32x4 greaterThanOrEqual(Float32x4 other) native "Float32x4_cmpgte"; + Int32x4 equal(Float32x4 other) native "Float32x4_cmpequal"; + Int32x4 notEqual(Float32x4 other) native "Float32x4_cmpnequal"; + Float32x4 scale(double s) native "Float32x4_scale"; + Float32x4 abs() native "Float32x4_abs"; + Float32x4 clamp(Float32x4 lowerLimit, Float32x4 upperLimit) + native "Float32x4_clamp"; + double get x native "Float32x4_getX"; + double get y native "Float32x4_getY"; + double get z native "Float32x4_getZ"; + double get w native "Float32x4_getW"; + int get signMask native "Float32x4_getSignMask"; + + Float32x4 shuffle(int mask) native "Float32x4_shuffle"; + Float32x4 shuffleMix(Float32x4 zw, int mask) native "Float32x4_shuffleMix"; + + Float32x4 withX(double x) native "Float32x4_setX"; + Float32x4 withY(double y) native "Float32x4_setY"; + Float32x4 withZ(double z) native "Float32x4_setZ"; + Float32x4 withW(double w) native "Float32x4_setW"; + Float32x4 min(Float32x4 other) native "Float32x4_min"; + Float32x4 max(Float32x4 other) native "Float32x4_max"; + Float32x4 sqrt() native "Float32x4_sqrt"; + Float32x4 reciprocal() native "Float32x4_reciprocal"; + Float32x4 reciprocalSqrt() native "Float32x4_reciprocalSqrt"; +} + +@patch +class Int32x4 { + @patch + factory Int32x4(int x, int y, int z, int w) native "Int32x4_fromInts"; + + @patch + factory Int32x4.bool(bool x, bool y, bool z, bool w) + native "Int32x4_fromBools"; + + @patch + factory Int32x4.fromFloat32x4Bits(Float32x4 x) + native "Int32x4_fromFloat32x4Bits"; +} + +class _Int32x4 implements Int32x4 { + Int32x4 operator |(Int32x4 other) native "Int32x4_or"; + Int32x4 operator &(Int32x4 other) native "Int32x4_and"; + Int32x4 operator ^(Int32x4 other) native "Int32x4_xor"; + Int32x4 operator +(Int32x4 other) native "Int32x4_add"; + Int32x4 operator -(Int32x4 other) native "Int32x4_sub"; + int get x native "Int32x4_getX"; + int get y native "Int32x4_getY"; + int get z native "Int32x4_getZ"; + int get w native "Int32x4_getW"; + int get signMask native "Int32x4_getSignMask"; + Int32x4 shuffle(int mask) native "Int32x4_shuffle"; + Int32x4 shuffleMix(Int32x4 zw, int mask) native "Int32x4_shuffleMix"; + Int32x4 withX(int x) native "Int32x4_setX"; + Int32x4 withY(int y) native "Int32x4_setY"; + Int32x4 withZ(int z) native "Int32x4_setZ"; + Int32x4 withW(int w) native "Int32x4_setW"; + bool get flagX native "Int32x4_getFlagX"; + bool get flagY native "Int32x4_getFlagY"; + bool get flagZ native "Int32x4_getFlagZ"; + bool get flagW native "Int32x4_getFlagW"; + Int32x4 withFlagX(bool x) native "Int32x4_setFlagX"; + Int32x4 withFlagY(bool y) native "Int32x4_setFlagY"; + Int32x4 withFlagZ(bool z) native "Int32x4_setFlagZ"; + Int32x4 withFlagW(bool w) native "Int32x4_setFlagW"; + Float32x4 select(Float32x4 trueValue, Float32x4 falseValue) + native "Int32x4_select"; +} + +@patch +class Float64x2 { + @patch + factory Float64x2(double x, double y) native "Float64x2_fromDoubles"; + + @patch + factory Float64x2.splat(double v) native "Float64x2_splat"; + + @patch + factory Float64x2.zero() native "Float64x2_zero"; + + @patch + factory Float64x2.fromFloat32x4(Float32x4 v) native "Float64x2_fromFloat32x4"; +} + +class _Float64x2 implements Float64x2 { + Float64x2 operator +(Float64x2 other) native "Float64x2_add"; + Float64x2 operator -() native "Float64x2_negate"; + Float64x2 operator -(Float64x2 other) native "Float64x2_sub"; + Float64x2 operator *(Float64x2 other) native "Float64x2_mul"; + Float64x2 operator /(Float64x2 other) native "Float64x2_div"; + Float64x2 scale(double s) native "Float64x2_scale"; + Float64x2 abs() native "Float64x2_abs"; + Float64x2 clamp(Float64x2 lowerLimit, Float64x2 upperLimit) + native "Float64x2_clamp"; + double get x native "Float64x2_getX"; + double get y native "Float64x2_getY"; + int get signMask native "Float64x2_getSignMask"; + Float64x2 withX(double x) native "Float64x2_setX"; + Float64x2 withY(double y) native "Float64x2_setY"; + Float64x2 min(Float64x2 other) native "Float64x2_min"; + Float64x2 max(Float64x2 other) native "Float64x2_max"; + Float64x2 sqrt() native "Float64x2_sqrt"; +} + +class _TypedListIterator<E> implements Iterator<E> { + final List<E> _array; + final int _length; + int _position; + E _current; + + _TypedListIterator(List array) + : _array = array, + _length = array.length, + _position = -1 { + assert(array is _TypedList || array is _TypedListView); + } + + bool moveNext() { + int nextPosition = _position + 1; + if (nextPosition < _length) { + _current = _array[nextPosition]; + _position = nextPosition; + return true; + } + _position = _length; + _current = null; + return false; + } + + E get current => _current; +} + +class _TypedListView extends _TypedListBase implements TypedData { + _TypedListView(_ByteBuffer _buffer, int _offset, int _length) + : _typedData = _buffer._data, + offsetInBytes = _offset, + length = _length {} + + // Method(s) implementing the TypedData interface. + + int get lengthInBytes { + return length * elementSizeInBytes; + } + + _ByteBuffer get buffer { + return _typedData.buffer; + } + + final _TypedList _typedData; + final int offsetInBytes; + final int length; +} + +class _Int8ArrayView extends _TypedListView + with _IntListMixin + implements Int8List { + // Constructor. + _Int8ArrayView(_ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) + : super( + buffer, + _offsetInBytes, + _defaultIfNull( + _length, + ((buffer.lengthInBytes - _offsetInBytes) ~/ + Int8List.BYTES_PER_ELEMENT))) { + _rangeCheck(buffer.lengthInBytes, _offsetInBytes, + length * Int8List.BYTES_PER_ELEMENT); + } + + // Method(s) implementing List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _typedData + ._getInt8(offsetInBytes + (index * Int8List.BYTES_PER_ELEMENT)); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _typedData._setInt8( + offsetInBytes + (index * Int8List.BYTES_PER_ELEMENT), _toInt8(value)); + } + + // Method(s) implementing TypedData interface. + int get elementSizeInBytes { + return Int8List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Int8List _createList(int length) { + return new Int8List(length); + } +} + +class _Uint8ArrayView extends _TypedListView + with _IntListMixin + implements Uint8List { + // Constructor. + _Uint8ArrayView(_ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) + : super( + buffer, + _offsetInBytes, + _defaultIfNull( + _length, + ((buffer.lengthInBytes - _offsetInBytes) ~/ + Uint8List.BYTES_PER_ELEMENT))) { + _rangeCheck(buffer.lengthInBytes, _offsetInBytes, + length * Uint8List.BYTES_PER_ELEMENT); + } + + // Method(s) implementing List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _typedData + ._getUint8(offsetInBytes + (index * Uint8List.BYTES_PER_ELEMENT)); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _typedData._setUint8( + offsetInBytes + (index * Uint8List.BYTES_PER_ELEMENT), _toUint8(value)); + } + + // Method(s) implementing TypedData interface. + int get elementSizeInBytes { + return Uint8List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Uint8List _createList(int length) { + return new Uint8List(length); + } +} + +class _Uint8ClampedArrayView extends _TypedListView + with _IntListMixin + implements Uint8ClampedList { + // Constructor. + _Uint8ClampedArrayView(_ByteBuffer buffer, + [int _offsetInBytes = 0, int _length]) + : super( + buffer, + _offsetInBytes, + _defaultIfNull( + _length, + ((buffer.lengthInBytes - _offsetInBytes) ~/ + Uint8List.BYTES_PER_ELEMENT))) { + _rangeCheck(buffer.lengthInBytes, offsetInBytes, + length * Uint8List.BYTES_PER_ELEMENT); + } + + // Method(s) implementing List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _typedData + ._getUint8(offsetInBytes + (index * Uint8List.BYTES_PER_ELEMENT)); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _typedData._setUint8(offsetInBytes + (index * Uint8List.BYTES_PER_ELEMENT), + _toClampedUint8(value)); + } + + // Method(s) implementing TypedData interface. + int get elementSizeInBytes { + return Uint8List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Uint8ClampedList _createList(int length) { + return new Uint8ClampedList(length); + } +} + +class _Int16ArrayView extends _TypedListView + with _IntListMixin + implements Int16List { + // Constructor. + _Int16ArrayView(_ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) + : super( + buffer, + _offsetInBytes, + _defaultIfNull( + _length, + ((buffer.lengthInBytes - _offsetInBytes) ~/ + Int16List.BYTES_PER_ELEMENT))) { + _rangeCheck(buffer.lengthInBytes, offsetInBytes, + length * Int16List.BYTES_PER_ELEMENT); + _offsetAlignmentCheck(_offsetInBytes, Int16List.BYTES_PER_ELEMENT); + } + + // Method(s) implementing List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _typedData + ._getInt16(offsetInBytes + (index * Int16List.BYTES_PER_ELEMENT)); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _typedData._setInt16( + offsetInBytes + (index * Int16List.BYTES_PER_ELEMENT), _toInt16(value)); + } + + void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { + if (iterable is CodeUnits) { + end = RangeError.checkValidRange(start, end, this.length); + int length = end - start; + int byteStart = this.offsetInBytes + start * Int16List.BYTES_PER_ELEMENT; + _typedData._setCodeUnits(iterable, byteStart, length, skipCount); + } else { + super.setRange(start, end, iterable, skipCount); + } + } + + // Method(s) implementing TypedData interface. + + int get elementSizeInBytes { + return Int16List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Int16List _createList(int length) { + return new Int16List(length); + } +} + +class _Uint16ArrayView extends _TypedListView + with _IntListMixin + implements Uint16List { + // Constructor. + _Uint16ArrayView(_ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) + : super( + buffer, + _offsetInBytes, + _defaultIfNull( + _length, + ((buffer.lengthInBytes - _offsetInBytes) ~/ + Uint16List.BYTES_PER_ELEMENT))) { + _rangeCheck(buffer.lengthInBytes, offsetInBytes, + length * Uint16List.BYTES_PER_ELEMENT); + _offsetAlignmentCheck(_offsetInBytes, Uint16List.BYTES_PER_ELEMENT); + } + + // Method(s) implementing List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _typedData + ._getUint16(offsetInBytes + (index * Uint16List.BYTES_PER_ELEMENT)); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _typedData._setUint16( + offsetInBytes + (index * Uint16List.BYTES_PER_ELEMENT), + _toUint16(value)); + } + + void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { + if (iterable is CodeUnits) { + end = RangeError.checkValidRange(start, end, this.length); + int length = end - start; + int byteStart = this.offsetInBytes + start * Uint16List.BYTES_PER_ELEMENT; + _typedData._setCodeUnits(iterable, byteStart, length, skipCount); + } else { + super.setRange(start, end, iterable, skipCount); + } + } + + // Method(s) implementing TypedData interface. + + int get elementSizeInBytes { + return Uint16List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + + Uint16List _createList(int length) { + return new Uint16List(length); + } +} + +class _Int32ArrayView extends _TypedListView + with _IntListMixin + implements Int32List { + // Constructor. + _Int32ArrayView(_ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) + : super( + buffer, + _offsetInBytes, + _defaultIfNull( + _length, + ((buffer.lengthInBytes - _offsetInBytes) ~/ + Int32List.BYTES_PER_ELEMENT))) { + _rangeCheck(buffer.lengthInBytes, offsetInBytes, + length * Int32List.BYTES_PER_ELEMENT); + _offsetAlignmentCheck(_offsetInBytes, Int32List.BYTES_PER_ELEMENT); + } + + // Method(s) implementing List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _typedData + ._getInt32(offsetInBytes + (index * Int32List.BYTES_PER_ELEMENT)); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _typedData._setInt32( + offsetInBytes + (index * Int32List.BYTES_PER_ELEMENT), _toInt32(value)); + } + + // Method(s) implementing TypedData interface. + int get elementSizeInBytes { + return Int32List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Int32List _createList(int length) { + return new Int32List(length); + } +} + +class _Uint32ArrayView extends _TypedListView + with _IntListMixin + implements Uint32List { + // Constructor. + _Uint32ArrayView(_ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) + : super( + buffer, + _offsetInBytes, + _defaultIfNull( + _length, + ((buffer.lengthInBytes - _offsetInBytes) ~/ + Uint32List.BYTES_PER_ELEMENT))) { + _rangeCheck(buffer.lengthInBytes, offsetInBytes, + length * Uint32List.BYTES_PER_ELEMENT); + _offsetAlignmentCheck(_offsetInBytes, Uint32List.BYTES_PER_ELEMENT); + } + + // Method(s) implementing List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _typedData + ._getUint32(offsetInBytes + (index * Uint32List.BYTES_PER_ELEMENT)); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _typedData._setUint32( + offsetInBytes + (index * Uint32List.BYTES_PER_ELEMENT), + _toUint32(value)); + } + + // Method(s) implementing TypedData interface. + int get elementSizeInBytes { + return Uint32List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Uint32List _createList(int length) { + return new Uint32List(length); + } +} + +class _Int64ArrayView extends _TypedListView + with _IntListMixin + implements Int64List { + // Constructor. + _Int64ArrayView(_ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) + : super( + buffer, + _offsetInBytes, + _defaultIfNull( + _length, + ((buffer.lengthInBytes - _offsetInBytes) ~/ + Int64List.BYTES_PER_ELEMENT))) { + _rangeCheck(buffer.lengthInBytes, offsetInBytes, + length * Int64List.BYTES_PER_ELEMENT); + _offsetAlignmentCheck(_offsetInBytes, Int64List.BYTES_PER_ELEMENT); + } + + // Method(s) implementing List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _typedData + ._getInt64(offsetInBytes + (index * Int64List.BYTES_PER_ELEMENT)); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _typedData._setInt64( + offsetInBytes + (index * Int64List.BYTES_PER_ELEMENT), _toInt64(value)); + } + + // Method(s) implementing TypedData interface. + int get elementSizeInBytes { + return Int64List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Int64List _createList(int length) { + return new Int64List(length); + } +} + +class _Uint64ArrayView extends _TypedListView + with _IntListMixin + implements Uint64List { + // Constructor. + _Uint64ArrayView(_ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) + : super( + buffer, + _offsetInBytes, + _defaultIfNull( + _length, + ((buffer.lengthInBytes - _offsetInBytes) ~/ + Uint64List.BYTES_PER_ELEMENT))) { + _rangeCheck(buffer.lengthInBytes, offsetInBytes, + length * Uint64List.BYTES_PER_ELEMENT); + _offsetAlignmentCheck(_offsetInBytes, Uint64List.BYTES_PER_ELEMENT); + } + + // Method(s) implementing List interface. + int operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _typedData + ._getUint64(offsetInBytes + (index * Uint64List.BYTES_PER_ELEMENT)); + } + + void operator []=(int index, int value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _typedData._setUint64( + offsetInBytes + (index * Uint64List.BYTES_PER_ELEMENT), + _toUint64(value)); + } + + // Method(s) implementing TypedData interface. + int get elementSizeInBytes { + return Uint64List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Uint64List _createList(int length) { + return new Uint64List(length); + } +} + +class _Float32ArrayView extends _TypedListView + with _DoubleListMixin + implements Float32List { + // Constructor. + _Float32ArrayView(_ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) + : super( + buffer, + _offsetInBytes, + _defaultIfNull( + _length, + ((buffer.lengthInBytes - _offsetInBytes) ~/ + Float32List.BYTES_PER_ELEMENT))) { + _rangeCheck(buffer.lengthInBytes, offsetInBytes, + length * Float32List.BYTES_PER_ELEMENT); + _offsetAlignmentCheck(_offsetInBytes, Float32List.BYTES_PER_ELEMENT); + } + + // Method(s) implementing List interface. + double operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _typedData + ._getFloat32(offsetInBytes + (index * Float32List.BYTES_PER_ELEMENT)); + } + + void operator []=(int index, double value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _typedData._setFloat32( + offsetInBytes + (index * Float32List.BYTES_PER_ELEMENT), value); + } + + // Method(s) implementing TypedData interface. + int get elementSizeInBytes { + return Float32List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Float32List _createList(int length) { + return new Float32List(length); + } +} + +class _Float64ArrayView extends _TypedListView + with _DoubleListMixin + implements Float64List { + // Constructor. + _Float64ArrayView(_ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) + : super( + buffer, + _offsetInBytes, + _defaultIfNull( + _length, + ((buffer.lengthInBytes - _offsetInBytes) ~/ + Float64List.BYTES_PER_ELEMENT))) { + _rangeCheck(buffer.lengthInBytes, offsetInBytes, + length * Float64List.BYTES_PER_ELEMENT); + _offsetAlignmentCheck(_offsetInBytes, Float64List.BYTES_PER_ELEMENT); + } + + // Method(s) implementing List interface. + double operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _typedData + ._getFloat64(offsetInBytes + (index * Float64List.BYTES_PER_ELEMENT)); + } + + void operator []=(int index, double value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _typedData._setFloat64( + offsetInBytes + (index * Float64List.BYTES_PER_ELEMENT), value); + } + + // Method(s) implementing TypedData interface. + int get elementSizeInBytes { + return Float64List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Float64List _createList(int length) { + return new Float64List(length); + } +} + +class _Float32x4ArrayView extends _TypedListView + with _Float32x4ListMixin + implements Float32x4List { + // Constructor. + _Float32x4ArrayView(_ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) + : super( + buffer, + _offsetInBytes, + _defaultIfNull( + _length, + ((buffer.lengthInBytes - _offsetInBytes) ~/ + Float32x4List.BYTES_PER_ELEMENT))) { + _rangeCheck(buffer.lengthInBytes, offsetInBytes, + length * Float32x4List.BYTES_PER_ELEMENT); + _offsetAlignmentCheck(_offsetInBytes, Float32x4List.BYTES_PER_ELEMENT); + } + + // Method(s) implementing List interface. + Float32x4 operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _typedData._getFloat32x4( + offsetInBytes + (index * Float32x4List.BYTES_PER_ELEMENT)); + } + + void operator []=(int index, Float32x4 value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _typedData._setFloat32x4( + offsetInBytes + (index * Float32x4List.BYTES_PER_ELEMENT), value); + } + + // Method(s) implementing TypedData interface. + int get elementSizeInBytes { + return Float32x4List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Float32x4List _createList(int length) { + return new Float32x4List(length); + } +} + +class _Int32x4ArrayView extends _TypedListView + with _Int32x4ListMixin + implements Int32x4List { + // Constructor. + _Int32x4ArrayView(_ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) + : super( + buffer, + _offsetInBytes, + _defaultIfNull( + _length, + ((buffer.lengthInBytes - _offsetInBytes) ~/ + Int32x4List.BYTES_PER_ELEMENT))) { + _rangeCheck(buffer.lengthInBytes, offsetInBytes, + length * Int32x4List.BYTES_PER_ELEMENT); + _offsetAlignmentCheck(_offsetInBytes, Int32x4List.BYTES_PER_ELEMENT); + } + + // Method(s) implementing List interface. + Int32x4 operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _typedData + ._getInt32x4(offsetInBytes + (index * Int32x4List.BYTES_PER_ELEMENT)); + } + + void operator []=(int index, Int32x4 value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _typedData._setInt32x4( + offsetInBytes + (index * Int32x4List.BYTES_PER_ELEMENT), value); + } + + // Method(s) implementing TypedData interface. + int get elementSizeInBytes { + return Int32x4List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Int32x4List _createList(int length) { + return new Int32x4List(length); + } +} + +class _Float64x2ArrayView extends _TypedListView + with _Float64x2ListMixin + implements Float64x2List { + // Constructor. + _Float64x2ArrayView(_ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) + : super( + buffer, + _offsetInBytes, + _defaultIfNull( + _length, + ((buffer.lengthInBytes - _offsetInBytes) ~/ + Float64x2List.BYTES_PER_ELEMENT))) { + _rangeCheck(buffer.lengthInBytes, offsetInBytes, + length * Float64x2List.BYTES_PER_ELEMENT); + _offsetAlignmentCheck(_offsetInBytes, Float64x2List.BYTES_PER_ELEMENT); + } + + // Method(s) implementing List interface. + Float64x2 operator [](int index) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + return _typedData._getFloat64x2( + offsetInBytes + (index * Float64x2List.BYTES_PER_ELEMENT)); + } + + void operator []=(int index, Float64x2 value) { + if (index < 0 || index >= length) { + throw new RangeError.index(index, this, "index"); + } + _typedData._setFloat64x2( + offsetInBytes + (index * Float64x2List.BYTES_PER_ELEMENT), value); + } + + // Method(s) implementing TypedData interface. + int get elementSizeInBytes { + return Float64x2List.BYTES_PER_ELEMENT; + } + + // Internal utility methods. + Float64x2List _createList(int length) { + return new Float64x2List(length); + } +} + +class _ByteDataView implements ByteData { + _ByteDataView(TypedData typedData, int _offsetInBytes, int _lengthInBytes) + : _typedData = typedData, + _offset = _offsetInBytes, + length = _lengthInBytes { + _rangeCheck(_typedData.lengthInBytes, _offset, length); + } + + // Method(s) implementing TypedData interface. + _ByteBuffer get buffer { + return _typedData.buffer; + } + + int get lengthInBytes { + return length; + } + + int get offsetInBytes { + return _offset; + } + + int get elementSizeInBytes { + return 1; + } + + // Method(s) implementing ByteData interface. + + int getInt8(int byteOffset) { + if (byteOffset < 0 || byteOffset >= length) { + throw new RangeError.index(byteOffset, this, "byteOffset"); + } + return _typedData._getInt8(_offset + byteOffset); + } + + void setInt8(int byteOffset, int value) { + if (byteOffset < 0 || byteOffset >= length) { + throw new RangeError.index(byteOffset, this, "byteOffset"); + } + _typedData._setInt8(_offset + byteOffset, value); + } + + int getUint8(int byteOffset) { + if (byteOffset < 0 || byteOffset >= length) { + throw new RangeError.index(byteOffset, this, "byteOffset"); + } + return _typedData._getUint8(_offset + byteOffset); + } + + void setUint8(int byteOffset, int value) { + if (byteOffset < 0 || byteOffset >= length) { + throw new RangeError.index(byteOffset, this, "byteOffset"); + } + _typedData._setUint8(_offset + byteOffset, value); + } + + int getInt16(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) { + if (byteOffset < 0 || byteOffset + 1 >= length) { + throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset"); + } + var result = _typedData._getInt16(_offset + byteOffset); + if (identical(endian, Endianness.HOST_ENDIAN)) { + return result; + } + return _byteSwap16(result).toSigned(16); + } + + void setInt16(int byteOffset, int value, + [Endianness endian = Endianness.BIG_ENDIAN]) { + if (byteOffset < 0 || byteOffset + 1 >= length) { + throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset"); + } + _typedData._setInt16(_offset + byteOffset, + identical(endian, Endianness.HOST_ENDIAN) ? value : _byteSwap16(value)); + } + + int getUint16(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) { + if (byteOffset < 0 || byteOffset + 1 >= length) { + throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset"); + } + var result = _typedData._getUint16(_offset + byteOffset); + if (identical(endian, Endianness.HOST_ENDIAN)) { + return result; + } + return _byteSwap16(result); + } + + void setUint16(int byteOffset, int value, + [Endianness endian = Endianness.BIG_ENDIAN]) { + if (byteOffset < 0 || byteOffset + 1 >= length) { + throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset"); + } + _typedData._setUint16(_offset + byteOffset, + identical(endian, Endianness.HOST_ENDIAN) ? value : _byteSwap16(value)); + } + + int getInt32(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) { + if (byteOffset < 0 || byteOffset + 3 >= length) { + throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); + } + var result = _typedData._getInt32(_offset + byteOffset); + if (identical(endian, Endianness.HOST_ENDIAN)) { + return result; + } + return _byteSwap32(result).toSigned(32); + } + + void setInt32(int byteOffset, int value, + [Endianness endian = Endianness.BIG_ENDIAN]) { + if (byteOffset < 0 || byteOffset + 3 >= length) { + throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); + } + _typedData._setInt32(_offset + byteOffset, + identical(endian, Endianness.HOST_ENDIAN) ? value : _byteSwap32(value)); + } + + int getUint32(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) { + if (byteOffset < 0 || byteOffset + 3 >= length) { + throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); + } + var result = _typedData._getUint32(_offset + byteOffset); + if (identical(endian, Endianness.HOST_ENDIAN)) { + return result; + } + return _byteSwap32(result); + } + + void setUint32(int byteOffset, int value, + [Endianness endian = Endianness.BIG_ENDIAN]) { + if (byteOffset < 0 || byteOffset + 3 >= length) { + throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); + } + _typedData._setUint32(_offset + byteOffset, + identical(endian, Endianness.HOST_ENDIAN) ? value : _byteSwap32(value)); + } + + int getInt64(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) { + if (byteOffset < 0 || byteOffset + 7 >= length) { + throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset"); + } + var result = _typedData._getInt64(_offset + byteOffset); + if (identical(endian, Endianness.HOST_ENDIAN)) { + return result; + } + return _byteSwap64(result).toSigned(64); + } + + void setInt64(int byteOffset, int value, + [Endianness endian = Endianness.BIG_ENDIAN]) { + if (byteOffset < 0 || byteOffset + 7 >= length) { + throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset"); + } + _typedData._setInt64(_offset + byteOffset, + identical(endian, Endianness.HOST_ENDIAN) ? value : _byteSwap64(value)); + } + + int getUint64(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) { + if (byteOffset < 0 || byteOffset + 7 >= length) { + throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset"); + } + var result = _typedData._getUint64(_offset + byteOffset); + if (identical(endian, Endianness.HOST_ENDIAN)) { + return result; + } + return _byteSwap64(result); + } + + void setUint64(int byteOffset, int value, + [Endianness endian = Endianness.BIG_ENDIAN]) { + if (byteOffset < 0 || byteOffset + 7 >= length) { + throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset"); + } + _typedData._setUint64(_offset + byteOffset, + identical(endian, Endianness.HOST_ENDIAN) ? value : _byteSwap64(value)); + } + + double getFloat32(int byteOffset, + [Endianness endian = Endianness.BIG_ENDIAN]) { + if (byteOffset < 0 || byteOffset + 3 >= length) { + throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); + } + if (identical(endian, Endianness.HOST_ENDIAN)) { + return _typedData._getFloat32(_offset + byteOffset); + } + _convU32[0] = _byteSwap32(_typedData._getUint32(_offset + byteOffset)); + return _convF32[0]; + } + + void setFloat32(int byteOffset, double value, + [Endianness endian = Endianness.BIG_ENDIAN]) { + if (byteOffset < 0 || byteOffset + 3 >= length) { + throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); + } + if (identical(endian, Endianness.HOST_ENDIAN)) { + _typedData._setFloat32(_offset + byteOffset, value); + return; + } + _convF32[0] = value; + _typedData._setUint32(_offset + byteOffset, _byteSwap32(_convU32[0])); + } + + double getFloat64(int byteOffset, + [Endianness endian = Endianness.BIG_ENDIAN]) { + if (byteOffset < 0 || byteOffset + 7 >= length) { + throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset"); + } + if (identical(endian, Endianness.HOST_ENDIAN)) { + return _typedData._getFloat64(_offset + byteOffset); + } + _convU64[0] = _byteSwap64(_typedData._getUint64(_offset + byteOffset)); + return _convF64[0]; + } + + void setFloat64(int byteOffset, double value, + [Endianness endian = Endianness.BIG_ENDIAN]) { + if (byteOffset < 0 || byteOffset + 7 >= length) { + throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset"); + } + if (identical(endian, Endianness.HOST_ENDIAN)) { + _typedData._setFloat64(_offset + byteOffset, value); + return; + } + _convF64[0] = value; + _typedData._setUint64(_offset + byteOffset, _byteSwap64(_convU64[0])); + } + + Float32x4 getFloat32x4(int byteOffset, + [Endianness endian = Endianness.BIG_ENDIAN]) { + if (byteOffset < 0 || byteOffset + 3 >= length) { + throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); + } + // TODO(johnmccutchan) : Need to resolve this for endianity. + return _typedData._getFloat32x4(_offset + byteOffset); + } + + void setFloat32x4(int byteOffset, Float32x4 value, + [Endianness endian = Endianness.BIG_ENDIAN]) { + if (byteOffset < 0 || byteOffset + 3 >= length) { + throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); + } + // TODO(johnmccutchan) : Need to resolve this for endianity. + _typedData._setFloat32x4(_offset + byteOffset, value); + } + + final TypedData _typedData; + final int _offset; + final int length; +} + +int _byteSwap16(int value) { + return ((value & 0xFF00) >> 8) | ((value & 0x00FF) << 8); +} + +int _byteSwap32(int value) { + value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); + value = ((value & 0xFFFF0000) >> 16) | ((value & 0x0000FFFF) << 16); + return value; +} + +int _byteSwap64(int value) { + return (_byteSwap32(value) << 32) | _byteSwap32(value >> 32); +} + +final _convU32 = new Uint32List(2); +final _convU64 = new Uint64List.view(_convU32.buffer); +final _convF32 = new Float32List.view(_convU32.buffer); +final _convF64 = new Float64List.view(_convU32.buffer); + +// Top level utility methods. +int _toInt(int value, int mask) { + value &= mask; + if (value > (mask >> 1)) value -= mask + 1; + return value; +} + +int _toInt8(int value) { + return _toInt(value, 0xFF); +} + +int _toUint8(int value) { + return value & 0xFF; +} + +int _toClampedUint8(int value) { + if (value < 0) return 0; + if (value > 0xFF) return 0xFF; + return value; +} + +int _toInt16(int value) { + return _toInt(value, 0xFFFF); +} + +int _toUint16(int value) { + return value & 0xFFFF; +} + +int _toInt32(int value) { + return _toInt(value, 0xFFFFFFFF); +} + +int _toUint32(int value) { + return value & 0xFFFFFFFF; +} + +int _toInt64(int value) { + // Avoid bigint mask when possible. + return (ClassID.getID(value) == ClassID.cidBigint) + ? _toInt(value, 0xFFFFFFFFFFFFFFFF) + : value; +} + +int _toUint64(int value) { + // Avoid bigint mask when possible. + return (ClassID.getID(value) == ClassID.cidBigint) + ? _toInt(value, 0xFFFFFFFFFFFFFFFF) + : value; +} + +void _rangeCheck(int listLength, int start, int length) { + if (length < 0) { + throw new RangeError.value(length); + } + if (start < 0) { + throw new RangeError.value(start); + } + if (start + length > listLength) { + throw new RangeError.value(start + length); + } +} + +void _offsetAlignmentCheck(int offset, int alignment) { + if ((offset % alignment) != 0) { + throw new RangeError('Offset ($offset) must be a multiple of ' + 'BYTES_PER_ELEMENT ($alignment)'); + } +} + +int _defaultIfNull(object, value) { + if (object == null) { + return value; + } + return object; +}
diff --git a/runtime/lib/typed_data_sources.gypi b/runtime/lib/typed_data_sources.gypi index 28d6a53..d68daed 100644 --- a/runtime/lib/typed_data_sources.gypi +++ b/runtime/lib/typed_data_sources.gypi
@@ -7,8 +7,7 @@ { 'sources': [ 'typed_data.cc', - 'typed_data.dart', + 'typed_data_patch.dart', 'simd128.cc', ], } -
diff --git a/runtime/observatory/lib/src/elements/css/shared.css b/runtime/observatory/lib/src/elements/css/shared.css index 717ad46..4e6e480 100644 --- a/runtime/observatory/lib/src/elements/css/shared.css +++ b/runtime/observatory/lib/src/elements/css/shared.css
@@ -283,6 +283,12 @@ flex-basis: 90%; } +.indent { + margin-left: 1.5em; + font: 400 14px 'Montserrat', sans-serif; + line-height: 150%; +} + .well { min-height: 20px; padding: 19px;
diff --git a/runtime/observatory/lib/src/elements/isolate_view.dart b/runtime/observatory/lib/src/elements/isolate_view.dart index 73fde1a..ef157c0 100644 --- a/runtime/observatory/lib/src/elements/isolate_view.dart +++ b/runtime/observatory/lib/src/elements/isolate_view.dart
@@ -27,6 +27,7 @@ import 'package:observatory/src/elements/script_inset.dart'; import 'package:observatory/src/elements/source_inset.dart'; import 'package:observatory/src/elements/view_footer.dart'; +import 'package:observatory/utils.dart'; class IsolateViewElement extends HtmlElement implements Renderable { static const tag = @@ -133,6 +134,7 @@ void render() { final uptime = new DateTime.now().difference(_isolate.startTime); final libraries = _isolate.libraries.toList(); + final List<Thread> threads = _isolate.threads; children = [ navBar([ new NavTopMenuElement(queue: _r.queue), @@ -294,6 +296,20 @@ ]) .toList() ] + ], + new DivElement() + ..classes = ['memberItem'] + ..children = [ + new DivElement() + ..classes = ['memberName'] + ..text = 'threads (${threads.length})', + new DivElement() + ..classes = ['memberValue'] + ..children = [ + new CurlyBlockElement(queue: _r.queue) + ..content = threads + .map(_populateThreadInfo) + ] ] ], new HRElement(), @@ -314,6 +330,67 @@ ]; } + DivElement _populateThreadInfo(Thread t) { + int index = 0; + return new DivElement() + ..classes = ['indent'] + ..children = [ + new SpanElement() + ..text = '${t.id} ', + new CurlyBlockElement(queue: _r.queue) + ..content = [ + new DivElement() + ..classes = ['indent'] + ..text = 'kind ${t.kindString}', + new DivElement() + ..children = t.zones + .map((z) => new DivElement() + ..classes = ['indent'] + ..children = [ + new DivElement() + ..children = [ + new SpanElement() + ..children = [ + new SpanElement() + ..text = 'zone ${index++} ', + new CurlyBlockElement(queue: _r.queue) + ..content = [ + new DivElement() + ..classes = ['memberList'] + ..children = [ + new DivElement() + ..classes = ['memberItem'] + ..children = [ + new SpanElement() + ..classes = ['memberName'] + ..text = 'used ', + new SpanElement() + ..classes = ['memberValue'] + ..title = '${z.used}B' + ..text = + Utils.formatSize(z.used) + ], + new DivElement() + ..classes = ['memberItem'] + ..children = [ + new SpanElement() + ..classes = ['memberName'] + ..text = 'capacity', + new SpanElement() + ..classes = ['memberValue'] + ..title = '${z.capacity}B' + ..text = + Utils.formatSize(z.capacity) + ] + ] + ] + ] + ] + ] + )] + ]; + } + Future _loadExtraData() async { _function = null; _rootScript = null;
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart index 3611ef8..b9e0f6e 100644 --- a/runtime/observatory/lib/src/service/object.dart +++ b/runtime/observatory/lib/src/service/object.dart
@@ -2551,33 +2551,33 @@ return M.InstanceKind.float64x2; case 'Int32x4': return M.InstanceKind.int32x4; - case 'Uint8ClampedList': + case '_Uint8ClampedList': return M.InstanceKind.uint8ClampedList; - case 'Uint8List': + case '_Uint8List': return M.InstanceKind.uint8List; - case 'Uint16List': + case '_Uint16List': return M.InstanceKind.uint16List; - case 'Uint32List': + case '_Uint32List': return M.InstanceKind.uint32List; - case 'Uint64List': + case '_Uint64List': return M.InstanceKind.uint64List; - case 'Int8List': + case '_Int8List': return M.InstanceKind.int8List; - case 'Int16List': + case '_Int16List': return M.InstanceKind.int16List; - case 'Int32List': + case '_Int32List': return M.InstanceKind.int32List; - case 'Int64List': + case '_Int64List': return M.InstanceKind.int64List; - case 'Float32List': + case '_Float32List': return M.InstanceKind.float32List; - case 'Float64List': + case '_Float64List': return M.InstanceKind.float64List; - case 'Int32x4List': + case '_Int32x4List': return M.InstanceKind.int32x4List; - case 'Float32x4List': + case '_Float32x4List': return M.InstanceKind.float32x4List; - case 'Float64x2List': + case '_Float64x2List': return M.InstanceKind.float64x2List; case 'StackTrace': return M.InstanceKind.stackTrace; @@ -2791,46 +2791,46 @@ if (map['bytes'] != null) { Uint8List bytes = BASE64.decode(map['bytes']); switch (map['kind']) { - case "Uint8ClampedList": + case "_Uint8ClampedList": typedElements = bytes.buffer.asUint8ClampedList(); break; - case "Uint8List": + case "_Uint8List": typedElements = bytes.buffer.asUint8List(); break; - case "Uint16List": + case "_Uint16List": typedElements = bytes.buffer.asUint16List(); break; - case "Uint32List": + case "_Uint32List": typedElements = bytes.buffer.asUint32List(); break; - case "Uint64List": + case "_Uint64List": typedElements = bytes.buffer.asUint64List(); break; - case "Int8List": + case "_Int8List": typedElements = bytes.buffer.asInt8List(); break; - case "Int16List": + case "_Int16List": typedElements = bytes.buffer.asInt16List(); break; - case "Int32List": + case "_Int32List": typedElements = bytes.buffer.asInt32List(); break; - case "Int64List": + case "_Int64List": typedElements = bytes.buffer.asInt64List(); break; - case "Float32List": + case "_Float32List": typedElements = bytes.buffer.asFloat32List(); break; - case "Float64List": + case "_Float64List": typedElements = bytes.buffer.asFloat64List(); break; - case "Int32x4List": + case "_Int32x4List": typedElements = bytes.buffer.asInt32x4List(); break; - case "Float32x4List": + case "_Float32x4List": typedElements = bytes.buffer.asFloat32x4List(); break; - case "Float64x2List": + case "_Float64x2List": typedElements = bytes.buffer.asFloat64x2List(); break; } @@ -3070,33 +3070,41 @@ class Thread extends ServiceObject implements M.Thread { M.ThreadKind get kind => _kind; M.ThreadKind _kind; + String get kindString => _kindString; + String _kindString; List<Zone> get zones => _zones; final List<Zone> _zones = new List<Zone>(); Thread._empty(ServiceObjectOwner owner) : super._empty(owner); void _update(Map map, bool mapIsRef) { - String kindString = map['kind']; + String rawKind = map['kind']; List<Map> zoneList = map['zones']; - switch(kindString) { + switch(rawKind) { case "kUnknownTask": _kind = M.ThreadKind.unknownTask; + _kindString = 'unknown'; break; case "kMutatorTask": _kind = M.ThreadKind.mutatorTask; + _kindString = 'mutator'; break; case "kCompilerTask": _kind = M.ThreadKind.compilerTask; + _kindString = 'compiler'; break; case "kSweeperTask": _kind = M.ThreadKind.sweeperTask; + _kindString = 'sweeper'; break; case "kMarkerTask": _kind = M.ThreadKind.markerTask; + _kindString = 'marker'; break; case "kFinalizerTask": _kind = M.ThreadKind.finalizerTask; + _kindString = 'finalizer'; break; default: assert(false);
diff --git a/runtime/observatory/tests/service/get_object_rpc_test.dart b/runtime/observatory/tests/service/get_object_rpc_test.dart index 2f45f3a..893ec84 100644 --- a/runtime/observatory/tests/service/get_object_rpc_test.dart +++ b/runtime/observatory/tests/service/get_object_rpc_test.dart
@@ -436,12 +436,12 @@ }; var result = await isolate.invokeRpcNoUpgrade('getObject', params); expect(result['type'], equals('Instance')); - expect(result['kind'], equals('Uint8List')); + expect(result['kind'], equals('_Uint8List')); expect(result['_vmType'], equals('TypedData')); expect(result['id'], startsWith('objects/')); expect(result['valueAsString'], isNull); expect(result['class']['type'], equals('@Class')); - expect(result['class']['name'], equals('Uint8List')); + expect(result['class']['name'], equals('_Uint8List')); expect(result['size'], isPositive); expect(result['fields'], isEmpty); expect(result['length'], equals(3)); @@ -462,12 +462,12 @@ }; var result = await isolate.invokeRpcNoUpgrade('getObject', params); expect(result['type'], equals('Instance')); - expect(result['kind'], equals('Uint8List')); + expect(result['kind'], equals('_Uint8List')); expect(result['_vmType'], equals('TypedData')); expect(result['id'], startsWith('objects/')); expect(result['valueAsString'], isNull); expect(result['class']['type'], equals('@Class')); - expect(result['class']['name'], equals('Uint8List')); + expect(result['class']['name'], equals('_Uint8List')); expect(result['size'], isPositive); expect(result['fields'], isEmpty); expect(result['length'], equals(3)); @@ -489,12 +489,12 @@ }; var result = await isolate.invokeRpcNoUpgrade('getObject', params); expect(result['type'], equals('Instance')); - expect(result['kind'], equals('Uint8List')); + expect(result['kind'], equals('_Uint8List')); expect(result['_vmType'], equals('TypedData')); expect(result['id'], startsWith('objects/')); expect(result['valueAsString'], isNull); expect(result['class']['type'], equals('@Class')); - expect(result['class']['name'], equals('Uint8List')); + expect(result['class']['name'], equals('_Uint8List')); expect(result['size'], isPositive); expect(result['fields'], isEmpty); expect(result['length'], equals(3)); @@ -516,12 +516,12 @@ }; var result = await isolate.invokeRpcNoUpgrade('getObject', params); expect(result['type'], equals('Instance')); - expect(result['kind'], equals('Uint8List')); + expect(result['kind'], equals('_Uint8List')); expect(result['_vmType'], equals('TypedData')); expect(result['id'], startsWith('objects/')); expect(result['valueAsString'], isNull); expect(result['class']['type'], equals('@Class')); - expect(result['class']['name'], equals('Uint8List')); + expect(result['class']['name'], equals('_Uint8List')); expect(result['size'], isPositive); expect(result['fields'], isEmpty); expect(result['length'], equals(3)); @@ -539,12 +539,12 @@ }; var result = await isolate.invokeRpcNoUpgrade('getObject', params); expect(result['type'], equals('Instance')); - expect(result['kind'], equals('Uint64List')); + expect(result['kind'], equals('_Uint64List')); expect(result['_vmType'], equals('TypedData')); expect(result['id'], startsWith('objects/')); expect(result['valueAsString'], isNull); expect(result['class']['type'], equals('@Class')); - expect(result['class']['name'], equals('Uint64List')); + expect(result['class']['name'], equals('_Uint64List')); expect(result['size'], isPositive); expect(result['fields'], isEmpty); expect(result['length'], equals(3)); @@ -565,12 +565,12 @@ }; var result = await isolate.invokeRpcNoUpgrade('getObject', params); expect(result['type'], equals('Instance')); - expect(result['kind'], equals('Uint64List')); + expect(result['kind'], equals('_Uint64List')); expect(result['_vmType'], equals('TypedData')); expect(result['id'], startsWith('objects/')); expect(result['valueAsString'], isNull); expect(result['class']['type'], equals('@Class')); - expect(result['class']['name'], equals('Uint64List')); + expect(result['class']['name'], equals('_Uint64List')); expect(result['size'], isPositive); expect(result['fields'], isEmpty); expect(result['length'], equals(3)); @@ -592,12 +592,12 @@ }; var result = await isolate.invokeRpcNoUpgrade('getObject', params); expect(result['type'], equals('Instance')); - expect(result['kind'], equals('Uint64List')); + expect(result['kind'], equals('_Uint64List')); expect(result['_vmType'], equals('TypedData')); expect(result['id'], startsWith('objects/')); expect(result['valueAsString'], isNull); expect(result['class']['type'], equals('@Class')); - expect(result['class']['name'], equals('Uint64List')); + expect(result['class']['name'], equals('_Uint64List')); expect(result['size'], isPositive); expect(result['fields'], isEmpty); expect(result['length'], equals(3)); @@ -619,12 +619,12 @@ }; var result = await isolate.invokeRpcNoUpgrade('getObject', params); expect(result['type'], equals('Instance')); - expect(result['kind'], equals('Uint64List')); + expect(result['kind'], equals('_Uint64List')); expect(result['_vmType'], equals('TypedData')); expect(result['id'], startsWith('objects/')); expect(result['valueAsString'], isNull); expect(result['class']['type'], equals('@Class')); - expect(result['class']['name'], equals('Uint64List')); + expect(result['class']['name'], equals('_Uint64List')); expect(result['size'], isPositive); expect(result['fields'], isEmpty); expect(result['length'], equals(3));
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status index 009d9a7..d39e46f 100644 --- a/runtime/observatory/tests/service/service.status +++ b/runtime/observatory/tests/service/service.status
@@ -8,9 +8,12 @@ pause_on_start_and_exit_test: Pass, RuntimeError # Issue 26470 pause_on_start_then_step_test: Pass, RuntimeError # Issue 26470 get_allocation_samples_test: Pass, RuntimeError # Inconsistent stack trace +get_isolate_rpc_test: Pass, RuntimeError # Issue 28185 set_library_debuggable_test: Pass, RuntimeError # Issue 28091 -# Reload is slow on the bots -reload_sources_test: Pass, Slow +reload_sources_test: Pass, Slow # Reload is slow on the bots +rewind_test: Pass, RuntimeError # Issue 28047 +tcp_socket_service_test: Pass, RuntimeError # Issue 28184 +get_retained_size_rpc_test: Pass, RuntimeError # Issue 28193 [ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) ] evaluate_activation_test/instance: RuntimeError # http://dartbug.com/20047 @@ -50,7 +53,6 @@ address_mapper_test: CompileTimeError # Issue 27806 capture_stdio_test: CompileTimeError # Issue 27806 complex_reload_test: RuntimeError # Issue 27806 -debugger_location_second_test: RuntimeError # Issue 27806 dev_fs_spawn_test: RuntimeError # Issue 27806 developer_extension_test: RuntimeError # Issue 27806 evaluate_activation_test/instance: RuntimeError # Issue 27806 @@ -60,6 +62,8 @@ set_name_rpc_test: RuntimeError # Issue 27806 vm_restart_test: CompileTimeError # Issue 27806 +debugger_location_second_test: RuntimeError, Crash # Issue 28180 + [ $compiler == dart2analyzer ] evaluate_activation_in_method_class_test: CompileTimeError # Issue 24478 @@ -78,7 +82,6 @@ dev_fs_weird_char_test: Skip # Windows disallows question mark in paths dev_fs_http_put_weird_char_test: Skip # Windows disallows carriage returns in paths complex_reload_test: Skip # Issue 27861 -rewind_test: Pass, RuntimeError # Issue 28047 # Service protocol is not supported in product mode. [ $mode == product ]
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn index 2c04933..bc89894 100644 --- a/runtime/vm/BUILD.gn +++ b/runtime/vm/BUILD.gn
@@ -344,10 +344,12 @@ ], [ "typed_data", + processed_gypis.typed_data_sdk_sources, + "../../sdk/lib/typed_data", + "typed_data", + true, processed_gypis.typed_data_runtime_sources, "../lib", - "typed_data", - false, ], [ "_vmservice", @@ -428,7 +430,6 @@ # Files below are not patches, they will not be in [concatenation_files] # but the `patch_sdk.dart` script will copy them into the patched sdk. inputs += [ - "../lib/typed_data.dart", "../bin/builtin.dart", "../bin/vmservice/vmservice_io.dart", "../bin/vmservice/loader.dart",
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc index 0dc6e7c..8ef219d 100644 --- a/runtime/vm/bootstrap.cc +++ b/runtime/vm/bootstrap.cc
@@ -44,7 +44,6 @@ const char** Bootstrap::profiler_patch_paths_ = NULL; -const char** Bootstrap::typed_data_patch_paths_ = NULL; #define MAKE_PROPERTIES(CamelName, name) \
diff --git a/runtime/vm/bootstrap.h b/runtime/vm/bootstrap.h index 15f454b..0c271b3 100644 --- a/runtime/vm/bootstrap.h +++ b/runtime/vm/bootstrap.h
@@ -55,11 +55,11 @@ static const char* isolate_patch_paths_[]; static const char* math_patch_paths_[]; static const char* mirrors_patch_paths_[]; + static const char* typed_data_patch_paths_[]; static const char* _vmservice_patch_paths_[]; // NULL patch paths for libraries that do not have patch files. static const char** profiler_patch_paths_; - static const char** typed_data_patch_paths_; }; } // namespace dart
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc index 89f3be7..51e3f3d 100644 --- a/runtime/vm/clustered_snapshot.cc +++ b/runtime/vm/clustered_snapshot.cc
@@ -772,6 +772,85 @@ data->ptr()->parent_function_ = static_cast<RawFunction*>(d->ReadRef()); data->ptr()->signature_type_ = static_cast<RawType*>(d->ReadRef()); data->ptr()->closure_ = static_cast<RawInstance*>(d->ReadRef()); + data->ptr()->hash_ = Object::null(); + } + } +}; + + +#if !defined(DART_PRECOMPILED_RUNTIME) +class SignatureDataSerializationCluster : public SerializationCluster { + public: + SignatureDataSerializationCluster() {} + virtual ~SignatureDataSerializationCluster() {} + + void Trace(Serializer* s, RawObject* object) { + RawSignatureData* data = SignatureData::RawCast(object); + objects_.Add(data); + + RawObject** from = data->from(); + RawObject** to = data->to(); + for (RawObject** p = from; p <= to; p++) { + s->Push(*p); + } + } + + void WriteAlloc(Serializer* s) { + s->WriteCid(kSignatureDataCid); + intptr_t count = objects_.length(); + s->Write<int32_t>(count); + for (intptr_t i = 0; i < count; i++) { + RawSignatureData* data = objects_[i]; + s->AssignRef(data); + } + } + + void WriteFill(Serializer* s) { + intptr_t count = objects_.length(); + for (intptr_t i = 0; i < count; i++) { + RawSignatureData* data = objects_[i]; + RawObject** from = data->from(); + RawObject** to = data->to(); + for (RawObject** p = from; p <= to; p++) { + s->WriteRef(*p); + } + } + } + + private: + GrowableArray<RawSignatureData*> objects_; +}; +#endif // !DART_PRECOMPILED_RUNTIME + + +class SignatureDataDeserializationCluster : public DeserializationCluster { + public: + SignatureDataDeserializationCluster() {} + virtual ~SignatureDataDeserializationCluster() {} + + void ReadAlloc(Deserializer* d) { + start_index_ = d->next_index(); + PageSpace* old_space = d->heap()->old_space(); + intptr_t count = d->Read<int32_t>(); + for (intptr_t i = 0; i < count; i++) { + d->AssignRef( + AllocateUninitialized(old_space, SignatureData::InstanceSize())); + } + stop_index_ = d->next_index(); + } + + void ReadFill(Deserializer* d) { + bool is_vm_object = d->isolate() == Dart::vm_isolate(); + + for (intptr_t id = start_index_; id < stop_index_; id++) { + RawSignatureData* data = reinterpret_cast<RawSignatureData*>(d->Ref(id)); + Deserializer::InitializeHeader( + data, kSignatureDataCid, SignatureData::InstanceSize(), is_vm_object); + RawObject** from = data->from(); + RawObject** to = data->to(); + for (RawObject** p = from; p <= to; p++) { + *p = d->ReadRef(); + } } } }; @@ -4446,6 +4525,8 @@ return new (Z) FunctionSerializationCluster(); case kClosureDataCid: return new (Z) ClosureDataSerializationCluster(); + case kSignatureDataCid: + return new (Z) SignatureDataSerializationCluster(); case kRedirectionDataCid: return new (Z) RedirectionDataSerializationCluster(); case kFieldCid: @@ -4810,6 +4891,8 @@ return new (Z) FunctionDeserializationCluster(); case kClosureDataCid: return new (Z) ClosureDataDeserializationCluster(); + case kSignatureDataCid: + return new (Z) SignatureDataDeserializationCluster(); case kRedirectionDataCid: return new (Z) RedirectionDataDeserializationCluster(); case kFieldCid:
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc index a68cfbf..8ff2deb 100644 --- a/runtime/vm/dart_api_impl.cc +++ b/runtime/vm/dart_api_impl.cc
@@ -3539,8 +3539,8 @@ RETURN_TYPE_ERROR(Z, typed_data, 'TypedData'); } Object& result = Object::Handle(Z); - result = GetByteBufferConstructor(T, Symbols::ByteBuffer(), - Symbols::ByteBufferDot_New(), 1); + result = GetByteBufferConstructor(T, Symbols::_ByteBuffer(), + Symbols::_ByteBufferDot_New(), 1); ASSERT(!result.IsNull()); ASSERT(result.IsFunction()); const Function& factory = Function::Cast(result);
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc index e3963d9..265c308 100644 --- a/runtime/vm/flow_graph_builder.cc +++ b/runtime/vm/flow_graph_builder.cc
@@ -76,12 +76,11 @@ } -#define RECOGNIZE_FACTORY(test_factory_symbol, cid, fp) \ - {Symbols::k##test_factory_symbol##Id, cid, fp, \ - #test_factory_symbol ", " #cid}, // NOLINT +#define RECOGNIZE_FACTORY(symbol, class_name, constructor_name, cid, fp) \ + {Symbols::k##symbol##Id, cid, fp, #symbol ", " #cid}, // NOLINT static struct { - intptr_t symbold_id; + intptr_t symbol_id; intptr_t cid; intptr_t finger_print; const char* name; @@ -98,10 +97,10 @@ (lib.raw() == Library::TypedDataLibrary())); const String& factory_name = String::Handle(factory.name()); for (intptr_t i = 0; - factory_recognizer_list[i].symbold_id != Symbols::kIllegal; i++) { + factory_recognizer_list[i].symbol_id != Symbols::kIllegal; i++) { if (String::EqualsIgnoringPrivateKey( factory_name, - Symbols::Symbol(factory_recognizer_list[i].symbold_id))) { + Symbols::Symbol(factory_recognizer_list[i].symbol_id))) { return factory_recognizer_list[i].cid; } }
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc index 6cf0684..f07e7cd 100644 --- a/runtime/vm/flow_graph_inliner.cc +++ b/runtime/vm/flow_graph_inliner.cc
@@ -2233,15 +2233,13 @@ } case kTypedDataFloat32x4ArrayCid: { type_args = flow_graph->constant_null(); - ASSERT((array_cid != kTypedDataFloat32x4ArrayCid) || - value_type.IsFloat32x4Type()); + ASSERT(value_type.IsFloat32x4Type()); ASSERT(value_type.IsInstantiated()); break; } case kTypedDataFloat64x2ArrayCid: { type_args = flow_graph->constant_null(); - ASSERT((array_cid != kTypedDataFloat64x2ArrayCid) || - value_type.IsFloat64x2Type()); + ASSERT(value_type.IsFloat64x2Type()); ASSERT(value_type.IsInstantiated()); break; }
diff --git a/runtime/vm/gypi_contents.gni b/runtime/vm/gypi_contents.gni index 403efdf..4ba651e 100644 --- a/runtime/vm/gypi_contents.gni +++ b/runtime/vm/gypi_contents.gni
@@ -42,6 +42,7 @@ "../../sdk/lib/math/math_sources.gypi", "../../sdk/lib/mirrors/mirrors_sources.gypi", "../../sdk/lib/profiler/profiler_sources.gypi", + "../../sdk/lib/typed_data/typed_data_sources.gypi", "../../sdk/lib/vmservice/vmservice_sources.gypi", "../bin/io_sources.gypi", ]
diff --git a/runtime/vm/method_recognizer.h b/runtime/vm/method_recognizer.h index 043dd70..14410a1 100644 --- a/runtime/vm/method_recognizer.h +++ b/runtime/vm/method_recognizer.h
@@ -57,63 +57,65 @@ 0x46d00995) \ V(Float32x4, Float32x4.fromFloat64x2, Float32x4FromFloat64x2, Float32x4, \ 0x685a86d2) \ - V(Float32x4, shuffle, Float32x4Shuffle, Float32x4, 0x7829101f) \ - V(Float32x4, shuffleMix, Float32x4ShuffleMix, Float32x4, 0x4182c06b) \ - V(Float32x4, get:signMask, Float32x4GetSignMask, Dynamic, 0x1d07ca93) \ - V(Float32x4, _cmpequal, Float32x4Equal, Int32x4, 0x16ad0fea) \ - V(Float32x4, _cmpgt, Float32x4GreaterThan, Int32x4, 0x0641f613) \ - V(Float32x4, _cmpgte, Float32x4GreaterThanOrEqual, Int32x4, 0x464b8ffc) \ - V(Float32x4, _cmplt, Float32x4LessThan, Int32x4, 0x3eecd0de) \ - V(Float32x4, _cmplte, Float32x4LessThanOrEqual, Int32x4, 0x06384754) \ - V(Float32x4, _cmpnequal, Float32x4NotEqual, Int32x4, 0x2f25ef10) \ - V(Float32x4, _min, Float32x4Min, Float32x4, 0x1ee6c750) \ - V(Float32x4, _max, Float32x4Max, Float32x4, 0x4db6bbb4) \ - V(Float32x4, _scale, Float32x4Scale, Float32x4, 0x52052a66) \ - V(Float32x4, _sqrt, Float32x4Sqrt, Float32x4, 0x479f6b4a) \ - V(Float32x4, _reciprocalSqrt, Float32x4ReciprocalSqrt, Float32x4, \ - 0x6d35bfcf) \ - V(Float32x4, _reciprocal, Float32x4Reciprocal, Float32x4, 0x21a56839) \ - V(Float32x4, _negate, Float32x4Negate, Float32x4, 0x6cfd5db7) \ - V(Float32x4, _abs, Float32x4Absolute, Float32x4, 0x249b8078) \ - V(Float32x4, _clamp, Float32x4Clamp, Float32x4, 0x28b06c7a) \ - V(Float32x4, withX, Float32x4WithX, Float32x4, 0x4e336aff) \ - V(Float32x4, withY, Float32x4WithY, Float32x4, 0x0a72b910) \ - V(Float32x4, withZ, Float32x4WithZ, Float32x4, 0x31e93658) \ - V(Float32x4, withW, Float32x4WithW, Float32x4, 0x60ddc105) \ + V(_Float32x4, shuffle, Float32x4Shuffle, Float32x4, 0x7829101f) \ + V(_Float32x4, shuffleMix, Float32x4ShuffleMix, Float32x4, 0x4182c06b) \ + V(_Float32x4, get:signMask, Float32x4GetSignMask, Dynamic, 0x1d07ca93) \ + V(_Float32x4, equal, Float32x4Equal, Int32x4, 0x11adb239) \ + V(_Float32x4, greaterThan, Float32x4GreaterThan, Int32x4, 0x48adaf58) \ + V(_Float32x4, greaterThanOrEqual, Float32x4GreaterThanOrEqual, Int32x4, \ + 0x32db94ca) \ + V(_Float32x4, lessThan, Float32x4LessThan, Int32x4, 0x425b000c) \ + V(_Float32x4, lessThanOrEqual, Float32x4LessThanOrEqual, Int32x4, \ + 0x0278c2f8) \ + V(_Float32x4, notEqual, Float32x4NotEqual, Int32x4, 0x2987cd26) \ + V(_Float32x4, min, Float32x4Min, Float32x4, 0x5ed74b6f) \ + V(_Float32x4, max, Float32x4Max, Float32x4, 0x68696442) \ + V(_Float32x4, scale, Float32x4Scale, Float32x4, 0x704e4122) \ + V(_Float32x4, sqrt, Float32x4Sqrt, Float32x4, 0x2c967a6f) \ + V(_Float32x4, reciprocalSqrt, Float32x4ReciprocalSqrt, Float32x4, \ + 0x6264bfe8) \ + V(_Float32x4, reciprocal, Float32x4Reciprocal, Float32x4, 0x3cd7e819) \ + V(_Float32x4, unary-, Float32x4Negate, Float32x4, 0x34431a14) \ + V(_Float32x4, abs, Float32x4Absolute, Float32x4, 0x471cdd87) \ + V(_Float32x4, clamp, Float32x4Clamp, Float32x4, 0x2cb30492) \ + V(_Float32x4, withX, Float32x4WithX, Float32x4, 0x4e336aff) \ + V(_Float32x4, withY, Float32x4WithY, Float32x4, 0x0a72b910) \ + V(_Float32x4, withZ, Float32x4WithZ, Float32x4, 0x31e93658) \ + V(_Float32x4, withW, Float32x4WithW, Float32x4, 0x60ddc105) \ V(Float64x2, Float64x2., Float64x2Constructor, Float64x2, 0x193be61d) \ V(Float64x2, Float64x2.zero, Float64x2Zero, Float64x2, 0x7b2ed5df) \ V(Float64x2, Float64x2.splat, Float64x2Splat, Float64x2, 0x2abbfcb2) \ V(Float64x2, Float64x2.fromFloat32x4, Float64x2FromFloat32x4, Float64x2, \ 0x2f43d3a6) \ - V(Float64x2, get:x, Float64x2GetX, Double, 0x58bfb39a) \ - V(Float64x2, get:y, Float64x2GetY, Double, 0x3cf4fcfa) \ - V(Float64x2, _negate, Float64x2Negate, Float64x2, 0x523937da) \ - V(Float64x2, abs, Float64x2Abs, Float64x2, 0x031f9e47) \ - V(Float64x2, sqrt, Float64x2Sqrt, Float64x2, 0x77f711dd) \ - V(Float64x2, get:signMask, Float64x2GetSignMask, Dynamic, 0x27ddf18d) \ - V(Float64x2, scale, Float64x2Scale, Float64x2, 0x26830a61) \ - V(Float64x2, withX, Float64x2WithX, Float64x2, 0x1d2bcaf5) \ - V(Float64x2, withY, Float64x2WithY, Float64x2, 0x383ed6ac) \ - V(Float64x2, min, Float64x2Min, Float64x2, 0x28d7ddf6) \ - V(Float64x2, max, Float64x2Max, Float64x2, 0x0bd74e5b) \ + V(_Float64x2, get:x, Float64x2GetX, Double, 0x58bfb39a) \ + V(_Float64x2, get:y, Float64x2GetY, Double, 0x3cf4fcfa) \ + V(_Float64x2, unary-, Float64x2Negate, Float64x2, 0x3df2eecb) \ + V(_Float64x2, abs, Float64x2Abs, Float64x2, 0x031f9e47) \ + V(_Float64x2, sqrt, Float64x2Sqrt, Float64x2, 0x77f711dd) \ + V(_Float64x2, get:signMask, Float64x2GetSignMask, Dynamic, 0x27ddf18d) \ + V(_Float64x2, scale, Float64x2Scale, Float64x2, 0x26830a61) \ + V(_Float64x2, withX, Float64x2WithX, Float64x2, 0x1d2bcaf5) \ + V(_Float64x2, withY, Float64x2WithY, Float64x2, 0x383ed6ac) \ + V(_Float64x2, min, Float64x2Min, Float64x2, 0x28d7ddf6) \ + V(_Float64x2, max, Float64x2Max, Float64x2, 0x0bd74e5b) \ V(Int32x4, Int32x4., Int32x4Constructor, Int32x4, 0x26b199a7) \ V(Int32x4, Int32x4.bool, Int32x4BoolConstructor, Int32x4, 0x1b55a5e1) \ V(Int32x4, Int32x4.fromFloat32x4Bits, Int32x4FromFloat32x4Bits, Int32x4, \ 0x7e82564c) \ - V(Int32x4, get:flagX, Int32x4GetFlagX, Bool, 0x563883c4) \ - V(Int32x4, get:flagY, Int32x4GetFlagY, Bool, 0x446f5e7a) \ - V(Int32x4, get:flagZ, Int32x4GetFlagZ, Bool, 0x20d61679) \ - V(Int32x4, get:flagW, Int32x4GetFlagW, Bool, 0x504478ac) \ - V(Int32x4, get:signMask, Int32x4GetSignMask, Dynamic, 0x2c1ec9e5) \ - V(Int32x4, shuffle, Int32x4Shuffle, Int32x4, 0x20bc0b16) \ - V(Int32x4, shuffleMix, Int32x4ShuffleMix, Int32x4, 0x5c7056e1) \ - V(Int32x4, select, Int32x4Select, Float32x4, 0x5c254e86) \ - V(Int32x4, withFlagX, Int32x4WithFlagX, Int32x4, 0x0ef58fcf) \ - V(Int32x4, withFlagY, Int32x4WithFlagY, Int32x4, 0x6485a9c4) \ - V(Int32x4, withFlagZ, Int32x4WithFlagZ, Int32x4, 0x267acdfa) \ - V(Int32x4, withFlagW, Int32x4WithFlagW, Int32x4, 0x345ac675) \ - V(Int64List, [], Int64ArrayGetIndexed, Dynamic, 0x680ec59b) \ - V(Int64List, []=, Int64ArraySetIndexed, Dynamic, 0x0872fc15) \ + V(_Int32x4, get:flagX, Int32x4GetFlagX, Bool, 0x563883c4) \ + V(_Int32x4, get:flagY, Int32x4GetFlagY, Bool, 0x446f5e7a) \ + V(_Int32x4, get:flagZ, Int32x4GetFlagZ, Bool, 0x20d61679) \ + V(_Int32x4, get:flagW, Int32x4GetFlagW, Bool, 0x504478ac) \ + V(_Int32x4, get:signMask, Int32x4GetSignMask, Dynamic, 0x2c1ec9e5) \ + V(_Int32x4, shuffle, Int32x4Shuffle, Int32x4, 0x20bc0b16) \ + V(_Int32x4, shuffleMix, Int32x4ShuffleMix, Int32x4, 0x5c7056e1) \ + V(_Int32x4, select, Int32x4Select, Float32x4, 0x6b49654f) \ + V(_Int32x4, withFlagX, Int32x4WithFlagX, Int32x4, 0x0ef58fcf) \ + V(_Int32x4, withFlagY, Int32x4WithFlagY, Int32x4, 0x6485a9c4) \ + V(_Int32x4, withFlagZ, Int32x4WithFlagZ, Int32x4, 0x267acdfa) \ + V(_Int32x4, withFlagW, Int32x4WithFlagW, Int32x4, 0x345ac675) \ + V(_Int64List, [], Int64ArrayGetIndexed, Dynamic, 0x680ec59b) \ + V(_Int64List, []=, Int64ArraySetIndexed, Dynamic, 0x0872fc15) \ V(_Bigint, get:_neg, Bigint_getNeg, Bool, 0x355fa565) \ V(_Bigint, get:_used, Bigint_getUsed, Smi, 0x33b9dcd2) \ V(_Bigint, get:_digits, Bigint_getDigits, TypedDataUint32Array, 0x68de883a) \ @@ -266,45 +268,45 @@ TypedDataFloat64x2Array, 0x18cbf4d9) \ #define GRAPH_TYPED_DATA_INTRINSICS_LIST(V) \ - V(Int8List, [], Int8ArrayGetIndexed, Smi, 0x5f9a4430) \ - V(Int8List, []=, Int8ArraySetIndexed, Dynamic, 0x5f880110) \ - V(Uint8List, [], Uint8ArrayGetIndexed, Smi, 0x1eb150d8) \ - V(Uint8List, []=, Uint8ArraySetIndexed, Dynamic, 0x4cf76981) \ + V(_Int8List, [], Int8ArrayGetIndexed, Smi, 0x5f9a4430) \ + V(_Int8List, []=, Int8ArraySetIndexed, Dynamic, 0x5f880110) \ + V(_Uint8List, [], Uint8ArrayGetIndexed, Smi, 0x1eb150d8) \ + V(_Uint8List, []=, Uint8ArraySetIndexed, Dynamic, 0x4cf76981) \ V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, Smi, 0x1eb150d8) \ V(_ExternalUint8Array, []=, ExternalUint8ArraySetIndexed, Dynamic, \ 0x4cf76981) \ - V(Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, Smi, 0x1eb150d8) \ - V(Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, Dynamic, 0x2224afe1) \ + V(_Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, Smi, 0x1eb150d8) \ + V(_Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, Dynamic, 0x2224afe1) \ V(_ExternalUint8ClampedArray, [], ExternalUint8ClampedArrayGetIndexed, \ Smi, 0x1eb150d8) \ V(_ExternalUint8ClampedArray, []=, ExternalUint8ClampedArraySetIndexed, \ Dynamic, 0x2224afe1) \ - V(Int16List, [], Int16ArrayGetIndexed, Smi, 0x74ea134c) \ - V(Int16List, []=, Int16ArraySetIndexed, Dynamic, 0x48e25661) \ - V(Uint16List, [], Uint16ArrayGetIndexed, Smi, 0x756d9a97) \ - V(Uint16List, []=, Uint16ArraySetIndexed, Dynamic, 0x698f9d4f) \ - V(Int32List, [], Int32ArrayGetIndexed, Dynamic, 0x61e49de1) \ - V(Int32List, []=, Int32ArraySetIndexed, Dynamic, 0x55736c63) \ - V(Uint32List, [], Uint32ArrayGetIndexed, Dynamic, 0x2eaa22d2) \ - V(Uint32List, []=, Uint32ArraySetIndexed, Dynamic, 0x3c88eeb9) \ - V(Float64List, [], Float64ArrayGetIndexed, Double, 0x20950e8a) \ - V(Float64List, []=, Float64ArraySetIndexed, Dynamic, 0x556a0727) \ - V(Float32List, [], Float32ArrayGetIndexed, Double, 0x7101fa23) \ - V(Float32List, []=, Float32ArraySetIndexed, Dynamic, 0x5e32c1eb) \ - V(Float32x4List, [], Float32x4ArrayGetIndexed, Float32x4, 0x28b0a7ef) \ - V(Float32x4List, []=, Float32x4ArraySetIndexed, Dynamic, 0x4babf032) \ - V(Int32x4List, [], Int32x4ArrayGetIndexed, Int32x4, 0x619c79a0) \ - V(Int32x4List, []=, Int32x4ArraySetIndexed, Dynamic, 0x021bd16b) \ - V(Float64x2List, [], Float64x2ArrayGetIndexed, Float64x2, 0x7a6dd5e5) \ - V(Float64x2List, []=, Float64x2ArraySetIndexed, Dynamic, 0x3c59fecb) \ + V(_Int16List, [], Int16ArrayGetIndexed, Smi, 0x74ea134c) \ + V(_Int16List, []=, Int16ArraySetIndexed, Dynamic, 0x48e25661) \ + V(_Uint16List, [], Uint16ArrayGetIndexed, Smi, 0x756d9a97) \ + V(_Uint16List, []=, Uint16ArraySetIndexed, Dynamic, 0x698f9d4f) \ + V(_Int32List, [], Int32ArrayGetIndexed, Dynamic, 0x61e49de1) \ + V(_Int32List, []=, Int32ArraySetIndexed, Dynamic, 0x55736c63) \ + V(_Uint32List, [], Uint32ArrayGetIndexed, Dynamic, 0x2eaa22d2) \ + V(_Uint32List, []=, Uint32ArraySetIndexed, Dynamic, 0x3c88eeb9) \ + V(_Float64List, [], Float64ArrayGetIndexed, Double, 0x20950e8a) \ + V(_Float64List, []=, Float64ArraySetIndexed, Dynamic, 0x556a0727) \ + V(_Float32List, [], Float32ArrayGetIndexed, Double, 0x7101fa23) \ + V(_Float32List, []=, Float32ArraySetIndexed, Dynamic, 0x5e32c1eb) \ + V(_Float32x4List, [], Float32x4ArrayGetIndexed, Float32x4, 0x28b0a7ef) \ + V(_Float32x4List, []=, Float32x4ArraySetIndexed, Dynamic, 0x4babf032) \ + V(_Int32x4List, [], Int32x4ArrayGetIndexed, Int32x4, 0x619c79a0) \ + V(_Int32x4List, []=, Int32x4ArraySetIndexed, Dynamic, 0x021bd16b) \ + V(_Float64x2List, [], Float64x2ArrayGetIndexed, Float64x2, 0x7a6dd5e5) \ + V(_Float64x2List, []=, Float64x2ArraySetIndexed, Dynamic, 0x3c59fecb) \ V(_TypedList, get:length, TypedDataLength, Smi, 0x2090dc1a) \ - V(Float32x4, get:x, Float32x4ShuffleX, Double, 0x63d0c13f) \ - V(Float32x4, get:y, Float32x4ShuffleY, Double, 0x20343b1b) \ - V(Float32x4, get:z, Float32x4ShuffleZ, Double, 0x13181dba) \ - V(Float32x4, get:w, Float32x4ShuffleW, Double, 0x69895020) \ - V(Float32x4, _mul, Float32x4Mul, Float32x4, 0x6183ae12) \ - V(Float32x4, _sub, Float32x4Sub, Float32x4, 0x22a8d3ea) \ - V(Float32x4, _add, Float32x4Add, Float32x4, 0x613c30f4) \ + V(_Float32x4, get:x, Float32x4ShuffleX, Double, 0x63d0c13f) \ + V(_Float32x4, get:y, Float32x4ShuffleY, Double, 0x20343b1b) \ + V(_Float32x4, get:z, Float32x4ShuffleZ, Double, 0x13181dba) \ + V(_Float32x4, get:w, Float32x4ShuffleW, Double, 0x69895020) \ + V(_Float32x4, *, Float32x4Mul, Float32x4, 0x0e2a0ef4) \ + V(_Float32x4, -, Float32x4Sub, Float32x4, 0x6edeeaa3) \ + V(_Float32x4, +, Float32x4Add, Float32x4, 0x303a9943) \ #define GRAPH_CORE_INTRINSICS_LIST(V) \ V(_List, get:length, ObjectArrayLength, Smi, 0x25943ad2) \ @@ -538,23 +540,30 @@ // clang-format off // List of recognized list factories: -// (factory-name-symbol, result-cid, fingerprint). +// (factory-name-symbol, class-name-string, constructor-name-string, +// result-cid, fingerprint). #define RECOGNIZED_LIST_FACTORY_LIST(V) \ - V(_ListFactory, kArrayCid, 0x375519ad) \ - V(_GrowableListWithData, kGrowableObjectArrayCid, 0x401f3150) \ - V(_GrowableListFactory, kGrowableObjectArrayCid, 0x0b8d9feb) \ - V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 0x2e7749e3) \ - V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 0x6ab75439) \ - V(_Uint8ClampedArrayFactory, kTypedDataUint8ClampedArrayCid, 0x183129d7) \ - V(_Int16ArrayFactory, kTypedDataInt16ArrayCid, 0x14b563ea) \ - V(_Uint16ArrayFactory, kTypedDataUint16ArrayCid, 0x07456be4) \ - V(_Int32ArrayFactory, kTypedDataInt32ArrayCid, 0x5bd49250) \ - V(_Uint32ArrayFactory, kTypedDataUint32ArrayCid, 0x3c59b3a4) \ - V(_Int64ArrayFactory, kTypedDataInt64ArrayCid, 0x57d85ac7) \ - V(_Uint64ArrayFactory, kTypedDataUint64ArrayCid, 0x2c093004) \ - V(_Float64ArrayFactory, kTypedDataFloat64ArrayCid, 0x501be4f1) \ - V(_Float32ArrayFactory, kTypedDataFloat32ArrayCid, 0x738e124b) \ - V(_Float32x4ArrayFactory, kTypedDataFloat32x4ArrayCid, 0x7a7dd718) + V(_ListFactory, _List, ., kArrayCid, 0x375519ad) \ + V(_GrowableListWithData, _GrowableList, .withData, kGrowableObjectArrayCid, \ + 0x401f3150) \ + V(_GrowableListFactory, _GrowableList, ., kGrowableObjectArrayCid, \ + 0x0b8d9feb) \ + V(_Int8ArrayFactory, Int8List, ., kTypedDataInt8ArrayCid, 0x2e7749e3) \ + V(_Uint8ArrayFactory, Uint8List, ., kTypedDataUint8ArrayCid, 0x6ab75439) \ + V(_Uint8ClampedArrayFactory, Uint8ClampedList, ., \ + kTypedDataUint8ClampedArrayCid, 0x183129d7) \ + V(_Int16ArrayFactory, Int16List, ., kTypedDataInt16ArrayCid, 0x14b563ea) \ + V(_Uint16ArrayFactory, Uint16List, ., kTypedDataUint16ArrayCid, 0x07456be4) \ + V(_Int32ArrayFactory, Int32List, ., kTypedDataInt32ArrayCid, 0x5bd49250) \ + V(_Uint32ArrayFactory, Uint32List, ., kTypedDataUint32ArrayCid, 0x3c59b3a4) \ + V(_Int64ArrayFactory, Int64List, ., kTypedDataInt64ArrayCid, 0x57d85ac7) \ + V(_Uint64ArrayFactory, Uint64List, ., kTypedDataUint64ArrayCid, 0x2c093004) \ + V(_Float64ArrayFactory, Float64List, ., kTypedDataFloat64ArrayCid, \ + 0x501be4f1) \ + V(_Float32ArrayFactory, Float32List, ., kTypedDataFloat32ArrayCid, \ + 0x738e124b) \ + V(_Float32x4ArrayFactory, Float32x4List, ., kTypedDataFloat32x4ArrayCid, \ + 0x7a7dd718) // clang-format on
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index 14a9b63..fd81fee 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc
@@ -142,6 +142,7 @@ RawClass* Object::patch_class_class_ = reinterpret_cast<RawClass*>(RAW_NULL); RawClass* Object::function_class_ = reinterpret_cast<RawClass*>(RAW_NULL); RawClass* Object::closure_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL); +RawClass* Object::signature_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL); RawClass* Object::redirection_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL); RawClass* Object::field_class_ = reinterpret_cast<RawClass*>(RAW_NULL); @@ -631,6 +632,9 @@ cls = Class::New<ClosureData>(); closure_data_class_ = cls.raw(); + cls = Class::New<SignatureData>(); + signature_data_class_ = cls.raw(); + cls = Class::New<RedirectionData>(); redirection_data_class_ = cls.raw(); @@ -999,6 +1003,7 @@ SET_CLASS_NAME(patch_class, PatchClass); SET_CLASS_NAME(function, Function); SET_CLASS_NAME(closure_data, ClosureData); + SET_CLASS_NAME(signature_data, SignatureData); SET_CLASS_NAME(redirection_data, RedirectionData); SET_CLASS_NAME(field, Field); SET_CLASS_NAME(literal_token, LiteralToken); @@ -1505,7 +1510,7 @@ ASSERT(lib.raw() == Library::TypedDataLibrary()); #define REGISTER_TYPED_DATA_CLASS(clazz) \ cls = Class::NewTypedDataClass(kTypedData##clazz##ArrayCid); \ - RegisterClass(cls, Symbols::clazz##List(), lib); + RegisterPrivateClass(cls, Symbols::clazz##List(), lib); DART_CLASS_LIST_TYPED_DATA(REGISTER_TYPED_DATA_CLASS); #undef REGISTER_TYPED_DATA_CLASS @@ -1526,39 +1531,48 @@ cls = Class::New<Instance>(kByteBufferCid); cls.set_instance_size(0); cls.set_next_field_offset(-kWordSize); - RegisterClass(cls, Symbols::ByteBuffer(), lib); + RegisterPrivateClass(cls, Symbols::_ByteBuffer(), lib); pending_classes.Add(cls); CLASS_LIST_TYPED_DATA(REGISTER_EXT_TYPED_DATA_CLASS); #undef REGISTER_EXT_TYPED_DATA_CLASS - // Register Float32x4 and Int32x4 in the object store. + // Register Float32x4, Int32x4, and Float64x2 in the object store. cls = Class::New<Float32x4>(); + RegisterPrivateClass(cls, Symbols::_Float32x4(), lib); + pending_classes.Add(cls); + object_store->set_float32x4_class(cls); + + cls = Class::New<Instance>(kIllegalCid); RegisterClass(cls, Symbols::Float32x4(), lib); cls.set_num_type_arguments(0); cls.set_num_own_type_arguments(0); cls.set_is_prefinalized(); - pending_classes.Add(cls); - object_store->set_float32x4_class(cls); type = Type::NewNonParameterizedType(cls); object_store->set_float32x4_type(type); cls = Class::New<Int32x4>(); + RegisterPrivateClass(cls, Symbols::_Int32x4(), lib); + pending_classes.Add(cls); + object_store->set_int32x4_class(cls); + + cls = Class::New<Instance>(kIllegalCid); RegisterClass(cls, Symbols::Int32x4(), lib); cls.set_num_type_arguments(0); cls.set_num_own_type_arguments(0); cls.set_is_prefinalized(); - pending_classes.Add(cls); - object_store->set_int32x4_class(cls); type = Type::NewNonParameterizedType(cls); object_store->set_int32x4_type(type); cls = Class::New<Float64x2>(); + RegisterPrivateClass(cls, Symbols::_Float64x2(), lib); + pending_classes.Add(cls); + object_store->set_float64x2_class(cls); + + cls = Class::New<Instance>(kIllegalCid); RegisterClass(cls, Symbols::Float64x2(), lib); cls.set_num_type_arguments(0); cls.set_num_own_type_arguments(0); cls.set_is_prefinalized(); - pending_classes.Add(cls); - object_store->set_float64x2_class(cls); type = Type::NewNonParameterizedType(cls); object_store->set_float64x2_type(type); @@ -3367,6 +3381,8 @@ return Symbols::Function().raw(); case kClosureDataCid: return Symbols::ClosureData().raw(); + case kSignatureDataCid: + return Symbols::SignatureData().raw(); case kRedirectionDataCid: return Symbols::RedirectionData().raw(); case kFieldCid: @@ -5437,15 +5453,13 @@ RawFunction* Function::parent_function() const { - if (IsClosureFunction()) { + if (IsClosureFunction() || IsSignatureFunction()) { const Object& obj = Object::Handle(raw_ptr()->data_); ASSERT(!obj.IsNull()); - return ClosureData::Cast(obj).parent_function(); - } else if (IsSignatureFunction()) { - const Object& obj = Object::Handle(raw_ptr()->data_); - // Parent function may be null or data_ may already be set to function type. - if (!obj.IsNull() && obj.IsFunction()) { - return Function::Cast(obj).raw(); + if (IsClosureFunction()) { + return ClosureData::Cast(obj).parent_function(); + } else { + return SignatureData::Cast(obj).parent_function(); } } return Function::null(); @@ -5453,16 +5467,14 @@ void Function::set_parent_function(const Function& value) const { + const Object& obj = Object::Handle(raw_ptr()->data_); + ASSERT(!obj.IsNull()); if (IsClosureFunction()) { - const Object& obj = Object::Handle(raw_ptr()->data_); - ASSERT(!obj.IsNull()); ClosureData::Cast(obj).set_parent_function(value); - return; - } else if (IsSignatureFunction()) { - set_data(value); // Temporarily set during parsing only. - return; + } else { + ASSERT(IsSignatureFunction()); + SignatureData::Cast(obj).set_parent_function(value); } - UNREACHABLE(); } @@ -5502,12 +5514,11 @@ RawType* Function::SignatureType() const { Type& type = Type::Handle(); const Object& obj = Object::Handle(raw_ptr()->data_); + ASSERT(!obj.IsNull()); if (IsSignatureFunction()) { - ASSERT(obj.IsNull() || Type::Cast(obj).IsFunctionType()); - type = obj.IsNull() ? Type::null() : Type::Cast(obj).raw(); + type = SignatureData::Cast(obj).signature_type(); } else { ASSERT(IsClosureFunction()); - ASSERT(!obj.IsNull()); type = ClosureData::Cast(obj).signature_type(); } if (type.IsNull()) { @@ -5548,12 +5559,12 @@ void Function::SetSignatureType(const Type& value) const { + const Object& obj = Object::Handle(raw_ptr()->data_); + ASSERT(!obj.IsNull()); if (IsSignatureFunction()) { - set_data(value); + SignatureData::Cast(obj).set_signature_type(value); } else { ASSERT(IsClosureFunction()); - const Object& obj = Object::Handle(raw_ptr()->data_); - ASSERT(!obj.IsNull()); ClosureData::Cast(obj).set_signature_type(value); } } @@ -5676,7 +5687,7 @@ // This field is heavily overloaded: // eval function: Script expression source -// signature function: Function type +// signature function: SignatureData // method extractor: Function extracted closure function // noSuchMethod dispatcher: Array arguments descriptor // invoke-field dispatcher: Array arguments descriptor @@ -6547,6 +6558,9 @@ if (kind == RawFunction::kClosureFunction) { const ClosureData& data = ClosureData::Handle(ClosureData::New()); result.set_data(data); + } else if (kind == RawFunction::kSignatureFunction) { + const SignatureData& data = SignatureData::Handle(SignatureData::New()); + result.set_data(data); } return result.raw(); } @@ -6840,6 +6854,28 @@ } +RawSmi* Function::GetClosureHashCode() const { + ASSERT(IsClosureFunction()); + const Object& obj = Object::Handle(raw_ptr()->data_); + ASSERT(!obj.IsNull()); + if (ClosureData::Cast(obj).hash() != Object::null()) { + return Smi::RawCast(ClosureData::Cast(obj).hash()); + } + // Hash not yet computed. Compute and cache it. + const Class& cls = Class::Handle(Owner()); + intptr_t result = String::Handle(name()).Hash(); + result += String::Handle(Signature()).Hash(); + result += String::Handle(cls.Name()).Hash(); + // Finalize hash value like for strings so that it fits into a smi. + result += result << 3; + result ^= result >> 11; + result += result << 15; + result &= ((static_cast<intptr_t>(1) << String::kHashBits) - 1); + ClosureData::Cast(obj).set_hash(result); + return Smi::New(result); +} + + RawString* Function::BuildSignature(bool instantiate, NameVisibility name_visibility, const TypeArguments& instantiator) const { @@ -7216,6 +7252,11 @@ } +void ClosureData::set_hash(intptr_t value) const { + StorePointer(&raw_ptr()->hash_, static_cast<RawObject*>(Smi::New(value))); +} + + void ClosureData::set_parent_function(const Function& value) const { StorePointer(&raw_ptr()->parent_function_, value.raw()); } @@ -7235,7 +7276,65 @@ const char* ClosureData::ToCString() const { - return "ClosureData class"; + if (IsNull()) { + return "ClosureData: null"; + } + const Function& parent = Function::Handle(parent_function()); + const Type& type = Type::Handle(signature_type()); + return OS::SCreate(Thread::Current()->zone(), + "ClosureData: context_scope: 0x%" Px + " parent_function: %s signature_type: %s" + " implicit_static_closure: 0x%" Px, + reinterpret_cast<uword>(context_scope()), + parent.IsNull() ? "null" : parent.ToCString(), + type.IsNull() ? "null" : type.ToCString(), + reinterpret_cast<uword>(implicit_static_closure())); +} + + +void SignatureData::set_parent_function(const Function& value) const { + StorePointer(&raw_ptr()->parent_function_, value.raw()); +} + + +void SignatureData::set_signature_type(const Type& value) const { + StorePointer(&raw_ptr()->signature_type_, value.raw()); + // If the signature type is resolved, the parent function is not needed + // anymore (type parameters may be declared by generic parent functions). + // Keeping the parent function can unnecessarily pull more objects into a + // snapshot. Also, the parent function is meaningless once the signature type + // is canonicalized. + +// TODO(rmacnak): Keeping the parent function for unresolved signature types +// is causing a tree shaking issue in AOT. Please, investigate. +#if 0 + if (value.IsResolved()) { + set_parent_function(Function::Handle()); + } +#else + set_parent_function(Function::Handle()); +#endif +} + + +RawSignatureData* SignatureData::New() { + ASSERT(Object::signature_data_class() != Class::null()); + RawObject* raw = Object::Allocate(SignatureData::kClassId, + SignatureData::InstanceSize(), Heap::kOld); + return reinterpret_cast<RawSignatureData*>(raw); +} + + +const char* SignatureData::ToCString() const { + if (IsNull()) { + return "SignatureData: null"; + } + const Function& parent = Function::Handle(parent_function()); + const Type& type = Type::Handle(signature_type()); + return OS::SCreate(Thread::Current()->zone(), + "SignatureData parent_function: %s signature_type: %s", + parent.IsNull() ? "null" : parent.ToCString(), + type.IsNull() ? "null" : type.ToCString()); } @@ -7264,7 +7363,17 @@ const char* RedirectionData::ToCString() const { - return "RedirectionData class"; + if (IsNull()) { + return "RedirectionData: null"; + } + const Type& redir_type = Type::Handle(type()); + const String& ident = String::Handle(identifier()); + const Function& target_fun = Function::Handle(target()); + return OS::SCreate(Thread::Current()->zone(), + "RedirectionData: type: %s identifier: %s target: %s", + redir_type.IsNull() ? "null" : redir_type.ToCString(), + ident.IsNull() ? "null" : ident.ToCString(), + target_fun.IsNull() ? "null" : target_fun.ToCString()); } @@ -7594,7 +7703,7 @@ const char* Field::ToCString() const { if (IsNull()) { - return "Field::null"; + return "Field: null"; } const char* kF0 = is_static() ? " static" : ""; const char* kF1 = is_final() ? " final" : ""; @@ -11508,19 +11617,16 @@ #undef CHECK_FINGERPRINTS2 - Class& cls = Class::Handle(); - -#define CHECK_FACTORY_FINGERPRINTS(factory_symbol, cid, fp) \ - cls = Isolate::Current()->class_table()->At(cid); \ - func = cls.LookupFunctionAllowPrivate(Symbols::factory_symbol()); \ +#define CHECK_FACTORY_FINGERPRINTS(symbol, class_name, factory_name, cid, fp) \ + func = GetFunction(all_libs, #class_name, #factory_name); \ if (func.IsNull()) { \ has_errors = true; \ - OS::Print("Function not found %s.%s\n", cls.ToCString(), \ - Symbols::factory_symbol().ToCString()); \ + OS::Print("Function not found %s.%s\n", #class_name, #factory_name); \ } else { \ - CHECK_FINGERPRINT2(func, factory_symbol, cid, fp); \ + CHECK_FINGERPRINT2(func, symbol, cid, fp); \ } + all_libs.Add(&Library::ZoneHandle(Library::CoreLibrary())); RECOGNIZED_LIST_FACTORY_LIST(CHECK_FACTORY_FINGERPRINTS); #undef CHECK_FACTORY_FINGERPRINTS
diff --git a/runtime/vm/object.h b/runtime/vm/object.h index f3a4d29..2c62d62 100644 --- a/runtime/vm/object.h +++ b/runtime/vm/object.h
@@ -488,6 +488,7 @@ static RawClass* patch_class_class() { return patch_class_class_; } static RawClass* function_class() { return function_class_; } static RawClass* closure_data_class() { return closure_data_class_; } + static RawClass* signature_data_class() { return signature_data_class_; } static RawClass* redirection_data_class() { return redirection_data_class_; } static RawClass* field_class() { return field_class_; } static RawClass* literal_token_class() { return literal_token_class_; } @@ -745,6 +746,7 @@ static RawClass* patch_class_class_; // Class of the PatchClass vm object. static RawClass* function_class_; // Class of the Function vm object. static RawClass* closure_data_class_; // Class of ClosureData vm obj. + static RawClass* signature_data_class_; // Class of SignatureData vm obj. static RawClass* redirection_data_class_; // Class of RedirectionData vm obj. static RawClass* field_class_; // Class of the Field vm object. static RawClass* literal_token_class_; // Class of LiteralToken vm object. @@ -2345,6 +2347,8 @@ RawInstance* ImplicitInstanceClosure(const Instance& receiver) const; + RawSmi* GetClosureHashCode() const; + // Redirection information for a redirecting factory. bool IsRedirectingFactory() const; RawType* RedirectionType() const; @@ -3013,6 +3017,9 @@ RawInstance* implicit_static_closure() const { return raw_ptr()->closure_; } void set_implicit_static_closure(const Instance& closure) const; + RawObject* hash() const { return raw_ptr()->hash_; } + void set_hash(intptr_t value) const; + static RawClosureData* New(); FINAL_HEAP_OBJECT_IMPLEMENTATION(ClosureData, Object); @@ -3022,6 +3029,30 @@ }; +class SignatureData : public Object { + public: + static intptr_t InstanceSize() { + return RoundedAllocationSize(sizeof(RawSignatureData)); + } + + private: + // Enclosing function of this signature function. + RawFunction* parent_function() const { return raw_ptr()->parent_function_; } + void set_parent_function(const Function& value) const; + + // Signature type of this signature function. + RawType* signature_type() const { return raw_ptr()->signature_type_; } + void set_signature_type(const Type& value) const; + + static RawSignatureData* New(); + + FINAL_HEAP_OBJECT_IMPLEMENTATION(SignatureData, Object); + friend class Class; + friend class Function; + friend class HeapProfiler; +}; + + class RedirectionData : public Object { public: static intptr_t InstanceSize() {
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc index 93dfce9..99e1157 100644 --- a/runtime/vm/object_service.cc +++ b/runtime/vm/object_service.cc
@@ -1482,6 +1482,11 @@ } +void SignatureData::PrintJSONImpl(JSONStream* stream, bool ref) const { + Object::PrintJSONImpl(stream, ref); +} + + void Closure::PrintJSONImpl(JSONStream* stream, bool ref) const { Instance::PrintJSONImpl(stream, ref); }
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc index 9b87e85..802c472 100644 --- a/runtime/vm/parser.cc +++ b/runtime/vm/parser.cc
@@ -2089,7 +2089,6 @@ ASSERT(innermost_function().raw() == signature_function.raw()); innermost_function_ = signature_function.parent_function(); - signature_function.set_data(Object::Handle(Z)); Type& signature_type = Type::ZoneHandle(Z, signature_function.SignatureType());
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc index e45c04c..d190d5a 100644 --- a/runtime/vm/precompiler.cc +++ b/runtime/vm/precompiler.cc
@@ -678,7 +678,7 @@ {"dart:isolate", "_SendPortImpl", "send"}, {"dart:typed_data", "ByteData", "ByteData."}, {"dart:typed_data", "ByteData", "ByteData._view"}, - {"dart:typed_data", "ByteBuffer", "ByteBuffer._New"}, + {"dart:typed_data", "_ByteBuffer", "_ByteBuffer._New"}, {"dart:_vmservice", "::", "_registerIsolate"}, {"dart:_vmservice", "::", "boot"}, #if !defined(PRODUCT) @@ -2959,7 +2959,13 @@ ASSERT(pending_functions_.Length() == 0); sent_selectors_.Clear(); enqueued_functions_.Clear(); + + classes_to_retain_.Clear(); consts_to_retain_.Clear(); + fields_to_retain_.Clear(); + functions_to_retain_.Clear(); + typeargs_to_retain_.Clear(); + types_to_retain_.Clear(); Library& lib = Library::Handle(Z); Class& cls = Class::Handle(Z);
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc index a150c30..dce810e 100644 --- a/runtime/vm/profiler_test.cc +++ b/runtime/vm/profiler_test.cc
@@ -994,7 +994,7 @@ Library::Handle(isolate->object_store()->typed_data_library()); const Class& float32_list_class = - Class::Handle(GetClass(typed_data_library, "Float32List")); + Class::Handle(GetClass(typed_data_library, "_Float32List")); EXPECT(!float32_list_class.IsNull()); Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 0, NULL);
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc index 79a6193..f4a1bc1 100644 --- a/runtime/vm/raw_object.cc +++ b/runtime/vm/raw_object.cc
@@ -393,6 +393,14 @@ } +intptr_t RawSignatureData::VisitSignatureDataPointers( + RawSignatureData* raw_obj, + ObjectPointerVisitor* visitor) { + visitor->VisitPointers(raw_obj->from(), raw_obj->to()); + return SignatureData::InstanceSize(); +} + + intptr_t RawRedirectionData::VisitRedirectionDataPointers( RawRedirectionData* raw_obj, ObjectPointerVisitor* visitor) {
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h index 7c97320..f43b12e 100644 --- a/runtime/vm/raw_object.h +++ b/runtime/vm/raw_object.h
@@ -22,6 +22,7 @@ V(PatchClass) \ V(Function) \ V(ClosureData) \ + V(SignatureData) \ V(RedirectionData) \ V(Field) \ V(LiteralToken) \ @@ -861,7 +862,28 @@ RawFunction* parent_function_; // Enclosing function of this local function. RawType* signature_type_; RawInstance* closure_; // Closure object for static implicit closures. - RawObject** to() { return reinterpret_cast<RawObject**>(&ptr()->closure_); } + RawObject** to_snapshot() { + return reinterpret_cast<RawObject**>(&ptr()->closure_); + } + RawObject* hash_; + RawObject** to() { return reinterpret_cast<RawObject**>(&ptr()->hash_); } + + friend class Function; +}; + + +class RawSignatureData : public RawObject { + private: + RAW_HEAP_OBJECT_IMPLEMENTATION(SignatureData); + + RawObject** from() { + return reinterpret_cast<RawObject**>(&ptr()->parent_function_); + } + RawFunction* parent_function_; // Enclosing function of this sig. function. + RawType* signature_type_; + RawObject** to() { + return reinterpret_cast<RawObject**>(&ptr()->signature_type_); + } friend class Function; };
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc index 11ab304..77f0576 100644 --- a/runtime/vm/raw_object_snapshot.cc +++ b/runtime/vm/raw_object_snapshot.cc
@@ -590,7 +590,8 @@ reader->AddBackRef(object_id, &data, kIsDeserialized); // Set all the object fields. - READ_OBJECT_FIELDS(data, data.raw()->from(), data.raw()->to(), + // Cached hash is null-initialized by ClosureData::New() + READ_OBJECT_FIELDS(data, data.raw()->from(), data.raw()->to_snapshot(), kAsInlinedObject); return data.raw(); @@ -632,6 +633,47 @@ } +RawSignatureData* SignatureData::ReadFrom(SnapshotReader* reader, + intptr_t object_id, + intptr_t tags, + Snapshot::Kind kind, + bool as_reference) { + ASSERT(reader != NULL); + ASSERT(kind == Snapshot::kScript); + + // Allocate signature data object. + SignatureData& data = + SignatureData::ZoneHandle(reader->zone(), SignatureData::New()); + reader->AddBackRef(object_id, &data, kIsDeserialized); + + // Set all the object fields. + READ_OBJECT_FIELDS(data, data.raw()->from(), data.raw()->to(), + kAsInlinedObject); + + return data.raw(); +} + + +void RawSignatureData::WriteTo(SnapshotWriter* writer, + intptr_t object_id, + Snapshot::Kind kind, + bool as_reference) { + ASSERT(writer != NULL); + ASSERT(kind == Snapshot::kScript); + + // Write out the serialization header value for this object. + writer->WriteInlinedObjectHeader(object_id); + + // Write out the class and tags information. + writer->WriteVMIsolateObject(kSignatureDataCid); + writer->WriteTags(writer->GetObjectTags(this)); + + // Write out all the object pointer fields. + SnapshotWriterVisitor visitor(writer, kAsInlinedObject); + visitor.VisitPointers(from(), to()); +} + + RawRedirectionData* RedirectionData::ReadFrom(SnapshotReader* reader, intptr_t object_id, intptr_t tags,
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h index b3c087d..76f48a6 100644 --- a/runtime/vm/snapshot.h +++ b/runtime/vm/snapshot.h
@@ -77,6 +77,7 @@ class RawReceivePort; class RawRedirectionData; class RawScript; +class RawSignatureData; class RawSendPort; class RawSmi; class RawStackMap; @@ -542,6 +543,7 @@ friend class PatchClass; friend class RedirectionData; friend class Script; + friend class SignatureData; friend class SubtypeTestCache; friend class TokenStream; friend class Type;
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h index f03f209..30f7f90 100644 --- a/runtime/vm/symbols.h +++ b/runtime/vm/symbols.h
@@ -156,6 +156,7 @@ V(FunctionResult, "function result") \ V(FactoryResult, "factory result") \ V(ClosureData, "ClosureData") \ + V(SignatureData, "SignatureData") \ V(RedirectionData, "RedirectionData") \ V(Field, "Field") \ V(LiteralToken, "LiteralToken") \ @@ -217,20 +218,23 @@ V(Float32x4, "Float32x4") \ V(Float64x2, "Float64x2") \ V(Int32x4, "Int32x4") \ - V(Int8List, "Int8List") \ - V(Uint8List, "Uint8List") \ - V(Uint8ClampedList, "Uint8ClampedList") \ - V(Int16List, "Int16List") \ - V(Uint16List, "Uint16List") \ - V(Int32List, "Int32List") \ - V(Uint32List, "Uint32List") \ - V(Int64List, "Int64List") \ - V(Uint64List, "Uint64List") \ - V(Float32x4List, "Float32x4List") \ - V(Int32x4List, "Int32x4List") \ - V(Float64x2List, "Float64x2List") \ - V(Float32List, "Float32List") \ - V(Float64List, "Float64List") \ + V(_Float32x4, "_Float32x4") \ + V(_Float64x2, "_Float64x2") \ + V(_Int32x4, "_Int32x4") \ + V(Int8List, "_Int8List") \ + V(Uint8List, "_Uint8List") \ + V(Uint8ClampedList, "_Uint8ClampedList") \ + V(Int16List, "_Int16List") \ + V(Uint16List, "_Uint16List") \ + V(Int32List, "_Int32List") \ + V(Uint32List, "_Uint32List") \ + V(Int64List, "_Int64List") \ + V(Uint64List, "_Uint64List") \ + V(Float32x4List, "_Float32x4List") \ + V(Int32x4List, "_Int32x4List") \ + V(Float64x2List, "_Float64x2List") \ + V(Float32List, "_Float32List") \ + V(Float64List, "_Float64List") \ V(_Int8ArrayFactory, "Int8List.") \ V(_Uint8ArrayFactory, "Uint8List.") \ V(_Uint8ClampedArrayFactory, "Uint8ClampedList.") \ @@ -277,8 +281,8 @@ V(ByteDataDot, "ByteData.") \ V(ByteDataDot_view, "ByteData._view") \ V(_ByteDataView, "_ByteDataView") \ - V(ByteBuffer, "ByteBuffer") \ - V(ByteBufferDot_New, "ByteBuffer._New") \ + V(_ByteBuffer, "_ByteBuffer") \ + V(_ByteBufferDot_New, "_ByteBuffer._New") \ V(_WeakProperty, "_WeakProperty") \ V(_MirrorReference, "_MirrorReference") \ V(FreeListElement, "FreeListElement") \
diff --git a/runtime/vm/virtual_memory.cc b/runtime/vm/virtual_memory.cc index 1e62f8b..93e3b84 100644 --- a/runtime/vm/virtual_memory.cc +++ b/runtime/vm/virtual_memory.cc
@@ -20,7 +20,7 @@ ASSERT(new_size <= size()); if (try_unmap && (reserved_size_ == size()) && /* Don't create holes in reservation. */ - FreeSubSegment(reinterpret_cast<void*>(start() + new_size), + FreeSubSegment(handle(), reinterpret_cast<void*>(start() + new_size), size() - new_size)) { reserved_size_ = new_size; }
diff --git a/runtime/vm/virtual_memory.h b/runtime/vm/virtual_memory.h index a26b8ce7..baa714d 100644 --- a/runtime/vm/virtual_memory.h +++ b/runtime/vm/virtual_memory.h
@@ -73,7 +73,7 @@ // Free a sub segment. On operating systems that support it this // can give back the virtual memory to the system. Returns true on success. - static bool FreeSubSegment(void* address, intptr_t size); + static bool FreeSubSegment(int32_t handle, void* address, intptr_t size); // This constructor is only used internally when reserving new virtual spaces. // It does not reserve any virtual address space on its own.
diff --git a/runtime/vm/virtual_memory_android.cc b/runtime/vm/virtual_memory_android.cc index 7406d22..bae5a82 100644 --- a/runtime/vm/virtual_memory_android.cc +++ b/runtime/vm/virtual_memory_android.cc
@@ -60,7 +60,9 @@ } -bool VirtualMemory::FreeSubSegment(void* address, intptr_t size) { +bool VirtualMemory::FreeSubSegment(int32_t handle, + void* address, + intptr_t size) { unmap(address, size); return true; }
diff --git a/runtime/vm/virtual_memory_fuchsia.cc b/runtime/vm/virtual_memory_fuchsia.cc index bfbac54..0e627ec 100644 --- a/runtime/vm/virtual_memory_fuchsia.cc +++ b/runtime/vm/virtual_memory_fuchsia.cc
@@ -7,13 +7,27 @@ #include "vm/virtual_memory.h" +#include <magenta/status.h> #include <magenta/syscalls.h> -#include <unistd.h> // NOLINT +#include <sys/mman.h> +#include <unistd.h> #include "platform/assert.h" +#include "vm/isolate.h" #include "vm/memory_region.h" #include "vm/os.h" +// #define VIRTUAL_MEMORY_LOGGING 1 +#if defined(VIRTUAL_MEMORY_LOGGING) +#define LOG_ERR(msg, ...) \ + OS::PrintErr("VMVM: %s:%d: " msg, __FILE__, __LINE__, ##__VA_ARGS__) +#define LOG_INFO(msg, ...) \ + OS::Print("VMVM: %s:%d: " msg, __FILE__, __LINE__, ##__VA_ARGS__) +#else +#define LOG_ERR(msg, ...) +#define LOG_INFO(msg, ...) +#endif // defined(VIRTUAL_MEMORY_LOGGING) + namespace dart { uword VirtualMemory::page_size_ = 0; @@ -25,65 +39,86 @@ VirtualMemory* VirtualMemory::ReserveInternal(intptr_t size) { - mx_handle_t vmo = MX_HANDLE_INVALID; - mx_status_t status = mx_vmo_create(size, 0u, &vmo); + mx_handle_t vmar = MX_HANDLE_INVALID; + uword addr = 0; + const uint32_t flags = MX_VM_FLAG_COMPACT | MX_VM_FLAG_CAN_MAP_SPECIFIC | + MX_VM_FLAG_CAN_MAP_READ | MX_VM_FLAG_CAN_MAP_WRITE | + MX_VM_FLAG_CAN_MAP_EXECUTE; + mx_status_t status = + mx_vmar_allocate(mx_vmar_root_self(), 0, size, flags, &vmar, &addr); if (status != NO_ERROR) { - return NULL; - } - - // TODO(zra): map with PERM_NONE, when that works, and relax with - // Commit and Protect when they are implemented. - // Issue MG-161. - const int prot = - MX_VM_FLAG_PERM_READ | MX_VM_FLAG_PERM_WRITE | MX_VM_FLAG_PERM_EXECUTE; - uintptr_t addr; - status = mx_vmar_map(mx_vmar_root_self(), 0, vmo, 0, size, prot, &addr); - if (status != NO_ERROR) { - mx_handle_close(vmo); - FATAL("VirtualMemory::ReserveInternal FAILED"); + LOG_ERR("mx_vmar_allocate(size = %ld) failed: %s\n", size, + mx_status_get_string(status)); return NULL; } MemoryRegion region(reinterpret_cast<void*>(addr), size); - return new VirtualMemory(region, vmo); + return new VirtualMemory(region, vmar); } VirtualMemory::~VirtualMemory() { if (!embedder_allocated()) { - // TODO(zra): Use reserved_size_. - // Issue MG-162. - uintptr_t addr = reinterpret_cast<uintptr_t>(address()); - mx_status_t status = - mx_vmar_unmap(mx_vmar_root_self(), addr, 0 /*reserved_size_*/); + mx_handle_t vmar = static_cast<mx_handle_t>(handle()); + mx_status_t status = mx_vmar_destroy(vmar); if (status != NO_ERROR) { - FATAL("VirtualMemory::~VirtualMemory: unamp FAILED"); + LOG_ERR("mx_vmar_destroy failed: %s\n", mx_status_get_string(status)); } - - status = mx_handle_close(handle()); + status = mx_handle_close(vmar); if (status != NO_ERROR) { - FATAL("VirtualMemory::~VirtualMemory: handle_close FAILED"); + LOG_ERR("mx_handle_close failed: %s\n", mx_status_get_string(status)); } } } -bool VirtualMemory::FreeSubSegment(void* address, intptr_t size) { - // TODO(zra): It should be possible to free a subsegment after - // Issue MG-162 is addressed. - return false; +bool VirtualMemory::FreeSubSegment(int32_t handle, + void* address, + intptr_t size) { + mx_handle_t vmar = static_cast<mx_handle_t>(handle); + mx_status_t status = + mx_vmar_unmap(vmar, reinterpret_cast<uintptr_t>(address), size); + if (status != NO_ERROR) { + LOG_ERR("mx_vmar_unmap failed: %s\n", mx_status_get_string(status)); + return false; + } + return true; } bool VirtualMemory::Commit(uword addr, intptr_t size, bool executable) { - // TODO(zra): Implement when the protections for a mapping can be changed. - // Issue MG-133. + ASSERT(Contains(addr)); + ASSERT(Contains(addr + size) || (addr + size == end())); + mx_handle_t vmo = MX_HANDLE_INVALID; + mx_status_t status = mx_vmo_create(size, 0u, &vmo); + if (status != NO_ERROR) { + LOG_ERR("mx_vmo_create(%ld) failed: %s\n", size, + mx_status_get_string(status)); + return false; + } + + mx_handle_t vmar = static_cast<mx_handle_t>(handle()); + const size_t offset = addr - start(); + const uint32_t flags = MX_VM_FLAG_SPECIFIC | MX_VM_FLAG_PERM_READ | + MX_VM_FLAG_PERM_WRITE | MX_VM_FLAG_PERM_EXECUTE; + uintptr_t mapped_addr; + status = mx_vmar_map(vmar, offset, vmo, 0, size, flags, &mapped_addr); + if (status != NO_ERROR) { + mx_handle_close(vmo); + LOG_ERR("mx_vmar_map(%ld, %ld, %u) failed: %s\n", offset, size, flags, + mx_status_get_string(status)); + return false; + } + if (addr != mapped_addr) { + LOG_ERR("mx_vmar_map: addr != mapped_addr: %lx != %lx\n", addr, + mapped_addr); + return false; + } return true; } bool VirtualMemory::Protect(void* address, intptr_t size, Protection mode) { - // TODO(zra): Implement when Fuchsia has an mprotect-like call. return true; }
diff --git a/runtime/vm/virtual_memory_linux.cc b/runtime/vm/virtual_memory_linux.cc index be3655f..3c4abec 100644 --- a/runtime/vm/virtual_memory_linux.cc +++ b/runtime/vm/virtual_memory_linux.cc
@@ -59,7 +59,9 @@ } -bool VirtualMemory::FreeSubSegment(void* address, intptr_t size) { +bool VirtualMemory::FreeSubSegment(int32_t handle, + void* address, + intptr_t size) { unmap(address, size); return true; }
diff --git a/runtime/vm/virtual_memory_macos.cc b/runtime/vm/virtual_memory_macos.cc index 6f42b55..c3b004d 100644 --- a/runtime/vm/virtual_memory_macos.cc +++ b/runtime/vm/virtual_memory_macos.cc
@@ -60,7 +60,9 @@ } -bool VirtualMemory::FreeSubSegment(void* address, intptr_t size) { +bool VirtualMemory::FreeSubSegment(int32_t handle, + void* address, + intptr_t size) { unmap(address, size); return true; }
diff --git a/runtime/vm/virtual_memory_win.cc b/runtime/vm/virtual_memory_win.cc index de9156d..7e876a4 100644 --- a/runtime/vm/virtual_memory_win.cc +++ b/runtime/vm/virtual_memory_win.cc
@@ -44,7 +44,9 @@ } -bool VirtualMemory::FreeSubSegment(void* address, intptr_t size) { +bool VirtualMemory::FreeSubSegment(int32_t handle, + void* address, + intptr_t size) { // On Windows only the entire segment returned by VirtualAlloc // can be freed. Therefore we will have to waste these unused // virtual memory sub-segments.
diff --git a/runtime/vm/vm.gypi b/runtime/vm/vm.gypi index 3da3291..a8c0e74 100644 --- a/runtime/vm/vm.gypi +++ b/runtime/vm/vm.gypi
@@ -30,6 +30,7 @@ 'snapshot_test_in_dat_file': 'snapshot_test_in.dat', 'snapshot_test_dart_file': 'snapshot_test.dart', 'typed_data_cc_file': '<(gen_source_dir)/typed_data_gen.cc', + 'typed_data_patch_cc_file': '<(gen_source_dir)/typed_data_patch_gen.cc', 'vmservice_cc_file': '<(gen_source_dir)/vmservice_gen.cc', 'vmservice_patch_cc_file': '<(gen_source_dir)/vmservice_patch_gen.cc', }, @@ -233,6 +234,7 @@ 'generate_mirrors_patch_cc_file#host', 'generate_profiler_cc_file#host', 'generate_typed_data_cc_file#host', + 'generate_typed_data_patch_cc_file#host', 'generate_vmservice_cc_file#host', 'generate_vmservice_patch_cc_file#host', ], @@ -271,6 +273,7 @@ '<(mirrors_patch_cc_file)', '<(profiler_cc_file)', '<(typed_data_cc_file)', + '<(typed_data_patch_cc_file)', '<(vmservice_cc_file)', '<(vmservice_patch_cc_file)', ], @@ -967,16 +970,12 @@ ] }, { - # Unlike the other libraries in the SDK, dart:typed_data is not - # implemented as a patch applied to the base SDK implementation. - # Instead the VM has a complete replacement library and the - # implementation in the SDK is ignored. 'target_name': 'generate_typed_data_cc_file', 'type': 'none', 'toolsets':['host'], 'includes': [ # Load the runtime implementation sources. - '../lib/typed_data_sources.gypi', + '../../sdk/lib/typed_data/typed_data_sources.gypi', ], 'sources/': [ # Exclude all .[cc|h] files. @@ -1011,6 +1010,46 @@ ] }, { + 'target_name': 'generate_typed_data_patch_cc_file', + 'type': 'none', + 'toolsets':['host'], + 'includes': [ + # Load the patch sources. + '../lib/typed_data_sources.gypi', + ], + 'sources/': [ + # Exclude all .[cc|h] files. + # This is only here for reference. Excludes happen after + # variable expansion, so the script has to do its own + # exclude processing of the sources being passed. + ['exclude', '\\.cc|h$'], + ], + 'actions': [ + { + 'action_name': 'generate_typed_data_patch_cc', + 'inputs': [ + '../tools/gen_library_src_paths.py', + '<(libgen_in_cc_file)', + '<@(_sources)', + ], + 'outputs': [ + '<(typed_data_patch_cc_file)', + ], + 'action': [ + 'python', + 'tools/gen_library_src_paths.py', + '--output', '<(typed_data_patch_cc_file)', + '--input_cc', '<(libgen_in_cc_file)', + '--include', 'vm/bootstrap.h', + '--var_name', 'dart::Bootstrap::typed_data_patch_paths_', + '--library_name', 'dart:typed_data', + '<@(_sources)', + ], + 'message': 'Generating ''<(typed_data_patch_cc_file)'' file.' + }, + ] + }, + { 'target_name': 'generate_profiler_cc_file', 'type': 'none', 'toolsets':['host'], @@ -1255,6 +1294,7 @@ 'generate_math_library_patch', 'generate_mirrors_library_patch', 'generate_profiler_library_patch', + 'generate_typed_data_library_patch', 'generate_vmservice_library_patch', ], 'actions': [ @@ -1265,11 +1305,6 @@ '"dart$", "sdk/lib"])', '../../tools/patch_sdk.py', '../../tools/patch_sdk.dart', - # Unlike the other libraries in the SDK, dart:typed_data is not - # implemented as a patch applied to the base SDK implementation. - # Instead the VM has a complete replacement library and the - # implementation in the SDK is ignored. - '../lib/typed_data.dart', # Unlike the other libraries in the SDK, dart:_builtin and # dart:nativewrappers are only available for the Dart VM. '../bin/builtin.dart', @@ -1287,6 +1322,7 @@ '<(gen_source_dir)/patches/math_patch.dart', '<(gen_source_dir)/patches/mirrors_patch.dart', '<(gen_source_dir)/patches/profiler_patch.dart', + '<(gen_source_dir)/patches/typed_data_patch.dart', '<(gen_source_dir)/patches/vmservice_patch.dart', ], 'outputs': [ @@ -1660,6 +1696,38 @@ }, { 'variables': { + 'library_name': 'typed_data', + 'library_uri': 'dart:typed_data', + }, + 'target_name': 'generate_<(library_name)_library_patch', + 'type': 'none', + 'toolsets': ['host'], + 'includes': [ + '../lib/typed_data_sources.gypi', + ], + 'actions': [ + { + 'action_name': 'concatenate_<(library_name)_patches', + 'inputs': [ + '../tools/concatenate_patches.py', + '<@(_sources)', + ], + 'outputs': [ + '<(gen_source_dir)/patches/<(library_name)_patch.dart' + ], + 'action': [ + 'python', + 'tools/concatenate_patches.py', + '--output', + '<(gen_source_dir)/patches/<(library_name)_patch.dart', + '<@(_sources)', + ], + 'message': 'Generating <(library_uri) patch.', + }, + ], + }, + { + 'variables': { 'library_name': 'vmservice', 'library_uri': 'dart:_vmservice', },
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart index a80f0e2..07d1cbb 100644 --- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart +++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -154,6 +154,15 @@ JS_GET_NAME(JsGetName.FUNCTION_CLASS_TYPE_NAME)); } +/// Returns true if the given [type] is _the_ `Null` type. +@ForceInline() +bool isNullType(Object type) { + return JS_BUILTIN('returns:bool;effects:none;depends:none', + JsBuiltin.isGivenTypeRti, + type, + JS_GET_NAME(JsGetName.NULL_CLASS_TYPE_NAME)); +} + /// Returns whether the given type is _the_ Dart Object type. // TODO(floitsch): move this to foreign_helper.dart or similar. @ForceInline()
diff --git a/sdk/lib/_internal/js_runtime/lib/js_rti.dart b/sdk/lib/_internal/js_runtime/lib/js_rti.dart index 0ce3e69..f9cd698 100644 --- a/sdk/lib/_internal/js_runtime/lib/js_rti.dart +++ b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
@@ -448,12 +448,13 @@ if (isIdentical(s, t)) return true; // If either type is dynamic, [s] is a subtype of [t]. if (s == null || t == null) return true; + if (isNullType(s)) return true; if (isDartFunctionType(t)) { return isFunctionSubtype(s, t); } - // Check function types against the Function class. + // Check function types against the Function class and the Object class. if (isDartFunctionType(s)) { - return isDartFunctionTypeRti(t); + return isDartFunctionTypeRti(t) || isDartObjectTypeRti(t); } // Get the object describing the class and check for the subtyping flag
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart index d16d0d0..ad4adaf 100644 --- a/sdk/lib/html/dart2js/html_dart2js.dart +++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -1209,8 +1209,8 @@ return _create_2(blobParts, bag); } - static _create_1(parts) => JS('Blob', 'new window.Blob(#)', parts); - static _create_2(parts, bag) => JS('Blob', 'new window.Blob(#, #)', parts, bag); + static _create_1(parts) => JS('Blob', 'new self.Blob(#)', parts); + static _create_2(parts, bag) => JS('Blob', 'new self.Blob(#, #)', parts, bag); static _create_bag() => JS('var', '{}'); static _bag_set(bag, key, value) { JS('void', '#[#] = #', bag, key, value); }
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status index 6ee00c2..8a461b2 100644 --- a/tests/co19/co19-dart2js.status +++ b/tests/co19/co19-dart2js.status
@@ -5026,8 +5026,7 @@ LibTest/html/Element/getBoundingClientRect_A01_t02: Pass, RuntimeError # Issue 53 LibTest/html/Element/getClientRects_A01_t02: RuntimeError # Please triage this failure LibTest/html/Element/getNamespacedAttributes_A01_t01: RuntimeError # Please triage this failure -LibTest/html/Element/isContentEditable_A01_t01: RuntimeError # Fails 10 out of 10. -LibTest/html/Element/isContentEditable_A01_t01: RuntimeError # Please triage this failure +LibTest/html/Element/isContentEditable_A01_t01: Pass, RuntimeError # Issue 28187 LibTest/html/Element/isContentEditable_A02_t01: RuntimeError # Fails 10 out of 10. LibTest/html/Element/isTagSupported_A01_t01: RuntimeError # Please triage this failure LibTest/html/Element/isTagSupported_A01_t02: RuntimeError # Please triage this failure
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status index 22d2c68..4b3bfaf 100644 --- a/tests/compiler/dart2js/dart2js.status +++ b/tests/compiler/dart2js/dart2js.status
@@ -69,6 +69,7 @@ value_range_test: Pass, Slow jsinterop/world_test: Pass, Slow sourcemaps/stacktrace_test: Pass, Slow +kernel/impact_test: Skip # Times out. Issue 28157 [ $mode == debug ] check_elements_invariants_test: Skip # Slow and only needs to be run in one
diff --git a/tests/compiler/dart2js/expect_annotations_test.dart b/tests/compiler/dart2js/expect_annotations_test.dart index e8b5e18..9af76b7 100644 --- a/tests/compiler/dart2js/expect_annotations_test.dart +++ b/tests/compiler/dart2js/expect_annotations_test.dart
@@ -106,8 +106,8 @@ TypeMask jsStringType = closedWorld.commonMasks.stringType; TypeMask jsIntType = closedWorld.commonMasks.intType; - TypeMask coreStringType = - new TypeMask.subtype(compiler.coreClasses.stringClass, closedWorld); + TypeMask coreStringType = new TypeMask.subtype( + closedWorld.commonElements.stringClass, closedWorld); test('method'); test('methodAssumeDynamic', expectAssumeDynamic: true);
diff --git a/tests/compiler/dart2js/jsinterop/world_test.dart b/tests/compiler/dart2js/jsinterop/world_test.dart index 0337799..1ddbd39 100644 --- a/tests/compiler/dart2js/jsinterop/world_test.dart +++ b/tests/compiler/dart2js/jsinterop/world_test.dart
@@ -89,7 +89,8 @@ ClosedWorld world = env.closedWorld; JavaScriptBackend backend = env.compiler.backend; - ClassElement Object_ = registerClass(env.compiler.coreClasses.objectClass); + ClassElement Object_ = + registerClass(env.compiler.commonElements.objectClass); ClassElement Interceptor = registerClass(backend.helpers.jsInterceptorClass); ClassElement JavaScriptObject =
diff --git a/tests/compiler/dart2js/kernel/closed_world_test.dart b/tests/compiler/dart2js/kernel/closed_world_test.dart index 60a4505..c51d57c 100644 --- a/tests/compiler/dart2js/kernel/closed_world_test.dart +++ b/tests/compiler/dart2js/kernel/closed_world_test.dart
@@ -80,7 +80,7 @@ worldBuilder.useInstantiationMap = true; compiler.resolution.retainCachesForTesting = true; await compiler.run(entryPoint); - compiler.resolverWorld.openWorld.closeWorld(compiler.reporter); + compiler.resolverWorld.closeWorld(compiler.reporter); JavaScriptBackend backend = compiler.backend; // Create a new resolution enqueuer and feed it with the [WorldImpact]s @@ -114,8 +114,7 @@ .transformResolutionImpact(enqueuer, resolutionImpact); enqueuer.applyImpact(worldImpact, impactSource: element); }); - ClosedWorld closedWorld = - enqueuer.universe.openWorld.closeWorld(compiler.reporter); + ClosedWorld closedWorld = enqueuer.universe.closeWorld(compiler.reporter); checkResolutionEnqueuers(compiler.enqueuer.resolution, enqueuer, typeEquivalence: (DartType a, DartType b) {
diff --git a/tests/compiler/dart2js/mirrors_used_test.dart b/tests/compiler/dart2js/mirrors_used_test.dart index 9282b16..3975516 100644 --- a/tests/compiler/dart2js/mirrors_used_test.dart +++ b/tests/compiler/dart2js/mirrors_used_test.dart
@@ -50,9 +50,9 @@ diagnosticHandler: new LegacyCompilerDiagnostics(expectOnlyVerboseInfo), options: ['--enable-experimental-mirrors']); CompilerImpl compiler = result.compiler; + JavaScriptBackend backend = compiler.backend; print(''); - List generatedCode = - Elements.sortedByPosition(compiler.enqueuer.codegen.processedEntities); + List generatedCode = Elements.sortedByPosition(backend.generatedCode.keys); for (var element in generatedCode) { print(element); } @@ -84,15 +84,14 @@ // We always include the names of some native classes. List<Element> nativeClasses = [ - compiler.coreClasses.intClass, - compiler.coreClasses.doubleClass, - compiler.coreClasses.numClass, - compiler.coreClasses.stringClass, - compiler.coreClasses.boolClass, - compiler.coreClasses.nullClass, - compiler.coreClasses.listClass + compiler.commonElements.intClass, + compiler.commonElements.doubleClass, + compiler.commonElements.numClass, + compiler.commonElements.stringClass, + compiler.commonElements.boolClass, + compiler.commonElements.nullClass, + compiler.commonElements.listClass ]; - JavaScriptBackend backend = compiler.backend; Iterable<String> nativeNames = nativeClasses.map(backend.namer.className); expectedNames = expectedNames.map(backend.namer.asName).toList(); expectedNames.addAll(nativeNames);
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart index fb5f8243..f82aa5a 100644 --- a/tests/compiler/dart2js/mock_compiler.dart +++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -148,7 +148,7 @@ // dynamic invocation the ArgumentTypesRegistry eventually iterates over // the interfaces of the Object class which would be 'null' if the class // wasn't resolved. - coreClasses.objectClass.ensureResolved(resolution); + commonElements.objectClass.ensureResolved(resolution); }).then((_) => uri); }
diff --git a/tests/compiler/dart2js/null_is_bottom_test.dart b/tests/compiler/dart2js/null_is_bottom_test.dart new file mode 100644 index 0000000..4d2ca6b --- /dev/null +++ b/tests/compiler/dart2js/null_is_bottom_test.dart
@@ -0,0 +1,21 @@ +// Copyright (c) 2016, 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. + +// Test that dart2js produces the expected static type warnings for proxy +// language tests. This ensures that the analyzer and dart2js agrees on these +// tests. + +import 'warnings_checker.dart'; + +/// Map from test files to a map of their expected status. If the status map is +/// `null` no warnings must be missing or unexpected, otherwise the status map +/// can contain a list of line numbers for keys 'missing' and 'unexpected' for +/// the warnings of each category. +const Map<String, dynamic> TESTS = const { + 'language/null_is_bottom_type_test.dart': null, +}; + +void main(List<String> args) { + checkWarnings(TESTS, args); +}
diff --git a/tests/compiler/dart2js/related_types.dart b/tests/compiler/dart2js/related_types.dart index 61203ec..2db7785 100644 --- a/tests/compiler/dart2js/related_types.dart +++ b/tests/compiler/dart2js/related_types.dart
@@ -79,9 +79,7 @@ ClosedWorld get world => compiler.resolverWorld.closedWorldForTesting; - CoreClasses get coreClasses => compiler.coreClasses; - - CoreTypes get coreTypes => compiler.coreTypes; + CommonElements get commonElements => compiler.commonElements; DiagnosticReporter get reporter => compiler.reporter; @@ -165,7 +163,7 @@ /// Returns the supertype of [receiver] that implements `Iterable`, if any. InterfaceType findIterableType(DartType receiver) { - return findClassType(receiver, coreClasses.iterableClass); + return findClassType(receiver, commonElements.iterableClass); } /// Returns the element type of the supertype of [receiver] that implements @@ -177,7 +175,7 @@ /// Returns the supertype of [receiver] that implements `Map`, if any. InterfaceType findMapType(DartType receiver) { - return findClassType(receiver, coreClasses.mapClass); + return findClassType(receiver, commonElements.mapClass); } /// Returns the key type of the supertype of [receiver] that implements @@ -196,7 +194,7 @@ /// Returns the supertype of [receiver] that implements `List`, if any. InterfaceType findListType(DartType receiver) { - return findClassType(receiver, coreClasses.listClass); + return findClassType(receiver, commonElements.listClass); } /// Returns the element type of the supertype of [receiver] that implements @@ -260,7 +258,7 @@ DartType leftType = apply(left); DartType rightType = apply(right); checkRelated(node, leftType, rightType); - return coreTypes.boolType; + return commonElements.boolType; } @override @@ -268,7 +266,7 @@ DartType leftType = apply(left); DartType rightType = apply(right); checkRelated(node, leftType, rightType); - return coreTypes.boolType; + return commonElements.boolType; } @override @@ -284,17 +282,17 @@ @override DartType visitLiteralInt(LiteralInt node) { - return coreTypes.intType; + return commonElements.intType; } @override DartType visitLiteralString(LiteralString node) { - return coreTypes.stringType; + return commonElements.stringType; } @override DartType visitLiteralBool(LiteralBool node) { - return coreTypes.boolType; + return commonElements.boolType; } @override
diff --git a/tests/compiler/dart2js/resolver_test.dart b/tests/compiler/dart2js/resolver_test.dart index 7be75ef1..f49f8e5 100644 --- a/tests/compiler/dart2js/resolver_test.dart +++ b/tests/compiler/dart2js/resolver_test.dart
@@ -164,8 +164,10 @@ ResolverVisitor visitor = compiler.resolverVisitor(); compiler.parseScript('class Foo<T, U> {}'); ClassElement foo = compiler.mainApp.find('Foo'); - matchResolvedTypes(visitor, 'Foo<int, String> x;', 'Foo', - [compiler.coreClasses.intClass, compiler.coreClasses.stringClass]); + matchResolvedTypes(visitor, 'Foo<int, String> x;', 'Foo', [ + compiler.commonElements.intClass, + compiler.commonElements.stringClass + ]); matchResolvedTypes(visitor, 'Foo<Foo, Foo> x;', 'Foo', [foo, foo]); }), MockCompiler.create((MockCompiler compiler) {
diff --git a/tests/compiler/dart2js/serialization/model_test_helper.dart b/tests/compiler/dart2js/serialization/model_test_helper.dart index 735205d..4ac1e1e 100644 --- a/tests/compiler/dart2js/serialization/model_test_helper.dart +++ b/tests/compiler/dart2js/serialization/model_test_helper.dart
@@ -162,8 +162,10 @@ checkClassHierarchyNodes( closedWorld1, closedWorld2, - closedWorld1.getClassHierarchyNode(closedWorld1.coreClasses.objectClass), - closedWorld2.getClassHierarchyNode(closedWorld2.coreClasses.objectClass), + closedWorld1 + .getClassHierarchyNode(closedWorld1.commonElements.objectClass), + closedWorld2 + .getClassHierarchyNode(closedWorld2.commonElements.objectClass), verbose: verbose); } @@ -334,10 +336,10 @@ if (child.isInstantiated) { print('Missing subclass ${child.cls} of ${node1.cls} ' 'in ${node2.directSubclasses}'); - print(closedWorld1 - .dump(verbose ? closedWorld1.coreClasses.objectClass : node1.cls)); - print(closedWorld2 - .dump(verbose ? closedWorld2.coreClasses.objectClass : node2.cls)); + print(closedWorld1.dump( + verbose ? closedWorld1.commonElements.objectClass : node1.cls)); + print(closedWorld2.dump( + verbose ? closedWorld2.commonElements.objectClass : node2.cls)); } Expect.isFalse( child.isInstantiated,
diff --git a/tests/compiler/dart2js/simple_inferrer_test.dart b/tests/compiler/dart2js/simple_inferrer_test.dart index 08b5620..fb54674 100644 --- a/tests/compiler/dart2js/simple_inferrer_test.dart +++ b/tests/compiler/dart2js/simple_inferrer_test.dart
@@ -761,7 +761,7 @@ checkReturn('returnEmpty1', const TypeMask.nonNullEmpty()); checkReturn('returnEmpty2', const TypeMask.nonNullEmpty()); TypeMask intType = new TypeMask.nonNullSubtype( - compiler.coreClasses.intClass, closedWorld); + compiler.commonElements.intClass, closedWorld); checkReturn('testIsCheck1', intType); checkReturn('testIsCheck2', intType); checkReturn('testIsCheck3', intType.nullable()); @@ -796,7 +796,7 @@ checkReturn( 'returnAsString', new TypeMask.subtype( - compiler.coreClasses.stringClass, closedWorld)); + compiler.commonElements.stringClass, closedWorld)); checkReturn('returnIntAsNum', commonMasks.uint31Type); checkReturn('returnAsTypedef', commonMasks.functionType.nullable()); checkReturn('returnTopLevelGetter', commonMasks.uint31Type);
diff --git a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart index b6fc660..e02a22b 100644 --- a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart +++ b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
@@ -187,7 +187,7 @@ checkReturn( 'returnInt6', new TypeMask.nonNullSubtype( - closedWorld.coreClasses.intClass, closedWorld)); + closedWorld.commonElements.intClass, closedWorld)); var subclassOfInterceptor = commonMasks.interceptorType;
diff --git a/tests/compiler/dart2js/subtype_test.dart b/tests/compiler/dart2js/subtype_test.dart index ad8fba5..bae104f 100644 --- a/tests/compiler/dart2js/subtype_test.dart +++ b/tests/compiler/dart2js/subtype_test.dart
@@ -60,6 +60,7 @@ DartType String_ = env['String']; DartType dynamic_ = env['dynamic']; DartType void_ = env['void']; + DartType Null_ = env['Null']; expect(true, void_, void_); expect(true, void_, dynamic_); @@ -67,78 +68,105 @@ expect(true, dynamic_, void_, expectMoreSpecific: false); expect(false, void_, Object_); expect(false, Object_, void_); + expect(true, Null_, void_); expect(true, Object_, Object_); expect(true, num_, Object_); expect(true, int_, Object_); expect(true, String_, Object_); expect(true, dynamic_, Object_, expectMoreSpecific: false); + expect(true, Null_, Object_); expect(false, Object_, num_); expect(true, num_, num_); expect(true, int_, num_); expect(false, String_, num_); expect(true, dynamic_, num_, expectMoreSpecific: false); + expect(true, Null_, num_); expect(false, Object_, int_); expect(false, num_, int_); expect(true, int_, int_); expect(false, String_, int_); expect(true, dynamic_, int_, expectMoreSpecific: false); + expect(true, Null_, int_); expect(false, Object_, String_); expect(false, num_, String_); expect(false, int_, String_); expect(true, String_, String_); expect(true, dynamic_, String_, expectMoreSpecific: false); + expect(true, Null_, String_); expect(true, Object_, dynamic_); expect(true, num_, dynamic_); expect(true, int_, dynamic_); expect(true, String_, dynamic_); expect(true, dynamic_, dynamic_); + expect(true, Null_, dynamic_); + + expect(false, Object_, Null_); + expect(false, num_, Null_); + expect(false, int_, Null_); + expect(false, String_, Null_); + expect(true, dynamic_, Null_, expectMoreSpecific: false); + expect(true, Null_, Null_); DartType A_Object = instantiate(A, [Object_]); DartType A_num = instantiate(A, [num_]); DartType A_int = instantiate(A, [int_]); DartType A_String = instantiate(A, [String_]); DartType A_dynamic = instantiate(A, [dynamic_]); + DartType A_Null = instantiate(A, [Null_]); expect(true, A_Object, Object_); expect(false, A_Object, num_); expect(false, A_Object, int_); expect(false, A_Object, String_); expect(true, A_Object, dynamic_); + expect(false, A_Object, Null_); expect(true, A_Object, A_Object); expect(true, A_num, A_Object); expect(true, A_int, A_Object); expect(true, A_String, A_Object); expect(true, A_dynamic, A_Object, expectMoreSpecific: false); + expect(true, A_Null, A_Object); expect(false, A_Object, A_num); expect(true, A_num, A_num); expect(true, A_int, A_num); expect(false, A_String, A_num); expect(true, A_dynamic, A_num, expectMoreSpecific: false); + expect(true, A_Null, A_num); expect(false, A_Object, A_int); expect(false, A_num, A_int); expect(true, A_int, A_int); expect(false, A_String, A_int); expect(true, A_dynamic, A_int, expectMoreSpecific: false); + expect(true, A_Null, A_int); expect(false, A_Object, A_String); expect(false, A_num, A_String); expect(false, A_int, A_String); expect(true, A_String, A_String); expect(true, A_dynamic, A_String, expectMoreSpecific: false); + expect(true, A_Null, A_String); expect(true, A_Object, A_dynamic); expect(true, A_num, A_dynamic); expect(true, A_int, A_dynamic); expect(true, A_String, A_dynamic); expect(true, A_dynamic, A_dynamic); + expect(true, A_Null, A_dynamic); + + expect(false, A_Object, A_Null); + expect(false, A_num, A_Null); + expect(false, A_int, A_Null); + expect(false, A_String, A_Null); + expect(true, A_dynamic, A_Null, expectMoreSpecific: false); + expect(true, A_Null, A_Null); DartType B_Object_Object = instantiate(B, [Object_, Object_]); DartType B_num_num = instantiate(B, [num_, num_]);
diff --git a/tests/compiler/dart2js/trust_type_annotations_test.dart b/tests/compiler/dart2js/trust_type_annotations_test.dart index 70fb5f1..abf00f0 100644 --- a/tests/compiler/dart2js/trust_type_annotations_test.dart +++ b/tests/compiler/dart2js/trust_type_annotations_test.dart
@@ -69,7 +69,7 @@ } var intMask = - new TypeMask.subtype(compiler.coreClasses.intClass, closedWorld); + new TypeMask.subtype(compiler.commonElements.intClass, closedWorld); checkReturn('foo', intMask); checkReturn('faa', intMask);
diff --git a/tests/compiler/dart2js/type_checker_test.dart b/tests/compiler/dart2js/type_checker_test.dart index 96dba28..0ca2865 100644 --- a/tests/compiler/dart2js/type_checker_test.dart +++ b/tests/compiler/dart2js/type_checker_test.dart
@@ -75,10 +75,10 @@ Expect.equals(type, analyzeType(compiler, code)); } - checkType(compiler.coreTypes.intType, "3"); - checkType(compiler.coreTypes.boolType, "false"); - checkType(compiler.coreTypes.boolType, "true"); - checkType(compiler.coreTypes.stringType, "'hestfisk'"); + checkType(compiler.commonElements.intType, "3"); + checkType(compiler.commonElements.boolType, "false"); + checkType(compiler.commonElements.boolType, "true"); + checkType(compiler.commonElements.stringType, "'hestfisk'"); } Future testReturn(MockCompiler compiler) { @@ -2699,7 +2699,7 @@ new TypeCheckerVisitor(compiler, mapping, compiler.types); DiagnosticCollector collector = compiler.diagnosticCollector; collector.clear(); - checker.analyze(node); + checker.analyze(node, mustHaveType: false); compareWarningKinds(text, expectedWarnings, collector.warnings); compiler.diagnosticHandler = null; @@ -2736,7 +2736,7 @@ new TypeCheckerVisitor(compiler, elements, compiler.types); DiagnosticCollector collector = compiler.diagnosticCollector; collector.clear(); - checker.analyze(node); + checker.analyze(node, mustHaveType: false); if (flushDeferred) { compiler.enqueuer.resolution.emptyDeferredQueueForTesting(); } @@ -2777,7 +2777,7 @@ new TypeCheckerVisitor(compiler, elements, compiler.types); DiagnosticCollector collector = compiler.diagnosticCollector; collector.clear(); - checker.analyze(node); + checker.analyze(node, mustHaveType: false); generateOutput(compiler, text); compareWarningKinds(text, warnings, collector.warnings); compareWarningKinds(text, hints, collector.hints);
diff --git a/tests/compiler/dart2js/type_combination_test.dart b/tests/compiler/dart2js/type_combination_test.dart index 479e717..9638ca2 100644 --- a/tests/compiler/dart2js/type_combination_test.dart +++ b/tests/compiler/dart2js/type_combination_test.dart
@@ -753,9 +753,9 @@ patternImplClass.ensureResolved(compiler.resolution); impactBuilder.registerTypeUse( - new TypeUse.instantiation(compiler.coreTypes.mapType())); + new TypeUse.instantiation(compiler.commonElements.mapType())); impactBuilder.registerTypeUse( - new TypeUse.instantiation(compiler.coreTypes.functionType)); + new TypeUse.instantiation(compiler.commonElements.functionType)); impactBuilder .registerTypeUse(new TypeUse.instantiation(patternImplClass.rawType)); compiler.enqueuer.resolution.applyImpact(impactBuilder); @@ -767,11 +767,11 @@ patternClass = closedWorld.commonElements.coreLibrary.find('Pattern'); nonPrimitive1 = new TypeMask.nonNullSubtype( - closedWorld.coreClasses.mapClass, closedWorld); + closedWorld.commonElements.mapClass, closedWorld); nonPrimitive2 = new TypeMask.nonNullSubtype( - closedWorld.coreClasses.functionClass, closedWorld); + closedWorld.commonElements.functionClass, closedWorld); potentialArray = - new TypeMask.subtype(closedWorld.coreClasses.listClass, closedWorld); + new TypeMask.subtype(closedWorld.commonElements.listClass, closedWorld); potentialString = new TypeMask.subtype(patternClass, closedWorld); jsInterceptor = new TypeMask.nonNullSubclass(helpers.jsInterceptorClass, closedWorld); @@ -812,10 +812,10 @@ jsDoubleOrNull = new TypeMask.exact(helpers.jsDoubleClass, closedWorld); nullType = const TypeMask.empty(); objectType = new TypeMask.nonNullSubclass( - closedWorld.coreClasses.objectClass, closedWorld); + closedWorld.commonElements.objectClass, closedWorld); emptyType = const TypeMask.nonNullEmpty(); - dynamicType = - new TypeMask.subclass(closedWorld.coreClasses.objectClass, closedWorld); + dynamicType = new TypeMask.subclass( + closedWorld.commonElements.objectClass, closedWorld); Expect.notEquals( emptyType, nonPrimitive1, "nonPrimitive1 expected to be non-empty.");
diff --git a/tests/compiler/dart2js/type_mask_test.dart b/tests/compiler/dart2js/type_mask_test.dart index fd197f1..6d0d958 100644 --- a/tests/compiler/dart2js/type_mask_test.dart +++ b/tests/compiler/dart2js/type_mask_test.dart
@@ -39,7 +39,7 @@ var subtypeA = new TypeMask.nonNullSubtype(classA, closedWorld); var subclassObject = new TypeMask.nonNullSubclass( - compiler.coreClasses.objectClass, closedWorld); + compiler.commonElements.objectClass, closedWorld); var unionABC = UnionTypeMask.unionOf([exactA, exactB, exactC], closedWorld);
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status index 2dfdb3b..5944e86 100644 --- a/tests/corelib/corelib.status +++ b/tests/corelib/corelib.status
@@ -40,6 +40,9 @@ symbol_reserved_word_test/07: MissingCompileTimeError # bug 11669, 19972 symbol_reserved_word_test/10: MissingCompileTimeError # bug 11669, 19972 +[ ($compiler == none || $compiler == app_jit) && $unchecked ] +iterable_generate_test/01: RuntimeError # Issue 28025 + [ $compiler == none && ($runtime == drt || $runtime == dartium) ] package_resource_test: RuntimeError # Issue 26842 symbol_reserved_word_test/02: RuntimeError # bug 20191 / dartium/drt cannot detect CompileTimeErrors
diff --git a/tests/corelib/iterable_generate_test.dart b/tests/corelib/iterable_generate_test.dart index 170dba9..abcae06 100644 --- a/tests/corelib/iterable_generate_test.dart +++ b/tests/corelib/iterable_generate_test.dart
@@ -59,7 +59,12 @@ // Invalid types: Expect.throws(() => new Iterable<String>.generate(5)); - Expect.throws(() => new Iterable<Null>.generate(5)); + if (checkedMode) { /// 01: ok + Expect.throws(() => new Iterable<Null>.generate(5).elementAt(2)); /// 01: continued + } else { /// 01: continued + Iterable<dynamic> iter5 = new Iterable<Null>.generate(5); /// 01: continued + Expect.equals(2, iter5.elementAt(2)); /// 01: continued + } /// 01: continued Expect.throws(() => new Iterable<bool>.generate(5)); // Regression: https://github.com/dart-lang/sdk/issues/26358
diff --git a/tests/html/html.status b/tests/html/html.status index 1907711..3b0d09c 100644 --- a/tests/html/html.status +++ b/tests/html/html.status
@@ -7,6 +7,8 @@ [ $compiler == none && ($runtime == dartium || $runtime == drt) ] +canvas_pixel_array_type_alias_test/types2_runtimeTypeName: RuntimeError # Issue 28183 + mirrors_js_typed_interop_test: Fail # Missing expected failure (Issue 25044) js_typed_interop_side_cast_exp_test: Fail, OK # tests dart2js-specific behavior. js_typed_interop_type1_test: Fail, OK # tests dart2js-specific behavior. @@ -45,7 +47,6 @@ custom/element_upgrade_test: Fail # Issue 17298 [ $compiler == dart2js && $browser ] -worker_api_test: RuntimeError # Issue 28155 custom/created_callback_test: Fail # Support for created constructor. Issue 14835 fontface_loaded_test: Fail # Support for promises.
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status index 038396b..22a15a1 100644 --- a/tests/isolate/isolate.status +++ b/tests/isolate/isolate.status
@@ -236,3 +236,4 @@ deferred_in_isolate_test: Crash # Requires deferred libraries deferred_in_isolate2_test: Crash # Requires deferred libraries issue_21398_parent_isolate2_test: Crash # Requires deferred libraries +spawn_uri_nested_vm_test: Pass, Crash # Issue 28192
diff --git a/tests/language/function_subtype0_test.dart b/tests/language/function_subtype0_test.dart index 1a39d92..4cc4809 100644 --- a/tests/language/function_subtype0_test.dart +++ b/tests/language/function_subtype0_test.dart
@@ -36,6 +36,7 @@ int int__int2(int i) => 0; int int__Object(Object o) => 0; Object Object__int(int i) => null; +void void__Object(Object o) => null; int int__double(double d) => 0; int int__int_int(int i1, int i2) => 0; void inline_void_(void f()) {} @@ -82,6 +83,8 @@ Expect.isFalse(int__int_int is t_int__int); // (()->void) -> void <: ((int)->void) -> void Expect.isFalse(inline_void_ is t_inline_void__int); + // (Object) -> void <: ((int)->void) -> void + Expect.isTrue(void__Object is t_inline_void__int); // ((int)->void) -> void <: (()->void) -> void Expect.isFalse(inline_void__int is t_inline_void_); }
diff --git a/tests/language/function_subtype1_test.dart b/tests/language/function_subtype1_test.dart index a7bd199..1938ebe 100644 --- a/tests/language/function_subtype1_test.dart +++ b/tests/language/function_subtype1_test.dart
@@ -17,6 +17,7 @@ typedef Object Object_(); typedef double double_(); typedef void void__int(int i); +typedef void void__Object(Object o); typedef int int__int(int i); typedef int int__int2(int i); typedef int int__Object(Object o); @@ -69,6 +70,8 @@ Expect.isFalse(new C<int__int_int>() is C<int__int>); // (()->void) -> void <: ((int)->void) -> void Expect.isFalse(new C<inline_void_>() is C<inline_void__int>); + // (Object) -> void <: ((int)->void) -> void + Expect.isTrue(new C<void__Object>() is C<inline_void__int>); // ((int)->void) -> void <: (()->void) -> void Expect.isFalse(new C<inline_void__int>() is C<inline_void_>); }
diff --git a/tests/language/language.status b/tests/language/language.status index 0cf4670..3fefdf6 100644 --- a/tests/language/language.status +++ b/tests/language/language.status
@@ -5,9 +5,22 @@ # This directory contains tests that are intended to show the # current state of the language. +[ $compiler == none || $compiler == app_jit ] +null_is_bottom_test/22: RuntimeError # Issue 28025 +null_is_bottom_test/34: RuntimeError # Issue 28025 + + [ $compiler == none || $compiler == precompiler || $compiler == app_jit ] tearoff_constructor_basic_test: Skip # Crashes in checked mode -- hausner investigating generic_methods_type_expression_test: RuntimeError # Issue 25869 +null_is_bottom_test/05: RuntimeError # Issue 28025 +null_is_bottom_test/07: RuntimeError # Issue 28025 +null_is_bottom_test/20: RuntimeError # Issue 28025 +null_is_bottom_test/25: RuntimeError # Issue 28025 +null_is_bottom_test/27: RuntimeError # Issue 28025 +null_is_bottom_test/32: RuntimeError # Issue 28025 +null_is_bottom_test/37: RuntimeError # Issue 28025 +null_is_bottom_test/39: RuntimeError # Issue 28025 # This is OK for now, but we may want to change the semantics to match the test. async_star_pause_test: Fail, OK @@ -60,6 +73,11 @@ generic_local_functions_test: Pass # Issue 25869 generic_functions_test: Pass # Issue 25869 generic_methods_generic_function_parameter_test: Pass # Issue 25869 +null_is_bottom_test/03: RuntimeError # Issue 28025 +null_is_bottom_test/18: RuntimeError # Issue 28025 +null_is_bottom_test/23: RuntimeError # Issue 28025 +null_is_bottom_test/30: RuntimeError # Issue 28025 +null_is_bottom_test/35: RuntimeError # Issue 28025 [ ($compiler == none || $compiler == precompiler || $compiler == app_jit) && ($runtime == vm || $runtime == dart_precompiled) ]
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status index d13f27a..d164e71 100644 --- a/tests/language/language_analyzer2.status +++ b/tests/language/language_analyzer2.status
@@ -45,6 +45,15 @@ const_for_in_variable_test/01: MissingCompileTimeError # Issue 25161 +null_is_bottom_type_test/01: StaticWarning # Issue 28027 +null_is_bottom_type_test/03: StaticWarning # Issue 28027 +null_is_bottom_type_test/06: StaticWarning # Issue 28027 +null_is_bottom_type_test/08: StaticWarning # Issue 28027 +null_is_bottom_type_test/10: StaticWarning # Issue 28027 +null_is_bottom_type_test/11: StaticWarning # Issue 28027 +null_is_bottom_type_test/14: StaticWarning # Issue 28027 +null_is_bottom_type_test/15: StaticWarning # Issue 28027 + # Please add new failing tests before this line. # Section below is for invalid tests. #
diff --git a/tests/language/language_kernel.status b/tests/language/language_kernel.status index a3730b6..5d65a3b 100644 --- a/tests/language/language_kernel.status +++ b/tests/language/language_kernel.status
@@ -7,6 +7,8 @@ large_class_declaration_test: Skip large_implicit_getter_test: Skip larger_implicit_getter_test: Skip +null_is_bottom_test/22: RuntimeError # Issue 28025 +null_is_bottom_test/34: RuntimeError # Issue 28025 ############################################################################### # Dartk Entries @@ -83,6 +85,14 @@ multiline_newline_test/06: MissingCompileTimeError no_main_test/01: DartkCrash not_enough_positional_arguments_test/01: DartkCompileTimeError +null_is_bottom_test/05: RuntimeError # Issue 28025 +null_is_bottom_test/07: RuntimeError # Issue 28025 +null_is_bottom_test/20: RuntimeError # Issue 28025 +null_is_bottom_test/25: RuntimeError # Issue 28025 +null_is_bottom_test/27: RuntimeError # Issue 28025 +null_is_bottom_test/32: RuntimeError # Issue 28025 +null_is_bottom_test/37: RuntimeError # Issue 28025 +null_is_bottom_test/39: RuntimeError # Issue 28025 regress_27617_test/1: MissingCompileTimeError super_call3_test/01: DartkCrash tearoff_basic_test: DartkCompileTimeError
diff --git a/tests/language/null_is_bottom_test.dart b/tests/language/null_is_bottom_test.dart new file mode 100644 index 0000000..e2ab54a --- /dev/null +++ b/tests/language/null_is_bottom_test.dart
@@ -0,0 +1,142 @@ +// Copyright (c) 2016, 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. + +// Test that Null is a subtype of any other type. + +import 'package:expect/expect.dart'; + +class A {} +typedef A ReturnA(); +typedef TakeA(A a); +typedef Null ReturnNull(); +typedef TakeNull(Null n); + +@NoInline() +testA(A a) {} + +@NoInline() +testListA(List<A> list) {} + +@NoInline() +testIsListA(var a) => a is List<A>; + +@NoInline() +testAsListA(var a) => a as List<A>; + +@NoInline() +testNull(Null n) {} + +@NoInline() +testListNull(List<Null> list) {} + +@NoInline() +testIsListNull(var a) => a is List<Null>; + +@NoInline() +testAsListNull(var a) => a as List<Null>; + +@NoInline() +testReturnA(ReturnA f) {} + +@NoInline() +testIsReturnA(var f) => f is ReturnA; + +@NoInline() +testAsReturnA(var f) => f as ReturnA; + +@NoInline() +testReturnNull(ReturnNull f) {} + +@NoInline() +testIsReturnNull(var f) => f is ReturnNull; + +@NoInline() +testAsReturnNull(var f) => f as ReturnNull; + +@NoInline() +testTakeA(TakeA f) {} + +@NoInline() +testIsTakeA(var f) => f is TakeA; + +@NoInline() +testAsTakeA(var f) => f as TakeA; + +@NoInline() +testTakeNull(TakeNull f) {} + +@NoInline() +testIsTakeNull(var f) => f is TakeNull; + +@NoInline() +testAsTakeNull(var f) => f as TakeNull; + +Null returnNullFunc() => null; +takeNullFunc(Null n) {} +A returnAFunc() => null; +takeAFunc(A a) {} + +main() { + var n = null; + var listNull = new List<Null>(); + var a = new A(); + var listA = new List<A>(); + + testA(n); /// 01: ok + testA(a); /// 02: ok + testListA(listNull); /// 03: ok + testListA(listA); /// 04: ok + Expect.isTrue(testIsListA(listNull)); /// 05: ok + Expect.isTrue(testIsListA(listA)); /// 06: ok + testAsListA(listNull); /// 07: ok + testAsListA(listA); /// 08: ok + + testNull(n); /// 09: ok + testNull(a); /// 10: dynamic type error + testListNull(listNull); /// 11: ok + testListNull(listA); /// 12: dynamic type error + Expect.isTrue(testIsListNull(listNull)); /// 13: ok + Expect.isFalse(testIsListNull(listA)); /// 14: ok + testAsListNull(listNull); /// 15: ok + Expect.throws(() => testAsListNull(listA), (e) => e is CastError); /// 16: ok + + var returnNull = returnNullFunc; + var takeNull = takeNullFunc; + var returnA = returnAFunc; + var takeA = takeAFunc; + + testReturnA(returnA); /// 17: ok + testReturnA(returnNull); /// 18: ok + Expect.isTrue(testIsReturnA(returnA)); /// 19: ok + Expect.isTrue(testIsReturnA(returnNull)); /// 20: ok + testAsReturnA(returnA); /// 21: ok + testAsReturnA(returnNull); /// 22: ok + + // This is not valid in strong-mode: ()->A <: ()->Null + testReturnNull(returnA); /// 23: ok + testReturnNull(returnNull); /// 24: ok + // This is not valid in strong-mode: ()->A <: ()->Null + Expect.isTrue(testIsReturnNull(returnA)); /// 25: ok + Expect.isTrue(testIsReturnNull(returnNull)); /// 26: ok + // This is not valid in strong-mode: ()->A <: ()->Null + testAsReturnNull(returnA); /// 27: ok + testAsReturnNull(returnNull); /// 28: ok + + testTakeA(takeA); /// 29: ok + // This is not valid in strong-mode: (Null)-> <: (A)-> + testTakeA(takeNull); /// 30: ok + Expect.isTrue(testIsTakeA(takeA)); /// 31: ok + // This is not valid in strong-mode: (Null)-> <: (A)-> + Expect.isTrue(testIsTakeA(takeNull)); /// 32: ok + testAsTakeA(takeA); /// 33: ok + // This is not valid in strong-mode: (Null)-> <: (A)-> + testAsTakeA(takeNull); /// 34: ok + + testTakeNull(takeA); /// 35: ok + testTakeNull(takeNull); /// 36: ok + Expect.isTrue(testIsTakeNull(takeA)); /// 37: ok + Expect.isTrue(testIsTakeNull(takeNull)); /// 38: ok + testAsTakeNull(takeA); /// 39: ok + testAsTakeNull(takeNull); /// 40: ok +} \ No newline at end of file
diff --git a/tests/language/null_is_bottom_type_test.dart b/tests/language/null_is_bottom_type_test.dart new file mode 100644 index 0000000..b12137e --- /dev/null +++ b/tests/language/null_is_bottom_type_test.dart
@@ -0,0 +1,60 @@ +// Copyright (c) 2016, 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. + +// Test that Null is a subtype of any other type. + +import 'package:expect/expect.dart'; + +class A {} +typedef A ReturnA(); +typedef TakeA(A a); +typedef Null ReturnNull(); +typedef TakeNull(Null n); + +testA(A a) {} +testListA(List<A> list) {} +testNull(Null n) {} +testListNull(List<Null> list) {} +testReturnA(ReturnA f) {} +testReturnNull(ReturnNull f) {} +testTakeA(TakeA f) {} +testTakeNull(TakeNull f) {} + +Null returnNull() => null; +takeNull(Null n) {} +A returnA() => null; +takeA(A a) {} + +main() { + if (false) test(); // Perform static checks only. +} + +test() { + Null n; + List<Null> listNull; + A a = new A(); + List<A> listA; + + testA(n); /// 01: ok + testA(a); /// 02: ok + testListA(listNull); /// 03: ok + testListA(listA); /// 04: ok + + testNull(n); /// 05: ok + testNull(a); /// 06: ok + testListNull(listNull); /// 07: ok + testListNull(listA); /// 08: ok + + testReturnA(returnA); /// 09: ok + testReturnA(returnNull); /// 10: ok + + testReturnNull(returnA); /// 11: ok + testReturnNull(returnNull); /// 12: ok + + testTakeA(takeA); /// 13: ok + testTakeA(takeNull); /// 14: ok + + testTakeNull(takeA); /// 15: ok + testTakeNull(takeNull); /// 16: ok +} \ No newline at end of file
diff --git a/tests/language/vm/lazy_deopt_vm_test.dart b/tests/language/vm/lazy_deopt_vm_test.dart index a10242a..17c7430 100644 --- a/tests/language/vm/lazy_deopt_vm_test.dart +++ b/tests/language/vm/lazy_deopt_vm_test.dart
@@ -1,7 +1,7 @@ // Copyright (c) 2016, 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. -// VMOptions=--deoptimize_every=10 --optimization-counter-threshold=10 --no-background-compilation +// VMOptions=--optimization-filter=foo --deoptimize_every=10 --optimization-counter-threshold=10 --no-background-compilation // Test that lazy deoptimization on stack checks does not damage unoptimized // frame.
diff --git a/tests/standalone/io/file_create_test.dart b/tests/standalone/io/file_create_test.dart new file mode 100644 index 0000000..f35c43d --- /dev/null +++ b/tests/standalone/io/file_create_test.dart
@@ -0,0 +1,44 @@ +// Copyright (c) 2016, 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 test program for testing file creation. + +import 'dart:async'; +import 'dart:io'; + +import "package:expect/expect.dart"; +import "package:path/path.dart"; + +testCreate() async { + Directory tmp = await Directory.systemTemp.createTemp('file_test_create'); + Expect.isTrue(await tmp.exists()); + String filePath = "${tmp.path}/foo"; + File file = new File(filePath); + File createdFile = await file.create(); + Expect.equals(file, createdFile); + Expect.isTrue(await createdFile.exists()); + await tmp.delete(recursive: true); +} + +testBadCreate() async { + Directory tmp = await Directory.systemTemp.createTemp('file_test_create'); + Expect.isTrue(await tmp.exists()); + Directory tmp2 = await tmp.createTemp('file_test_create'); + Expect.isTrue(await tmp2.exists()); + String badFilePath = tmp2.path; + File badFile = new File(badFilePath); + try { + await badFile.create(); + Expect.fail('Should be unreachable'); + } catch(e) { + Expect.isTrue(e is FileSystemException); + Expect.isNotNull(e.osError); + } + await tmp.delete(recursive: true); +} + +main() async { + await testCreate(); + await testBadCreate(); +}
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status index daecba8..1630b8e 100644 --- a/tests/standalone/standalone.status +++ b/tests/standalone/standalone.status
@@ -50,6 +50,9 @@ io/secure_server_client_certificate_test: Skip io/socket_test: Pass, Timeout # Issue 27453 +# This test sometimes hangs on Mac. +io/raw_server_socket_cancel_test: Skip # Issue 28182 + [ $runtime == vm && $system == linux ] # These tests have started timing out and issue 25649 has been filed to # investigate, skipping these tests temporarily to get the bots to be @@ -144,7 +147,7 @@ out_of_memory_test: Skip # passes on Mac, crashes on Linux oom_error_stacktrace_test: Skip # Fails on Linux -[ $arch == simarm && $mode == debug && $checked ] +[ ($arch == simarm || $arch == simdbc || $arch == simdbc64) && $mode == debug && $checked ] io/web_socket_test: Pass, Fail # Issue 26814 [ $arch == mips ]
diff --git a/tools/FAKE_COMMITS b/tools/FAKE_COMMITS index cc5aa2f..34df009 100644 --- a/tools/FAKE_COMMITS +++ b/tools/FAKE_COMMITS
@@ -18,4 +18,5 @@ CIT outage - all slaves rebooted Authentication failure flake - rerun all bots Trigger bots after master restart - switch dart2js bots to use downloaded sdk. -Trigger bots after master restart. \ No newline at end of file +Trigger bots after master restart. +Trigger mirroring of github repository
diff --git a/tools/VERSION b/tools/VERSION index 08e0575..5e7c910 100644 --- a/tools/VERSION +++ b/tools/VERSION
@@ -27,5 +27,5 @@ MAJOR 1 MINOR 22 PATCH 0 -PRERELEASE 3 +PRERELEASE 4 PRERELEASE_PATCH 0
diff --git a/tools/build.py b/tools/build.py index e30b1f8..5b66500 100755 --- a/tools/build.py +++ b/tools/build.py
@@ -114,7 +114,7 @@ for arch in options.arch: archs = ['ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6', 'simarmv5te', 'armv5te', 'simmips', 'mips', 'simarm64', 'arm64', - 'simdbc', 'simdbc64', 'armsimdbc'] + 'simdbc', 'simdbc64', 'armsimdbc', 'armsimdbc64'] if not arch in archs: print "Unknown arch %s" % arch return False
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS index c1a89e7..9192aaf 100644 --- a/tools/deps/dartium.deps/DEPS +++ b/tools/deps/dartium.deps/DEPS
@@ -51,7 +51,7 @@ "path_rev": "@b657c0854d1cf41c014986fa9d2321f1173df805", "plugin_tag": "@0.1.0", "pool_rev": "@22e12aeb16ad0b626900dbe79e4a25391ddfb28c", - "pub_rev": "@9d707158fedc86fc2b02f62cdfe804902b098d9d", + "pub_rev": "@d7649be15213c43669a40c33af516d8eb210e876", "pub_semver_tag": "@1.2.0", "quiver_tag": "@0.21.4", "root_certificates_rev": "@aed07942ce98507d2be28cbd29e879525410c7fc",
diff --git a/tools/dom/templates/html/impl/impl_Blob.darttemplate b/tools/dom/templates/html/impl/impl_Blob.darttemplate index 62ac4c70..8cf70b9 100644 --- a/tools/dom/templates/html/impl/impl_Blob.darttemplate +++ b/tools/dom/templates/html/impl/impl_Blob.darttemplate
@@ -20,8 +20,8 @@ return _create_2(blobParts, bag); } - static _create_1(parts) => JS('Blob', 'new window.Blob(#)', parts); - static _create_2(parts, bag) => JS('Blob', 'new window.Blob(#, #)', parts, bag); + static _create_1(parts) => JS('Blob', 'new self.Blob(#)', parts); + static _create_2(parts, bag) => JS('Blob', 'new self.Blob(#, #)', parts, bag); static _create_bag() => JS('var', '{}'); static _bag_set(bag, key, value) { JS('void', '#[#] = #', bag, key, value); }
diff --git a/tools/gn.py b/tools/gn.py index fd9a1b7..93bbf1b 100755 --- a/tools/gn.py +++ b/tools/gn.py
@@ -31,9 +31,10 @@ def host_cpu_for_arch(arch): if arch in ['ia32', 'arm', 'armv6', 'armv5te', 'mips', - 'simarm', 'simarmv6', 'simarmv5te', 'simmips', 'simdbc']: + 'simarm', 'simarmv6', 'simarmv5te', 'simmips', 'simdbc', + 'armsimdbc']: return 'x86' - if arch in ['x64', 'arm64', 'simarm64', 'simdbc64']: + if arch in ['x64', 'arm64', 'simarm64', 'simdbc64', 'armsimdbc64']: return 'x64' @@ -48,6 +49,10 @@ return 'arm' if target_os == 'android' else 'x86' if arch == 'simdbc64': return 'arm64' if target_os == 'android' else 'x64' + if arch == 'armsimdbc': + return 'arm' + if arch == 'armsimdbc64': + return 'arm64' return arch @@ -169,7 +174,7 @@ for arch in args.arch: archs = ['ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6', 'simarmv5te', 'armv5te', 'simmips', 'mips', 'simarm64', 'arm64', - 'simdbc', 'simdbc64', 'armsimdbc'] + 'simdbc', 'simdbc64', 'armsimdbc', 'armsimdbc64'] if not arch in archs: print "Unknown arch %s" % arch return False
diff --git a/tools/patch_sdk.dart b/tools/patch_sdk.dart index 5a76ff5..e9980ea 100644 --- a/tools/patch_sdk.dart +++ b/tools/patch_sdk.dart
@@ -110,14 +110,7 @@ var libraryOut = path.join(sdkLibIn, library.path); var libraryIn; - if (mode == 'vm' && library.path.contains('typed_data.dart')) { - // dart:typed_data is unlike the other libraries in the SDK. The VM does - // not apply a patch to the base SDK implementation of the library. - // Instead, the VM provides a replacement implementation and ignores the - // sources in the SDK. - libraryIn = - path.join(dartDir, 'runtime', 'lib', 'typed_data.dart'); - } else if (mode == 'ddc' && library.path.contains(INTERNAL_PATH)) { + if (mode == 'ddc' && library.path.contains(INTERNAL_PATH)) { libraryIn = path.join(privateIn, library.path.replaceAll(INTERNAL_PATH, '')); } else {
diff --git a/tools/utils.py b/tools/utils.py index 341321d..161ea4b 100644 --- a/tools/utils.py +++ b/tools/utils.py
@@ -243,6 +243,7 @@ 'simdbc': 'ia32', 'simdbc64': 'ia32', 'armsimdbc': 'arm', + 'armsimdbc64': 'arm', } ARCH_GUESS = GuessArchitecture()