mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 13:08:01 +00:00
Remove dart:isolate runtime support in DDC
This disables most runtime features of dart:isolate, similar to dart:io. For now, this supports `new ReceivePort()` and `ReceivePort.close` as those are used by async tests to keep the Dart VM alive. Those are no-ops in DDC. Also removes most of dart:_isolate_helper, except for the JS API that's used to bootstrap DDC `main()`. Change-Id: I84eab6cd39d05a70a6afe982e952076ddaaa8c0f Reviewed-on: https://dart-review.googlesource.com/45754 Commit-Queue: Jenny Messerly <jmesserly@google.com> Reviewed-by: Vijay Menon <vsm@google.com>
This commit is contained in:
parent
0482cf4da1
commit
c9e9c1d8e9
|
@ -20,7 +20,6 @@ class DevCompilerTarget extends Target {
|
|||
'dart:_interceptors',
|
||||
'dart:_internal',
|
||||
'dart:_isolate_helper',
|
||||
'dart:_js_embedded_names',
|
||||
'dart:_js_helper',
|
||||
'dart:_js_mirrors',
|
||||
'dart:_js_primitives',
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
library dev_compiler.test.sourcemap.ddc_common;
|
||||
|
||||
import 'dart:io';
|
||||
import 'dart:mirrors' show currentMirrorSystem;
|
||||
|
||||
import 'package:front_end/src/api_unstable/ddc.dart' as fe;
|
||||
import 'package:path/path.dart' as path;
|
||||
|
@ -127,10 +130,14 @@ String getWrapperContent(
|
|||
return """
|
||||
import { dart, _isolate_helper } from '${uriPathForwardSlashed(jsSdkPath)}';
|
||||
import { $inputFileNameNoExt } from '$outputFilename';
|
||||
|
||||
let global = new Function('return this;')();
|
||||
$d8Preambles
|
||||
|
||||
let main = $inputFileNameNoExt.main;
|
||||
dart.ignoreWhitelistedErrors(false);
|
||||
try {
|
||||
_isolate_helper.startRootIsolate(main, []);
|
||||
dartMainRunner(main, []);
|
||||
} catch(e) {
|
||||
console.error(e.toString(), dart.stackTrace(e).toString());
|
||||
}
|
||||
|
@ -181,3 +188,10 @@ String getWrapperHtmlContent(String jsRootDart, String outFileRootBuild) {
|
|||
</html>
|
||||
""";
|
||||
}
|
||||
|
||||
Uri selfUri = currentMirrorSystem()
|
||||
.findLibrary(#dev_compiler.test.sourcemap.ddc_common)
|
||||
.uri;
|
||||
String d8Preambles = new File.fromUri(
|
||||
selfUri.resolve('../../tool/input_sdk/private/preambles/d8.js'))
|
||||
.readAsStringSync();
|
||||
|
|
|
@ -23,7 +23,6 @@ main(List<String> arguments) {
|
|||
'dart:_interceptors',
|
||||
'dart:_internal',
|
||||
'dart:_isolate_helper',
|
||||
'dart:_js_embedded_names',
|
||||
'dart:_js_helper',
|
||||
'dart:_js_mirrors',
|
||||
'dart:_js_primitives',
|
||||
|
|
|
@ -23,9 +23,6 @@
|
|||
"_isolate_helper": {
|
||||
"uri": "../private/isolate_helper.dart"
|
||||
},
|
||||
"_js_embedded_names": {
|
||||
"uri": "../private/shared/embedded_names.dart"
|
||||
},
|
||||
"_js_helper": {
|
||||
"uri": "../private/js_helper.dart"
|
||||
},
|
||||
|
|
|
@ -162,11 +162,6 @@ const Map<String, LibraryInfo> libraries = const {
|
|||
categories: "",
|
||||
documented: false,
|
||||
platforms: DART2JS_PLATFORM),
|
||||
"_js_embedded_names": const LibraryInfo(
|
||||
"_internal/js_runtime/lib/shared/embedded_names.dart",
|
||||
categories: "",
|
||||
documented: false,
|
||||
platforms: DART2JS_PLATFORM),
|
||||
"_metadata": const LibraryInfo("html/html_common/metadata.dart",
|
||||
categories: "", documented: false, platforms: DART2JS_PLATFORM),
|
||||
"_debugger": const LibraryInfo("_internal/js_runtime/lib/debugger.dart",
|
||||
|
|
|
@ -22,9 +22,6 @@
|
|||
"_isolate_helper": {
|
||||
"uri": "_internal/js_runtime/lib/isolate_helper.dart"
|
||||
},
|
||||
"_js_embedded_names": {
|
||||
"uri": "_internal/js_runtime/lib/shared/embedded_names.dart"
|
||||
},
|
||||
"_js_helper": {
|
||||
"uri": "_internal/js_runtime/lib/js_helper.dart"
|
||||
},
|
||||
|
|
|
@ -4,16 +4,9 @@
|
|||
|
||||
// Patch file for the dart:async library.
|
||||
|
||||
import 'dart:_js_helper'
|
||||
show patch, Primitives, ReifyFunctionTypes, DartIterator;
|
||||
import 'dart:_js_helper' show patch, ReifyFunctionTypes;
|
||||
import 'dart:_isolate_helper'
|
||||
show
|
||||
IsolateNatives,
|
||||
TimerImpl,
|
||||
global,
|
||||
leaveJsAsync,
|
||||
enterJsAsync,
|
||||
isWorker;
|
||||
show TimerImpl, global, leaveJsAsync, enterJsAsync;
|
||||
|
||||
import 'dart:_foreign_helper' show JS, JSExportName;
|
||||
|
||||
|
|
|
@ -189,7 +189,7 @@ class Error {
|
|||
}
|
||||
|
||||
@patch
|
||||
StackTrace get stackTrace => Primitives.extractStackTrace(this);
|
||||
StackTrace get stackTrace => getTraceFromException(this);
|
||||
}
|
||||
|
||||
@patch
|
||||
|
|
|
@ -4,30 +4,22 @@
|
|||
|
||||
// Patch file for the dart:isolate library.
|
||||
|
||||
import 'dart:_js_helper' show patch;
|
||||
import 'dart:_isolate_helper'
|
||||
show CapabilityImpl, IsolateNatives, ReceivePortImpl, RawReceivePortImpl;
|
||||
import 'dart:_js_helper' show patch, NoReifyGeneric;
|
||||
|
||||
@patch
|
||||
class Isolate {
|
||||
static final _currentIsolateCache = IsolateNatives.currentIsolate;
|
||||
|
||||
// `current` must be a getter, not just a final field,
|
||||
// to match the external declaration.
|
||||
@patch
|
||||
static Isolate get current => _currentIsolateCache;
|
||||
static Isolate get current => _unsupported();
|
||||
|
||||
@patch
|
||||
static Future<Uri> get packageRoot {
|
||||
throw new UnsupportedError("Isolate.packageRoot");
|
||||
}
|
||||
static Future<Uri> get packageRoot => _unsupported();
|
||||
|
||||
@patch
|
||||
static Future<Uri> get packageConfig {
|
||||
throw new UnsupportedError("Isolate.packageConfig");
|
||||
}
|
||||
static Future<Uri> get packageConfig => _unsupported();
|
||||
|
||||
static Uri _packageBase = Uri.base.resolve(IsolateNatives.packagesBase);
|
||||
static Uri _packageBase = Uri.base.resolve('packages/');
|
||||
|
||||
@patch
|
||||
static Future<Uri> resolvePackageUri(Uri packageUri) async {
|
||||
|
@ -37,199 +29,90 @@ class Isolate {
|
|||
|
||||
@patch
|
||||
static Future<Isolate> spawn<T>(void entryPoint(T message), T message,
|
||||
{bool paused: false,
|
||||
bool errorsAreFatal,
|
||||
SendPort onExit,
|
||||
SendPort onError}) {
|
||||
bool forcePause =
|
||||
(errorsAreFatal != null) || (onExit != null) || (onError != null);
|
||||
try {
|
||||
// TODO: Consider passing the errorsAreFatal/onExit/onError values
|
||||
// as arguments to the internal spawnUri instead of setting
|
||||
// them after the isolate has been created.
|
||||
return IsolateNatives
|
||||
.spawnFunction(entryPoint, message, paused || forcePause)
|
||||
.then((msg) {
|
||||
var isolate = new Isolate(msg[1],
|
||||
pauseCapability: msg[2], terminateCapability: msg[3]);
|
||||
if (forcePause) {
|
||||
if (errorsAreFatal != null) {
|
||||
isolate.setErrorsFatal(errorsAreFatal);
|
||||
}
|
||||
if (onExit != null) {
|
||||
isolate.addOnExitListener(onExit);
|
||||
}
|
||||
if (onError != null) {
|
||||
isolate.addErrorListener(onError);
|
||||
}
|
||||
if (!paused) {
|
||||
isolate.resume(isolate.pauseCapability);
|
||||
}
|
||||
}
|
||||
return isolate;
|
||||
});
|
||||
} catch (e, st) {
|
||||
return new Future<Isolate>.error(e, st);
|
||||
}
|
||||
}
|
||||
{bool paused: false,
|
||||
bool errorsAreFatal,
|
||||
SendPort onExit,
|
||||
SendPort onError}) =>
|
||||
_unsupported();
|
||||
|
||||
@patch
|
||||
static Future<Isolate> spawnUri(Uri uri, List<String> args, var message,
|
||||
{bool paused: false,
|
||||
SendPort onExit,
|
||||
SendPort onError,
|
||||
bool errorsAreFatal,
|
||||
bool checked,
|
||||
Map<String, String> environment,
|
||||
Uri packageRoot,
|
||||
Uri packageConfig,
|
||||
bool automaticPackageResolution: false}) {
|
||||
if (environment != null) throw new UnimplementedError("environment");
|
||||
if (packageRoot != null) throw new UnimplementedError("packageRoot");
|
||||
if (packageConfig != null) throw new UnimplementedError("packageConfig");
|
||||
// TODO(lrn): Figure out how to handle the automaticPackageResolution
|
||||
// parameter.
|
||||
bool forcePause =
|
||||
(errorsAreFatal != null) || (onExit != null) || (onError != null);
|
||||
try {
|
||||
if (args is List<String>) {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i] is! String) {
|
||||
throw new ArgumentError("Args must be a list of Strings $args");
|
||||
}
|
||||
}
|
||||
} else if (args != null) {
|
||||
throw new ArgumentError("Args must be a list of Strings $args");
|
||||
}
|
||||
// TODO: Handle [packageRoot] somehow, possibly by throwing.
|
||||
// TODO: Consider passing the errorsAreFatal/onExit/onError values
|
||||
// as arguments to the internal spawnUri instead of setting
|
||||
// them after the isolate has been created.
|
||||
return IsolateNatives
|
||||
.spawnUri(uri, args, message, paused || forcePause)
|
||||
.then((msg) {
|
||||
var isolate = new Isolate(msg[1],
|
||||
pauseCapability: msg[2], terminateCapability: msg[3]);
|
||||
if (forcePause) {
|
||||
if (errorsAreFatal != null) {
|
||||
isolate.setErrorsFatal(errorsAreFatal);
|
||||
}
|
||||
if (onExit != null) {
|
||||
isolate.addOnExitListener(onExit);
|
||||
}
|
||||
if (onError != null) {
|
||||
isolate.addErrorListener(onError);
|
||||
}
|
||||
if (!paused) {
|
||||
isolate.resume(isolate.pauseCapability);
|
||||
}
|
||||
}
|
||||
return isolate;
|
||||
});
|
||||
} catch (e, st) {
|
||||
return new Future<Isolate>.error(e, st);
|
||||
}
|
||||
}
|
||||
{bool paused: false,
|
||||
SendPort onExit,
|
||||
SendPort onError,
|
||||
bool errorsAreFatal,
|
||||
bool checked,
|
||||
Map<String, String> environment,
|
||||
Uri packageRoot,
|
||||
Uri packageConfig,
|
||||
bool automaticPackageResolution: false}) =>
|
||||
_unsupported();
|
||||
|
||||
@patch
|
||||
void _pause(Capability resumeCapability) {
|
||||
var message = new List(3)
|
||||
..[0] = "pause"
|
||||
..[1] = pauseCapability
|
||||
..[2] = resumeCapability;
|
||||
controlPort.send(message);
|
||||
}
|
||||
void _pause(Capability resumeCapability) => _unsupported();
|
||||
|
||||
@patch
|
||||
void resume(Capability resumeCapability) {
|
||||
var message = new List(2)
|
||||
..[0] = "resume"
|
||||
..[1] = resumeCapability;
|
||||
controlPort.send(message);
|
||||
}
|
||||
void resume(Capability resumeCapability) => _unsupported();
|
||||
|
||||
@patch
|
||||
void addOnExitListener(SendPort responsePort, {Object response}) {
|
||||
// TODO(lrn): Can we have an internal method that checks if the receiving
|
||||
// isolate of a SendPort is still alive?
|
||||
var message = new List(3)
|
||||
..[0] = "add-ondone"
|
||||
..[1] = responsePort
|
||||
..[2] = response;
|
||||
controlPort.send(message);
|
||||
}
|
||||
void addOnExitListener(SendPort responsePort, {Object response}) =>
|
||||
_unsupported();
|
||||
|
||||
@patch
|
||||
void removeOnExitListener(SendPort responsePort) {
|
||||
var message = new List(2)
|
||||
..[0] = "remove-ondone"
|
||||
..[1] = responsePort;
|
||||
controlPort.send(message);
|
||||
}
|
||||
void removeOnExitListener(SendPort responsePort) => _unsupported();
|
||||
|
||||
@patch
|
||||
void setErrorsFatal(bool errorsAreFatal) {
|
||||
var message = new List(3)
|
||||
..[0] = "set-errors-fatal"
|
||||
..[1] = terminateCapability
|
||||
..[2] = errorsAreFatal;
|
||||
controlPort.send(message);
|
||||
}
|
||||
void setErrorsFatal(bool errorsAreFatal) => _unsupported();
|
||||
|
||||
@patch
|
||||
void kill({int priority: beforeNextEvent}) {
|
||||
controlPort.send(["kill", terminateCapability, priority]);
|
||||
}
|
||||
void kill({int priority: beforeNextEvent}) => _unsupported();
|
||||
@patch
|
||||
void ping(SendPort responsePort,
|
||||
{Object response, int priority: immediate}) =>
|
||||
_unsupported();
|
||||
|
||||
@patch
|
||||
void ping(SendPort responsePort, {Object response, int priority: immediate}) {
|
||||
var message = new List(4)
|
||||
..[0] = "ping"
|
||||
..[1] = responsePort
|
||||
..[2] = priority
|
||||
..[3] = response;
|
||||
controlPort.send(message);
|
||||
}
|
||||
void addErrorListener(SendPort port) => _unsupported();
|
||||
|
||||
@patch
|
||||
void addErrorListener(SendPort port) {
|
||||
var message = new List(2)
|
||||
..[0] = "getErrors"
|
||||
..[1] = port;
|
||||
controlPort.send(message);
|
||||
}
|
||||
|
||||
@patch
|
||||
void removeErrorListener(SendPort port) {
|
||||
var message = new List(2)
|
||||
..[0] = "stopErrors"
|
||||
..[1] = port;
|
||||
controlPort.send(message);
|
||||
}
|
||||
void removeErrorListener(SendPort port) => _unsupported();
|
||||
}
|
||||
|
||||
/** Default factory for receive ports. */
|
||||
@patch
|
||||
class ReceivePort {
|
||||
@patch
|
||||
factory ReceivePort() = ReceivePortImpl;
|
||||
factory ReceivePort() = _ReceivePort;
|
||||
|
||||
@patch
|
||||
factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) {
|
||||
return new ReceivePortImpl.fromRawReceivePort(rawPort);
|
||||
}
|
||||
factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) =>
|
||||
_unsupported();
|
||||
}
|
||||
|
||||
/// ReceivePort is supported by dev_compiler because async test packages
|
||||
/// (async_helper, unittest) create a dummy receive port to keep the Dart VM
|
||||
/// alive.
|
||||
class _ReceivePort extends Stream implements ReceivePort {
|
||||
close() {}
|
||||
|
||||
get sendPort => _unsupported();
|
||||
|
||||
listen(onData, {onError, onDone, cancelOnError}) => _unsupported();
|
||||
}
|
||||
|
||||
@patch
|
||||
class RawReceivePort {
|
||||
@patch
|
||||
factory RawReceivePort([void handler(event)]) {
|
||||
return new RawReceivePortImpl(handler);
|
||||
}
|
||||
factory RawReceivePort([void handler(event)]) => _unsupported();
|
||||
}
|
||||
|
||||
@patch
|
||||
class Capability {
|
||||
@patch
|
||||
factory Capability() = CapabilityImpl;
|
||||
factory Capability() => _unsupported();
|
||||
}
|
||||
|
||||
@NoReifyGeneric()
|
||||
T _unsupported<T>() {
|
||||
throw new UnsupportedError('dart:isolate is not supported on dart4web');
|
||||
}
|
||||
|
|
|
@ -137,32 +137,6 @@ class JSExportName {
|
|||
const JSExportName(this.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the isolate in which this code is running.
|
||||
*/
|
||||
IsolateContext JS_CURRENT_ISOLATE_CONTEXT() {}
|
||||
|
||||
abstract class IsolateContext {
|
||||
/// Holds a (native) JavaScript instance of Isolate, see
|
||||
/// finishIsolateConstructorFunction in emitter.dart.
|
||||
get isolateStatics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes [function] in the context of [isolate].
|
||||
*/
|
||||
JS_CALL_IN_ISOLATE(isolate, Function function) {}
|
||||
|
||||
/**
|
||||
* Sets the current isolate to [isolate].
|
||||
*/
|
||||
void JS_SET_CURRENT_ISOLATE(isolate) {}
|
||||
|
||||
/**
|
||||
* Creates an isolate and returns it.
|
||||
*/
|
||||
JS_CREATE_ISOLATE() {}
|
||||
|
||||
/**
|
||||
* Returns the JavaScript constructor function for Dart's Object class.
|
||||
* This can be used for type tests, as in
|
||||
|
@ -205,11 +179,6 @@ String JS_FUNCTION_CLASS_NAME() {}
|
|||
*/
|
||||
String JS_IS_INDEXABLE_FIELD_NAME() {}
|
||||
|
||||
/**
|
||||
* Returns the object corresponding to Namer.CURRENT_ISOLATE.
|
||||
*/
|
||||
JS_CURRENT_ISOLATE() {}
|
||||
|
||||
/// Returns the name used for generated function types on classes and methods.
|
||||
String JS_SIGNATURE_NAME() {}
|
||||
|
||||
|
@ -252,11 +221,6 @@ String JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG() {}
|
|||
/// Returns the JS name for [name] from the Namer.
|
||||
String JS_GET_NAME(String name) {}
|
||||
|
||||
/// Reads an embedded global.
|
||||
///
|
||||
/// The [name] should be a constant defined in the `_embedded_names` library.
|
||||
JS_EMBEDDED_GLOBAL(String typeDescription, String name) {}
|
||||
|
||||
/// Returns the state of a flag that is determined by the state of the compiler
|
||||
/// when the program has been analyzed.
|
||||
bool JS_GET_FLAG(String name) {}
|
||||
|
|
|
@ -100,7 +100,7 @@ class UnknownJavaScriptObject extends JavaScriptObject {
|
|||
// it to be picked up as an extension type.
|
||||
@JsPeerInterface(name: 'TypeError')
|
||||
class NullError extends Interceptor implements NoSuchMethodError {
|
||||
StackTrace get stackTrace => Primitives.extractStackTrace(this);
|
||||
StackTrace get stackTrace => getTraceFromException(this);
|
||||
|
||||
String toString() {
|
||||
// TODO(vsm): Distinguish between null reference errors and other
|
||||
|
@ -161,7 +161,7 @@ final Object jsNull = new JSNull();
|
|||
// it to be picked up as an extension type.
|
||||
@JsPeerInterface(name: 'RangeError')
|
||||
class JSRangeError extends Interceptor implements ArgumentError {
|
||||
StackTrace get stackTrace => Primitives.extractStackTrace(this);
|
||||
StackTrace get stackTrace => getTraceFromException(this);
|
||||
|
||||
get invalidValue => null;
|
||||
get name => null;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,377 +0,0 @@
|
|||
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
part of dart._isolate_helper;
|
||||
|
||||
/// Serialize [message].
|
||||
_serializeMessage(message) {
|
||||
return new _Serializer().serialize(message);
|
||||
}
|
||||
|
||||
/// Deserialize [message].
|
||||
_deserializeMessage(message) {
|
||||
return new _Deserializer().deserialize(message);
|
||||
}
|
||||
|
||||
/// Clones the message.
|
||||
///
|
||||
/// Contrary to a `_deserializeMessage(_serializeMessage(x))` the `_clone`
|
||||
/// function will not try to adjust SendPort values and pass them through.
|
||||
_clone(message) {
|
||||
_Serializer serializer = new _Serializer(serializeSendPorts: false);
|
||||
_Deserializer deserializer = new _Deserializer();
|
||||
return deserializer.deserialize(serializer.serialize(message));
|
||||
}
|
||||
|
||||
class _Serializer {
|
||||
final bool _serializeSendPorts;
|
||||
Map<dynamic, int> serializedObjectIds = new Map<dynamic, int>.identity();
|
||||
|
||||
_Serializer({serializeSendPorts: true})
|
||||
: _serializeSendPorts = serializeSendPorts;
|
||||
|
||||
/// Returns a message that can be transmitted through web-worker channels.
|
||||
serialize(x) {
|
||||
if (isPrimitive(x)) return serializePrimitive(x);
|
||||
|
||||
int serializationId = serializedObjectIds[x];
|
||||
if (serializationId != null) return makeRef(serializationId);
|
||||
|
||||
serializationId = serializedObjectIds.length;
|
||||
serializedObjectIds[x] = serializationId;
|
||||
|
||||
if (x is NativeByteBuffer) return serializeByteBuffer(x);
|
||||
if (x is NativeTypedData) return serializeTypedData(x);
|
||||
if (x is JSIndexable) return serializeJSIndexable(x);
|
||||
if (x is InternalMap) return serializeMap(x);
|
||||
|
||||
if (x is JSObject) return serializeJSObject(x);
|
||||
|
||||
// We should not have any interceptors any more.
|
||||
if (x is Interceptor) unsupported(x);
|
||||
|
||||
if (x is RawReceivePort) {
|
||||
unsupported(x, "RawReceivePorts can't be transmitted:");
|
||||
}
|
||||
|
||||
// SendPorts need their workerIds adjusted (either during serialization or
|
||||
// deserialization).
|
||||
if (x is _NativeJsSendPort) return serializeJsSendPort(x);
|
||||
if (x is _WorkerSendPort) return serializeWorkerSendPort(x);
|
||||
|
||||
if (x is Function) return serializeClosure(x);
|
||||
|
||||
return serializeDartObject(x);
|
||||
}
|
||||
|
||||
void unsupported(x, [String message]) {
|
||||
if (message == null) message = "Can't transmit:";
|
||||
throw new UnsupportedError("$message $x");
|
||||
}
|
||||
|
||||
makeRef(int serializationId) => ["ref", serializationId];
|
||||
|
||||
bool isPrimitive(x) => x == null || x is String || x is num || x is bool;
|
||||
serializePrimitive(primitive) => primitive;
|
||||
|
||||
serializeByteBuffer(NativeByteBuffer buffer) {
|
||||
return ["buffer", buffer];
|
||||
}
|
||||
|
||||
serializeTypedData(NativeTypedData data) {
|
||||
return ["typed", data];
|
||||
}
|
||||
|
||||
serializeJSIndexable(JSIndexable indexable) {
|
||||
// Strings are JSIndexable but should have been treated earlier.
|
||||
assert(indexable is! String);
|
||||
List serialized = serializeArray(indexable);
|
||||
if (indexable is JSFixedArray) return ["fixed", serialized];
|
||||
if (indexable is JSExtendableArray) return ["extendable", serialized];
|
||||
// MutableArray check must be last, since JSFixedArray and JSExtendableArray
|
||||
// extend JSMutableArray.
|
||||
if (indexable is JSMutableArray) return ["mutable", serialized];
|
||||
// The only JSArrays left are the const Lists (as in `const [1, 2]`).
|
||||
if (indexable is JSArray) return ["const", serialized];
|
||||
unsupported(indexable, "Can't serialize indexable: ");
|
||||
return null;
|
||||
}
|
||||
|
||||
serializeArray(JSArray x) {
|
||||
List serialized = [];
|
||||
serialized.length = x.length;
|
||||
for (int i = 0; i < x.length; i++) {
|
||||
serialized[i] = serialize(x[i]);
|
||||
}
|
||||
return serialized;
|
||||
}
|
||||
|
||||
serializeArrayInPlace(JSArray x) {
|
||||
for (int i = 0; i < x.length; i++) {
|
||||
x[i] = serialize(x[i]);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
serializeMap(InternalMap x) {
|
||||
Function serializeTearOff = serialize;
|
||||
return [
|
||||
'map',
|
||||
x.keys.map(serializeTearOff).toList(),
|
||||
x.values.map(serializeTearOff).toList()
|
||||
];
|
||||
}
|
||||
|
||||
serializeJSObject(JSObject x) {
|
||||
// Don't serialize objects if their `constructor` property isn't `Object`
|
||||
// or undefined/null.
|
||||
// A different constructor is taken as a sign that the object has complex
|
||||
// internal state, or that it is a function, and won't be serialized.
|
||||
if (JS('bool', '!!(#.constructor)', x) &&
|
||||
JS('bool', 'x.constructor !== Object')) {
|
||||
unsupported(x, "Only plain JS Objects are supported:");
|
||||
}
|
||||
List keys = JS('JSArray', 'Object.keys(#)', x);
|
||||
List values = [];
|
||||
values.length = keys.length;
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
values[i] = serialize(JS('', '#[#]', x, keys[i]));
|
||||
}
|
||||
return ['js-object', keys, values];
|
||||
}
|
||||
|
||||
serializeWorkerSendPort(_WorkerSendPort x) {
|
||||
if (_serializeSendPorts) {
|
||||
return ['sendport', x._workerId, x._isolateId, x._receivePortId];
|
||||
}
|
||||
return ['raw sendport', x];
|
||||
}
|
||||
|
||||
serializeJsSendPort(_NativeJsSendPort x) {
|
||||
if (_serializeSendPorts) {
|
||||
int workerId = _globalState.currentManagerId;
|
||||
return ['sendport', workerId, x._isolateId, x._receivePort._id];
|
||||
}
|
||||
return ['raw sendport', x];
|
||||
}
|
||||
|
||||
serializeCapability(CapabilityImpl x) => ['capability', x._id];
|
||||
|
||||
serializeClosure(Function x) {
|
||||
final name = IsolateNatives._getJSFunctionName(x);
|
||||
if (name == null) {
|
||||
unsupported(x, "Closures can't be transmitted:");
|
||||
}
|
||||
return ['function', name];
|
||||
}
|
||||
|
||||
serializeDartObject(x) {
|
||||
var classExtractor = JS_EMBEDDED_GLOBAL('', CLASS_ID_EXTRACTOR);
|
||||
var fieldsExtractor = JS_EMBEDDED_GLOBAL('', CLASS_FIELDS_EXTRACTOR);
|
||||
String classId = JS('String', '#(#)', classExtractor, x);
|
||||
List fields = JS('JSArray', '#(#)', fieldsExtractor, x);
|
||||
return ['dart', classId, serializeArrayInPlace(fields)];
|
||||
}
|
||||
}
|
||||
|
||||
class _Deserializer {
|
||||
/// When `true`, encodes sendports specially so that they can be adjusted on
|
||||
/// the receiving end.
|
||||
///
|
||||
/// When `false`, sendports are cloned like any other object.
|
||||
final bool _adjustSendPorts;
|
||||
|
||||
List<dynamic> deserializedObjects = new List<dynamic>();
|
||||
|
||||
_Deserializer({adjustSendPorts: true}) : _adjustSendPorts = adjustSendPorts;
|
||||
|
||||
/// Returns a message that can be transmitted through web-worker channels.
|
||||
deserialize(x) {
|
||||
if (isPrimitive(x)) return deserializePrimitive(x);
|
||||
|
||||
if (x is! JSArray) throw new ArgumentError("Bad serialized message: $x");
|
||||
|
||||
switch (x.first) {
|
||||
case "ref":
|
||||
return deserializeRef(x);
|
||||
case "buffer":
|
||||
return deserializeByteBuffer(x);
|
||||
case "typed":
|
||||
return deserializeTypedData(x);
|
||||
case "fixed":
|
||||
return deserializeFixed(x);
|
||||
case "extendable":
|
||||
return deserializeExtendable(x);
|
||||
case "mutable":
|
||||
return deserializeMutable(x);
|
||||
case "const":
|
||||
return deserializeConst(x);
|
||||
case "map":
|
||||
return deserializeMap(x);
|
||||
case "sendport":
|
||||
return deserializeSendPort(x);
|
||||
case "raw sendport":
|
||||
return deserializeRawSendPort(x);
|
||||
case "js-object":
|
||||
return deserializeJSObject(x);
|
||||
case "function":
|
||||
return deserializeClosure(x);
|
||||
case "dart":
|
||||
return deserializeDartObject(x);
|
||||
default:
|
||||
throw "couldn't deserialize: $x";
|
||||
}
|
||||
}
|
||||
|
||||
bool isPrimitive(x) => x == null || x is String || x is num || x is bool;
|
||||
deserializePrimitive(x) => x;
|
||||
|
||||
// ['ref', id].
|
||||
deserializeRef(x) {
|
||||
assert(x[0] == 'ref');
|
||||
int serializationId = x[1];
|
||||
return deserializedObjects[serializationId];
|
||||
}
|
||||
|
||||
// ['buffer', <byte buffer>].
|
||||
NativeByteBuffer deserializeByteBuffer(x) {
|
||||
assert(x[0] == 'buffer');
|
||||
NativeByteBuffer result = x[1];
|
||||
deserializedObjects.add(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// ['typed', <typed array>].
|
||||
NativeTypedData deserializeTypedData(x) {
|
||||
assert(x[0] == 'typed');
|
||||
NativeTypedData result = x[1];
|
||||
deserializedObjects.add(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Updates the given array in place with its deserialized content.
|
||||
List deserializeArrayInPlace(JSArray x) {
|
||||
for (int i = 0; i < x.length; i++) {
|
||||
x[i] = deserialize(x[i]);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
// ['fixed', <array>].
|
||||
List deserializeFixed(x) {
|
||||
assert(x[0] == 'fixed');
|
||||
List result = x[1];
|
||||
deserializedObjects.add(result);
|
||||
return new JSArray.fixed(deserializeArrayInPlace(result));
|
||||
}
|
||||
|
||||
// ['extendable', <array>].
|
||||
List deserializeExtendable(x) {
|
||||
assert(x[0] == 'extendable');
|
||||
List result = x[1];
|
||||
deserializedObjects.add(result);
|
||||
return new JSArray.of(deserializeArrayInPlace(result));
|
||||
}
|
||||
|
||||
// ['mutable', <array>].
|
||||
List deserializeMutable(x) {
|
||||
assert(x[0] == 'mutable');
|
||||
List result = x[1];
|
||||
deserializedObjects.add(result);
|
||||
return deserializeArrayInPlace(result);
|
||||
}
|
||||
|
||||
// ['const', <array>].
|
||||
List deserializeConst(x) {
|
||||
assert(x[0] == 'const');
|
||||
List result = x[1];
|
||||
deserializedObjects.add(result);
|
||||
// TODO(floitsch): need to mark list as non-changeable.
|
||||
return new JSArray.unmodifiable(deserializeArrayInPlace(result));
|
||||
}
|
||||
|
||||
// ['map', <key-list>, <value-list>].
|
||||
Map deserializeMap(InternalMap x) {
|
||||
assert(x[0] == 'map');
|
||||
List keys = x[1];
|
||||
List values = x[2];
|
||||
Map result = {};
|
||||
deserializedObjects.add(result);
|
||||
// We need to keep the order of how objects were serialized.
|
||||
// First deserialize all keys, and then only deserialize the values.
|
||||
keys = keys.map(deserialize).toList();
|
||||
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
result[keys[i]] = deserialize(values[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// ['sendport', <managerId>, <isolateId>, <receivePortId>].
|
||||
SendPort deserializeSendPort(x) {
|
||||
assert(x[0] == 'sendport');
|
||||
int managerId = x[1];
|
||||
int isolateId = x[2];
|
||||
int receivePortId = x[3];
|
||||
SendPort result;
|
||||
// If two isolates are in the same manager, we use NativeJsSendPorts to
|
||||
// deliver messages directly without using postMessage.
|
||||
if (managerId == _globalState.currentManagerId) {
|
||||
var isolate = _globalState.isolates[isolateId];
|
||||
if (isolate == null) return null; // Isolate has been closed.
|
||||
var receivePort = isolate.lookup(receivePortId);
|
||||
if (receivePort == null) return null; // Port has been closed.
|
||||
result = new _NativeJsSendPort(receivePort, isolateId);
|
||||
} else {
|
||||
result = new _WorkerSendPort(managerId, isolateId, receivePortId);
|
||||
}
|
||||
deserializedObjects.add(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// ['raw sendport', <sendport>].
|
||||
SendPort deserializeRawSendPort(x) {
|
||||
assert(x[0] == 'raw sendport');
|
||||
SendPort result = x[1];
|
||||
deserializedObjects.add(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// ['js-object', <key-list>, <value-list>].
|
||||
deserializeJSObject(x) {
|
||||
assert(x[0] == 'js-object');
|
||||
List keys = x[1];
|
||||
List values = x[2];
|
||||
var o = JS('', '{}');
|
||||
deserializedObjects.add(o);
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
JS('', '#[#]=#', o, keys[i], deserialize(values[i]));
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
// ['function', <name>].
|
||||
Function deserializeClosure(x) {
|
||||
assert(x[0] == 'function');
|
||||
String name = x[1];
|
||||
Function result = IsolateNatives._getJSFunctionFromName(name);
|
||||
deserializedObjects.add(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// ['dart', <class-id>, <field-list>].
|
||||
deserializeDartObject(x) {
|
||||
assert(x[0] == 'dart');
|
||||
String classId = x[1];
|
||||
List fields = x[2];
|
||||
var instanceFromClassId = JS_EMBEDDED_GLOBAL('', INSTANCE_FROM_CLASS_ID);
|
||||
var initializeObject = JS_EMBEDDED_GLOBAL('', INITIALIZE_EMPTY_INSTANCE);
|
||||
|
||||
var emptyInstance = JS('', '#(#)', instanceFromClassId, classId);
|
||||
deserializedObjects.add(emptyInstance);
|
||||
deserializeArrayInPlace(fields);
|
||||
return JS(
|
||||
'', '#(#, #, #)', initializeObject, classId, emptyInstance, fields);
|
||||
}
|
||||
}
|
|
@ -66,25 +66,6 @@ class SyncIterable<E> extends IterableBase<E> {
|
|||
}
|
||||
|
||||
class Primitives {
|
||||
/// Isolate-unique ID for caching [JsClosureMirror.function].
|
||||
/// Note the initial value is used by the first isolate (or if there are no
|
||||
/// isolates), new isolates will update this value to avoid conflicts by
|
||||
/// calling [initializeStatics].
|
||||
static String mirrorFunctionCacheName = '\$cachedFunction';
|
||||
|
||||
/// Isolate-unique ID for caching [JsInstanceMirror._invoke].
|
||||
static String mirrorInvokeCacheName = '\$cachedInvocation';
|
||||
|
||||
/// Called when creating a new isolate (see _IsolateContext constructor in
|
||||
/// isolate_helper.dart).
|
||||
/// Please don't add complicated code to this method, as it will impact
|
||||
/// start-up performance.
|
||||
static void initializeStatics(int id) {
|
||||
// Benchmarking shows significant performance improvements if this is a
|
||||
// fixed value.
|
||||
mirrorFunctionCacheName += '_$id';
|
||||
mirrorInvokeCacheName += '_$id';
|
||||
}
|
||||
|
||||
@NoInline()
|
||||
static int _parseIntError(String source, int handleError(String source)) {
|
||||
|
@ -196,7 +177,7 @@ class Primitives {
|
|||
return result;
|
||||
}
|
||||
|
||||
/** [: r"$".codeUnitAt(0) :] */
|
||||
/** `r"$".codeUnitAt(0)` */
|
||||
static const int DOLLAR_CHAR_VALUE = 36;
|
||||
|
||||
static int dateNow() => JS('int', r'Date.now()');
|
||||
|
@ -485,9 +466,6 @@ class Primitives {
|
|||
}
|
||||
JS('void', '#[#] = #', object, key, value);
|
||||
}
|
||||
|
||||
static StackTrace extractStackTrace(Error error) =>
|
||||
getTraceFromException(error);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
/// Contains the names of globals that are embedded into the output by the
|
||||
/// compiler.
|
||||
///
|
||||
/// Variables embedded this way should be access with `JS_EMBEDDED_GLOBAL` from
|
||||
/// the `_foreign_helper` library.
|
||||
///
|
||||
/// This library is shared between the compiler and the runtime system.
|
||||
library dart2js._embedded_names;
|
||||
|
||||
const DISPATCH_PROPERTY_NAME = "dispatchPropertyName";
|
||||
const TYPE_INFORMATION = 'typeInformation';
|
||||
const GLOBAL_FUNCTIONS = 'globalFunctions';
|
||||
const STATICS = 'statics';
|
||||
|
||||
/**
|
||||
* If [JSInvocationMirror._invokeOn] is being used, this embedded global
|
||||
* contains a JavaScript map with the names of methods that are
|
||||
* intercepted.
|
||||
*/
|
||||
const INTERCEPTED_NAMES = 'interceptedNames';
|
||||
|
||||
const MANGLED_GLOBAL_NAMES = 'mangledGlobalNames';
|
||||
const MANGLED_NAMES = 'mangledNames';
|
||||
const LIBRARIES = 'libraries';
|
||||
const FINISHED_CLASSES = 'finishedClasses';
|
||||
const ALL_CLASSES = 'allClasses';
|
||||
const METADATA = 'metadata';
|
||||
const INTERCEPTORS_BY_TAG = 'interceptorsByTag';
|
||||
const LEAF_TAGS = 'leafTags';
|
||||
const LAZIES = 'lazies';
|
||||
const GET_ISOLATE_TAG = 'getIsolateTag';
|
||||
const ISOLATE_TAG = 'isolateTag';
|
||||
const CURRENT_SCRIPT = 'currentScript';
|
||||
const DEFERRED_LIBRARY_URIS = 'deferredLibraryUris';
|
||||
const DEFERRED_LIBRARY_HASHES = 'deferredLibraryHashes';
|
||||
const INITIALIZE_LOADED_HUNK = 'initializeLoadedHunk';
|
||||
const IS_HUNK_LOADED = 'isHunkLoaded';
|
||||
const IS_HUNK_INITIALIZED = 'isHunkInitialized';
|
||||
const DEFERRED_INITIALIZED = 'deferredInitialized';
|
||||
const CLASS_ID_EXTRACTOR = 'classIdExtractor';
|
||||
const CLASS_FIELDS_EXTRACTOR = 'classFieldsExtractor';
|
||||
const INSTANCE_FROM_CLASS_ID = "instanceFromClassId";
|
||||
const INITIALIZE_EMPTY_INSTANCE = "initializeEmptyInstance";
|
||||
const TYPEDEF_TYPE_PROPERTY_NAME = r"$typedefType";
|
||||
const TYPEDEF_PREDICATE_PROPERTY_NAME = r"$$isTypedef";
|
||||
const NATIVE_SUPERCLASS_TAG_NAME = r"$nativeSuperclassTag";
|
||||
|
||||
const MAP_TYPE_TO_INTERCEPTOR = "mapTypeToInterceptor";
|
|
@ -43,7 +43,6 @@ import 'dart:web_audio' show AudioBuffer, AudioTrack, AudioTrackList;
|
|||
import 'dart:web_gl' as gl;
|
||||
import 'dart:web_gl' show RenderingContext, RenderingContext2;
|
||||
import 'dart:web_sql';
|
||||
import 'dart:_isolate_helper' show IsolateNatives;
|
||||
import 'dart:_foreign_helper' show JS, JS_INTERCEPTOR_CONSTANT;
|
||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
|
|
|
@ -63,7 +63,6 @@ import 'dart:_interceptors' show
|
|||
findConstructorForNativeSubclassType,
|
||||
getNativeInterceptor,
|
||||
setDispatchProperty;
|
||||
import 'dart:_isolate_helper' show IsolateNatives;
|
||||
import 'dart:_foreign_helper' show JS, JS_INTERCEPTOR_CONSTANT;
|
||||
|
||||
export 'dart:math' show Rectangle, Point;
|
||||
|
|
Loading…
Reference in a new issue