Box* callCompiledFunc(CompiledFunction *cf, int64_t nargs, Box* arg1, Box* arg2, Box* arg3, Box**args) { assert(cf); // TODO these shouldn't have to be initialized, but I don't want to issue a #pragma // that disables the warning for the whole file: Box *rarg1 = arg1, *rarg2 = arg2, *rarg3 = arg3; Box **rargs = NULL; if (nargs > 3) { if (cf->sig->is_vararg) { // the +2 is for the varargs and kwargs rargs = (Box**)alloca((nargs - 3 + 2) * sizeof(Box*)); memcpy(rargs, args, (nargs - 3) * sizeof(Box*)); } else { rargs = args; } } int nsig_args = cf->sig->arg_types.size(); BoxedList* made_vararg = NULL; if (cf->sig->is_vararg) { made_vararg = (BoxedList*)createList(); if (nsig_args == 0) rarg1 = made_vararg; else if (nsig_args == 1) rarg2 = made_vararg; else if (nsig_args == 2) rarg3 = made_vararg; else rargs[nsig_args-3] = made_vararg; for (int i = nsig_args; i < nargs; i++) { if (i == 0) listAppendInternal(made_vararg, arg1); else if (i == 1) listAppendInternal(made_vararg, arg2); else if (i == 2) listAppendInternal(made_vararg, arg3); else listAppendInternal(made_vararg, args[i - 3]); } } if (!cf->is_interpreted) { if (cf->sig->is_vararg) { Box* rtn = cf->call(rarg1, rarg2, rarg3, rargs); return rtn; } else { return cf->call(rarg1, rarg2, rarg3, rargs); } } else { return interpretFunction(cf->func, nargs, rarg1, rarg2, rarg3, rargs); } }
Box* dictValues(BoxedDict* self) { BoxedList* rtn = new BoxedList(); for (const auto& p : self->d) { listAppendInternal(rtn, p.second); } return rtn; }
Box* dictKeys(BoxedDict* self) { BoxedList* rtn = new BoxedList(); for (BoxedDict::PyDict::const_iterator it = self->d.begin(), end = self->d.end(); it != end; ++it) { listAppendInternal(rtn, it->first); } return rtn; }
extern "C" Box* listInsert(BoxedList* self, Box* idx, Box* v) { if (idx->cls != int_cls) { raiseExcHelper(TypeError, "an integer is required"); } LOCK_REGION(self->lock.asWrite()); int64_t n = static_cast<BoxedInt*>(idx)->n; if (n < 0) n = self->size + n; if (n >= self->size) { listAppendInternal(self, v); } else { if (n < 0) n = 0; assert(0 <= n && n < self->size); self->ensure(1); memmove(self->elts->elts + n + 1, self->elts->elts + n, (self->size - n) * sizeof(Box*)); self->size++; self->elts->elts[n] = v; } return None; }
Box* _listSlice(BoxedList* self, i64 start, i64 stop, i64 step) { // printf("%ld %ld %ld\n", start, stop, step); assert(step != 0); if (step > 0) { assert(0 <= start); assert(stop <= self->size); } else { assert(start < self->size); assert(-1 <= stop); } BoxedList* rtn = new BoxedList(); if ((step == 1) && ((stop - start) > 0)) { listAppendArrayInternal(rtn, &self->elts->elts[start], stop - start); } else { int cur = start; while ((step > 0 && cur < stop) || (step < 0 && cur > stop)) { listAppendInternal(rtn, self->elts->elts[cur]); cur += step; } } return rtn; }
static Box* createAndRunModule(BoxedString* name, const std::string& fn, const std::string& module_path) { BoxedModule* module = createModule(name, fn.c_str()); Box* b_path = boxString(module_path); BoxedList* path_list = new BoxedList(); listAppendInternal(path_list, b_path); static BoxedString* path_str = internStringImmortal("__path__"); module->setattr(path_str, path_list, NULL); AST_Module* ast = caching_parse_file(fn.c_str(), /* future_flags = */ 0); assert(ast); try { compileAndRunModule(ast, module); } catch (ExcInfo e) { removeModule(name); throw e; } Box* r = getSysModulesDict()->getOrNull(name); if (!r) raiseExcHelper(ImportError, "Loaded module %.200s not found in sys.modules", name->c_str()); return r; }
Box* dictKeys(BoxedDict* self) { BoxedList* rtn = new BoxedList(); for (const auto& p : self->d) { listAppendInternal(rtn, p.first); } return rtn; }
// TODO the inliner doesn't want to inline these; is there any point to having them in the inline section? extern "C" Box* listAppend(Box* s, Box* v) { assert(s->cls == list_cls); BoxedList* self = static_cast<BoxedList*>(s); listAppendInternal(self, v); return None; }
Box* JitFragmentWriter::createListHelper(uint64_t num, Box** data) { BoxedList* list = (BoxedList*)createList(); list->ensure(num); for (uint64_t i = 0; i < num; ++i) { assert(gc::isValidGCObject(data[i])); listAppendInternal(list, data[i]); } return list; }
Box* dictKeys(BoxedDict* self) { RELEASE_ASSERT(isSubclass(self->cls, dict_cls), ""); BoxedList* rtn = new BoxedList(); rtn->ensure(self->d.size()); for (const auto& p : self->d) { listAppendInternal(rtn, p.first); } return rtn; }
Box* range1(Box* end) { RELEASE_ASSERT(end->cls == int_cls, "%s", getTypeName(end)->c_str()); BoxedList *rtn = new BoxedList(); i64 iend = static_cast<BoxedInt*>(end)->n; for (i64 i = 0; i < iend; i++) { Box *bi = boxInt(i); listAppendInternal(rtn, bi); } return rtn; }
Box* dictItems(BoxedDict* self) { BoxedList* rtn = new BoxedList(); rtn->ensure(self->d.size()); for (const auto& p : self->d) { BoxedTuple* t = BoxedTuple::create({ p.first, p.second }); listAppendInternal(rtn, t); } return rtn; }
extern "C" Box* listNew(Box* cls, Box* container) { assert(cls == list_cls); if (container == None) return new BoxedList(); BoxedList* rtn = new BoxedList(); for (Box* e : container->pyElements()) { listAppendInternal(rtn, e); } return rtn; }
Box* dictItems(BoxedDict* self) { BoxedList* rtn = new BoxedList(); for (const auto& p : self->d) { BoxedTuple::GCVector elts; elts.push_back(p.first); elts.push_back(p.second); BoxedTuple* t = new BoxedTuple(std::move(elts)); listAppendInternal(rtn, t); } return rtn; }
Box* dictItems(BoxedDict* self) { BoxedList* rtn = new BoxedList(); for (BoxedDict::PyDict::const_iterator it = self->d.begin(), end = self->d.end(); it != end; ++it) { std::vector<Box*> elts; elts.push_back(it->first); elts.push_back(it->second); BoxedTuple *t = new BoxedTuple(elts); listAppendInternal(rtn, t); } return rtn; }
Box* range3(Box* start, Box* end, Box* step) { RELEASE_ASSERT(start->cls == int_cls, "%s", getTypeName(start)->c_str()); RELEASE_ASSERT(end->cls == int_cls, "%s", getTypeName(end)->c_str()); RELEASE_ASSERT(step->cls == int_cls, "%s", getTypeName(step)->c_str()); BoxedList *rtn = new BoxedList(); i64 istart = static_cast<BoxedInt*>(start)->n; i64 iend = static_cast<BoxedInt*>(end)->n; i64 istep = static_cast<BoxedInt*>(step)->n; RELEASE_ASSERT(istep != 0, "step can't be 0"); if (istep > 0) { for (i64 i = istart; i < iend; i += istep) { Box *bi = boxInt(i); listAppendInternal(rtn, bi); } } else { for (i64 i = istart; i > iend; i += istep) { Box *bi = boxInt(i); listAppendInternal(rtn, bi); } } return rtn; }
Box* BoxedTraceback::getLines(Box* b) { assert(b->cls == traceback_cls); BoxedTraceback* tb = static_cast<BoxedTraceback*>(b); if (!tb->py_lines) { BoxedList* lines = new BoxedList(); for (BoxedTraceback* wtb = tb; wtb && wtb != None; wtb = static_cast<BoxedTraceback*>(wtb->tb_next)) { auto& line = wtb->line; auto l = BoxedTuple::create({ line.file, line.func, boxInt(line.line) }); listAppendInternal(lines, l); } tb->py_lines = lines; } return tb->py_lines; }
Box* listIAdd(BoxedList* self, Box* _rhs) { LOCK_REGION(self->lock.asWrite()); if (_rhs->cls == list_cls) { // This branch is safe if self==rhs: BoxedList* rhs = static_cast<BoxedList*>(_rhs); int s1 = self->size; int s2 = rhs->size; self->ensure(s1 + s2); memcpy(self->elts->elts + s1, rhs->elts->elts, sizeof(rhs->elts->elts[0]) * s2); self->size = s1 + s2; return self; } RELEASE_ASSERT(_rhs != self, "unsupported"); for (auto* b : _rhs->pyElements()) listAppendInternal(self, b); return self; }
Box* listMul(BoxedList* self, Box* rhs) { if (rhs->cls != int_cls) { raiseExcHelper(TypeError, "can't multiply sequence by non-int of type '%s'", getTypeName(rhs)->c_str()); } LOCK_REGION(self->lock.asRead()); int n = static_cast<BoxedInt*>(rhs)->n; int s = self->size; BoxedList* rtn = new BoxedList(); rtn->ensure(n * s); if (s == 1) { for (int i = 0; i < n; i++) { listAppendInternal(rtn, self->elts->elts[0]); } } else { for (int i = 0; i < n; i++) { listAppendArrayInternal(rtn, &self->elts->elts[0], s); } } return rtn; }
void appendToSysPath(const std::string& path) { BoxedList* sys_path = getSysPath(); listAppendInternal(sys_path, boxStringPtr(&path)); }
void addToSysArgv(const char* str) { Box* sys_argv = sys_module->getattr("argv"); assert(sys_argv); assert(sys_argv->cls == list_cls); listAppendInternal(sys_argv, boxStrConstant(str)); }
void appendToSysPath(llvm::StringRef path) { BoxedList* sys_path = getSysPath(); listAppendInternal(sys_path, boxString(path)); }