Skip to content

Commit

Permalink
[vm] Fail more gracefully when reload removes a static target.
Browse files Browse the repository at this point in the history
Bug: #37517
Change-Id: I83b6bed09235d2abe3e168a49ca28434b127442f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/109140
Commit-Queue: Ryan Macnak <[email protected]>
Reviewed-by: Siva Annamalai <[email protected]>
  • Loading branch information
rmacnak-google authored and [email protected] committed Jul 17, 2019
1 parent 8cb7e4c commit c304336
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 17 deletions.
56 changes: 39 additions & 17 deletions runtime/vm/compiler/frontend/kernel_translation_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,20 @@ const String& TranslationHelper::DartFactoryName(NameIndex factory) {
return String::ZoneHandle(Z, Symbols::FromConcatAll(thread_, pieces));
}

// TODO(https://github.com/dart-lang/sdk/issues/37517): Should emit code to
// throw a NoSuchMethodError.
static void CheckStaticLookup(const Object& target) {
if (target.IsNull()) {
#ifndef PRODUCT
ASSERT(Isolate::Current()->HasAttemptedReload());
Report::LongJump(LanguageError::Handle(LanguageError::New(String::Handle(
String::New("Unimplemented handling of missing static target")))));
#else
UNREACHABLE();
#endif
}
}

RawLibrary* TranslationHelper::LookupLibraryByKernelLibrary(
NameIndex kernel_library) {
// We only use the string and don't rely on having any particular parent.
Expand All @@ -538,7 +552,7 @@ RawLibrary* TranslationHelper::LookupLibraryByKernelLibrary(
ASSERT(!library_name.IsNull());
const Library& library =
Library::Handle(Z, Library::LookupLibrary(thread_, library_name));
ASSERT(!library.IsNull());
CheckStaticLookup(library);
name_index_handle_ = Smi::New(kernel_library);
return info_.InsertLibrary(thread_, name_index_handle_, library);
}
Expand All @@ -558,8 +572,10 @@ RawClass* TranslationHelper::LookupClassByKernelClass(NameIndex kernel_class) {
NameIndex kernel_library = CanonicalNameParent(kernel_class);
Library& library =
Library::Handle(Z, LookupLibraryByKernelLibrary(kernel_library));
ASSERT(!library.IsNull());
const Class& klass =
Class::Handle(Z, library.LookupClassAllowPrivate(class_name));
CheckStaticLookup(klass);
ASSERT(!klass.IsNull());
name_index_handle_ = Smi::New(kernel_class);
return info_.InsertClass(thread_, name_index_handle_, klass);
Expand All @@ -574,14 +590,16 @@ RawField* TranslationHelper::LookupFieldByKernelField(NameIndex kernel_field) {
Library& library =
Library::Handle(Z, LookupLibraryByKernelLibrary(enclosing));
klass = library.toplevel_class();
CheckStaticLookup(klass);
} else {
ASSERT(IsClass(enclosing));
klass = LookupClassByKernelClass(enclosing);
}
RawField* field = klass.LookupFieldAllowPrivate(
DartSymbolObfuscate(CanonicalNameString(kernel_field)));
ASSERT(field != Object::null());
return field;
Field& field = Field::Handle(
Z, klass.LookupFieldAllowPrivate(
DartSymbolObfuscate(CanonicalNameString(kernel_field))));
CheckStaticLookup(field);
return field.raw();
}

RawFunction* TranslationHelper::LookupStaticMethodByKernelProcedure(
Expand All @@ -594,15 +612,16 @@ RawFunction* TranslationHelper::LookupStaticMethodByKernelProcedure(
if (IsLibrary(enclosing)) {
Library& library =
Library::Handle(Z, LookupLibraryByKernelLibrary(enclosing));
RawFunction* function = library.LookupFunctionAllowPrivate(procedure_name);
ASSERT(function != Object::null());
return function;
Function& function =
Function::Handle(Z, library.LookupFunctionAllowPrivate(procedure_name));
CheckStaticLookup(function);
return function.raw();
} else {
ASSERT(IsClass(enclosing));
Class& klass = Class::Handle(Z, LookupClassByKernelClass(enclosing));
Function& function = Function::ZoneHandle(
Z, klass.LookupFunctionAllowPrivate(procedure_name));
ASSERT(!function.IsNull());
CheckStaticLookup(function);
// Redirecting factory must be resolved.
ASSERT(!function.IsRedirectingFactory() ||
function.RedirectionTarget() != Function::null());
Expand All @@ -615,17 +634,18 @@ RawFunction* TranslationHelper::LookupConstructorByKernelConstructor(
ASSERT(IsConstructor(constructor));
Class& klass =
Class::Handle(Z, LookupClassByKernelClass(EnclosingName(constructor)));
CheckStaticLookup(klass);
return LookupConstructorByKernelConstructor(klass, constructor);
}

RawFunction* TranslationHelper::LookupConstructorByKernelConstructor(
const Class& owner,
NameIndex constructor) {
ASSERT(IsConstructor(constructor));
RawFunction* function =
owner.LookupConstructorAllowPrivate(DartConstructorName(constructor));
ASSERT(function != Object::null());
return function;
Function& function = Function::Handle(
Z, owner.LookupConstructorAllowPrivate(DartConstructorName(constructor)));
CheckStaticLookup(function);
return function.raw();
}

RawFunction* TranslationHelper::LookupConstructorByKernelConstructor(
Expand All @@ -650,15 +670,17 @@ RawFunction* TranslationHelper::LookupMethodByMember(
NameIndex kernel_class = EnclosingName(target);
Class& klass = Class::Handle(Z, LookupClassByKernelClass(kernel_class));

RawFunction* function = klass.LookupFunctionAllowPrivate(method_name);
Function& function =
Function::Handle(Z, klass.LookupFunctionAllowPrivate(method_name));
CheckStaticLookup(function);
#ifdef DEBUG
if (function == Object::null()) {
if (function.IsNull()) {
THR_Print("Unable to find \'%s\' in %s\n", method_name.ToCString(),
klass.ToCString());
}
#endif
ASSERT(function != Object::null());
return function;
ASSERT(!function.IsNull());
return function.raw();
}

RawFunction* TranslationHelper::LookupDynamicFunction(const Class& klass,
Expand Down
7 changes: 7 additions & 0 deletions runtime/vm/object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3567,6 +3567,7 @@ void Class::EnsureDeclarationLoaded() const {

// Ensure that top level parsing of the class has been done.
RawError* Class::EnsureIsFinalized(Thread* thread) const {
ASSERT(!IsNull());
// Finalized classes have already been parsed.
if (is_finalized()) {
return Error::null();
Expand Down Expand Up @@ -4465,6 +4466,7 @@ RawFunction* Class::CheckFunctionType(const Function& func, MemberKind kind) {
}

RawFunction* Class::LookupFunction(const String& name, MemberKind kind) const {
ASSERT(!IsNull());
Thread* thread = Thread::Current();
if (EnsureIsFinalized(thread) != Error::null()) {
return Function::null();
Expand Down Expand Up @@ -4516,6 +4518,7 @@ RawFunction* Class::LookupFunction(const String& name, MemberKind kind) const {

RawFunction* Class::LookupFunctionAllowPrivate(const String& name,
MemberKind kind) const {
ASSERT(!IsNull());
Thread* thread = Thread::Current();
if (EnsureIsFinalized(thread) != Error::null()) {
return Function::null();
Expand Down Expand Up @@ -4551,6 +4554,7 @@ RawFunction* Class::LookupSetterFunction(const String& name) const {
RawFunction* Class::LookupAccessorFunction(const char* prefix,
intptr_t prefix_length,
const String& name) const {
ASSERT(!IsNull());
Thread* thread = Thread::Current();
if (EnsureIsFinalized(thread) != Error::null()) {
return Function::null();
Expand Down Expand Up @@ -4588,6 +4592,7 @@ RawField* Class::LookupField(const String& name) const {
}

RawField* Class::LookupField(const String& name, MemberKind kind) const {
ASSERT(!IsNull());
Thread* thread = Thread::Current();
if (EnsureIsFinalized(thread) != Error::null()) {
return Field::null();
Expand Down Expand Up @@ -4635,6 +4640,7 @@ RawField* Class::LookupField(const String& name, MemberKind kind) const {

RawField* Class::LookupFieldAllowPrivate(const String& name,
bool instance_only) const {
ASSERT(!IsNull());
// Use slow string compare, ignoring privacy name mangling.
Thread* thread = Thread::Current();
if (EnsureIsFinalized(thread) != Error::null()) {
Expand Down Expand Up @@ -10452,6 +10458,7 @@ RawObject* Library::LookupReExport(const String& name,
}

RawObject* Library::LookupEntry(const String& name, intptr_t* index) const {
ASSERT(!IsNull());
Thread* thread = Thread::Current();
REUSABLE_ARRAY_HANDLESCOPE(thread);
REUSABLE_OBJECT_HANDLESCOPE(thread);
Expand Down

0 comments on commit c304336

Please sign in to comment.