Commit aa5aaca4 authored by Marius Wachtler's avatar Marius Wachtler

bjit: add support for make function and lambda nodes

parent 3d146ce6
......@@ -75,7 +75,7 @@ public:
static Box* executeInner(ASTInterpreter& interpreter, CFGBlock* start_block, AST_stmt* start_at);
private:
Box* createFunction(AST* node, AST_arguments* args, const std::vector<AST_stmt*>& body);
Value createFunction(AST* node, AST_arguments* args, const std::vector<AST_stmt*>& body);
Value doBinOp(Value left, Value right, int op, BinExpType exp_type);
void doStore(AST_expr* node, Value value);
void doStore(AST_Name* name, Value value);
......@@ -943,13 +943,21 @@ Value ASTInterpreter::visit_return(AST_Return* node) {
return s;
}
Box* ASTInterpreter::createFunction(AST* node, AST_arguments* args, const std::vector<AST_stmt*>& body) {
abortJITing();
Value ASTInterpreter::createFunction(AST* node, AST_arguments* args, const std::vector<AST_stmt*>& body) {
CLFunction* cl = wrapFunction(node, args, body, source_info);
std::vector<Box*, StlCompatAllocator<Box*>> defaults;
for (AST_expr* d : args->defaults)
defaults.push_back(visit_expr(d).o);
RewriterVar* defaults_var = NULL;
if (jit)
defaults_var = args->defaults.size() ? jit->allocate(args->defaults.size()) : jit->imm(0ul);
int i = 0;
for (AST_expr* d : args->defaults) {
Value v = visit_expr(d);
defaults.push_back(v.o);
if (jit)
defaults_var->setAttr(i++ * sizeof(void*), v);
}
defaults.push_back(0);
// FIXME: Using initializer_list is pretty annoying since you're not supposed to create them:
......@@ -977,37 +985,60 @@ Box* ASTInterpreter::createFunction(AST* node, AST_arguments* args, const std::v
}
BoxedClosure* closure = 0;
RewriterVar* closure_var = NULL;
if (takes_closure) {
if (scope_info->createsClosure()) {
closure = created_closure;
if (jit)
closure_var = jit->getInterp()->getAttr(offsetof(ASTInterpreter, created_closure));
} else {
assert(scope_info->passesThroughClosure());
closure = passed_closure;
if (jit)
closure_var = jit->getInterp()->getAttr(offsetof(ASTInterpreter, passed_closure));
}
assert(closure);
}
Box* passed_globals = NULL;
if (!getCL()->source->scoping->areGlobalsFromModule())
RewriterVar* passed_globals_var = NULL;
if (!getCL()->source->scoping->areGlobalsFromModule()) {
passed_globals = globals;
return boxCLFunction(cl, closure, passed_globals, u.il);
if (jit)
passed_globals_var = jit->getInterp()->getAttr(offsetof(ASTInterpreter, globals));
}
Value rtn;
if (jit) {
if (!closure_var)
closure_var = jit->imm(0ul);
if (!passed_globals_var)
passed_globals_var = jit->imm(0ul);
rtn.var = jit->call(false, (void*)boxCLFunction, jit->imm(cl), closure_var, passed_globals_var, defaults_var,
jit->imm(args->defaults.size()));
}
rtn.o = boxCLFunction(cl, closure, passed_globals, u.il);
return rtn;
}
Value ASTInterpreter::visit_makeFunction(AST_MakeFunction* mkfn) {
abortJITing();
AST_FunctionDef* node = mkfn->function_def;
AST_arguments* args = node->args;
std::vector<Box*, StlCompatAllocator<Box*>> decorators;
std::vector<Value, StlCompatAllocator<Value>> decorators;
for (AST_expr* d : node->decorator_list)
decorators.push_back(visit_expr(d).o);
Box* func = createFunction(node, args, node->body);
decorators.push_back(visit_expr(d));
for (int i = decorators.size() - 1; i >= 0; i--)
func = runtimeCall(decorators[i], ArgPassSpec(1), func, 0, 0, 0, 0);
Value func = createFunction(node, args, node->body);
return Value(func, NULL);
for (int i = decorators.size() - 1; i >= 0; i--) {
if (jit)
func.var = jit->emitRuntimeCall(NULL, decorators[i], ArgPassSpec(1), { func }, NULL);
func.o = runtimeCall(decorators[i].o, ArgPassSpec(1), func.o, 0, 0, 0, 0);
}
return func;
}
Value ASTInterpreter::visit_makeClass(AST_MakeClass* mkclass) {
......@@ -1369,12 +1400,11 @@ Value ASTInterpreter::visit_repr(AST_Repr* node) {
}
Value ASTInterpreter::visit_lambda(AST_Lambda* node) {
abortJITing();
AST_Return* expr = new AST_Return();
expr->value = node->body;
std::vector<AST_stmt*> body = { expr };
return Value(createFunction(node, node->args, body), NULL);
return createFunction(node, node->args, body);
}
Value ASTInterpreter::visit_dict(AST_Dict* node) {
......
......@@ -149,6 +149,10 @@ JitFragmentWriter::JitFragmentWriter(CFGBlock* block, std::unique_ptr<ICInfo> ic
addAction([=]() { vregs_array->bumpUse(); }, vregs_array, ActionType::NORMAL);
}
RewriterVar* JitFragmentWriter::getInterp() {
return interp;
}
RewriterVar* JitFragmentWriter::imm(uint64_t val) {
return loadConst(val);
}
......@@ -642,10 +646,6 @@ uint64_t JitFragmentWriter::asUInt(InternedString s) {
}
#endif
RewriterVar* JitFragmentWriter::getInterp() {
return interp;
}
RewriterVar* JitFragmentWriter::emitPPCall(void* func_addr, llvm::ArrayRef<RewriterVar*> args, int num_slots,
int slot_size, TypeRecorder* type_recorder) {
RewriterVar::SmallVector args_vec(args.begin(), args.end());
......
......@@ -200,10 +200,10 @@ public:
JitFragmentWriter(CFGBlock* block, std::unique_ptr<ICInfo> ic_info, std::unique_ptr<ICSlotRewrite> rewrite,
int code_offset, int num_bytes_overlapping, void* entry_code, JitCodeBlock& code_block);
RewriterVar* getInterp();
RewriterVar* imm(uint64_t val);
RewriterVar* imm(void* val);
RewriterVar* emitAugbinop(RewriterVar* lhs, RewriterVar* rhs, int op_type);
RewriterVar* emitBinop(RewriterVar* lhs, RewriterVar* rhs, int op_type);
RewriterVar* emitCallattr(AST_expr* node, RewriterVar* obj, BoxedString* attr, CallattrFlags flags,
......@@ -273,7 +273,6 @@ private:
#else
uint64_t asUInt(InternedString s);
#endif
RewriterVar* getInterp();
RewriterVar* emitPPCall(void* func_addr, llvm::ArrayRef<RewriterVar*> args, int num_slots, int slot_size,
TypeRecorder* type_recorder = NULL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment