mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 14:32:24 +00:00
Fix crash that happens when we send an object whose type is in a defer
loaded a library that is loaded in the isolate that is sending the message but has not been loaded yet in the isolate which is receiving the message. R=hausner@google.com Review URL: https://codereview.chromium.org//926073002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@43774 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
c7c2b4584b
commit
62d6e2e0bc
4 changed files with 85 additions and 2 deletions
|
@ -7,6 +7,7 @@
|
|||
#include "platform/assert.h"
|
||||
#include "vm/bootstrap.h"
|
||||
#include "vm/class_finalizer.h"
|
||||
#include "vm/dart_entry.h"
|
||||
#include "vm/exceptions.h"
|
||||
#include "vm/heap.h"
|
||||
#include "vm/lockers.h"
|
||||
|
@ -223,11 +224,15 @@ RawClass* SnapshotReader::ReadClassId(intptr_t object_id) {
|
|||
// Read the library/class information and lookup the class.
|
||||
str_ ^= ReadObjectImpl(class_header);
|
||||
library_ = Library::LookupLibrary(str_);
|
||||
ASSERT(!library_.IsNull());
|
||||
if (library_.IsNull() || !library_.Loaded()) {
|
||||
SetReadException("Invalid object found in message.");
|
||||
}
|
||||
str_ ^= ReadObjectImpl();
|
||||
cls = library_.LookupClass(str_);
|
||||
if (cls.IsNull()) {
|
||||
SetReadException("Invalid object found in message.");
|
||||
}
|
||||
cls.EnsureIsFinalized(isolate());
|
||||
ASSERT(!cls.IsNull());
|
||||
return cls.raw();
|
||||
}
|
||||
|
||||
|
@ -247,6 +252,24 @@ intptr_t SnapshotReader::NextAvailableObjectId() const {
|
|||
}
|
||||
|
||||
|
||||
void SnapshotReader::SetReadException(const char* msg) {
|
||||
Isolate* isolate = Isolate::Current();
|
||||
const String& error_str = String::Handle(isolate, String::New(msg));
|
||||
const Array& args = Array::Handle(isolate, Array::New(1));
|
||||
args.SetAt(0, error_str);
|
||||
Object& result = Object::Handle(isolate);
|
||||
const Library& library = Library::Handle(isolate, Library::CoreLibrary());
|
||||
result = DartLibraryCalls::InstanceCreate(library,
|
||||
Symbols::ArgumentError(),
|
||||
Symbols::Dot(),
|
||||
args);
|
||||
const Stacktrace& stacktrace = Stacktrace::Handle(isolate);
|
||||
const UnhandledException& error = UnhandledException::Handle(
|
||||
isolate, UnhandledException::New(Instance::Cast(result), stacktrace));
|
||||
isolate->long_jump_base()->Jump(1, error);
|
||||
}
|
||||
|
||||
|
||||
RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value) {
|
||||
if (IsVMIsolateObject(header_value)) {
|
||||
return ReadVMIsolateObject(header_value);
|
||||
|
|
|
@ -368,6 +368,8 @@ class SnapshotReader : public BaseReader {
|
|||
|
||||
intptr_t NextAvailableObjectId() const;
|
||||
|
||||
void SetReadException(const char* msg);
|
||||
|
||||
Snapshot::Kind kind_; // Indicates type of snapshot(full, script, message).
|
||||
Isolate* isolate_; // Current isolate.
|
||||
Heap* heap_; // Heap of the current isolate.
|
||||
|
|
9
tests/isolate/deferred_loaded_lib.dart
Normal file
9
tests/isolate/deferred_loaded_lib.dart
Normal file
|
@ -0,0 +1,9 @@
|
|||
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
class FromChildIsolate {
|
||||
String toString() => 'from child isolate';
|
||||
int get fld => 10;
|
||||
}
|
||||
|
49
tests/isolate/issue_21398_parent_isolate2_test.dart
Normal file
49
tests/isolate/issue_21398_parent_isolate2_test.dart
Normal file
|
@ -0,0 +1,49 @@
|
|||
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'dart:isolate';
|
||||
import 'dart:async';
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
import "deferred_loaded_lib.dart" deferred as lib;
|
||||
|
||||
// In this test case we send an object created from a deferred library
|
||||
// that is loaded in the child isolate but not the parent isolate. The
|
||||
// parent isolate does not know about the type of this object and throws
|
||||
// an unhandled exception.
|
||||
funcChild(args) {
|
||||
var replyPort = args[0];
|
||||
// Deferred load a library, create an object from that library and send
|
||||
// it over to the parent isolate which has not yet loaded that library.
|
||||
lib.loadLibrary().then((_) {
|
||||
replyPort.send(new lib.FromChildIsolate());
|
||||
});
|
||||
}
|
||||
|
||||
void helperFunction() {
|
||||
var receivePort = new ReceivePort();
|
||||
|
||||
// Spawn an isolate using spawnFunction.
|
||||
Isolate.spawn(funcChild, [receivePort.sendPort]).then(
|
||||
(isolate) {
|
||||
receivePort.listen(
|
||||
(msg) {
|
||||
// We don't expect to receive any valid messages.
|
||||
Expect.fail("We don't expect to receive any valid messages");
|
||||
receivePort.close();
|
||||
},
|
||||
onError: (e) {
|
||||
// We don't expect to receive any error messages, per spec listen
|
||||
// does not receive an error object.
|
||||
Expect.fail("We don't expect to receive any error messages");
|
||||
receivePort.close();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
main() {
|
||||
helperFunction(); /// 01: runtime error
|
||||
}
|
Loading…
Reference in a new issue