diff options
| author | 2012-01-02 22:49:53 +0800 | |
|---|---|---|
| committer | 2012-02-17 00:57:43 -0800 | |
| commit | 48f1d2a5c2ff904feb21b55be086903392e7548c (patch) | |
| tree | d51b8b0e65f479c6ba9255cc4924927d148b7437 /src/compiler_llvm/method_compiler.cc | |
| parent | 8dabb43c4640b6f64a3c288d670b97ed1cd7b537 (diff) | |
Implement iget* instructions.
Change-Id: Ia1ae88d9219d35a0b68acecf586e63e67351fe71
Diffstat (limited to 'src/compiler_llvm/method_compiler.cc')
| -rw-r--r-- | src/compiler_llvm/method_compiler.cc | 62 |
1 files changed, 61 insertions, 1 deletions
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc index 596ae876e3..3f5766648d 100644 --- a/src/compiler_llvm/method_compiler.cc +++ b/src/compiler_llvm/method_compiler.cc @@ -1688,10 +1688,70 @@ void MethodCompiler::EmitInsn_APut(uint32_t dex_pc, } +void MethodCompiler::PrintUnresolvedFieldWarning(int32_t field_idx) { + DexFile const& dex_file = method_helper_.GetDexFile(); + DexFile::FieldId const& field_id = dex_file.GetFieldId(field_idx); + + LOG(WARNING) << "unable to resolve static field " << field_idx << " (" + << dex_file.GetFieldName(field_id) << ") in " + << dex_file.GetFieldDeclaringClassDescriptor(field_id); +} + + void MethodCompiler::EmitInsn_IGet(uint32_t dex_pc, Instruction const* insn, JType field_jty) { - // UNIMPLEMENTED(WARNING); + + Instruction::DecodedInstruction dec_insn(insn); + + uint32_t reg_idx = dec_insn.vB_; + uint32_t field_idx = dec_insn.vC_; + + Field* field = dex_cache_->GetResolvedField(field_idx); + + llvm::Value* object_addr = EmitLoadDalvikReg(reg_idx, kObject, kAccurate); + + EmitGuard_NullPointerException(dex_pc, object_addr); + + llvm::Value* field_value; + + if (field == NULL) { + PrintUnresolvedFieldWarning(field_idx); + + llvm::Function* runtime_func; + + if (field_jty == kObject) { + runtime_func = irb_.GetRuntime(SetObjectInstance); + } else if (field_jty == kLong || field_jty == kDouble) { + runtime_func = irb_.GetRuntime(Set64Instance); + } else { + runtime_func = irb_.GetRuntime(Set32Instance); + } + + llvm::ConstantInt* field_idx_value = irb_.getInt32(field_idx); + + llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); + + field_value = irb_.CreateCall2(runtime_func, field_idx_value, + method_object_addr); + + EmitGuard_ExceptionLandingPad(dex_pc); + + } else { + llvm::PointerType* field_type = + irb_.getJType(field_jty, kField)->getPointerTo(); + + llvm::ConstantInt* field_offset = + irb_.getPtrEquivInt(field->GetOffset().Int32Value()); + + llvm::Value* field_addr = + irb_.CreatePtrDisp(object_addr, field_offset, field_type); + + field_value = irb_.CreateLoad(field_addr); + } + + EmitStoreDalvikReg(dec_insn.vA_, field_jty, kField, field_value); + irb_.CreateBr(GetNextBasicBlock(dex_pc)); } |