Chromium Code Reviews| Index: runtime/vm/object.cc |
| diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
| index 894452d9d8129ad33a01af9b4d1ec9e7675022a8..a0609f47b6272e07f36b0d0495c61ad367ccde7c 100644 |
| --- a/runtime/vm/object.cc |
| +++ b/runtime/vm/object.cc |
| @@ -2779,6 +2779,78 @@ void Class::SetTraceAllocation(bool trace_allocation) const { |
| } |
| +bool Class::ValidatePostFinalizePatch(const Class& orig_class, |
| + Error* error) const { |
| + ASSERT(error != NULL); |
| + // Not allowed to add new fields in a post finalization patch. |
| + if (fields() != Object::empty_array().raw()) { |
| + *error = LanguageError::NewFormatted( |
| + *error, // No previous error. |
| + Script::Handle(script()), |
| + token_pos(), |
| + Report::AtLocation, |
| + Report::kError, |
| + Heap::kNew, |
| + "new fields are not allowed for this patch"); |
| + return false; |
| + } |
| + // There seem to be no functions, the patch is pointless. |
| + if (functions() == Object::empty_array().raw()) { |
| + *error = LanguageError::NewFormatted( |
| + *error, // No previous error. |
| + Script::Handle(script()), |
| + token_pos(), |
| + Report::AtLocation, |
| + Report::kError, |
| + Heap::kNew, |
| + "no functions to patch"); |
| + return false; |
| + } |
| + // Iterate over all functions that will be patched and make sure |
| + // the original function was declared 'external' and has not executed |
| + // so far i.e no code has been generated for it. |
| + Thread* thread = Thread::Current(); |
| + ASSERT(thread->IsMutatorThread()); |
| + Zone* zone = thread->zone(); |
| + const Array& funcs = Array::Handle(zone, functions()); |
| + Function& func = Function::Handle(zone); |
| + Function& orig_func = Function::Handle(zone); |
| + String& name = String::Handle(zone); |
| + for (intptr_t i = 0; i < funcs.Length(); i++) { |
| + func ^= funcs.At(i); |
| + name ^= func.name(); |
| + orig_func ^= orig_class.LookupFunctionAllowPrivate(name); |
| + if (!orig_func.IsNull()) { |
| + if (!orig_func.is_external() || orig_func.HasCode()) { |
| + // We can only patch external functions in a post finalized class. |
| + *error = LanguageError::NewFormatted( |
| + *error, // No previous error. |
| + Script::Handle(script()), |
| + token_pos(), |
| + Report::AtLocation, |
| + Report::kError, |
| + Heap::kNew, |
| + "only external functions that have not executed " |
| + "so far can be patched '%s'", name.ToCString()); |
|
regis
2016/03/31 18:16:49
The error message is not quite a correct sentence
siva
2016/03/31 23:48:08
Done.
|
| + return false; |
| + } |
| + } else if (!Library::IsPrivate(name)) { |
| + // We can only have new private functions that are added. |
| + *error = LanguageError::NewFormatted( |
| + *error, // No previous error. |
| + Script::Handle(script()), |
| + token_pos(), |
| + Report::AtLocation, |
| + Report::kError, |
| + Heap::kNew, |
| + "only private new functions are allowed '%s'", name.ToCString()); |
|
regis
2016/03/31 18:16:49
ditto
"'%s' is not private and therefore cannot be
siva
2016/03/31 23:48:08
Done.
|
| + return false; |
| + } |
| + } |
| + return true; |
| +} |
| + |
| + |
| void Class::set_cha_codes(const Array& cache) const { |
| StorePointer(&raw_ptr()->cha_codes_, cache.raw()); |
| } |
| @@ -3422,6 +3494,14 @@ void Class::set_is_finalized() const { |
| } |
| +void Class::SetRefinalize() const { |
| + ASSERT(!IsTopLevel()); |
| + set_state_bits(ClassFinalizedBits::update(RawClass::kRefinalize, |
| + raw_ptr()->state_bits_)); |
| + set_state_bits(TypeFinalizedBit::update(false, raw_ptr()->state_bits_)); |
| +} |
| + |
| + |
| void Class::ResetFinalization() const { |
| ASSERT(IsTopLevel()); |
| set_state_bits(ClassFinalizedBits::update(RawClass::kAllocated, |
| @@ -5832,6 +5912,7 @@ void Function::SetIsNativeAutoSetupScope(bool value) const { |
| bool Function::CanBeInlined() const { |
| Thread* thread = Thread::Current(); |
| return is_inlinable() && |
| + !is_external() && |
| !is_generated_body() && |
| (!FLAG_support_debugger || |
| !thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone())); |