diff options
author | Roberto Raggi <roberto.raggi@nokia.com> | 2012-06-06 15:30:50 +0200 |
---|---|---|
committer | Roberto Raggi <roberto.raggi@nokia.com> | 2012-06-06 15:30:50 +0200 |
commit | 55287cde510182c95f65a5acefe6b80337b0b744 (patch) | |
tree | 36e80fc559a5ce4fc707907cd0eba5e29758ff5e /qv4isel_llvm.cpp | |
parent | 9366999ac2b7af81e3e1ce6e89160fc759a8c637 (diff) |
Initial work on exceptions for the AOT compiler.
Diffstat (limited to 'qv4isel_llvm.cpp')
-rw-r--r-- | qv4isel_llvm.cpp | 73 |
1 files changed, 54 insertions, 19 deletions
diff --git a/qv4isel_llvm.cpp b/qv4isel_llvm.cpp index a997272fa3..d7829bf034 100644 --- a/qv4isel_llvm.cpp +++ b/qv4isel_llvm.cpp @@ -570,35 +570,70 @@ void LLVMInstructionSelection::genCallTemp(IR::Call *e, llvm::Value *result) _llvmValue = CreateLoad(result); } +void LLVMInstructionSelection::genCallName(IR::Call *e, llvm::Value *result) +{ + IR::Name *base = e->base->asName(); + + if (! result) + result = newLLVMTemp(_valueTy); + + if (! base->id) { + switch (base->builtin) { + case IR::Name::builtin_invalid: + break; + + case IR::Name::builtin_typeof: + // inline void __qmljs_typeof(Context *ctx, Value *result, const Value *value) + CreateCall3(_llvmModule->getFunction("__qmljs_llvm_typeof"), + _llvmFunction->arg_begin(), result, getLLVMTempReference(e->args->expr)); + _llvmValue = CreateLoad(result); + return; + + case IR::Name::builtin_throw: + CreateCall2(_llvmModule->getFunction("__qmljs_llvm_throw"), + _llvmFunction->arg_begin(), getLLVMTempReference(e->args->expr)); + _llvmValue = llvm::UndefValue::get(_valueTy); + return; + + case IR::Name::builtin_rethrow: + CreateCall2(_llvmModule->getFunction("__qmljs_llvm_rethrow"), + _llvmFunction->arg_begin(), result); + _llvmValue = CreateLoad(result); + return; + } + + Q_UNREACHABLE(); + } else { + llvm::Value *name = getIdentifier(*base->id); + + int argc = 0; + llvm::Value *args = genArguments(e->args, argc); + + CreateCall5(_llvmModule->getFunction("__qmljs_call_activation_property"), + _llvmFunction->arg_begin(), result, name, args, getInt32(argc)); + + _llvmValue = CreateLoad(result); + } +} + void LLVMInstructionSelection::visitCall(IR::Call *e) { if (e->base->asMember()) { genCallMember(e); - return; } else if (e->base->asTemp()) { genCallTemp(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_call_value"); - } else if (IR::Name *n = e->base->asName()) { - if (n->id) { - base = getIdentifier(*n->id); - func = _llvmModule->getFunction("__qmljs_llvm_call_activation_property"); - } - } + } else if (e->base->asName()) { + genCallName(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_call_value"), + _llvmFunction->arg_begin(), result, base, args, getInt32(argc)); _llvmValue = CreateLoad(result); } else { Q_UNIMPLEMENTED(); |