diff options
author | Roberto Raggi <roberto.raggi@nokia.com> | 2012-06-07 15:28:45 +0200 |
---|---|---|
committer | Roberto Raggi <roberto.raggi@nokia.com> | 2012-06-07 15:28:45 +0200 |
commit | 56de925f00696de45e2d2132c46a4f6cee563ec9 (patch) | |
tree | 288aad41233708200cb6d989052fecf2a9dff217 /qv4isel_llvm.cpp | |
parent | 5c869a3c812e443fe2d6598ddbeafa42634d11ed (diff) |
Generate LLVM code for constructor calls
Diffstat (limited to 'qv4isel_llvm.cpp')
-rw-r--r-- | qv4isel_llvm.cpp | 84 |
1 files changed, 63 insertions, 21 deletions
diff --git a/qv4isel_llvm.cpp b/qv4isel_llvm.cpp index 7c666c7fe2..7ec7065a16 100644 --- a/qv4isel_llvm.cpp +++ b/qv4isel_llvm.cpp @@ -106,6 +106,10 @@ llvm::Function *LLVMInstructionSelection::compileLLVMFunction(IR::Function *func qSwap(_tempMap, tempMap); qSwap(_blockMap, blockMap); + // create the LLVM blocks + foreach (IR::BasicBlock *block, _function->basicBlocks) + (void) getLLVMBasicBlock(block); + // entry block SetInsertPoint(getLLVMBasicBlock(_function->basicBlocks.first())); @@ -122,6 +126,9 @@ llvm::Function *LLVMInstructionSelection::compileLLVMFunction(IR::Function *func CreateStore(llvm::Constant::getNullValue(_valueTy), t); } + CreateCall(_llvmModule->getFunction("__qmljs_llvm_init_this_object"), + _llvmFunction->arg_begin()); + foreach (IR::BasicBlock *block, _function->basicBlocks) { qSwap(_block, block); SetInsertPoint(getLLVMBasicBlock(_block)); @@ -222,7 +229,7 @@ llvm::Value *LLVMInstructionSelection::getStringPtr(const QString &s) llvm::Value *LLVMInstructionSelection::getIdentifier(const QString &s) { llvm::Value *str = getStringPtr(s); - llvm::Value *id = CreateCall2(_llvmModule->getFunction("__qmljs_llvm_get_identifier"), + llvm::Value *id = CreateCall2(_llvmModule->getFunction("__qmljs_identifier_from_utf8"), _llvmFunction->arg_begin(), str); return id; } @@ -576,6 +583,29 @@ void LLVMInstructionSelection::genCallTemp(IR::Call *e, llvm::Value *result) _llvmValue = CreateLoad(result); } +void LLVMInstructionSelection::genConstructTemp(IR::New *e, llvm::Value *result) +{ + if (! result) + result = newLLVMTemp(_valueTy); + + llvm::Value *func = getLLVMTempReference(e->base); + + int argc = 0; + llvm::Value *args = genArguments(e->args, argc); + + llvm::Value *actuals[] = { + _llvmFunction->arg_begin(), + result, + func, + args, + getInt32(argc) + }; + + CreateCall(_llvmModule->getFunction("__qmljs_llvm_construct_value"), actuals); + + _llvmValue = CreateLoad(result); +} + void LLVMInstructionSelection::genCallName(IR::Call *e, llvm::Value *result) { IR::Name *base = e->base->asName(); @@ -656,6 +686,28 @@ void LLVMInstructionSelection::genCallName(IR::Call *e, llvm::Value *result) } } +void LLVMInstructionSelection::genConstructName(IR::New *e, llvm::Value *result) +{ + IR::Name *base = e->base->asName(); + + if (! result) + result = newLLVMTemp(_valueTy); + + if (! base->id) { + Q_UNREACHABLE(); + } else { + llvm::Value *name = getIdentifier(*base->id); + + int argc = 0; + llvm::Value *args = genArguments(e->args, argc); + + CreateCall5(_llvmModule->getFunction("__qmljs_construct_activation_property"), + _llvmFunction->arg_begin(), result, name, args, getInt32(argc)); + + _llvmValue = CreateLoad(result); + } +} + void LLVMInstructionSelection::visitCall(IR::Call *e) { if (e->base->asMember()) { @@ -684,30 +736,20 @@ void LLVMInstructionSelection::visitNew(IR::New *e) { if (e->base->asMember()) { genConstructMember(e); - return; - } - - llvm::Value *func = 0; - llvm::Value *base = 0; - if (IR::Temp *t = e->base->asTemp()) { - base = getLLVMTemp(t); - func = _llvmModule->getFunction("__qmljs_llvm_construct_value"); - } else if (IR::Name *n = e->base->asName()) { - if (n->id) { - llvm::Value *str = getStringPtr(*n->id); - base = CreateCall2(_llvmModule->getFunction("__qmljs_llvm_get_identifier"), - _llvmFunction->arg_begin(), str); - func = _llvmModule->getFunction("__qmljs_llvm_construct_activation_property"); - } - } + } else if (e->base->asTemp()) { + genConstructTemp(e); + } else if (e->base->asName()) { + genConstructName(e); + } else if (IR::Temp *t = e->base->asTemp()) { + llvm::Value *base = getLLVMTemp(t); - int argc = 0; - llvm::Value *args = genArguments(e->args, argc); + int argc = 0; + llvm::Value *args = genArguments(e->args, argc); - if (func) { llvm::Value *result = newLLVMTemp(_valueTy); CreateStore(llvm::Constant::getNullValue(_valueTy), result); - CreateCall5(func, _llvmFunction->arg_begin(), result, base, args, getInt32(argc)); + CreateCall5(_llvmModule->getFunction("__qmljs_llvm_construct_value"), + _llvmFunction->arg_begin(), result, base, args, getInt32(argc)); _llvmValue = CreateLoad(result); } else { Q_UNIMPLEMENTED(); |