capi.cpp 29.5 KB
Newer Older
Kevin Modzelewski's avatar
Kevin Modzelewski committed
1
// Copyright (c) 2014 Dropbox, Inc.
Kevin Modzelewski's avatar
Kevin Modzelewski committed
2
//
Kevin Modzelewski's avatar
Kevin Modzelewski committed
3 4 5
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
Kevin Modzelewski's avatar
Kevin Modzelewski committed
6
//
Kevin Modzelewski's avatar
Kevin Modzelewski committed
7
//    http://www.apache.org/licenses/LICENSE-2.0
Kevin Modzelewski's avatar
Kevin Modzelewski committed
8
//
Kevin Modzelewski's avatar
Kevin Modzelewski committed
9 10 11 12 13 14 15
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <dlfcn.h>
Alex Şuhan's avatar
Alex Şuhan committed
16
#include <stdarg.h>
Kevin Modzelewski's avatar
Kevin Modzelewski committed
17 18
#include <string.h>

19
#include "Python.h"
Kevin Modzelewski's avatar
Kevin Modzelewski committed
20

21
#include "capi/types.h"
Kevin Modzelewski's avatar
Kevin Modzelewski committed
22
#include "core/threading.h"
23
#include "core/types.h"
Travis Hance's avatar
Travis Hance committed
24
#include "runtime/import.h"
25
#include "runtime/objmodel.h"
Kevin Modzelewski's avatar
Kevin Modzelewski committed
26 27 28 29
#include "runtime/types.h"

namespace pyston {

30 31 32 33
BoxedClass* method_cls;
class BoxedMethodDescriptor : public Box {
public:
    PyMethodDef* method;
34
    BoxedClass* type;
35

36
    BoxedMethodDescriptor(PyMethodDef* method, BoxedClass* type) : Box(method_cls), method(method), type(type) {}
37

38 39 40 41 42 43 44 45 46
    static Box* __get__(BoxedMethodDescriptor* self, Box* inst, Box* owner) {
        RELEASE_ASSERT(self->cls == method_cls, "");

        if (inst == None)
            return self;
        // CPython apparently returns a "builtin_function_or_method" object
        return boxInstanceMethod(inst, self);
    }

47 48 49 50 51 52 53
    static Box* __call__(BoxedMethodDescriptor* self, Box* obj, BoxedTuple* varargs, Box** _args) {
        BoxedDict* kwargs = static_cast<BoxedDict*>(_args[0]);

        assert(self->cls == method_cls);
        assert(varargs->cls == tuple_cls);
        assert(kwargs->cls == dict_cls);

54 55 56 57
        if (!isSubclass(obj->cls, self->type))
            raiseExcHelper(TypeError, "descriptor '%s' requires a '%s' object but received a '%s'",
                           self->method->ml_name, getFullNameOfClass(self->type).c_str(), getFullTypeName(obj).c_str());

58 59 60 61 62 63 64 65 66 67 68
        threading::GLPromoteRegion _gil_lock;

        int ml_flags = self->method->ml_flags;
        Box* rtn;
        if (ml_flags == METH_NOARGS) {
            assert(varargs->elts.size() == 0);
            assert(kwargs->d.size() == 0);
            rtn = (Box*)self->method->ml_meth(obj, NULL);
        } else if (ml_flags == METH_VARARGS) {
            assert(kwargs->d.size() == 0);
            rtn = (Box*)self->method->ml_meth(obj, varargs);
69 70
        } else if (ml_flags == (METH_VARARGS | METH_KEYWORDS)) {
            rtn = (Box*)((PyCFunctionWithKeywords)self->method->ml_meth)(obj, varargs, kwargs);
Marius Wachtler's avatar
Marius Wachtler committed
71 72 73 74
        } 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]);
75 76 77 78 79 80 81 82
        } else {
            RELEASE_ASSERT(0, "0x%x", ml_flags);
        }
        assert(rtn);
        return rtn;
    }
};

83 84 85 86 87 88 89 90 91
#define MAKE_CHECK(NAME, cls_name)                                                                                     \
    extern "C" bool Py##NAME##_Check(PyObject* op) { return isSubclass(op->cls, cls_name); }

MAKE_CHECK(Int, int_cls)
MAKE_CHECK(String, str_cls)
MAKE_CHECK(Long, long_cls)
MAKE_CHECK(List, list_cls)
MAKE_CHECK(Tuple, tuple_cls)
MAKE_CHECK(Dict, dict_cls)
92 93 94 95 96

#ifdef Py_USING_UNICODE
MAKE_CHECK(Unicode, unicode_cls)
#endif

97 98
#undef MAKE_CHECK

Kevin Modzelewski's avatar
Kevin Modzelewski committed
99 100 101
extern "C" {
int Py_Py3kWarningFlag;
}
102

103
BoxedClass* capifunc_cls;
Kevin Modzelewski's avatar
Kevin Modzelewski committed
104

105 106 107 108
extern "C" void conservativeGCHandler(GCVisitor* v, Box* b) {
    v->visitPotentialRange((void* const*)b, (void* const*)((char*)b + b->cls->tp_basicsize));
}

Marius Wachtler's avatar
Marius Wachtler committed
109
extern "C" PyObject* PyType_GenericAlloc(PyTypeObject* cls, Py_ssize_t nitems) {
110 111 112 113 114 115 116 117
    RELEASE_ASSERT(nitems == 0, "unimplemented");
    RELEASE_ASSERT(cls->tp_itemsize == 0, "unimplemented");

    auto rtn = (PyObject*)gc_alloc(cls->tp_basicsize, gc::GCKind::PYTHON);
    memset(rtn, 0, cls->tp_basicsize);

    PyObject_Init(rtn, cls);
    return rtn;
Marius Wachtler's avatar
Marius Wachtler committed
118 119
}

120
BoxedClass* wrapperdescr_cls, *wrapperobject_cls;
121 122 123 124 125 126 127 128
struct wrapper_def {
    const char* name;
    int offset;
    int flags;
};

wrapper_def call_wrapper = { "__call__", offsetof(PyTypeObject, tp_call), PyWrapperFlag_KEYWORDS };

129 130
class BoxedWrapperDescriptor : public Box {
public:
131 132 133 134
    const wrapper_def* wrapper;
    BoxedClass* type;
    BoxedWrapperDescriptor(const wrapper_def* wrapper, BoxedClass* type)
        : Box(wrapperdescr_cls), wrapper(wrapper), type(type) {}
135 136 137 138 139 140 141 142 143 144 145 146

    static Box* __get__(BoxedWrapperDescriptor* self, Box* inst, Box* owner);
};

class BoxedWrapperObject : public Box {
public:
    BoxedWrapperDescriptor* descr;
    Box* obj;

    BoxedWrapperObject(BoxedWrapperDescriptor* descr, Box* obj) : Box(wrapperobject_cls), descr(descr), obj(obj) {}

    static Box* __call__(BoxedWrapperObject* self, Box* args, Box* kwds) {
147
        assert(self->cls == wrapperobject_cls);
148 149 150
        assert(args->cls == tuple_cls);
        assert(kwds->cls == dict_cls);

151 152 153 154 155 156 157 158 159
        int flags = self->descr->wrapper->flags;
        char* ptr = (char*)self->descr->type + self->descr->wrapper->offset;

        if (flags & PyWrapperFlag_KEYWORDS) {
            PyCFunctionWithKeywords f = *(PyCFunctionWithKeywords*)ptr;
            return f(self->obj, args, kwds);
        } else {
            abort();
        }
160 161 162 163 164 165 166 167 168 169
        abort();
    }
};

Box* BoxedWrapperDescriptor::__get__(BoxedWrapperDescriptor* self, Box* inst, Box* owner) {
    RELEASE_ASSERT(self->cls == wrapperdescr_cls, "");

    if (inst == None)
        return self;

170 171 172 173
    if (!isSubclass(inst->cls, self->type))
        raiseExcHelper(TypeError, "Descriptor '' for '%s' objects doesn't apply to '%s' object",
                       getFullNameOfClass(self->type).c_str(), getFullTypeName(inst).c_str());

174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
    return new BoxedWrapperObject(self, inst);
}

PyObject* tp_new_wrapper(PyTypeObject* self, BoxedTuple* args, Box* kwds) {
    RELEASE_ASSERT(isSubclass(self->cls, type_cls), "");

    // ASSERT(self->tp_new != Py_CallPythonNew, "going to get in an infinite loop");

    RELEASE_ASSERT(args->cls == tuple_cls, "");
    RELEASE_ASSERT(kwds->cls == dict_cls, "");
    RELEASE_ASSERT(args->elts.size() >= 1, "");

    BoxedClass* subtype = static_cast<BoxedClass*>(args->elts[0]);
    RELEASE_ASSERT(isSubclass(subtype->cls, type_cls), "");
    RELEASE_ASSERT(isSubclass(subtype, self), "");

    BoxedTuple* new_args = new BoxedTuple(BoxedTuple::GCVector(args->elts.begin() + 1, args->elts.end()));

    return self->tp_new(subtype, new_args, kwds);
}

195
extern "C" int PyType_Ready(PyTypeObject* cls) {
196
    gc::registerNonheapRootObject(cls);
197 198 199 200 201 202 203 204 205 206 207 208

    // unhandled fields:
    RELEASE_ASSERT(cls->tp_print == NULL, "");
    RELEASE_ASSERT(cls->tp_getattr == NULL, "");
    RELEASE_ASSERT(cls->tp_setattr == NULL, "");
    RELEASE_ASSERT(cls->tp_compare == NULL, "");
    RELEASE_ASSERT(cls->tp_repr == NULL, "");
    RELEASE_ASSERT(cls->tp_as_number == NULL, "");
    RELEASE_ASSERT(cls->tp_as_sequence == NULL, "");
    RELEASE_ASSERT(cls->tp_as_mapping == NULL, "");
    RELEASE_ASSERT(cls->tp_hash == NULL, "");
    RELEASE_ASSERT(cls->tp_str == NULL, "");
Marius Wachtler's avatar
Marius Wachtler committed
209
    RELEASE_ASSERT(cls->tp_getattro == NULL || cls->tp_getattro == PyObject_GenericGetAttr, "");
210 211
    RELEASE_ASSERT(cls->tp_setattro == NULL, "");
    RELEASE_ASSERT(cls->tp_as_buffer == NULL, "");
212 213 214 215 216 217

    int ALLOWABLE_FLAGS = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC;
    RELEASE_ASSERT((cls->tp_flags & ~ALLOWABLE_FLAGS) == 0, "");
    // RELEASE_ASSERT(cls->tp_traverse == NULL, "");
    // RELEASE_ASSERT(cls->tp_clear == NULL, "");

218 219 220 221 222 223 224 225 226
    RELEASE_ASSERT(cls->tp_richcompare == NULL, "");
    RELEASE_ASSERT(cls->tp_iter == NULL, "");
    RELEASE_ASSERT(cls->tp_iternext == NULL, "");
    RELEASE_ASSERT(cls->tp_base == NULL, "");
    RELEASE_ASSERT(cls->tp_dict == NULL, "");
    RELEASE_ASSERT(cls->tp_descr_get == NULL, "");
    RELEASE_ASSERT(cls->tp_descr_set == NULL, "");
    RELEASE_ASSERT(cls->tp_init == NULL, "");
    RELEASE_ASSERT(cls->tp_alloc == NULL, "");
Marius Wachtler's avatar
Marius Wachtler committed
227
    RELEASE_ASSERT(cls->tp_free == NULL || cls->tp_free == PyObject_Del, "");
228 229 230 231 232 233 234 235 236
    RELEASE_ASSERT(cls->tp_is_gc == NULL, "");
    RELEASE_ASSERT(cls->tp_base == NULL, "");
    RELEASE_ASSERT(cls->tp_mro == NULL, "");
    RELEASE_ASSERT(cls->tp_cache == NULL, "");
    RELEASE_ASSERT(cls->tp_subclasses == NULL, "");
    RELEASE_ASSERT(cls->tp_weaklist == NULL, "");
    RELEASE_ASSERT(cls->tp_del == NULL, "");
    RELEASE_ASSERT(cls->tp_version_tag == 0, "");

237 238 239
// I think it is safe to ignore tp_weaklistoffset for now:
// RELEASE_ASSERT(cls->tp_weaklistoffset == 0, "");

240 241 242 243 244
#define INITIALIZE(a) new (&(a)) decltype(a)
    INITIALIZE(cls->attrs);
    INITIALIZE(cls->dependent_icgetattrs);
#undef INITIALIZE

245
    BoxedClass* base = cls->base = object_cls;
246 247 248
    if (!cls->cls)
        cls->cls = cls->base->cls;

249 250 251 252 253 254
    assert(cls->tp_name);
    cls->giveAttr("__name__", boxStrConstant(cls->tp_name));
    // tp_name
    // tp_basicsize, tp_itemsize
    // tp_doc

255 256
    if (!cls->tp_new && base != object_cls)
        cls->tp_new = base->tp_new;
257

258 259 260
    if (cls->tp_new) {
        cls->giveAttr("__new__",
                      new BoxedCApiFunction(METH_VARARGS | METH_KEYWORDS, cls, "__new__", (PyCFunction)tp_new_wrapper));
Marius Wachtler's avatar
Marius Wachtler committed
261 262
    }

263 264 265 266
    if (cls->tp_call) {
        cls->giveAttr("__call__", new BoxedWrapperDescriptor(&call_wrapper, cls));
    }

Marius Wachtler's avatar
Marius Wachtler committed
267 268 269
    if (!cls->tp_alloc) {
        cls->tp_alloc = reinterpret_cast<decltype(cls->tp_alloc)>(PyType_GenericAlloc);
    }
270 271

    for (PyMethodDef* method = cls->tp_methods; method && method->ml_name; ++method) {
272
        cls->giveAttr(method->ml_name, new BoxedMethodDescriptor(method, cls));
273 274 275 276
    }

    for (PyMemberDef* member = cls->tp_members; member && member->name; ++member) {
        cls->giveAttr(member->name, new BoxedMemberDescriptor(member));
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
    }

    if (cls->tp_getset) {
        if (VERBOSITY())
            printf("warning: ignoring tp_getset for now\n");
    }

    cls->gc_visit = &conservativeGCHandler;

    // TODO not sure how we can handle extension types that manually
    // specify a dict...
    RELEASE_ASSERT(cls->tp_dictoffset == 0, "");
    // this should get automatically initialized to 0 on this path:
    assert(cls->attrs_offset == 0);

    return 0;
}

Marius Wachtler's avatar
Marius Wachtler committed
295 296 297 298
extern "C" int PyType_IsSubtype(PyTypeObject*, PyTypeObject*) {
    Py_FatalError("unimplemented");
}

299 300 301 302 303 304 305 306 307 308
// copied from CPython's getargs.c:
extern "C" int PyBuffer_FillInfo(Py_buffer* view, PyObject* obj, void* buf, Py_ssize_t len, int readonly, int flags) {
    if (view == NULL)
        return 0;
    if (((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) && (readonly == 1)) {
        // Don't support PyErr_SetString yet:
        assert(0);
        // PyErr_SetString(PyExc_BufferError, "Object is not writable.");
        // return -1;
    }
Kevin Modzelewski's avatar
Kevin Modzelewski committed
309

310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345
    view->obj = obj;
    if (obj)
        Py_INCREF(obj);
    view->buf = buf;
    view->len = len;
    view->readonly = readonly;
    view->itemsize = 1;
    view->format = NULL;
    if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT)
        view->format = "B";
    view->ndim = 1;
    view->shape = NULL;
    if ((flags & PyBUF_ND) == PyBUF_ND)
        view->shape = &(view->len);
    view->strides = NULL;
    if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES)
        view->strides = &(view->itemsize);
    view->suboffsets = NULL;
    view->internal = NULL;
    return 0;
}

extern "C" void PyBuffer_Release(Py_buffer* view) {
    if (!view->buf) {
        assert(!view->obj);
        return;
    }

    PyObject* obj = view->obj;
    assert(obj);
    assert(obj->cls == str_cls);
    if (obj && Py_TYPE(obj)->tp_as_buffer && Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer)
        Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer(obj, view);
    Py_XDECREF(obj);
    view->obj = NULL;
}
Kevin Modzelewski's avatar
Kevin Modzelewski committed
346

347 348
// Not sure why we need another declaration here:
extern "C" void Py_FatalError(const char* msg) __attribute__((__noreturn__));
349
extern "C" void Py_FatalError(const char* msg) {
350
    fprintf(stderr, "\nFatal Python error: %s\n", msg);
351 352
    abort();
}
353

354
extern "C" void _PyErr_BadInternalCall(const char* filename, int lineno) {
355
    Py_FatalError("unimplemented");
356
}
357

358
extern "C" PyObject* PyObject_Init(PyObject* op, PyTypeObject* tp) {
359 360 361
    RELEASE_ASSERT(op, "");
    RELEASE_ASSERT(tp, "");

362 363 364
    assert(gc::isValidGCObject(op));
    assert(gc::isValidGCObject(tp));

365
    Py_TYPE(op) = tp;
366 367 368 369 370 371 372 373 374

    // I think CPython defers the dict creation (equivalent of our initUserAttrs) to the
    // first time that an attribute gets set.
    // Our HCAttrs object already includes this optimization of no-allocation-if-empty,
    // but it's nice to initialize the hcls here so we don't have to check it on every getattr/setattr.
    // TODO It does mean that anything not defering to this function will have to call
    // initUserAttrs themselves, though.
    initUserAttrs(op, tp);

375 376
    return op;
}
377

378
extern "C" PyVarObject* PyObject_InitVar(PyVarObject* op, PyTypeObject* tp, Py_ssize_t size) {
379 380 381
    assert(gc::isValidGCObject(op));
    assert(gc::isValidGCObject(tp));

382 383 384 385 386 387 388 389 390
    RELEASE_ASSERT(op, "");
    RELEASE_ASSERT(tp, "");
    Py_TYPE(op) = tp;
    op->ob_size = size;
    return op;
}

extern "C" PyObject* _PyObject_New(PyTypeObject* cls) {
    assert(cls->tp_itemsize == 0);
391

392
    auto rtn = (PyObject*)gc_alloc(cls->tp_basicsize, gc::GCKind::PYTHON);
393 394 395
    // no memset for this function

    PyObject_Init(rtn, cls);
396 397 398 399 400 401 402 403
    return rtn;
}

extern "C" void PyObject_Free(void* p) {
    gc::gc_free(p);
    ASSERT(0, "I think this is good enough but I'm not sure; should test");
}

404 405 406
extern "C" PyObject* _PyObject_GC_Malloc(size_t) {
    Py_FatalError("unimplemented");
}
407 408 409

extern "C" PyObject* _PyObject_GC_New(PyTypeObject* cls) {
    return _PyObject_New(cls);
410
}
411

412 413 414
extern "C" PyVarObject* _PyObject_GC_NewVar(PyTypeObject*, Py_ssize_t) {
    Py_FatalError("unimplemented");
}
415

416
extern "C" void PyObject_GC_Track(void*) {
417
    // TODO do we have to do anything to support the C API GC protocol?
418
}
419

420
extern "C" void PyObject_GC_UnTrack(void*) {
421
    // TODO do we have to do anything to support the C API GC protocol?
422
}
423

424 425 426 427
extern "C" void PyObject_GC_Del(void*) {
    Py_FatalError("unimplemented");
}

428 429 430 431 432 433 434 435 436 437 438 439
extern "C" PyObject* PyObject_CallObject(PyObject* obj, PyObject* args) {
    RELEASE_ASSERT(args, ""); // actually it looks like this is allowed to be NULL
    RELEASE_ASSERT(args->cls == tuple_cls, "");

    // TODO do something like this?  not sure if this is safe; will people expect that calling into a known function
    // won't end up doing a GIL check?
    // threading::GLDemoteRegion _gil_demote;

    try {
        Box* r = runtimeCall(obj, ArgPassSpec(0, 0, true, false), args, NULL, NULL, NULL, NULL);
        return r;
    } catch (Box* b) {
440
        Py_FatalError("unimplemented");
441 442
    }
}
Kevin Modzelewski's avatar
Kevin Modzelewski committed
443

Kevin Modzelewski's avatar
Kevin Modzelewski committed
444
extern "C" PyObject* PyObject_CallMethod(PyObject* o, char* name, char* format, ...) {
445
    Py_FatalError("unimplemented");
Kevin Modzelewski's avatar
Kevin Modzelewski committed
446 447 448
}

extern "C" PyObject* _PyObject_CallMethod_SizeT(PyObject* o, char* name, char* format, ...) {
449
    Py_FatalError("unimplemented");
Kevin Modzelewski's avatar
Kevin Modzelewski committed
450 451
}

452 453 454 455
extern "C" PyObject* PyObject_GetAttrString(PyObject* o, const char* attr) {
    // TODO do something like this?  not sure if this is safe; will people expect that calling into a known function
    // won't end up doing a GIL check?
    // threading::GLDemoteRegion _gil_demote;
Kevin Modzelewski's avatar
Kevin Modzelewski committed
456

457 458 459
    try {
        return getattr(o, attr);
    } catch (Box* b) {
460
        Py_FatalError("unimplemented");
461 462
    }
}
Kevin Modzelewski's avatar
Kevin Modzelewski committed
463

Kevin Modzelewski's avatar
Kevin Modzelewski committed
464 465 466 467
extern "C" Py_ssize_t PyObject_Size(PyObject* o) {
    try {
        return len(o)->n;
    } catch (Box* b) {
468
        Py_FatalError("unimplemented");
Kevin Modzelewski's avatar
Kevin Modzelewski committed
469 470 471
    }
}

Marius Wachtler's avatar
Marius Wachtler committed
472 473 474 475
extern "C" PyObject* PyObject_GetIter(PyObject*) {
    Py_FatalError("unimplemented");
}

476 477 478 479
extern "C" PyObject* PyObject_Repr(PyObject*) {
    Py_FatalError("unimplemented");
}

480
extern "C" PyObject* PyObject_GetAttr(PyObject* o, PyObject* attr_name) {
481 482 483 484 485 486 487 488 489 490
    if (!isSubclass(attr_name->cls, str_cls)) {
        PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", Py_TYPE(attr_name)->tp_name);
        return NULL;
    }

    try {
        return getattr(o, static_cast<BoxedString*>(attr_name)->s.c_str());
    } catch (Box* b) {
        Py_FatalError("unimplemented");
    }
491 492 493 494 495 496
}

extern "C" PyObject* PyObject_GenericGetAttr(PyObject* o, PyObject* name) {
    Py_FatalError("unimplemented");
}

Kevin Modzelewski's avatar
Kevin Modzelewski committed
497 498 499 500
extern "C" PyObject* PyObject_GetItem(PyObject* o, PyObject* key) {
    try {
        return getitem(o, key);
    } catch (Box* b) {
501
        Py_FatalError("unimplemented");
Kevin Modzelewski's avatar
Kevin Modzelewski committed
502 503 504
    }
}

505 506 507 508 509 510 511 512 513 514 515 516
extern "C" int PyObject_SetItem(PyObject* o, PyObject* key, PyObject* v) {
    Py_FatalError("unimplemented");
}

extern "C" int PyObject_DelItem(PyObject* o, PyObject* key) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyObject_RichCompare(PyObject* o1, PyObject* o2, int opid) {
    Py_FatalError("unimplemented");
}

517 518 519 520 521 522
extern "C" long PyObject_Hash(PyObject* o) {
    try {
        return hash(o)->n;
    } catch (Box* b) {
        Py_FatalError("unimplemented");
    }
523 524
}

Marius Wachtler's avatar
Marius Wachtler committed
525 526 527 528 529 530 531 532 533
extern "C" int PyObject_IsTrue(PyObject* o) {
    try {
        return nonzero(o);
    } catch (Box* b) {
        Py_FatalError("unimplemented");
    }
}


534 535 536 537 538
extern "C" int PyObject_Not(PyObject* o) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyObject_Call(PyObject* callable_object, PyObject* args, PyObject* kw) {
539 540 541 542 543
    try {
        return runtimeCall(callable_object, ArgPassSpec(0, 0, true, true), args, kw, NULL, NULL, NULL);
    } catch (Box* b) {
        Py_FatalError("unimplemented");
    }
544 545
}

Kevin Modzelewski's avatar
Kevin Modzelewski committed
546
extern "C" void PyObject_ClearWeakRefs(PyObject* object) {
547
    Py_FatalError("unimplemented");
Kevin Modzelewski's avatar
Kevin Modzelewski committed
548 549
}

550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
extern "C" int PyObject_GetBuffer(PyObject* exporter, Py_buffer* view, int flags) {
    Py_FatalError("unimplemented");
}

extern "C" int PySequence_Check(PyObject*) {
    Py_FatalError("unimplemented");
}

extern "C" Py_ssize_t PySequence_Size(PyObject* o) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PySequence_Concat(PyObject* o1, PyObject* o2) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PySequence_Repeat(PyObject* o, Py_ssize_t count) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PySequence_InPlaceConcat(PyObject* o1, PyObject* o2) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PySequence_InPlaceRepeat(PyObject* o, Py_ssize_t count) {
    Py_FatalError("unimplemented");
}
Kevin Modzelewski's avatar
Kevin Modzelewski committed
577

578 579 580 581 582
extern "C" PyObject* PySequence_GetItem(PyObject* o, Py_ssize_t i) {
    try {
        // Not sure if this is really the same:
        return getitem(o, boxInt(i));
    } catch (Box* b) {
583
        Py_FatalError("unimplemented");
584 585 586 587 588 589 590 591
    }
}

extern "C" PyObject* PySequence_GetSlice(PyObject* o, Py_ssize_t i1, Py_ssize_t i2) {
    try {
        // Not sure if this is really the same:
        return getitem(o, new BoxedSlice(boxInt(i1), boxInt(i2), None));
    } catch (Box* b) {
592
        Py_FatalError("unimplemented");
593 594 595
    }
}

596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635
extern "C" int PySequence_SetItem(PyObject* o, Py_ssize_t i, PyObject* v) {
    Py_FatalError("unimplemented");
}

extern "C" int PySequence_DelItem(PyObject* o, Py_ssize_t i) {
    Py_FatalError("unimplemented");
}

extern "C" int PySequence_SetSlice(PyObject* o, Py_ssize_t i1, Py_ssize_t i2, PyObject* v) {
    Py_FatalError("unimplemented");
}

extern "C" int PySequence_DelSlice(PyObject* o, Py_ssize_t i1, Py_ssize_t i2) {
    Py_FatalError("unimplemented");
}

extern "C" Py_ssize_t PySequence_Count(PyObject* o, PyObject* value) {
    Py_FatalError("unimplemented");
}

extern "C" int PySequence_Contains(PyObject* o, PyObject* value) {
    Py_FatalError("unimplemented");
}

extern "C" Py_ssize_t PySequence_Index(PyObject* o, PyObject* value) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PySequence_List(PyObject* o) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PySequence_Tuple(PyObject* o) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PySequence_Fast(PyObject* o, const char* m) {
    Py_FatalError("unimplemented");
}

Marius Wachtler's avatar
Marius Wachtler committed
636 637 638
extern "C" PyObject* PyIter_Next(PyObject*) {
    Py_FatalError("unimplemented");
}
639

Kevin Modzelewski's avatar
Kevin Modzelewski committed
640 641 642 643 644 645 646 647
extern "C" int PyCallable_Check(PyObject* x) {
    if (x == NULL)
        return 0;

    static const std::string call_attr("__call__");
    return typeLookup(x->cls, call_attr, NULL) != NULL;
}

Kevin Modzelewski's avatar
Kevin Modzelewski committed
648

649
extern "C" void PyErr_Restore(PyObject* type, PyObject* value, PyObject* traceback) {
650
    Py_FatalError("setting exceptions from the C API is current unimplemented");
651 652
}

653 654 655
extern "C" void PyErr_Clear() {
    PyErr_Restore(NULL, NULL, NULL);
}
656

657 658 659
extern "C" void PyErr_SetString(PyObject* exception, const char* string) {
    PyErr_SetObject(exception, boxStrConstant(string));
}
660

661 662 663
extern "C" void PyErr_SetObject(PyObject* exception, PyObject* value) {
    PyErr_Restore(exception, value, NULL);
}
664

665
extern "C" PyObject* PyErr_Format(PyObject* exception, const char* format, ...) {
666
    Py_FatalError("unimplemented");
667
}
668

669
extern "C" PyObject* PyErr_NoMemory() {
670
    Py_FatalError("unimplemented");
671 672
}

673
extern "C" int PyErr_CheckSignals() {
674
    Py_FatalError("unimplemented");
675 676
}

677
extern "C" int PyErr_ExceptionMatches(PyObject* exc) {
678
    Py_FatalError("unimplemented");
679 680 681
}

extern "C" PyObject* PyErr_Occurred() {
682 683
    // While there clearly needs to be more here, I think this is ok for now because all of the exception-setting
    // functions will abort()
684
    return NULL;
Kevin Modzelewski's avatar
Kevin Modzelewski committed
685 686
}

Kevin Modzelewski's avatar
Kevin Modzelewski committed
687
extern "C" int PyErr_WarnEx(PyObject* category, const char* text, Py_ssize_t stacklevel) {
688
    Py_FatalError("unimplemented");
Kevin Modzelewski's avatar
Kevin Modzelewski committed
689 690
}

Marius Wachtler's avatar
Marius Wachtler committed
691 692 693 694
extern "C" PyObject* PyErr_SetFromErrno(PyObject* type) {
    Py_FatalError("unimplemented");
    return NULL;
}
695

Kevin Modzelewski's avatar
Kevin Modzelewski committed
696 697 698 699 700
extern "C" PyObject* PyImport_Import(PyObject* module_name) {
    RELEASE_ASSERT(module_name, "");
    RELEASE_ASSERT(module_name->cls == str_cls, "");

    try {
Travis Hance's avatar
Travis Hance committed
701
        return import(-1, None, &static_cast<BoxedString*>(module_name)->s);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
702
    } catch (Box* e) {
703
        Py_FatalError("unimplemented");
Kevin Modzelewski's avatar
Kevin Modzelewski committed
704 705 706
    }
}

707 708

extern "C" PyObject* PyCallIter_New(PyObject* callable, PyObject* sentinel) {
709
    Py_FatalError("unimplemented");
710 711
}

Marius Wachtler's avatar
Marius Wachtler committed
712 713 714 715 716 717 718 719 720 721 722 723
extern "C" void* PyMem_Malloc(size_t sz) {
    return gc_compat_malloc(sz);
}

extern "C" void* PyMem_Realloc(void* ptr, size_t sz) {
    return gc_compat_realloc(ptr, sz);
}

extern "C" void PyMem_Free(void* ptr) {
    gc_compat_free(ptr);
}

724 725 726 727
extern "C" int PyNumber_Check(PyObject*) {
    Py_FatalError("unimplemented");
}

728 729 730 731 732 733
extern "C" PyObject* PyNumber_Add(PyObject* lhs, PyObject* rhs) {
    try {
        return binop(lhs, rhs, AST_TYPE::Add);
    } catch (Box* b) {
        Py_FatalError("unimplemented");
    }
734 735
}

736 737 738 739 740 741
extern "C" PyObject* PyNumber_Subtract(PyObject* lhs, PyObject* rhs) {
    try {
        return binop(lhs, rhs, AST_TYPE::Sub);
    } catch (Box* b) {
        Py_FatalError("unimplemented");
    }
Marius Wachtler's avatar
Marius Wachtler committed
742 743
}

Marius Wachtler's avatar
Marius Wachtler committed
744 745 746 747 748 749
extern "C" PyObject* PyNumber_Multiply(PyObject* lhs, PyObject* rhs) {
    try {
        return binop(lhs, rhs, AST_TYPE::Mult);
    } catch (Box* b) {
        Py_FatalError("unimplemented");
    }
Marius Wachtler's avatar
Marius Wachtler committed
750
}
751

Marius Wachtler's avatar
Marius Wachtler committed
752 753 754 755 756 757
extern "C" PyObject* PyNumber_Divide(PyObject* lhs, PyObject* rhs) {
    try {
        return binop(lhs, rhs, AST_TYPE::Div);
    } catch (Box* b) {
        Py_FatalError("unimplemented");
    }
758 759 760 761 762 763 764 765 766 767
}

extern "C" PyObject* PyNumber_FloorDivide(PyObject*, PyObject*) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_TrueDivide(PyObject*, PyObject*) {
    Py_FatalError("unimplemented");
}

Marius Wachtler's avatar
Marius Wachtler committed
768 769 770 771 772 773
extern "C" PyObject* PyNumber_Remainder(PyObject* lhs, PyObject* rhs) {
    try {
        return binop(lhs, rhs, AST_TYPE::Mod);
    } catch (Box* b) {
        Py_FatalError("unimplemented");
    }
774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792
}

extern "C" PyObject* PyNumber_Divmod(PyObject*, PyObject*) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_Power(PyObject*, PyObject*, PyObject* o3) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_Negative(PyObject* o) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_Positive(PyObject* o) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_Absolute(PyObject* o) {
Marius Wachtler's avatar
Marius Wachtler committed
793 794 795 796 797
    try {
        return abs_(o);
    } catch (Box* b) {
        Py_FatalError("unimplemented");
    }
798 799 800 801 802 803 804 805 806 807
}

extern "C" PyObject* PyNumber_Invert(PyObject* o) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_Lshift(PyObject*, PyObject*) {
    Py_FatalError("unimplemented");
}

Marius Wachtler's avatar
Marius Wachtler committed
808 809 810 811 812 813
extern "C" PyObject* PyNumber_Rshift(PyObject* lhs, PyObject* rhs) {
    try {
        return binop(lhs, rhs, AST_TYPE::RShift);
    } catch (Box* b) {
        Py_FatalError("unimplemented");
    }
814 815
}

Marius Wachtler's avatar
Marius Wachtler committed
816 817 818 819 820 821
extern "C" PyObject* PyNumber_And(PyObject* lhs, PyObject* rhs) {
    try {
        return binop(lhs, rhs, AST_TYPE::BitAnd);
    } catch (Box* b) {
        Py_FatalError("unimplemented");
    }
822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915
}

extern "C" PyObject* PyNumber_Xor(PyObject*, PyObject*) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_Or(PyObject*, PyObject*) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_InPlaceAdd(PyObject*, PyObject*) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_InPlaceSubtract(PyObject*, PyObject*) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_InPlaceMultiply(PyObject*, PyObject*) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_InPlaceDivide(PyObject*, PyObject*) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_InPlaceFloorDivide(PyObject*, PyObject*) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_InPlaceTrueDivide(PyObject*, PyObject*) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_InPlaceRemainder(PyObject*, PyObject*) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_InPlacePower(PyObject*, PyObject*, PyObject* o3) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_InPlaceLshift(PyObject*, PyObject*) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_InPlaceRshift(PyObject*, PyObject*) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_InPlaceAnd(PyObject*, PyObject*) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_InPlaceXor(PyObject*, PyObject*) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_InPlaceOr(PyObject*, PyObject*) {
    Py_FatalError("unimplemented");
}

extern "C" int PyNumber_Coerce(PyObject**, PyObject**) {
    Py_FatalError("unimplemented");
}

extern "C" int PyNumber_CoerceEx(PyObject**, PyObject**) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_Int(PyObject* o) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_Long(PyObject* o) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_Float(PyObject* o) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_Index(PyObject* o) {
    Py_FatalError("unimplemented");
}

extern "C" PyObject* PyNumber_ToBase(PyObject* n, int base) {
    Py_FatalError("unimplemented");
}

extern "C" Py_ssize_t PyNumber_AsSsize_t(PyObject* o, PyObject* exc) {
    Py_FatalError("unimplemented");
}

916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931
extern "C" Py_ssize_t PyUnicode_GET_SIZE(PyObject*) {
    Py_FatalError("unimplemented");
}

extern "C" Py_ssize_t PyUnicode_GET_DATA_SIZE(PyObject*) {
    Py_FatalError("unimplemented");
}

extern "C" Py_UNICODE* PyUnicode_AS_UNICODE(PyObject*) {
    Py_FatalError("unimplemented");
}

extern "C" const char* PyUnicode_AS_DATA(PyObject*) {
    Py_FatalError("unimplemented");
}

932
BoxedModule* importTestExtension(const std::string& name) {
933
    std::string pathname_name = "test/test_extension/" + name + ".pyston.so";
934
    const char* pathname = pathname_name.c_str();
935
    void* handle = dlopen(pathname, RTLD_NOW);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
936 937 938 939 940 941
    if (!handle) {
        fprintf(stderr, "%s\n", dlerror());
        exit(1);
    }
    assert(handle);

942 943
    std::string initname = "init" + name;
    void (*init)() = (void (*)())dlsym(handle, initname.c_str());
Kevin Modzelewski's avatar
Kevin Modzelewski committed
944

945
    char* error;
Kevin Modzelewski's avatar
Kevin Modzelewski committed
946 947 948 949 950 951 952
    if ((error = dlerror()) != NULL) {
        fprintf(stderr, "%s\n", error);
        exit(1);
    }

    assert(init);
    (*init)();
953 954

    BoxedDict* sys_modules = getSysModulesDict();
955
    Box* s = boxStrConstant(name.c_str());
956 957 958 959 960 961 962 963
    Box* _m = sys_modules->d[s];
    RELEASE_ASSERT(_m, "module failed to initialize properly?");
    assert(_m->cls == module_cls);

    BoxedModule* m = static_cast<BoxedModule*>(_m);
    m->setattr("__file__", boxStrConstant(pathname), NULL);
    m->fn = pathname;
    return m;
Kevin Modzelewski's avatar
Kevin Modzelewski committed
964 965 966
}

void setupCAPI() {
Kevin Modzelewski's avatar
Kevin Modzelewski committed
967
    capifunc_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedCApiFunction), false);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
968 969
    capifunc_cls->giveAttr("__name__", boxStrConstant("capifunc"));

970
    capifunc_cls->giveAttr("__repr__",
971
                           new BoxedFunction(boxRTFunction((void*)BoxedCApiFunction::__repr__, UNKNOWN, 1)));
972
    capifunc_cls->giveAttr("__str__", capifunc_cls->getattr("__repr__"));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
973

974
    capifunc_cls->giveAttr(
975
        "__call__", new BoxedFunction(boxRTFunction((void*)BoxedCApiFunction::__call__, UNKNOWN, 1, 0, true, true)));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
976 977

    capifunc_cls->freeze();
978

Kevin Modzelewski's avatar
Kevin Modzelewski committed
979
    method_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedMethodDescriptor), false);
980
    method_cls->giveAttr("__name__", boxStrConstant("method"));
981 982
    method_cls->giveAttr("__get__",
                         new BoxedFunction(boxRTFunction((void*)BoxedMethodDescriptor::__get__, UNKNOWN, 3)));
983 984 985
    method_cls->giveAttr("__call__", new BoxedFunction(boxRTFunction((void*)BoxedMethodDescriptor::__call__, UNKNOWN, 2,
                                                                     0, true, true)));
    method_cls->freeze();
986 987 988 989 990 991 992 993 994 995 996 997

    wrapperdescr_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedWrapperDescriptor), false);
    wrapperdescr_cls->giveAttr("__name__", boxStrConstant("wrapper_descriptor"));
    wrapperdescr_cls->giveAttr("__get__",
                               new BoxedFunction(boxRTFunction((void*)BoxedWrapperDescriptor::__get__, UNKNOWN, 3)));
    wrapperdescr_cls->freeze();

    wrapperobject_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedWrapperObject), false);
    wrapperobject_cls->giveAttr("__name__", boxStrConstant("method-wrapper"));
    wrapperobject_cls->giveAttr(
        "__call__", new BoxedFunction(boxRTFunction((void*)BoxedWrapperObject::__call__, UNKNOWN, 1, 0, true, true)));
    wrapperobject_cls->freeze();
Kevin Modzelewski's avatar
Kevin Modzelewski committed
998 999 1000 1001 1002
}

void teardownCAPI() {
}
}