Commit 6052361d authored by Rudi Chen's avatar Rudi Chen

Move some small helper functions from objmodel.cpp to util.cpp

It's not too big of a move, hopefully this won't cause merge conflicts
for anyone. Just part of an attempt to reduce the size of objmodel.cpp
parent 6f55634f
......@@ -44,6 +44,7 @@
#include "runtime/objmodel.h"
#include "runtime/set.h"
#include "runtime/types.h"
#include "runtime/util.h"
#ifndef NDEBUG
#define DEBUG 1
......
......@@ -27,6 +27,7 @@
#include "runtime/objmodel.h"
#include "runtime/set.h"
#include "runtime/types.h"
#include "runtime/util.h"
namespace pyston {
......
......@@ -31,6 +31,7 @@
#include "runtime/int.h"
#include "runtime/objmodel.h"
#include "runtime/types.h"
#include "runtime/util.h"
namespace pyston {
......
......@@ -46,6 +46,7 @@
#include "runtime/objmodel.h"
#include "runtime/set.h"
#include "runtime/types.h"
#include "runtime/util.h"
extern "C" void* __cxa_begin_catch(void*);
extern "C" void __cxa_end_catch();
......
......@@ -26,6 +26,7 @@
#include "core/ast.h"
#include "runtime/inline/list.h"
#include "runtime/objmodel.h"
#include "runtime/util.h"
namespace pyston {
......
......@@ -32,6 +32,7 @@
#include "runtime/objmodel.h"
#include "runtime/set.h"
#include "runtime/types.h"
#include "runtime/util.h"
namespace pyston {
......
......@@ -1273,26 +1273,6 @@ Box* boxChar(char c) {
return boxString(llvm::StringRef(d, 1));
}
static Box* noneIfNull(Box* b) {
if (b == NULL) {
return None;
} else {
return b;
}
}
static Box* boxStringOrNone(const char* s) {
if (s == NULL) {
return None;
} else {
return boxString(s);
}
}
static Box* boxStringFromCharPtr(const char* s) {
return boxString(s);
}
Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, BoxedString* attr_name, Box* obj, Box* descr,
RewriterVar* r_descr, bool for_call, Box** bind_obj_out,
RewriterVar** r_bind_obj_out) {
......@@ -2745,177 +2725,6 @@ extern "C" i64 unboxedLen(Box* obj) {
return rtn;
}
extern "C" void dumpEx(void* p, int levels) {
printf("\n");
printf("Raw address: %p\n", p);
bool is_gc = gc::isValidGCMemory(p);
if (!is_gc) {
printf("non-gc memory\n");
return;
}
if (gc::isNonheapRoot(p)) {
printf("Non-heap GC object\n");
printf("Assuming it's a class object...\n");
PyTypeObject* type = (PyTypeObject*)(p);
printf("tp_name: %s\n", type->tp_name);
return;
}
gc::GCAllocation* al = gc::GCAllocation::fromUserData(p);
if (al->kind_id == gc::GCKind::UNTRACKED) {
printf("gc-untracked object\n");
return;
}
if (al->kind_id == gc::GCKind::PRECISE) {
printf("precise gc array\n");
return;
}
if (al->kind_id == gc::GCKind::CONSERVATIVE) {
printf("conservatively-scanned object object\n");
return;
}
if (al->kind_id == gc::GCKind::PYTHON || al->kind_id == gc::GCKind::CONSERVATIVE_PYTHON) {
if (al->kind_id == gc::GCKind::PYTHON)
printf("Python object (precisely scanned)\n");
else
printf("Python object (conservatively scanned)\n");
Box* b = (Box*)p;
printf("Class: %s", getFullTypeName(b).c_str());
if (b->cls->cls != type_cls) {
printf(" (metaclass: %s)\n", getFullTypeName(b->cls).c_str());
} else {
printf("\n");
}
if (b->cls == bool_cls) {
printf("The %s object\n", b == True ? "True" : "False");
}
if (isSubclass(b->cls, type_cls)) {
auto cls = static_cast<BoxedClass*>(b);
printf("Type name: %s\n", getFullNameOfClass(cls).c_str());
printf("MRO:");
if (cls->tp_mro && cls->tp_mro->cls == tuple_cls) {
bool first = true;
for (auto b : *static_cast<BoxedTuple*>(cls->tp_mro)) {
if (!first)
printf(" ->");
first = false;
printf(" %s", getFullNameOfClass(static_cast<BoxedClass*>(b)).c_str());
}
}
printf("\n");
}
if (isSubclass(b->cls, str_cls)) {
printf("String value: %s\n", static_cast<BoxedString*>(b)->data());
}
if (isSubclass(b->cls, tuple_cls)) {
BoxedTuple* t = static_cast<BoxedTuple*>(b);
printf("%ld elements\n", t->size());
if (levels > 0) {
int i = 0;
for (auto e : *t) {
printf("\nElement %d:", i);
i++;
dumpEx(e, levels - 1);
}
}
}
if (isSubclass(b->cls, dict_cls)) {
BoxedDict* d = static_cast<BoxedDict*>(b);
printf("%ld elements\n", d->d.size());
if (levels > 0) {
int i = 0;
for (auto t : d->d) {
printf("\nKey:");
dumpEx(t.first, levels - 1);
printf("Value:");
dumpEx(t.second, levels - 1);
}
}
}
if (isSubclass(b->cls, int_cls)) {
printf("Int value: %ld\n", static_cast<BoxedInt*>(b)->n);
}
if (isSubclass(b->cls, list_cls)) {
auto l = static_cast<BoxedList*>(b);
printf("%ld elements\n", l->size);
if (levels > 0) {
int i = 0;
for (int i = 0; i < l->size; i++) {
printf("\nElement %d:", i);
dumpEx(l->elts->elts[i], levels - 1);
}
}
}
if (isSubclass(b->cls, function_cls)) {
BoxedFunction* f = static_cast<BoxedFunction*>(b);
CLFunction* cl = f->f;
if (cl->source) {
printf("User-defined function '%s'\n", cl->source->getName().data());
} else {
printf("A builtin function\n");
}
printf("Has %ld function versions\n", cl->versions.size());
for (CompiledFunction* cf : cl->versions) {
bool got_name;
std::string name = g.func_addr_registry.getFuncNameAtAddress(cf->code, true, &got_name);
if (got_name)
printf("%s\n", name.c_str());
else
printf("%p\n", cf->code);
}
}
if (isSubclass(b->cls, module_cls)) {
printf("The '%s' module\n", static_cast<BoxedModule*>(b)->name().c_str());
}
/*
if (b->cls->instancesHaveHCAttrs()) {
HCAttrs* attrs = b->getHCAttrsPtr();
printf("Has %ld attrs\n", attrs->hcls->attr_offsets.size());
for (const auto& p : attrs->hcls->attr_offsets) {
printf("Index %d: %s: %p\n", p.second, p.first.c_str(), attrs->attr_list->attrs[p.second]);
}
}
*/
return;
}
if (al->kind_id == gc::GCKind::HIDDEN_CLASS) {
printf("Hidden class object\n");
return;
}
RELEASE_ASSERT(0, "%d", (int)al->kind_id);
}
extern "C" void dump(void* p) {
dumpEx(p, 0);
}
// For rewriting purposes, this function assumes that nargs will be constant.
// That's probably fine for some uses (ex binops), but otherwise it should be guarded on beforehand.
extern "C" Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallRewriteArgs* rewrite_args,
......@@ -5126,10 +4935,6 @@ Box* getiter(Box* o) {
return getiterHelper(o);
}
extern "C" bool hasnext(Box* o) {
return o->cls->tpp_hasnext(o);
}
llvm::iterator_range<BoxIterator> Box::pyElements() {
return BoxIterator::getRange(this);
}
......@@ -5655,19 +5460,6 @@ extern "C" Box* importStar(Box* _from_module, Box* to_globals) {
return None;
}
Box* coerceUnicodeToStr(Box* unicode) {
if (!isSubclass(unicode->cls, unicode_cls))
return unicode;
Box* r = PyUnicode_AsASCIIString(unicode);
if (!r) {
PyErr_Clear();
raiseExcHelper(TypeError, "Cannot use non-ascii unicode strings as attribute names or keywords");
}
return r;
}
// TODO Make these fast, do inline caches and stuff
extern "C" void boxedLocalsSet(Box* boxedLocals, BoxedString* attr, Box* val) {
......
......@@ -99,10 +99,6 @@ Box* getiter(Box* o);
extern "C" Box* getPystonIter(Box* o);
extern "C" Box* getiterHelper(Box* o);
extern "C" Box* createBoxedIterWrapperIfNeeded(Box* o);
extern "C" bool hasnext(Box* o);
extern "C" void dump(void* p);
extern "C" void dumpEx(void* p, int levels = 0);
struct SetattrRewriteArgs;
void setattrGeneric(Box* obj, BoxedString* attr, Box* val, SetattrRewriteArgs* rewrite_args);
......@@ -185,16 +181,6 @@ static const char* objectNewParameterTypeErrorMsg() {
}
}
// This function will ascii-encode any unicode objects it gets passed, or return the argument
// unmodified if it wasn't a unicode object.
// This is intended for functions that deal with attribute or variable names, which we internally
// assume will always be strings, but CPython lets be unicode.
// If we used an encoding like utf8 instead of ascii, we would allow collisions between unicode
// strings and a string that happens to be its encoding. It seems safer to just encode as ascii,
// which will throw an exception if you try to pass something that might run into this risk.
// (We wrap the unicode error and throw a TypeError)
Box* coerceUnicodeToStr(Box* unicode);
inline std::tuple<Box*, Box*, Box*, Box**> getTupleFromArgsArray(Box** args, int num_args) {
Box* arg1 = num_args >= 1 ? args[0] : nullptr;
Box* arg2 = num_args >= 2 ? args[1] : nullptr;
......
......@@ -14,6 +14,7 @@
#include "runtime/util.h"
#include "codegen/codegen.h"
#include "core/options.h"
#include "core/types.h"
#include "runtime/objmodel.h"
......@@ -71,4 +72,212 @@ void boundSliceWithLength(i64* start_out, i64* stop_out, i64 start, i64 stop, i6
*start_out = start;
*stop_out = stop;
}
Box* boxStringOrNone(const char* s) {
if (s == NULL) {
return None;
} else {
return boxString(s);
}
}
Box* noneIfNull(Box* b) {
if (b == NULL) {
return None;
} else {
return b;
}
}
Box* coerceUnicodeToStr(Box* unicode) {
if (!isSubclass(unicode->cls, unicode_cls))
return unicode;
Box* r = PyUnicode_AsASCIIString(unicode);
if (!r) {
PyErr_Clear();
raiseExcHelper(TypeError, "Cannot use non-ascii unicode strings as attribute names or keywords");
}
return r;
}
Box* boxStringFromCharPtr(const char* s) {
return boxString(s);
}
extern "C" bool hasnext(Box* o) {
return o->cls->tpp_hasnext(o);
}
extern "C" void dump(void* p) {
dumpEx(p, 0);
}
extern "C" void dumpEx(void* p, int levels) {
printf("\n");
printf("Raw address: %p\n", p);
bool is_gc = gc::isValidGCMemory(p);
if (!is_gc) {
printf("non-gc memory\n");
return;
}
if (gc::isNonheapRoot(p)) {
printf("Non-heap GC object\n");
printf("Assuming it's a class object...\n");
PyTypeObject* type = (PyTypeObject*)(p);
printf("tp_name: %s\n", type->tp_name);
return;
}
gc::GCAllocation* al = gc::GCAllocation::fromUserData(p);
if (al->kind_id == gc::GCKind::UNTRACKED) {
printf("gc-untracked object\n");
return;
}
if (al->kind_id == gc::GCKind::PRECISE) {
printf("precise gc array\n");
return;
}
if (al->kind_id == gc::GCKind::CONSERVATIVE) {
printf("conservatively-scanned object object\n");
return;
}
if (al->kind_id == gc::GCKind::PYTHON || al->kind_id == gc::GCKind::CONSERVATIVE_PYTHON) {
if (al->kind_id == gc::GCKind::PYTHON)
printf("Python object (precisely scanned)\n");
else
printf("Python object (conservatively scanned)\n");
Box* b = (Box*)p;
printf("Class: %s", getFullTypeName(b).c_str());
if (b->cls->cls != type_cls) {
printf(" (metaclass: %s)\n", getFullTypeName(b->cls).c_str());
} else {
printf("\n");
}
if (b->cls == bool_cls) {
printf("The %s object\n", b == True ? "True" : "False");
}
if (isSubclass(b->cls, type_cls)) {
auto cls = static_cast<BoxedClass*>(b);
printf("Type name: %s\n", getFullNameOfClass(cls).c_str());
printf("MRO:");
if (cls->tp_mro && cls->tp_mro->cls == tuple_cls) {
bool first = true;
for (auto b : *static_cast<BoxedTuple*>(cls->tp_mro)) {
if (!first)
printf(" ->");
first = false;
printf(" %s", getFullNameOfClass(static_cast<BoxedClass*>(b)).c_str());
}
}
printf("\n");
}
if (isSubclass(b->cls, str_cls)) {
printf("String value: %s\n", static_cast<BoxedString*>(b)->data());
}
if (isSubclass(b->cls, tuple_cls)) {
BoxedTuple* t = static_cast<BoxedTuple*>(b);
printf("%ld elements\n", t->size());
if (levels > 0) {
int i = 0;
for (auto e : *t) {
printf("\nElement %d:", i);
i++;
dumpEx(e, levels - 1);
}
}
}
if (isSubclass(b->cls, dict_cls)) {
BoxedDict* d = static_cast<BoxedDict*>(b);
printf("%ld elements\n", d->d.size());
if (levels > 0) {
int i = 0;
for (auto t : d->d) {
printf("\nKey:");
dumpEx(t.first, levels - 1);
printf("Value:");
dumpEx(t.second, levels - 1);
}
}
}
if (isSubclass(b->cls, int_cls)) {
printf("Int value: %ld\n", static_cast<BoxedInt*>(b)->n);
}
if (isSubclass(b->cls, list_cls)) {
auto l = static_cast<BoxedList*>(b);
printf("%ld elements\n", l->size);
if (levels > 0) {
int i = 0;
for (int i = 0; i < l->size; i++) {
printf("\nElement %d:", i);
dumpEx(l->elts->elts[i], levels - 1);
}
}
}
if (isSubclass(b->cls, function_cls)) {
BoxedFunction* f = static_cast<BoxedFunction*>(b);
CLFunction* cl = f->f;
if (cl->source) {
printf("User-defined function '%s'\n", cl->source->getName().data());
} else {
printf("A builtin function\n");
}
printf("Has %ld function versions\n", cl->versions.size());
for (CompiledFunction* cf : cl->versions) {
bool got_name;
std::string name = g.func_addr_registry.getFuncNameAtAddress(cf->code, true, &got_name);
if (got_name)
printf("%s\n", name.c_str());
else
printf("%p\n", cf->code);
}
}
if (isSubclass(b->cls, module_cls)) {
printf("The '%s' module\n", static_cast<BoxedModule*>(b)->name().c_str());
}
/*
if (b->cls->instancesHaveHCAttrs()) {
HCAttrs* attrs = b->getHCAttrsPtr();
printf("Has %ld attrs\n", attrs->hcls->attr_offsets.size());
for (const auto& p : attrs->hcls->attr_offsets) {
printf("Index %d: %s: %p\n", p.second, p.first.c_str(), attrs->attr_list->attrs[p.second]);
}
}
*/
return;
}
if (al->kind_id == gc::GCKind::HIDDEN_CLASS) {
printf("Hidden class object\n");
return;
}
RELEASE_ASSERT(0, "%d", (int)al->kind_id);
}
}
......@@ -44,6 +44,24 @@ void adjustNegativeIndicesOnObject(Box* obj, i64* start, i64* stop);
// Ensure stop >= start and remain within bounds.
void boundSliceWithLength(i64* start_out, i64* stop_out, i64 start, i64 stop, i64 size);
Box* noneIfNull(Box* b);
Box* boxStringOrNone(const char* s);
Box* boxStringFromCharPtr(const char* s);
// This function will ascii-encode any unicode objects it gets passed, or return the argument
// unmodified if it wasn't a unicode object.
// This is intended for functions that deal with attribute or variable names, which we internally
// assume will always be strings, but CPython lets be unicode.
// If we used an encoding like utf8 instead of ascii, we would allow collisions between unicode
// strings and a string that happens to be its encoding. It seems safer to just encode as ascii,
// which will throw an exception if you try to pass something that might run into this risk.
// (We wrap the unicode error and throw a TypeError)
Box* coerceUnicodeToStr(Box* unicode);
extern "C" bool hasnext(Box* o);
extern "C" void dump(void* p);
extern "C" void dumpEx(void* p, int levels = 0);
template <typename T> void copySlice(T* __restrict__ dst, const T* __restrict__ src, i64 start, i64 step, i64 length) {
assert(dst != src);
if (step == 1) {
......
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