Index: runtime/vm/parser.cc |
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc |
index 8eb3d515abfffe158757b339f49a04ddeb28102e..569152283b4f545cf0ce62443619786f17f82723 100644 |
--- a/runtime/vm/parser.cc |
+++ b/runtime/vm/parser.cc |
@@ -4565,8 +4565,11 @@ void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, |
cls.set_is_patch(); |
// Apply the changes to the patched class looked up above. |
ASSERT(obj.raw() == library_.LookupLocalObject(class_name)); |
- // The patched class must not be finalized yet. |
- ASSERT(!Class::Cast(obj).is_finalized()); |
+ const Class& orig_class = Class::Cast(obj); |
+ if (orig_class.is_finalized()) { |
+ orig_class.SetRefinalizeAfterPatch(); |
+ pending_classes.Add(orig_class, Heap::kOld); |
+ } |
library_.AddPatchClass(cls); |
} |
pending_classes.Add(cls, Heap::kOld); |
@@ -4634,6 +4637,14 @@ void Parser::ParseClassDefinition(const Class& cls) { |
const Class& orig_class = Class::Cast(obj); |
ASSERT(!orig_class.is_finalized()); |
Error& error = Error::Handle(Z); |
+ // Check if this is a case of patching a class after it has already |
+ // been finalized. |
+ if (orig_class.is_refinalize_after_patch()) { |
+ if (!cls.ValidatePostFinalizePatch(orig_class, &error)) { |
+ Report::LongJumpF(error, script_, class_pos, |
+ "patch validation failed, not applying patch.\n"); |
+ } |
+ } |
if (!orig_class.ApplyPatch(cls, &error)) { |
Report::LongJumpF(error, script_, class_pos, "applying patch failed"); |
} |