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