Commit b0f3ab79 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #143 from undingen/random

parents 7e308f7b 853c027d
......@@ -268,7 +268,7 @@ SRCS := $(MAIN_SRCS) $(STDLIB_SRCS)
STDLIB_OBJS := stdlib.bc.o stdlib.stripped.bc.o
STDLIB_RELEASE_OBJS := stdlib.release.bc.o
STDMODULE_SRCS := errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _sre.c operator.c binascii.c $(EXTRA_STDMODULE_SRCS)
STDMODULE_SRCS := errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c $(EXTRA_STDMODULE_SRCS)
FROM_CPYTHON_SRCS := $(addprefix ../lib_python/2.7_Modules/,$(STDMODULE_SRCS)) $(wildcard capi/*.c)
# The stdlib objects have slightly longer dependency chains,
......
......@@ -210,4 +210,19 @@ extern "C" int PyArg_UnpackTuple(PyObject* args, const char* name, Py_ssize_t mi
return true;
}
extern "C" int _PyArg_NoKeywords(const char* funcname, PyObject* kw) {
if (kw == NULL)
return 1;
if (kw->cls != dict_cls) {
PyErr_BadInternalCall();
return 0;
}
if (static_cast<BoxedDict*>(kw)->d.empty())
return 1;
PyErr_Format(PyExc_TypeError, "%s does not take keyword arguments", funcname);
return 0;
}
} // namespace pyston
......@@ -81,7 +81,7 @@ extern "C" PyObject* Py_InitModule4(const char* name, PyMethodDef* methods, cons
if (!passthrough)
passthrough = None;
while (methods->ml_name) {
while (methods && methods->ml_name) {
if (VERBOSITY())
printf("Loading method %s\n", methods->ml_name);
......
......@@ -55,6 +55,10 @@ public:
rtn = (Box*)self->method->ml_meth(obj, varargs);
} else if (ml_flags == (METH_VARARGS | METH_KEYWORDS)) {
rtn = (Box*)((PyCFunctionWithKeywords)self->method->ml_meth)(obj, varargs, kwargs);
} else if (ml_flags == METH_O) {
assert(kwargs->d.size() == 0);
assert(varargs->elts.size() == 1);
rtn = (Box*)self->method->ml_meth(obj, varargs->elts[0]);
} else {
RELEASE_ASSERT(0, "0x%x", ml_flags);
}
......@@ -114,6 +118,13 @@ extern "C" void conservativeGCHandler(GCVisitor* v, Box* b) {
v->visitPotentialRange((void* const*)b, (void* const*)((char*)b + b->cls->tp_basicsize));
}
extern "C" PyObject* PyType_GenericAlloc(PyTypeObject* cls, Py_ssize_t nitems) {
if (nitems == 0)
return _PyObject_New(cls);
Py_FatalError("unimplemented");
return NULL;
}
extern "C" int PyType_Ready(PyTypeObject* cls) {
gc::registerNonheapRootObject(cls);
......@@ -129,10 +140,10 @@ extern "C" int PyType_Ready(PyTypeObject* cls) {
RELEASE_ASSERT(cls->tp_hash == NULL, "");
RELEASE_ASSERT(cls->tp_call == NULL, "");
RELEASE_ASSERT(cls->tp_str == NULL, "");
RELEASE_ASSERT(cls->tp_getattro == NULL, "");
RELEASE_ASSERT(cls->tp_getattro == NULL || cls->tp_getattro == PyObject_GenericGetAttr, "");
RELEASE_ASSERT(cls->tp_setattro == NULL, "");
RELEASE_ASSERT(cls->tp_as_buffer == NULL, "");
RELEASE_ASSERT(cls->tp_flags == Py_TPFLAGS_DEFAULT, "");
RELEASE_ASSERT((cls->tp_flags & ~(Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE)) == 0, "");
RELEASE_ASSERT(cls->tp_traverse == NULL, "");
RELEASE_ASSERT(cls->tp_clear == NULL, "");
RELEASE_ASSERT(cls->tp_richcompare == NULL, "");
......@@ -144,8 +155,7 @@ extern "C" int PyType_Ready(PyTypeObject* cls) {
RELEASE_ASSERT(cls->tp_descr_set == NULL, "");
RELEASE_ASSERT(cls->tp_init == NULL, "");
RELEASE_ASSERT(cls->tp_alloc == NULL, "");
RELEASE_ASSERT(cls->tp_new == NULL, "");
RELEASE_ASSERT(cls->tp_free == NULL, "");
RELEASE_ASSERT(cls->tp_free == NULL || cls->tp_free == PyObject_Del, "");
RELEASE_ASSERT(cls->tp_is_gc == NULL, "");
RELEASE_ASSERT(cls->tp_base == NULL, "");
RELEASE_ASSERT(cls->tp_mro == NULL, "");
......@@ -173,6 +183,13 @@ extern "C" int PyType_Ready(PyTypeObject* cls) {
// tp_basicsize, tp_itemsize
// tp_doc
if (cls->tp_new) {
cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)cls->tp_new, UNKNOWN, 1, 0, true, true)));
}
if (!cls->tp_alloc) {
cls->tp_alloc = reinterpret_cast<decltype(cls->tp_alloc)>(PyType_GenericAlloc);
}
for (PyMethodDef* method = cls->tp_methods; method && method->ml_name; ++method) {
cls->giveAttr(method->ml_name, new BoxedMethodDescriptor(method));
......@@ -389,10 +406,19 @@ extern "C" PyObject* PyObject_RichCompare(PyObject* o1, PyObject* o2, int opid)
Py_FatalError("unimplemented");
}
extern "C" long PyObject_Hash(PyObject*) {
Py_FatalError("unimplemented");
}
extern "C" int PyObject_IsTrue(PyObject* o) {
try {
return nonzero(o);
} catch (Box* b) {
Py_FatalError("unimplemented");
}
}
extern "C" int PyObject_Not(PyObject* o) {
Py_FatalError("unimplemented");
}
......@@ -409,10 +435,6 @@ extern "C" int PyObject_GetBuffer(PyObject* exporter, Py_buffer* view, int flags
Py_FatalError("unimplemented");
}
extern "C" int _PyArg_NoKeywords(const char* funcname, PyObject* kw) {
Py_FatalError("unimplemented");
}
extern "C" int PySequence_Check(PyObject*) {
Py_FatalError("unimplemented");
}
......@@ -595,12 +617,20 @@ extern "C" PyObject* PyNumber_Subtract(PyObject*, PyObject*) {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Multiply(PyObject*, PyObject*) {
extern "C" PyObject* PyNumber_Multiply(PyObject* lhs, PyObject* rhs) {
try {
return binop(lhs, rhs, AST_TYPE::Mult);
} catch (Box* b) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_Divide(PyObject*, PyObject*) {
extern "C" PyObject* PyNumber_Divide(PyObject* lhs, PyObject* rhs) {
try {
return binop(lhs, rhs, AST_TYPE::Div);
} catch (Box* b) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_FloorDivide(PyObject*, PyObject*) {
......@@ -611,8 +641,12 @@ extern "C" PyObject* PyNumber_TrueDivide(PyObject*, PyObject*) {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Remainder(PyObject*, PyObject*) {
extern "C" PyObject* PyNumber_Remainder(PyObject* lhs, PyObject* rhs) {
try {
return binop(lhs, rhs, AST_TYPE::Mod);
} catch (Box* b) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_Divmod(PyObject*, PyObject*) {
......@@ -632,7 +666,11 @@ extern "C" PyObject* PyNumber_Positive(PyObject* o) {
}
extern "C" PyObject* PyNumber_Absolute(PyObject* o) {
try {
return abs_(o);
} catch (Box* b) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_Invert(PyObject* o) {
......@@ -643,12 +681,20 @@ extern "C" PyObject* PyNumber_Lshift(PyObject*, PyObject*) {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Rshift(PyObject*, PyObject*) {
extern "C" PyObject* PyNumber_Rshift(PyObject* lhs, PyObject* rhs) {
try {
return binop(lhs, rhs, AST_TYPE::RShift);
} catch (Box* b) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_And(PyObject*, PyObject*) {
extern "C" PyObject* PyNumber_And(PyObject* lhs, PyObject* rhs) {
try {
return binop(lhs, rhs, AST_TYPE::BitAnd);
} catch (Box* b) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_Xor(PyObject*, PyObject*) {
......
......@@ -83,6 +83,12 @@ extern "C" PyObject* PyLong_FromDouble(double v) {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyLong_FromLong(long ival) {
BoxedLong* rtn = new BoxedLong(long_cls);
mpz_init_set_si(rtn->n, ival);
return rtn;
}
extern "C" PyObject* PyLong_FromUnsignedLong(unsigned long ival) {
BoxedLong* rtn = new BoxedLong(long_cls);
mpz_init_set_ui(rtn->n, ival);
......@@ -93,6 +99,27 @@ extern "C" double _PyLong_Frexp(PyLongObject* a, Py_ssize_t* e) {
Py_FatalError("unimplemented");
}
extern "C" PyObject* _PyLong_FromByteArray(const unsigned char* bytes, size_t n, int little_endian, int is_signed) {
if (n == 0)
return PyLong_FromLong(0);
if (is_signed) {
Py_FatalError("unimplemented");
return 0;
}
if (!little_endian) {
// TODO: check if the behaviour of mpz_import is right when big endian is specified.
Py_FatalError("unimplemented");
return 0;
}
BoxedLong* rtn = new BoxedLong(long_cls);
mpz_init(rtn->n);
mpz_import(rtn->n, 1, 1, n, little_endian ? -1 : 1, 0, &bytes[0]);
return rtn;
}
extern "C" Box* createLong(const std::string* s) {
BoxedLong* rtn = new BoxedLong(long_cls);
int r = mpz_init_set_str(rtn->n, s->c_str(), 10);
......@@ -201,6 +228,33 @@ Box* longAdd(BoxedLong* v1, Box* _v2) {
}
}
extern "C" Box* longAnd(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__and__' requires a 'long' object but received a '%s'",
getTypeName(v1)->c_str());
if (isSubclass(_v2->cls, long_cls)) {
BoxedLong* v2 = static_cast<BoxedLong*>(_v2);
BoxedLong* r = new BoxedLong(long_cls);
mpz_init(r->n);
mpz_and(r->n, v1->n, v2->n);
return r;
} else if (isSubclass(_v2->cls, int_cls)) {
BoxedInt* v2_int = static_cast<BoxedInt*>(_v2);
BoxedLong* r = new BoxedLong(long_cls);
mpz_init(r->n);
mpz_t v2_long;
mpz_init(v2_long);
if (v2_int->n >= 0)
mpz_init_set_ui(v2_long, v2_int->n);
else
mpz_init_set_si(v2_long, v2_int->n);
mpz_and(r->n, v1->n, v2_long);
return r;
}
return NotImplemented;
}
// TODO reduce duplication between these 6 functions, and add double support
Box* longGt(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
......@@ -540,6 +594,9 @@ void setupLong() {
long_cls->giveAttr("__add__", new BoxedFunction(boxRTFunction((void*)longAdd, UNKNOWN, 2)));
long_cls->giveAttr("__radd__", long_cls->getattr("__add__"));
long_cls->giveAttr("__and__", new BoxedFunction(boxRTFunction((void*)longAnd, UNKNOWN, 2)));
long_cls->giveAttr("__rand__", long_cls->getattr("__and__"));
long_cls->giveAttr("__gt__", new BoxedFunction(boxRTFunction((void*)longGt, UNKNOWN, 2)));
long_cls->giveAttr("__ge__", new BoxedFunction(boxRTFunction((void*)longGe, UNKNOWN, 2)));
long_cls->giveAttr("__lt__", new BoxedFunction(boxRTFunction((void*)longLt, UNKNOWN, 2)));
......
......@@ -58,7 +58,7 @@ extern "C" BoxedString* reprOrNull(Box* obj); // similar to repr, but returns NU
extern "C" BoxedString* strOrNull(Box* obj); // similar to str, but returns NULL on exception
extern "C" bool isinstance(Box* obj, Box* cls, int64_t flags);
extern "C" BoxedInt* hash(Box* obj);
// extern "C" Box* abs_(Box* obj);
extern "C" Box* abs_(Box* obj);
Box* open(Box* arg1, Box* arg2);
// extern "C" Box* chr(Box* arg);
extern "C" Box* compare(Box*, Box*, int);
......
......@@ -39,6 +39,7 @@ extern "C" void init_sha();
extern "C" void init_sha256();
extern "C" void init_sha512();
extern "C" void init_md5();
extern "C" void init_random();
extern "C" void init_sre();
extern "C" void initmath();
extern "C" void initoperator();
......@@ -822,6 +823,7 @@ void setupRuntime() {
init_sha256();
init_sha512();
init_md5();
init_random();
init_sre();
initmath();
// TODO enable this
......
import _random
r = _random.Random(42)
print r.random()
s = r.getstate()
print r.getrandbits(100)
r.jumpahead(100)
print r.getrandbits(100)
r.setstate(s)
print r.getrandbits(100)
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