RewriterVar* JitFragmentWriter::emitCallattr(AST_expr* node, RewriterVar* obj, BoxedString* attr, CallattrFlags flags, const llvm::ArrayRef<RewriterVar*> args, std::vector<BoxedString*>* keyword_names) { TypeRecorder* type_recorder = getTypeRecorderForNode(node); #if ENABLE_BASELINEJIT_ICS RewriterVar* attr_var = imm(attr); RewriterVar* flags_var = imm(flags.asInt()); RewriterVar::SmallVector call_args; call_args.push_back(obj); call_args.push_back(attr_var); call_args.push_back(flags_var); call_args.push_back(args.size() > 0 ? args[0] : imm(0ul)); call_args.push_back(args.size() > 1 ? args[1] : imm(0ul)); call_args.push_back(args.size() > 2 ? args[2] : imm(0ul)); if (args.size() > 3) { RewriterVar* scratch = allocate(args.size() - 3); for (int i = 0; i < args.size() - 3; ++i) scratch->setAttr(i * sizeof(void*), args[i + 3]); call_args.push_back(scratch); } else if (keyword_names) { call_args.push_back(imm(0ul)); } if (keyword_names) call_args.push_back(imm(keyword_names)); return emitPPCall((void*)callattr, call_args, 2, 640, type_recorder); #else // We could make this faster but for now: keep it simple, stupid... RewriterVar* attr_var = imm(attr); RewriterVar* flags_var = imm(flags.asInt()); RewriterVar* keyword_names_var = keyword_names ? imm(keyword_names) : nullptr; RewriterVar* args_array = nullptr; if (args.size()) args_array = allocArgs(args); else RELEASE_ASSERT(!keyword_names_var, "0 args but keyword names are set"); RewriterVar::SmallVector call_args; call_args.push_back(obj); call_args.push_back(attr_var); call_args.push_back(flags_var); call_args.push_back(imm(type_recorder)); if (args_array) call_args.push_back(args_array); if (keyword_names_var) call_args.push_back(keyword_names_var); return call(false, (void*)callattrHelper, call_args); #endif }
RewriterVar* JitFragmentWriter::emitRuntimeCall(AST_expr* node, RewriterVar* obj, ArgPassSpec argspec, const llvm::ArrayRef<RewriterVar*> args, std::vector<BoxedString*>* keyword_names) { TypeRecorder* type_recorder = getTypeRecorderForNode(node); #if ENABLE_BASELINEJIT_ICS RewriterVar* argspec_var = imm(argspec.asInt()); RewriterVar::SmallVector call_args; call_args.push_back(obj); call_args.push_back(argspec_var); call_args.push_back(args.size() > 0 ? args[0] : imm(0ul)); call_args.push_back(args.size() > 1 ? args[1] : imm(0ul)); call_args.push_back(args.size() > 2 ? args[2] : imm(0ul)); if (args.size() > 3) { RewriterVar* scratch = allocate(args.size() - 3); for (int i = 0; i < args.size() - 3; ++i) scratch->setAttr(i * sizeof(void*), args[i + 3]); call_args.push_back(scratch); } else call_args.push_back(imm(0ul)); if (keyword_names) call_args.push_back(imm(keyword_names)); return emitPPCall((void*)runtimeCall, call_args, 2, 640, type_recorder); #else RewriterVar* argspec_var = imm(argspec.asInt()); RewriterVar* keyword_names_var = keyword_names ? imm(keyword_names) : nullptr; RewriterVar* args_array = nullptr; if (args.size()) { args_array = allocArgs(args); } else RELEASE_ASSERT(!keyword_names_var, "0 args but keyword names are set"); RewriterVar::SmallVector call_args; call_args.push_back(obj); call_args.push_back(argspec_var); call_args.push_back(imm(type_recorder)); if (args_array) call_args.push_back(args_array); if (keyword_names_var) call_args.push_back(keyword_names_var); return call(false, (void*)runtimeCallHelper, call_args); #endif }
void JitFragmentWriter::emitSetAttr(RewriterVar* obj, BoxedString* s, RewriterVar* attr) { emitPPCall((void*)setattr, { obj, imm(s), attr }, 2, 512); }
void JitFragmentWriter::emitDelItem(RewriterVar* target, RewriterVar* slice) { emitPPCall((void*)delitem, { target, slice }, 1, 512); }
void JitFragmentWriter::emitDelGlobal(BoxedString* name) { RewriterVar* globals = getInterp()->getAttr(ASTInterpreterJitInterface::getGlobalsOffset()); emitPPCall((void*)delGlobal, { globals, imm(name) }, 1, 512); }
void JitFragmentWriter::emitDelAttr(RewriterVar* target, BoxedString* attr) { emitPPCall((void*)delattr, { target, imm(attr) }, 1, 512); }
RewriterVar* JitFragmentWriter::emitUnaryop(RewriterVar* v, int op_type) { return emitPPCall((void*)unaryop, { v, imm(op_type) }, 2, 160); }
RewriterVar* JitFragmentWriter::emitGetGlobal(Box* global, BoxedString* s) { if (s->s() == "None") return imm(None); return emitPPCall((void*)getGlobal, { imm(global), imm(s) }, 2, 512); }
RewriterVar* JitFragmentWriter::emitGetGlobal(Box* global, BoxedString* s) { return emitPPCall((void*)getGlobal, { imm(global), imm(s) }, 2, 512); }
RewriterVar* JitFragmentWriter::emitGetClsAttr(RewriterVar* obj, BoxedString* s) { return emitPPCall((void*)getclsattr, { obj, imm(s) }, 2, 512); }
RewriterVar* JitFragmentWriter::emitGetAttr(RewriterVar* obj, BoxedString* s, AST_expr* node) { return emitPPCall((void*)getattr, { obj, imm(s) }, 2, 512, getTypeRecorderForNode(node)); }
RewriterVar* JitFragmentWriter::emitCompare(RewriterVar* lhs, RewriterVar* rhs, int op_type) { // TODO: can directly emit the assembly for Is/IsNot return emitPPCall((void*)compare, { lhs, rhs, imm(op_type) }, 2, 240); }
RewriterVar* JitFragmentWriter::emitBinop(RewriterVar* lhs, RewriterVar* rhs, int op_type) { return emitPPCall((void*)binop, { lhs, rhs, imm(op_type) }, 2, 240); }
void JitFragmentWriter::emitSetGlobal(Box* global, BoxedString* s, RewriterVar* v) { emitPPCall((void*)setGlobal, { imm(global), imm(s), v }, 2, 512); }
RewriterVar* JitFragmentWriter::emitGetItem(RewriterVar* value, RewriterVar* slice) { return emitPPCall((void*)getitem, { value, slice }, 2, 512); }
void JitFragmentWriter::emitSetItem(RewriterVar* target, RewriterVar* slice, RewriterVar* value) { emitPPCall((void*)setitem, { target, slice, value }, 2, 512); }
RewriterVar* JitFragmentWriter::emitAugbinop(AST_expr* node, RewriterVar* lhs, RewriterVar* rhs, int op_type) { return emitPPCall((void*)augbinop, { lhs, rhs, imm(op_type) }, 2, 320, node); }