diff options
author | Roberto Raggi <roberto.raggi@nokia.com> | 2012-06-06 11:50:13 +0200 |
---|---|---|
committer | Roberto Raggi <roberto.raggi@nokia.com> | 2012-06-06 11:50:13 +0200 |
commit | b3fbdb62f70000a0722cc60720a12baf26690d19 (patch) | |
tree | 069b1f72f248993914c710e05bcc078781654f36 /qv4isel_llvm.cpp | |
parent | b1e62cc60749e3a55805df7ed493ec84587dc3bd (diff) |
Lower IR::Call and IR::New
Diffstat (limited to 'qv4isel_llvm.cpp')
-rw-r--r-- | qv4isel_llvm.cpp | 114 |
1 files changed, 84 insertions, 30 deletions
diff --git a/qv4isel_llvm.cpp b/qv4isel_llvm.cpp index 4be0da1ebc..f92e8f05de 100644 --- a/qv4isel_llvm.cpp +++ b/qv4isel_llvm.cpp @@ -377,8 +377,85 @@ llvm::AllocaInst *LLVMInstructionSelection::newLLVMTemp(llvm::Type *type, llvm:: return addr; } +llvm::Value * LLVMInstructionSelection::genArguments(IR::ExprList *exprs, int &argc) +{ + llvm::Value *args = 0; + + argc = 0; + for (IR::ExprList *it = exprs; it; it = it->next) + ++argc; + + if (argc) + args = newLLVMTemp(_valueTy, getInt32(argc)); + else + args = llvm::Constant::getNullValue(_valueTy->getPointerTo()); + + int i = 0; + for (IR::ExprList *it = exprs; it; it = it->next) { + llvm::Value *arg = getLLVMValue(it->expr); + CreateStore(arg, CreateConstGEP1_32(args, i++)); + } + + return args; +} + +void LLVMInstructionSelection::genCallMember(IR::Call *e, llvm::Value *result) +{ + if (! result) + result = newLLVMTemp(_valueTy); + + IR::Member *m = e->base->asMember(); + llvm::Value *thisObject = getLLVMTemp(m->base->asTemp()); + llvm::Value *name = getIdentifier(*m->name); + + int argc = 0; + llvm::Value *args = genArguments(e->args, argc); + + llvm::Value *actuals[] = { + _llvmFunction->arg_begin(), + result, + thisObject, + name, + args, + getInt32(argc) + }; + + CreateCall(_llvmModule->getFunction("__qmljs_llvm_call_property"), llvm::ArrayRef<llvm::Value *>(actuals)); + _llvmValue = CreateLoad(result); +} + +void LLVMInstructionSelection::genConstructMember(IR::New *e, llvm::Value *result) +{ + if (! result) + result = newLLVMTemp(_valueTy); + + IR::Member *m = e->base->asMember(); + llvm::Value *thisObject = getLLVMTemp(m->base->asTemp()); + llvm::Value *name = getIdentifier(*m->name); + + int argc = 0; + llvm::Value *args = genArguments(e->args, argc); + + llvm::Value *actuals[] = { + _llvmFunction->arg_begin(), + result, + thisObject, + name, + args, + getInt32(argc) + }; + + CreateCall(_llvmModule->getFunction("__qmljs_llvm_construct_property"), llvm::ArrayRef<llvm::Value *>(actuals)); + _llvmValue = CreateLoad(result); +} + void LLVMInstructionSelection::visitCall(IR::Call *e) { + if (e->base->asMember()) { + genCallMember(e); + return; + } + llvm::Value *func = 0; llvm::Value *base = 0; if (IR::Temp *t = e->base->asTemp()) { @@ -392,21 +469,7 @@ void LLVMInstructionSelection::visitCall(IR::Call *e) } int argc = 0; - for (IR::ExprList *it = e->args; it; it = it->next) { - ++argc; - } - - llvm::Value *args = 0; - if (argc) - args = newLLVMTemp(_valueTy, getInt32(argc)); - else - args = llvm::Constant::getNullValue(_valueTy->getPointerTo()); - - int i = 0; - for (IR::ExprList *it = e->args; it; it = it->next) { - llvm::Value *arg = getLLVMValue(it->expr); - CreateStore(arg, CreateConstGEP1_32(args, i++)); - } + llvm::Value *args = genArguments(e->args, argc); if (func) { llvm::Value *result = newLLVMTemp(_valueTy); @@ -420,6 +483,11 @@ void LLVMInstructionSelection::visitCall(IR::Call *e) 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()) { @@ -435,21 +503,7 @@ void LLVMInstructionSelection::visitNew(IR::New *e) } int argc = 0; - for (IR::ExprList *it = e->args; it; it = it->next) { - ++argc; - } - - llvm::Value *args = 0; - if (argc) - args = newLLVMTemp(_valueTy, getInt32(argc)); - else - args = llvm::Constant::getNullValue(_valueTy->getPointerTo()); - - int i = 0; - for (IR::ExprList *it = e->args; it; it = it->next) { - llvm::Value *arg = getLLVMValue(it->expr); - CreateStore(arg, CreateConstGEP1_32(args, i++)); - } + llvm::Value *args = genArguments(e->args, argc); if (func) { llvm::Value *result = newLLVMTemp(_valueTy); |