mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 02:47:36 +00:00
- Implement some more missing pieces of the Isolate API.
Added: * addOnExitListener, removeOnExitListener * setErrorsFatal * addOnErrorListener, removeOnErrorListener R=asiva@google.com Review URL: https://codereview.chromium.org//881373002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@44307 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
87790063a4
commit
91e105d8c6
|
@ -335,6 +335,11 @@ patch class Isolate {
|
||||||
static const _RESUME = 2;
|
static const _RESUME = 2;
|
||||||
static const _PING = 3;
|
static const _PING = 3;
|
||||||
static const _KILL = 4;
|
static const _KILL = 4;
|
||||||
|
static const _ADD_EXIT = 5;
|
||||||
|
static const _DEL_EXIT = 6;
|
||||||
|
static const _ADD_ERROR = 7;
|
||||||
|
static const _DEL_ERROR = 8;
|
||||||
|
static const _ERROR_FATAL = 9;
|
||||||
|
|
||||||
|
|
||||||
static void _spawnFunction(SendPort readyPort, Function topLevelFunction,
|
static void _spawnFunction(SendPort readyPort, Function topLevelFunction,
|
||||||
|
@ -367,15 +372,28 @@ patch class Isolate {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* patch */ void addOnExitListener(SendPort responsePort) {
|
/* patch */ void addOnExitListener(SendPort responsePort) {
|
||||||
throw new UnsupportedError("addOnExitListener");
|
var msg = new List(3)
|
||||||
|
..[0] = 0 // Make room for OOB message type.
|
||||||
|
..[1] = _ADD_EXIT
|
||||||
|
..[2] = responsePort;
|
||||||
|
_sendOOB(controlPort, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* patch */ void removeOnExitListener(SendPort responsePort) {
|
/* patch */ void removeOnExitListener(SendPort responsePort) {
|
||||||
throw new UnsupportedError("removeOnExitListener");
|
var msg = new List(3)
|
||||||
|
..[0] = 0 // Make room for OOB message type.
|
||||||
|
..[1] = _DEL_EXIT
|
||||||
|
..[2] = responsePort;
|
||||||
|
_sendOOB(controlPort, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* patch */ void setErrorsFatal(bool errorsAreFatal) {
|
/* patch */ void setErrorsFatal(bool errorsAreFatal) {
|
||||||
throw new UnsupportedError("setErrorsFatal");
|
var msg = new List(4)
|
||||||
|
..[0] = 0 // Make room for OOB message type.
|
||||||
|
..[1] = _ERROR_FATAL
|
||||||
|
..[2] = terminateCapability
|
||||||
|
..[3] = errorsAreFatal;
|
||||||
|
_sendOOB(controlPort, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* patch */ void kill([int priority = BEFORE_NEXT_EVENT]) {
|
/* patch */ void kill([int priority = BEFORE_NEXT_EVENT]) {
|
||||||
|
@ -397,11 +415,19 @@ patch class Isolate {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* patch */ void addErrorListener(SendPort port) {
|
/* patch */ void addErrorListener(SendPort port) {
|
||||||
throw new UnsupportedError("addErrorListener");
|
var msg = new List(3)
|
||||||
|
..[0] = 0 // Make room for OOB message type.
|
||||||
|
..[1] = _ADD_ERROR
|
||||||
|
..[2] = port;
|
||||||
|
_sendOOB(controlPort, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* patch */ void removeErrorListener(SendPort port) {
|
/* patch */ void removeErrorListener(SendPort port) {
|
||||||
throw new UnsupportedError("removeErrorListener");
|
var msg = new List(3)
|
||||||
|
..[0] = 0 // Make room for OOB message type.
|
||||||
|
..[1] = _DEL_ERROR
|
||||||
|
..[2] = port;
|
||||||
|
_sendOOB(controlPort, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Isolate _getCurrentIsolate() {
|
static Isolate _getCurrentIsolate() {
|
||||||
|
|
|
@ -126,13 +126,21 @@ class IsolateMessageHandler : public MessageHandler {
|
||||||
virtual Isolate* isolate() const { return isolate_; }
|
virtual Isolate* isolate() const { return isolate_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Keep in sync with isolate_patch.dart.
|
// Keep both these enums in sync with isolate_patch.dart.
|
||||||
|
// The different Isolate API message types.
|
||||||
enum {
|
enum {
|
||||||
kPauseMsg = 1,
|
kPauseMsg = 1,
|
||||||
kResumeMsg = 2,
|
kResumeMsg = 2,
|
||||||
kPingMsg = 3,
|
kPingMsg = 3,
|
||||||
kKillMsg = 4,
|
kKillMsg = 4,
|
||||||
|
kAddExitMsg = 5,
|
||||||
|
kDelExitMsg = 6,
|
||||||
|
kAddErrorMsg = 7,
|
||||||
|
kDelErrorMsg = 8,
|
||||||
|
kErrorFatalMsg = 9,
|
||||||
|
};
|
||||||
|
// The different Isolate API message priorities for ping and kill messages.
|
||||||
|
enum {
|
||||||
kImmediateAction = 0,
|
kImmediateAction = 0,
|
||||||
kBeforeNextEventAction = 1,
|
kBeforeNextEventAction = 1,
|
||||||
kAsEventAction = 2
|
kAsEventAction = 2
|
||||||
|
@ -167,8 +175,8 @@ bool IsolateMessageHandler::HandleLibMessage(const Array& message) {
|
||||||
if (message.Length() < 2) return true;
|
if (message.Length() < 2) return true;
|
||||||
const Object& type = Object::Handle(I, message.At(1));
|
const Object& type = Object::Handle(I, message.At(1));
|
||||||
if (!type.IsSmi()) return true;
|
if (!type.IsSmi()) return true;
|
||||||
const Smi& msg_type = Smi::Cast(type);
|
const intptr_t msg_type = Smi::Cast(type).Value();
|
||||||
switch (msg_type.Value()) {
|
switch (msg_type) {
|
||||||
case kPauseMsg: {
|
case kPauseMsg: {
|
||||||
// [ OOB, kPauseMsg, pause capability, resume capability ]
|
// [ OOB, kPauseMsg, pause capability, resume capability ]
|
||||||
if (message.Length() != 4) return true;
|
if (message.Length() != 4) return true;
|
||||||
|
@ -255,6 +263,45 @@ bool IsolateMessageHandler::HandleLibMessage(const Array& message) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case kAddExitMsg:
|
||||||
|
case kDelExitMsg:
|
||||||
|
case kAddErrorMsg:
|
||||||
|
case kDelErrorMsg: {
|
||||||
|
// [ OOB, msg, listener port ]
|
||||||
|
if (message.Length() != 3) return true;
|
||||||
|
const Object& obj = Object::Handle(I, message.At(2));
|
||||||
|
if (!obj.IsSendPort()) return true;
|
||||||
|
const SendPort& listener = SendPort::Cast(obj);
|
||||||
|
switch (msg_type) {
|
||||||
|
case kAddExitMsg:
|
||||||
|
I->AddExitListener(listener);
|
||||||
|
break;
|
||||||
|
case kDelExitMsg:
|
||||||
|
I->RemoveExitListener(listener);
|
||||||
|
break;
|
||||||
|
case kAddErrorMsg:
|
||||||
|
I->AddErrorListener(listener);
|
||||||
|
break;
|
||||||
|
case kDelErrorMsg:
|
||||||
|
I->RemoveErrorListener(listener);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kErrorFatalMsg: {
|
||||||
|
// [ OOB, kErrorFatalMsg, terminate capability, val ]
|
||||||
|
if (message.Length() != 4) return true;
|
||||||
|
// Check that the terminate capability has been passed correctly.
|
||||||
|
Object& obj = Object::Handle(I, message.At(2));
|
||||||
|
if (!I->VerifyTerminateCapability(obj)) return true;
|
||||||
|
// Get the value to be set.
|
||||||
|
obj = message.At(3);
|
||||||
|
if (!obj.IsBool()) return true;
|
||||||
|
I->SetErrorsFatal(Bool::Cast(obj).value());
|
||||||
|
break;
|
||||||
|
}
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
// Malformed OOB messages are silently ignored in release builds.
|
// Malformed OOB messages are silently ignored in release builds.
|
||||||
default:
|
default:
|
||||||
|
@ -438,8 +485,35 @@ bool IsolateMessageHandler::ProcessUnhandledException(const Error& result) {
|
||||||
Dart_ExitScope();
|
Dart_ExitScope();
|
||||||
}
|
}
|
||||||
|
|
||||||
I->object_store()->set_sticky_error(result);
|
// Generate the error and stacktrace strings for the error message.
|
||||||
return false;
|
String& exc_str = String::Handle(I);
|
||||||
|
String& stacktrace_str = String::Handle(I);
|
||||||
|
if (result.IsUnhandledException()) {
|
||||||
|
const UnhandledException& uhe = UnhandledException::Cast(result);
|
||||||
|
const Instance& exception = Instance::Handle(I, uhe.exception());
|
||||||
|
Object& tmp = Object::Handle(I);
|
||||||
|
tmp = DartLibraryCalls::ToString(exception);
|
||||||
|
if (!tmp.IsString()) {
|
||||||
|
tmp = String::New(exception.ToCString());
|
||||||
|
}
|
||||||
|
exc_str ^= tmp.raw();
|
||||||
|
|
||||||
|
const Instance& stacktrace = Instance::Handle(I, uhe.stacktrace());
|
||||||
|
tmp = DartLibraryCalls::ToString(stacktrace);
|
||||||
|
if (!tmp.IsString()) {
|
||||||
|
tmp = String::New(stacktrace.ToCString());
|
||||||
|
}
|
||||||
|
stacktrace_str ^= tmp.raw();;
|
||||||
|
} else {
|
||||||
|
exc_str = String::New(result.ToErrorCString());
|
||||||
|
}
|
||||||
|
I->NotifyErrorListeners(exc_str, stacktrace_str);
|
||||||
|
|
||||||
|
if (I->ErrorsFatal()) {
|
||||||
|
I->object_store()->set_sticky_error(result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -470,6 +544,7 @@ Isolate::Isolate()
|
||||||
origin_id_(0),
|
origin_id_(0),
|
||||||
pause_capability_(0),
|
pause_capability_(0),
|
||||||
terminate_capability_(0),
|
terminate_capability_(0),
|
||||||
|
errors_fatal_(true),
|
||||||
heap_(NULL),
|
heap_(NULL),
|
||||||
object_store_(NULL),
|
object_store_(NULL),
|
||||||
top_exit_frame_info_(0),
|
top_exit_frame_info_(0),
|
||||||
|
@ -535,6 +610,7 @@ Isolate::Isolate(Isolate* original)
|
||||||
main_port_(0),
|
main_port_(0),
|
||||||
pause_capability_(0),
|
pause_capability_(0),
|
||||||
terminate_capability_(0),
|
terminate_capability_(0),
|
||||||
|
errors_fatal_(true),
|
||||||
heap_(NULL),
|
heap_(NULL),
|
||||||
object_store_(NULL),
|
object_store_(NULL),
|
||||||
top_exit_frame_info_(0),
|
top_exit_frame_info_(0),
|
||||||
|
@ -890,7 +966,7 @@ bool Isolate::VerifyTerminateCapability(const Object& capability) const {
|
||||||
|
|
||||||
bool Isolate::AddResumeCapability(const Capability& capability) {
|
bool Isolate::AddResumeCapability(const Capability& capability) {
|
||||||
// Ensure a limit for the number of resume capabilities remembered.
|
// Ensure a limit for the number of resume capabilities remembered.
|
||||||
static const intptr_t kMaxResumeCapabilities = kSmiMax / (6*kWordSize);
|
static const intptr_t kMaxResumeCapabilities = kSmiMax / (6 * kWordSize);
|
||||||
|
|
||||||
const GrowableObjectArray& caps = GrowableObjectArray::Handle(
|
const GrowableObjectArray& caps = GrowableObjectArray::Handle(
|
||||||
this, object_store()->resume_capabilities());
|
this, object_store()->resume_capabilities());
|
||||||
|
@ -938,6 +1014,148 @@ bool Isolate::RemoveResumeCapability(const Capability& capability) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO(iposva): Remove duplicated code and start using some hash based
|
||||||
|
// structure instead of these linear lookups.
|
||||||
|
void Isolate::AddExitListener(const SendPort& listener) {
|
||||||
|
// Ensure a limit for the number of listeners remembered.
|
||||||
|
static const intptr_t kMaxListeners = kSmiMax / (6 * kWordSize);
|
||||||
|
|
||||||
|
const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
|
||||||
|
this, object_store()->exit_listeners());
|
||||||
|
SendPort& current = SendPort::Handle(this);
|
||||||
|
intptr_t insertion_index = -1;
|
||||||
|
for (intptr_t i = 0; i < listeners.Length(); i++) {
|
||||||
|
current ^= listeners.At(i);
|
||||||
|
if (current.IsNull()) {
|
||||||
|
if (insertion_index < 0) {
|
||||||
|
insertion_index = i;
|
||||||
|
}
|
||||||
|
} else if (current.Id() == listener.Id()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (insertion_index < 0) {
|
||||||
|
if (listeners.Length() >= kMaxListeners) {
|
||||||
|
// Cannot grow the array of listeners beyond its max. Additional
|
||||||
|
// listeners are ignored. In practice will never happen as we will
|
||||||
|
// run out of memory beforehand.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
listeners.Add(listener);
|
||||||
|
} else {
|
||||||
|
listeners.SetAt(insertion_index, listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Isolate::RemoveExitListener(const SendPort& listener) {
|
||||||
|
const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
|
||||||
|
this, object_store()->exit_listeners());
|
||||||
|
SendPort& current = SendPort::Handle(this);
|
||||||
|
for (intptr_t i = 0; i < listeners.Length(); i++) {
|
||||||
|
current ^= listeners.At(i);
|
||||||
|
if (!current.IsNull() && (current.Id() == listener.Id())) {
|
||||||
|
// Remove the matching listener from the list.
|
||||||
|
current = SendPort::null();
|
||||||
|
listeners.SetAt(i, current);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Isolate::NotifyExitListeners() {
|
||||||
|
const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
|
||||||
|
this, this->object_store()->exit_listeners());
|
||||||
|
if (listeners.IsNull()) return;
|
||||||
|
|
||||||
|
SendPort& listener = SendPort::Handle(this);
|
||||||
|
for (intptr_t i = 0; i < listeners.Length(); i++) {
|
||||||
|
listener ^= listeners.At(i);
|
||||||
|
if (!listener.IsNull()) {
|
||||||
|
Dart_Port port_id = listener.Id();
|
||||||
|
uint8_t* data = NULL;
|
||||||
|
intptr_t len = 0;
|
||||||
|
SerializeObject(Object::null_instance(), &data, &len, false);
|
||||||
|
Message* msg = new Message(port_id, data, len, Message::kNormalPriority);
|
||||||
|
PortMap::PostMessage(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Isolate::AddErrorListener(const SendPort& listener) {
|
||||||
|
// Ensure a limit for the number of listeners remembered.
|
||||||
|
static const intptr_t kMaxListeners = kSmiMax / (6 * kWordSize);
|
||||||
|
|
||||||
|
const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
|
||||||
|
this, object_store()->error_listeners());
|
||||||
|
SendPort& current = SendPort::Handle(this);
|
||||||
|
intptr_t insertion_index = -1;
|
||||||
|
for (intptr_t i = 0; i < listeners.Length(); i++) {
|
||||||
|
current ^= listeners.At(i);
|
||||||
|
if (current.IsNull()) {
|
||||||
|
if (insertion_index < 0) {
|
||||||
|
insertion_index = i;
|
||||||
|
}
|
||||||
|
} else if (current.Id() == listener.Id()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (insertion_index < 0) {
|
||||||
|
if (listeners.Length() >= kMaxListeners) {
|
||||||
|
// Cannot grow the array of listeners beyond its max. Additional
|
||||||
|
// listeners are ignored. In practice will never happen as we will
|
||||||
|
// run out of memory beforehand.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
listeners.Add(listener);
|
||||||
|
} else {
|
||||||
|
listeners.SetAt(insertion_index, listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Isolate::RemoveErrorListener(const SendPort& listener) {
|
||||||
|
const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
|
||||||
|
this, object_store()->error_listeners());
|
||||||
|
SendPort& current = SendPort::Handle(this);
|
||||||
|
for (intptr_t i = 0; i < listeners.Length(); i++) {
|
||||||
|
current ^= listeners.At(i);
|
||||||
|
if (!current.IsNull() && (current.Id() == listener.Id())) {
|
||||||
|
// Remove the matching listener from the list.
|
||||||
|
current = SendPort::null();
|
||||||
|
listeners.SetAt(i, current);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Isolate::NotifyErrorListeners(const String& msg,
|
||||||
|
const String& stacktrace) {
|
||||||
|
const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
|
||||||
|
this, this->object_store()->error_listeners());
|
||||||
|
if (listeners.IsNull()) return;
|
||||||
|
|
||||||
|
const Array& arr = Array::Handle(this, Array::New(2));
|
||||||
|
arr.SetAt(0, msg);
|
||||||
|
arr.SetAt(1, stacktrace);
|
||||||
|
SendPort& listener = SendPort::Handle(this);
|
||||||
|
for (intptr_t i = 0; i < listeners.Length(); i++) {
|
||||||
|
listener ^= listeners.At(i);
|
||||||
|
if (!listener.IsNull()) {
|
||||||
|
Dart_Port port_id = listener.Id();
|
||||||
|
uint8_t* data = NULL;
|
||||||
|
intptr_t len = 0;
|
||||||
|
SerializeObject(arr, &data, &len, false);
|
||||||
|
Message* msg = new Message(port_id, data, len, Message::kNormalPriority);
|
||||||
|
PortMap::PostMessage(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void StoreError(Isolate* isolate, const Object& obj) {
|
static void StoreError(Isolate* isolate, const Object& obj) {
|
||||||
ASSERT(obj.IsError());
|
ASSERT(obj.IsError());
|
||||||
isolate->object_store()->set_sticky_error(Error::Cast(obj));
|
isolate->object_store()->set_sticky_error(Error::Cast(obj));
|
||||||
|
@ -1170,6 +1388,11 @@ void Isolate::Shutdown() {
|
||||||
StackZone stack_zone(this);
|
StackZone stack_zone(this);
|
||||||
HandleScope handle_scope(this);
|
HandleScope handle_scope(this);
|
||||||
|
|
||||||
|
// Notify exit listeners that this isolate is shutting down.
|
||||||
|
if (object_store() != NULL) {
|
||||||
|
NotifyExitListeners();
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up debugger resources.
|
// Clean up debugger resources.
|
||||||
debugger()->Shutdown();
|
debugger()->Shutdown();
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ class RawFloat32x4;
|
||||||
class RawInt32x4;
|
class RawInt32x4;
|
||||||
class RawUserTag;
|
class RawUserTag;
|
||||||
class SampleBuffer;
|
class SampleBuffer;
|
||||||
|
class SendPort;
|
||||||
class Simulator;
|
class Simulator;
|
||||||
class StackResource;
|
class StackResource;
|
||||||
class StackZone;
|
class StackZone;
|
||||||
|
@ -410,6 +411,17 @@ class Isolate : public BaseIsolate {
|
||||||
bool AddResumeCapability(const Capability& capability);
|
bool AddResumeCapability(const Capability& capability);
|
||||||
bool RemoveResumeCapability(const Capability& capability);
|
bool RemoveResumeCapability(const Capability& capability);
|
||||||
|
|
||||||
|
void AddExitListener(const SendPort& listener);
|
||||||
|
void RemoveExitListener(const SendPort& listener);
|
||||||
|
void NotifyExitListeners();
|
||||||
|
|
||||||
|
void AddErrorListener(const SendPort& listener);
|
||||||
|
void RemoveErrorListener(const SendPort& listener);
|
||||||
|
void NotifyErrorListeners(const String& msg, const String& stacktrace);
|
||||||
|
|
||||||
|
bool ErrorsFatal() const { return errors_fatal_; }
|
||||||
|
void SetErrorsFatal(bool val) { errors_fatal_ = val; }
|
||||||
|
|
||||||
Random* random() { return &random_; }
|
Random* random() { return &random_; }
|
||||||
|
|
||||||
Simulator* simulator() const { return simulator_; }
|
Simulator* simulator() const { return simulator_; }
|
||||||
|
@ -674,6 +686,7 @@ class Isolate : public BaseIsolate {
|
||||||
Dart_Port origin_id_; // Isolates created by spawnFunc have some origin id.
|
Dart_Port origin_id_; // Isolates created by spawnFunc have some origin id.
|
||||||
uint64_t pause_capability_;
|
uint64_t pause_capability_;
|
||||||
uint64_t terminate_capability_;
|
uint64_t terminate_capability_;
|
||||||
|
bool errors_fatal_;
|
||||||
Heap* heap_;
|
Heap* heap_;
|
||||||
ObjectStore* object_store_;
|
ObjectStore* object_store_;
|
||||||
uword top_exit_frame_info_;
|
uword top_exit_frame_info_;
|
||||||
|
|
|
@ -75,6 +75,8 @@ ObjectStore::ObjectStore()
|
||||||
pending_functions_(GrowableObjectArray::null()),
|
pending_functions_(GrowableObjectArray::null()),
|
||||||
pending_deferred_loads_(GrowableObjectArray::null()),
|
pending_deferred_loads_(GrowableObjectArray::null()),
|
||||||
resume_capabilities_(GrowableObjectArray::null()),
|
resume_capabilities_(GrowableObjectArray::null()),
|
||||||
|
exit_listeners_(GrowableObjectArray::null()),
|
||||||
|
error_listeners_(GrowableObjectArray::null()),
|
||||||
sticky_error_(Error::null()),
|
sticky_error_(Error::null()),
|
||||||
empty_context_(Context::null()),
|
empty_context_(Context::null()),
|
||||||
stack_overflow_(Instance::null()),
|
stack_overflow_(Instance::null()),
|
||||||
|
@ -125,6 +127,8 @@ bool ObjectStore::PreallocateObjects() {
|
||||||
this->pending_deferred_loads_ = GrowableObjectArray::New();
|
this->pending_deferred_loads_ = GrowableObjectArray::New();
|
||||||
|
|
||||||
this->resume_capabilities_ = GrowableObjectArray::New();
|
this->resume_capabilities_ = GrowableObjectArray::New();
|
||||||
|
this->exit_listeners_ = GrowableObjectArray::New();
|
||||||
|
this->error_listeners_ = GrowableObjectArray::New();
|
||||||
|
|
||||||
Object& result = Object::Handle();
|
Object& result = Object::Handle();
|
||||||
const Library& library = Library::Handle(Library::CoreLibrary());
|
const Library& library = Library::Handle(Library::CoreLibrary());
|
||||||
|
|
|
@ -342,6 +342,14 @@ class ObjectStore {
|
||||||
return resume_capabilities_;
|
return resume_capabilities_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RawGrowableObjectArray* exit_listeners() const {
|
||||||
|
return exit_listeners_;
|
||||||
|
}
|
||||||
|
|
||||||
|
RawGrowableObjectArray* error_listeners() const {
|
||||||
|
return error_listeners_;
|
||||||
|
}
|
||||||
|
|
||||||
RawError* sticky_error() const { return sticky_error_; }
|
RawError* sticky_error() const { return sticky_error_; }
|
||||||
void set_sticky_error(const Error& value) {
|
void set_sticky_error(const Error& value) {
|
||||||
ASSERT(!value.IsNull());
|
ASSERT(!value.IsNull());
|
||||||
|
@ -488,6 +496,8 @@ class ObjectStore {
|
||||||
RawGrowableObjectArray* pending_functions_;
|
RawGrowableObjectArray* pending_functions_;
|
||||||
RawGrowableObjectArray* pending_deferred_loads_;
|
RawGrowableObjectArray* pending_deferred_loads_;
|
||||||
RawGrowableObjectArray* resume_capabilities_;
|
RawGrowableObjectArray* resume_capabilities_;
|
||||||
|
RawGrowableObjectArray* exit_listeners_;
|
||||||
|
RawGrowableObjectArray* error_listeners_;
|
||||||
RawError* sticky_error_;
|
RawError* sticky_error_;
|
||||||
RawContext* empty_context_;
|
RawContext* empty_context_;
|
||||||
RawInstance* stack_overflow_;
|
RawInstance* stack_overflow_;
|
||||||
|
|
|
@ -47,7 +47,6 @@ Future spawn(entry) {
|
||||||
main(){
|
main(){
|
||||||
asyncStart();
|
asyncStart();
|
||||||
RawReceivePort reply = new RawReceivePort(null);
|
RawReceivePort reply = new RawReceivePort(null);
|
||||||
RawReceivePort reply2 = new RawReceivePort(null);
|
|
||||||
// Create two isolates waiting for commands, with errors non-fatal.
|
// Create two isolates waiting for commands, with errors non-fatal.
|
||||||
Future iso1 = spawn(isomain1);
|
Future iso1 = spawn(isomain1);
|
||||||
Future iso2 = spawn(isomain1);
|
Future iso2 = spawn(isomain1);
|
||||||
|
|
|
@ -92,7 +92,7 @@ main(){
|
||||||
case 2:
|
case 2:
|
||||||
Expect.equals(new RangeError.value(37).toString(), "$error");
|
Expect.equals(new RangeError.value(37).toString(), "$error");
|
||||||
state2++;
|
state2++;
|
||||||
reply.close();
|
reply2.close();
|
||||||
isolate2.removeErrorListener(errorPort2.sendPort);
|
isolate2.removeErrorListener(errorPort2.sendPort);
|
||||||
errorPort2.close();
|
errorPort2.close();
|
||||||
asyncEnd();
|
asyncEnd();
|
||||||
|
|
|
@ -11,16 +11,9 @@ mandel_isolate_test: Skip # Uses 600 MB Ram on our 1 GB test device.
|
||||||
|
|
||||||
[ $compiler == none || $compiler == dart2dart ]
|
[ $compiler == none || $compiler == dart2dart ]
|
||||||
compile_time_error_test/01: Skip # Issue 12587
|
compile_time_error_test/01: Skip # Issue 12587
|
||||||
ondone_test: Fail # Not implemented yet
|
|
||||||
ping_test: Skip # Resolve test issues
|
ping_test: Skip # Resolve test issues
|
||||||
ping_pause_test: Skip # Resolve test issues
|
ping_pause_test: Skip # Resolve test issues
|
||||||
kill_test: Fail # Not implemented yet
|
kill3_test: Pass, Fail # Bad test: expects total message order
|
||||||
kill2_test: Fail # Not implemented yet
|
|
||||||
kill3_test: Fail # Not implemented yet
|
|
||||||
kill_self_test: Fail # Not implemented yet
|
|
||||||
handle_error_test: Fail # Not implemented yet
|
|
||||||
handle_error2_test: Fail # Not implemented yet
|
|
||||||
handle_error3_test: Fail # Not implemented yet
|
|
||||||
|
|
||||||
message3_test/constList_identical: RuntimeError # Issue 21816
|
message3_test/constList_identical: RuntimeError # Issue 21816
|
||||||
message3_test/constMap: RuntimeError # Issue 21816
|
message3_test/constMap: RuntimeError # Issue 21816
|
||||||
|
|
Loading…
Reference in a new issue