diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/object.cc | 12 | ||||
| -rw-r--r-- | src/object.h | 4 | ||||
| -rw-r--r-- | src/runtime_support.S | 25 | ||||
| -rw-r--r-- | src/runtime_support.h | 1 | ||||
| -rw-r--r-- | src/thread.cc | 22 | ||||
| -rw-r--r-- | src/thread.h | 2 |
6 files changed, 47 insertions, 19 deletions
diff --git a/src/object.cc b/src/object.cc index 64607e8e4d..dac16a8bd6 100644 --- a/src/object.cc +++ b/src/object.cc @@ -927,18 +927,6 @@ bool Class::Implements(const Class* klass) const { return false; } -void Class::CanPutArrayElementFromCode(const Object* element, const Class* array_class) { - DCHECK(array_class != NULL); - if (element == NULL) { - return; - } - if (!array_class->GetComponentType()->IsAssignableFrom(element->GetClass())) { - LOG(ERROR) << "Can't put a " << PrettyClass(element->GetClass()) - << " into a " << PrettyClass(array_class); - UNIMPLEMENTED(FATAL) << "need to throw ArrayStoreException and unwind stack"; - } -} - // Determine whether "this" is assignable from "klazz", where both of these // are array classes. // diff --git a/src/object.h b/src/object.h index 63a2b30c1f..5b4c7ba1d5 100644 --- a/src/object.h +++ b/src/object.h @@ -1427,10 +1427,6 @@ class MANAGED Class : public StaticStorageBase { return !IsPrimitive() && GetSuperClass() == NULL; } - // Tests whether a possibly null 'element' can be - // assigned into an array of type 'array_class'. - static void CanPutArrayElementFromCode(const Object* element, const Class* array_class); - // Given the context of a calling Method, use its DexCache to // resolve a type to a Class. If it cannot be resolved, throw an // error. If it can, use it to create an instance. diff --git a/src/runtime_support.S b/src/runtime_support.S index 185cdc2acc..963e1aafdb 100644 --- a/src/runtime_support.S +++ b/src/runtime_support.S @@ -169,6 +169,31 @@ art_check_cast_from_code: mov r1, sp @ pass SP b artDeliverPendingExceptionFromCode @ artDeliverPendingExceptionFromCode(Thread*, SP) + .global art_can_put_array_element_from_code + .extern artCanPutArrayElementFromCode + /* + * Entry from managed code that calls artCanPutArrayElementFromCode and delivers exception on + * failure. + */ +art_can_put_array_element_from_code: + cmp r0, #0 @ return if element == NULL + moveq pc, lr + str sp, [R9, #THREAD_TOP_OF_MANAGED_STACK_OFFSET] @ record top of stack and pc in case of + str lr, [R9, #THREAD_TOP_OF_MANAGED_STACK_PC_OFFSET] @ walking stack + stmdb sp!, {lr} @ Save LR + sub sp, #12 @ Align stack + bl artCanPutArrayElementFromCode @ (Object* element, Class* array_class) + add sp, #12 + ldmia sp!, {lr} @ restore LR + cmp r0, #0 @ success? + moveq pc, lr @ return on success + @ set up for throwing exception + stmdb sp!, {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, lr} + sub sp, #16 @ 4 words of space, bottom word will hold Method* + mov r0, r9 @ pass Thread::Current + mov r1, sp @ pass SP + b artDeliverPendingExceptionFromCode @ artDeliverPendingExceptionFromCode(Thread*, SP) + .global art_initialize_static_storage_from_code .extern _ZN3art11ClassLinker31InitializeStaticStorageFromCodeEjPKNS_6MethodE /* diff --git a/src/runtime_support.h b/src/runtime_support.h index de2a975b27..9da06c3570 100644 --- a/src/runtime_support.h +++ b/src/runtime_support.h @@ -8,6 +8,7 @@ extern "C" void art_deliver_exception_from_code(void*); #if defined(__arm__) /* Compiler helpers */ + extern "C" void art_can_put_array_element_from_code(void*, void*); extern "C" void art_check_cast_from_code(void*, void*); extern "C" void art_handle_fill_data_from_code(void*, void*); extern "C" void* art_initialize_static_storage_from_code(uint32_t, void*); diff --git a/src/thread.cc b/src/thread.cc index 232c1150ab..271b67b418 100644 --- a/src/thread.cc +++ b/src/thread.cc @@ -201,7 +201,7 @@ Array* CheckAndAllocFromCode(uint32_t type_index, Method* method, int32_t compon return Array::AllocFromCode(type_index, method, component_count); } -// TODO: placeholder (throw on failure) +// Check whether it is safe to cast one class to the other, throw exception and return -1 on failure extern "C" int artCheckCastFromCode(const Class* a, const Class* b) { DCHECK(a->IsClass()); DCHECK(b->IsClass()); @@ -216,6 +216,24 @@ extern "C" int artCheckCastFromCode(const Class* a, const Class* b) { } } +// Tests whether 'element' can be assigned into an array of type 'array_class'. +// Returns 0 on success and -1 if an exception is pending. +extern "C" int artCanPutArrayElementFromCode(const Object* element, const Class* array_class) { + DCHECK(array_class != NULL); + // element can't be NULL as we catch this is screened in runtime_support + Class* element_class = element->GetClass(); + Class* component_type = array_class->GetComponentType(); + if (component_type->IsAssignableFrom(element_class)) { + return 0; // Success + } else { + Thread::Current()->ThrowNewException("Ljava/lang/ArrayStoreException;", + "Cannot store an object of type %s in to an array of type %s", + PrettyDescriptor(element_class->GetDescriptor()).c_str(), + PrettyDescriptor(array_class->GetDescriptor()).c_str()); + return -1; // Failure + } +} + extern "C" int artUnlockObjectFromCode(Thread* thread, Object* obj) { DCHECK(obj != NULL); // Assumed to have been checked before entry return obj->MonitorExit(thread) ? 0 /* Success */ : -1 /* Failure */; @@ -357,6 +375,7 @@ void Thread::InitFunctionPointers() { pFmod = fmod; pLdivmod = __aeabi_ldivmod; pLmul = __aeabi_lmul; + pCanPutArrayElementFromCode = art_can_put_array_element_from_code; pCheckCastFromCode = art_check_cast_from_code; pHandleFillArrayDataFromCode = art_handle_fill_data_from_code; pInitializeStaticStorage = art_initialize_static_storage_from_code; @@ -381,7 +400,6 @@ void Thread::InitFunctionPointers() { pSet64Static = Field::Set64StaticFromCode; pGetObjStatic = Field::GetObjStaticFromCode; pSetObjStatic = Field::SetObjStaticFromCode; - pCanPutArrayElementFromCode = Class::CanPutArrayElementFromCode; pInitializeTypeFromCode = InitializeTypeFromCode; pResolveMethodFromCode = ResolveMethodFromCode; pInstanceofNonTrivialFromCode = Object::InstanceOf; diff --git a/src/thread.h b/src/thread.h index 39d984bed3..53eff33803 100644 --- a/src/thread.h +++ b/src/thread.h @@ -211,7 +211,7 @@ class PACKED Thread { void (*pSet64Static)(uint32_t, const Method*, uint64_t); Object* (*pGetObjStatic)(uint32_t, const Method*); void (*pSetObjStatic)(uint32_t, const Method*, Object*); - void (*pCanPutArrayElementFromCode)(const Object*, const Class*); + void (*pCanPutArrayElementFromCode)(void*, void*); bool (*pInstanceofNonTrivialFromCode) (const Object*, const Class*); void (*pCheckCastFromCode) (void*, void*); Method* (*pFindInterfaceMethodInCache)(Class*, uint32_t, const Method*, struct DvmDex*); |