parent
c94b382231
commit
74e2a829d1
@ -0,0 +1,32 @@
|
||||
local z,x,y
|
||||
|
||||
-- test 1
|
||||
z = function(a)
|
||||
print(a)
|
||||
return a+1
|
||||
end
|
||||
x = function(yy)
|
||||
local j = 5
|
||||
j = yy(j)
|
||||
return j
|
||||
end
|
||||
|
||||
y = x(z)
|
||||
assert(y == 6)
|
||||
|
||||
-- test 2
|
||||
|
||||
z = function (a,p)
|
||||
p(a)
|
||||
return 6
|
||||
end
|
||||
|
||||
x = function (yy,p)
|
||||
local j = 5
|
||||
j = yy(j,p)
|
||||
return j
|
||||
end
|
||||
|
||||
y = x(z,print)
|
||||
assert(y == 6)
|
||||
|
@ -0,0 +1,80 @@
|
||||
#include "ravi_llvmcodegen.h"
|
||||
|
||||
namespace ravi {
|
||||
|
||||
void RaviCodeGenerator::emit_CALL(RaviFunctionDef *def, llvm::Value *L_ci, llvm::Value *proto,
|
||||
int A, int B, int C) {
|
||||
|
||||
//int nresults = c - 1;
|
||||
//if (b != 0) L->top = ra + b; /* else previous instruction set top */
|
||||
//if (luaD_precall(L, ra, nresults, 1)) { /* C function? */
|
||||
// if (nresults >= 0) L->top = ci->top; /* adjust results */
|
||||
//}
|
||||
//else { /* Lua function */
|
||||
// luaV_execute(L);
|
||||
//}
|
||||
|
||||
llvm::Instruction *base_ptr = emit_load_base(def);
|
||||
llvm::Value *top = nullptr;
|
||||
int nresults = C - 1;
|
||||
if (B != 0) {
|
||||
// L->top = ra + b
|
||||
// See similar construct in OP_RETURN
|
||||
// Get pointer to register at ra + b
|
||||
llvm::Value *ptr = emit_array_get(def, base_ptr, A + B);
|
||||
// Get pointer to L->top
|
||||
top = emit_gep(def, "L.top", def->L, 0, 4);
|
||||
// Assign to L->top
|
||||
llvm::Instruction *ins = def->builder->CreateStore(ptr, top);
|
||||
ins->setMetadata(llvm::LLVMContext::MD_tbaa,
|
||||
def->types->tbaa_luaState_topT);
|
||||
}
|
||||
llvm::Value *ra = emit_gep_ra(def, base_ptr, A);
|
||||
llvm::Value *precall_result = def->builder->CreateCall4(def->luaD_precallF, def->L, ra, llvm::ConstantInt::get(def->types->C_intT, nresults),
|
||||
def->types->kInt[2]);
|
||||
llvm::Value *precall_bool = def->builder->CreateICmpEQ(precall_result, def->types->kInt[0]);
|
||||
|
||||
llvm::BasicBlock *then_block =
|
||||
llvm::BasicBlock::Create(def->jitState->context(), "if.lua.function", def->f);
|
||||
llvm::BasicBlock *else_block =
|
||||
llvm::BasicBlock::Create(def->jitState->context(), "if.not.lua.function");
|
||||
llvm::BasicBlock *end_block =
|
||||
llvm::BasicBlock::Create(def->jitState->context(), "op_call.done");
|
||||
def->builder->CreateCondBr(precall_bool, then_block, else_block);
|
||||
def->builder->SetInsertPoint(then_block);
|
||||
// Call luaV_execute
|
||||
def->builder->CreateCall(def->luaV_executeF, def->L);
|
||||
def->builder->CreateBr(end_block);
|
||||
def->f->getBasicBlockList().push_back(else_block);
|
||||
def->builder->SetInsertPoint(else_block);
|
||||
|
||||
if (nresults >= 0) {
|
||||
|
||||
llvm::Value *precall_C = def->builder->CreateICmpEQ(precall_result, def->types->kInt[1]);
|
||||
|
||||
llvm::BasicBlock *then1_block =
|
||||
llvm::BasicBlock::Create(def->jitState->context(), "if.C.function", def->f);
|
||||
def->builder->CreateCondBr(precall_C, then1_block, end_block);
|
||||
def->builder->SetInsertPoint(then1_block);
|
||||
|
||||
// Get pointer to ci->top
|
||||
llvm::Value *citop = emit_gep(def, "ci_top", def->ci_val, 0, 1);
|
||||
// Load ci->top
|
||||
llvm::Instruction *citop_val = def->builder->CreateLoad(citop);
|
||||
// TODO set tbaa
|
||||
if (!top)
|
||||
// Get L->top
|
||||
top = emit_gep(def, "L_top", def->L, 0, 4);
|
||||
// Assign ci>top to L->top
|
||||
auto ins = def->builder->CreateStore(citop_val, top);
|
||||
ins->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_luaState_topT);
|
||||
|
||||
}
|
||||
def->builder->CreateBr(end_block);
|
||||
def->f->getBasicBlockList().push_back(end_block);
|
||||
def->builder->SetInsertPoint(end_block);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
Loading…
Reference in new issue