Implement CheckPutArrayElement. Change-Id: Ie9617df1debb57c80b937bc033ff231c4daedd0d
diff --git a/src/compiler_llvm/art_module.ll b/src/compiler_llvm/art_module.ll index b85ba7c..d18080f 100644 --- a/src/compiler_llvm/art_module.ll +++ b/src/compiler_llvm/art_module.ll
@@ -135,8 +135,9 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; RTTI +; Type Checking, in the nature of casting ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; declare i32 @art_is_assignable_from_code(%JavaObject*, %JavaObject*) declare void @art_check_cast_from_code(%JavaObject*, %JavaObject*) +declare void @art_check_put_array_element_from_code(%JavaObject*, %JavaObject*)
diff --git a/src/compiler_llvm/generated/art_module.cc b/src/compiler_llvm/generated/art_module.cc index 973ef06..07fc6a3 100644 --- a/src/compiler_llvm/generated/art_module.cc +++ b/src/compiler_llvm/generated/art_module.cc
@@ -773,6 +773,17 @@ AttrListPtr func_art_check_cast_from_code_PAL; func_art_check_cast_from_code->setAttributes(func_art_check_cast_from_code_PAL); +Function* func_art_check_put_array_element_from_code = mod->getFunction("art_check_put_array_element_from_code"); +if (!func_art_check_put_array_element_from_code) { +func_art_check_put_array_element_from_code = Function::Create( + /*Type=*/FuncTy_27, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"art_check_put_array_element_from_code", mod); // (external, no body) +func_art_check_put_array_element_from_code->setCallingConv(CallingConv::C); +} +AttrListPtr func_art_check_put_array_element_from_code_PAL; +func_art_check_put_array_element_from_code->setAttributes(func_art_check_put_array_element_from_code_PAL); + // Global Variable Declarations
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc index bcd40de..8b1cef6 100644 --- a/src/compiler_llvm/method_compiler.cc +++ b/src/compiler_llvm/method_compiler.cc
@@ -2328,6 +2328,14 @@ llvm::Value* new_value = EmitLoadDalvikReg(dec_insn.vA, elem_jty, kArray); + if (elem_jty == kObject) { // If put an object, check the type. + llvm::Function* runtime_func = irb_.GetRuntime(CheckPutArrayElement); + + irb_.CreateCall2(runtime_func, new_value, array_addr); + + EmitGuard_ExceptionLandingPad(dex_pc); + } + irb_.CreateStore(new_value, array_elem_addr); irb_.CreateBr(GetNextBasicBlock(dex_pc));
diff --git a/src/compiler_llvm/runtime_support_func_list.h b/src/compiler_llvm/runtime_support_func_list.h index 1c21d48..518a175 100644 --- a/src/compiler_llvm/runtime_support_func_list.h +++ b/src/compiler_llvm/runtime_support_func_list.h
@@ -31,6 +31,7 @@ V(InitializeType, art_initialize_type_from_code) \ V(IsAssignable, art_is_assignable_from_code) \ V(CheckCast, art_check_cast_from_code) \ + V(CheckPutArrayElement, art_check_put_array_element_from_code) \ V(AllocObject, art_alloc_object_from_code) \ V(AllocObjectWithAccessCheck, art_alloc_object_from_code_with_access_check) \ V(AllocArray, art_alloc_array_from_code) \
diff --git a/src/compiler_llvm/runtime_support_llvm.cc b/src/compiler_llvm/runtime_support_llvm.cc index 6ad80f8..ff31825 100644 --- a/src/compiler_llvm/runtime_support_llvm.cc +++ b/src/compiler_llvm/runtime_support_llvm.cc
@@ -39,7 +39,7 @@ void art_set_current_thread_from_code(void* thread_object_addr) { // TODO: LLVM IR generating something like "r9 = thread_object_addr" - UNIMPLEMENTED(WARNING); + // UNIMPLEMENTED(WARNING); } void art_lock_object_from_code(Object* obj) { @@ -438,7 +438,7 @@ } void art_check_cast_from_code(const Class* dest_type, const Class* src_type) { -DCHECK(dest_type->IsClass()) << PrettyClass(dest_type); + DCHECK(dest_type->IsClass()) << PrettyClass(dest_type); DCHECK(src_type->IsClass()) << PrettyClass(src_type); if (UNLIKELY(!dest_type->IsAssignableFrom(src_type))) { Thread::Current()->ThrowNewExceptionF("Ljava/lang/ClassCastException;", @@ -448,6 +448,24 @@ } } +void art_check_put_array_element_from_code(const Object* element, const Object* array) { + if (element == NULL) { + return; + } + DCHECK(array != NULL); + Class* array_class = array->GetClass(); + DCHECK(array_class != NULL); + Class* component_type = array_class->GetComponentType(); + Class* element_class = element->GetClass(); + if (UNLIKELY(!component_type->IsAssignableFrom(element_class))) { + Thread::Current()->ThrowNewExceptionF("Ljava/lang/ArrayStoreException;", + "%s cannot be stored in an array of type %s", + PrettyDescriptor(element_class).c_str(), + PrettyDescriptor(array_class).c_str()); + } + return; +} + //---------------------------------------------------------------------------- // Runtime Support Function Lookup Callback //----------------------------------------------------------------------------