Index: vm/snapshot.cc |
=================================================================== |
--- vm/snapshot.cc (revision 14802) |
+++ vm/snapshot.cc (working copy) |
@@ -795,12 +795,17 @@ |
return; |
} |
- NoGCScope no_gc; |
+ NoGCDuringSnapshotWriteScope no_gc; |
RawClass* cls = class_table_->At(raw->GetClassId()); |
intptr_t class_id = cls->ptr()->id_; |
ASSERT(class_id == raw->GetClassId()); |
if (class_id >= kNumPredefinedCids) { |
- ASSERT(!Class::IsSignatureClass(cls)); |
+ if (Class::IsSignatureClass(cls)) { |
+ // We do not allow closure objects in an isolate message. |
+ ThrowIllegalArgException(no_gc, |
+ "Illegal argument in isolate message" |
+ " : (object is a closure)"); |
+ } |
// Object is being referenced, add it to the forward ref list and mark |
// it so that future references to this object in the snapshot will use |
// this object id. Mark it as not having been serialized yet so that we |
@@ -913,7 +918,7 @@ |
intptr_t SnapshotWriter::MarkObject(RawObject* raw, SerializeState state) { |
- NoGCScope no_gc; |
+ NoGCDuringSnapshotWriteScope no_gc; |
intptr_t object_id = forward_list_.length() + kMaxPredefinedObjectIds; |
ASSERT(object_id <= kMaxObjectId); |
uword value = 0; |
@@ -929,7 +934,7 @@ |
void SnapshotWriter::UnmarkAll() { |
- NoGCScope no_gc; |
+ NoGCDuringSnapshotWriteScope no_gc; |
for (intptr_t i = 0; i < forward_list_.length(); i++) { |
RawObject* raw = forward_list_[i]->raw(); |
raw->ptr()->tags_ = forward_list_[i]->tags(); // Restore original tags. |
@@ -943,7 +948,7 @@ |
// - VM internal class (from VM isolate): (index of class in vm isolate | 0x3) |
// - Object that has already been written: (negative id in stream | 0x3) |
- NoGCScope no_gc; |
+ NoGCDuringSnapshotWriteScope no_gc; |
// First check if it is a Smi (i.e not a heap object). |
if (!rawobj->IsHeapObject()) { |
@@ -1022,7 +1027,7 @@ |
// (object size in multiples of kObjectAlignment | 0x1) |
// serialized fields of the object |
// ...... |
- NoGCScope no_gc; |
+ NoGCDuringSnapshotWriteScope no_gc; |
uword tags = raw->ptr()->tags_; |
ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); |
intptr_t object_id = SerializedHeaderData::decode(tags); |
@@ -1031,11 +1036,19 @@ |
intptr_t class_id = cls->ptr()->id_; |
if (class_id >= kNumPredefinedCids) { |
- ASSERT(!Class::IsSignatureClass(cls)); |
+ if (Class::IsSignatureClass(cls)) { |
+ // We do not allow closure objects in an isolate message. |
+ ThrowIllegalArgException(no_gc, |
+ "Illegal argument in isolate message" |
+ " : (object is a closure)"); |
+ } |
+ if (cls->ptr()->num_native_fields_ != 0) { |
+ // We do not allow objects with native fields in an isolate message. |
+ ThrowIllegalArgException(no_gc, |
+ "Illegal argument in isolate message" |
+ " : (object extends NativeWrapper)"); |
+ } |
// Object is regular dart instance. |
- // TODO(5411462): figure out what we need to do if an object with native |
- // fields is serialized (throw exception or serialize a null object). |
- ASSERT(cls->ptr()->num_native_fields_ == 0); |
intptr_t instance_size = cls->ptr()->instance_size_; |
ASSERT(instance_size != 0); |
@@ -1148,6 +1161,18 @@ |
} |
+void SnapshotWriter::ThrowIllegalArgException( |
+ const NoGCDuringSnapshotWriteScope& no_gc, const char* msg) { |
+ UnmarkAll(); |
+ no_gc.Reset(); |
+ const String& msg_obj = String::Handle(String::New(msg)); |
+ GrowableArray<const Object*> args(1); |
+ args.Add(&msg_obj); |
+ Exceptions::ThrowByType(Exceptions::kIllegalArgument, args); |
+ UNREACHABLE(); |
+} |
+ |
+ |
void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { |
ASSERT(kind() == Snapshot::kScript); |