this repo has no description
at trunk 1755 lines 59 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include <cstdarg> 3 4#include "../Python/modsupport-internal.h" 5#include "cpython-data.h" 6#include "cpython-func.h" 7 8#include "api-handle.h" 9#include "array-module.h" 10#include "attributedict.h" 11#include "bytearrayobject-utils.h" 12#include "bytesobject-utils.h" 13#include "capi-typeslots.h" 14#include "capi.h" 15#include "exception-builtins.h" 16#include "formatter.h" 17#include "frame.h" 18#include "int-builtins.h" 19#include "list-builtins.h" 20#include "object-builtins.h" 21#include "runtime.h" 22#include "type-builtins.h" 23 24namespace py { 25 26static PyObject* nullError(Thread* thread) { 27 if (!thread->hasPendingException()) { 28 thread->raiseWithFmt(LayoutId::kSystemError, 29 "null argument to internal routine"); 30 } 31 return nullptr; 32} 33 34static PyObject* doUnaryOp(SymbolId op, PyObject* obj) { 35 Thread* thread = Thread::current(); 36 if (obj == nullptr) { 37 return nullError(thread); 38 } 39 40 HandleScope scope(thread); 41 Object object(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 42 Object result(&scope, thread->invokeFunction1(ID(operator), op, object)); 43 return result.isError() ? nullptr 44 : ApiHandle::newReference(thread->runtime(), *result); 45} 46 47static PyObject* doBinaryOp(SymbolId op, PyObject* left, PyObject* right) { 48 Thread* thread = Thread::current(); 49 DCHECK(left != nullptr && right != nullptr, "null argument to binary op %s", 50 Symbols::predefinedSymbolAt(op)); 51 HandleScope scope(thread); 52 Object left_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(left))); 53 Object right_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(right))); 54 Object result(&scope, 55 thread->invokeFunction2(ID(operator), op, left_obj, right_obj)); 56 return result.isError() ? nullptr 57 : ApiHandle::newReference(thread->runtime(), *result); 58} 59 60static Py_ssize_t objectLength(PyObject* pyobj) { 61 Thread* thread = Thread::current(); 62 if (pyobj == nullptr) { 63 nullError(thread); 64 return -1; 65 } 66 67 HandleScope scope(thread); 68 Object obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(pyobj))); 69 Object len_index(&scope, thread->invokeMethod1(obj, ID(__len__))); 70 if (len_index.isError()) { 71 if (len_index.isErrorNotFound()) { 72 thread->raiseWithFmt(LayoutId::kTypeError, "object has no len()"); 73 } 74 return -1; 75 } 76 Object len(&scope, intFromIndex(thread, len_index)); 77 if (len.isError()) { 78 return -1; 79 } 80 Int index(&scope, intUnderlying(*len)); 81 if (index.isNegative()) { 82 thread->raiseWithFmt(LayoutId::kValueError, "__len__() should return >= 0"); 83 return -1; 84 } 85 if (index.numDigits() > 1) { 86 thread->raiseWithFmt(LayoutId::kOverflowError, 87 "cannot fit '%T' into an index-sized integer", 88 &len_index); 89 return -1; 90 } 91 return index.asWord(); 92} 93 94// Buffer Protocol 95 96static RawObject raiseBufferError(Thread* thread, const Object& obj) { 97 return thread->raiseWithFmt( 98 LayoutId::kTypeError, "a bytes-like object is required, not '%T'", &obj); 99} 100 101RawObject newBytesFromBuffer(Thread* thread, const Object& obj) { 102 HandleScope scope(thread); 103 Runtime* runtime = thread->runtime(); 104 Type type(&scope, runtime->typeOf(*obj)); 105 if (!typeHasSlots(type)) { 106 return raiseBufferError(thread, obj); 107 } 108 void* get_slot = typeSlotAt(type, Py_bf_getbuffer); 109 if (get_slot == nullptr) { 110 return raiseBufferError(thread, obj); 111 } 112 Py_buffer view; 113 int flags = PyBUF_SIMPLE; 114 ApiHandle* handle = ApiHandle::borrowedReference(runtime, *obj); 115 int get_result = 116 reinterpret_cast<getbufferproc>(get_slot)(handle, &view, flags); 117 if (get_result != 0) { 118 return Error::exception(); 119 } 120 DCHECK(view.readonly, "writable buffers not supported"); 121 DCHECK(view.ndim == 1, "multi-dimensional buffers not supported"); 122 Bytes result(&scope, runtime->newBytesWithAll( 123 {reinterpret_cast<byte*>(view.buf), view.len})); 124 void* release_slot = typeSlotAt(type, Py_bf_releasebuffer); 125 // The release slot may not be defined. That's allowed. 126 if (release_slot != nullptr) { 127 reinterpret_cast<releasebufferproc>(release_slot)(handle, &view); 128 } 129 return *result; 130} 131 132PY_EXPORT int PyBuffer_FillInfo(Py_buffer* view, PyObject* exporter, void* buf, 133 Py_ssize_t len, int readonly, int flags) { 134 if (view == nullptr) { 135 Thread::current()->raiseWithFmt( 136 LayoutId::kBufferError, 137 "PyBuffer_FillInfo: view==NULL argument is obsolete"); 138 return -1; 139 } 140 if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE && readonly == 1) { 141 Thread::current()->raiseWithFmt(LayoutId::kBufferError, 142 "Object is not writable."); 143 return -1; 144 } 145 146 if (exporter != nullptr) { 147 Py_INCREF(exporter); 148 } 149 view->obj = exporter; 150 view->buf = buf; 151 view->len = len; 152 view->readonly = readonly; 153 view->itemsize = 1; 154 view->format = nullptr; 155 if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) { 156 view->format = const_cast<char*>("B"); 157 } 158 view->ndim = 1; 159 view->shape = nullptr; 160 if ((flags & PyBUF_ND) == PyBUF_ND) { 161 view->shape = &(view->len); 162 } 163 view->strides = nullptr; 164 if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) { 165 view->strides = &(view->itemsize); 166 } 167 view->suboffsets = nullptr; 168 view->internal = nullptr; 169 return 0; 170} 171 172static bool isContiguousWithRowMajorOrder(const Py_buffer* view) { 173 if (view->suboffsets != nullptr) return false; 174 if (view->strides == nullptr) return true; 175 if (view->len == 0) return true; 176 177 Py_ssize_t dim_stride = view->itemsize; 178 for (int d = view->ndim - 1; d >= 0; d--) { 179 Py_ssize_t dim_size = view->shape[d]; 180 if (dim_size > 1 && view->strides[d] != dim_stride) { 181 return false; 182 } 183 dim_stride *= dim_size; 184 } 185 return true; 186} 187 188static bool isContiguousWithColumnMajorOrder(const Py_buffer* view) { 189 if (view->suboffsets != nullptr) return false; 190 if (view->len == 0) return true; 191 if (view->strides == nullptr) { 192 if (view->ndim <= 1) return true; 193 // Non-contiguous if there is more than 1 dimension with size > 0. 194 bool had_nonempty_dim = false; 195 for (int d = 0; d < view->ndim; d++) { 196 if (view->shape[d] > 1) { 197 if (had_nonempty_dim) return false; 198 had_nonempty_dim = true; 199 } 200 } 201 return true; 202 } 203 204 Py_ssize_t dim_stride = view->itemsize; 205 for (int d = 0; d < view->ndim; d++) { 206 Py_ssize_t dim_size = view->shape[d]; 207 if (dim_size > 1 && view->strides[d] != dim_stride) { 208 return false; 209 } 210 dim_stride *= dim_size; 211 } 212 return true; 213} 214 215PY_EXPORT int PyBuffer_IsContiguous(const Py_buffer* view, char order) { 216 if (order == 'C') { 217 return isContiguousWithRowMajorOrder(view); 218 } 219 if (order == 'F') { 220 return isContiguousWithColumnMajorOrder(view); 221 } 222 if (order == 'A') { 223 return isContiguousWithRowMajorOrder(view) || 224 isContiguousWithColumnMajorOrder(view); 225 } 226 return false; 227} 228 229PY_EXPORT void PyBuffer_Release(Py_buffer* view) { 230 DCHECK(view != nullptr, "view must not be nullptr"); 231 PyObject* pyobj = view->obj; 232 if (pyobj == nullptr) return; 233 234 Thread* thread = Thread::current(); 235 HandleScope scope(thread); 236 Runtime* runtime = thread->runtime(); 237 Object object(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(pyobj))); 238 Type type(&scope, runtime->typeOf(*object)); 239 if (typeHasSlots(type)) { 240 // Call Py_bf_releasebuffer slot if defined 241 void* releasebuffer_fn = 242 PyType_GetSlot(Py_TYPE(pyobj), Py_bf_releasebuffer); 243 if (releasebuffer_fn != nullptr) { 244 reinterpret_cast<releasebufferproc>(releasebuffer_fn)(pyobj, view); 245 } 246 } 247 view->obj = nullptr; 248 Py_DECREF(pyobj); 249} 250 251// PyIndex_Check 252 253PY_EXPORT int PyIndex_Check_Func(PyObject* obj) { 254 DCHECK(obj != nullptr, "Got null argument"); 255 Thread* thread = Thread::current(); 256 HandleScope scope(thread); 257 Object num(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 258 Type type(&scope, thread->runtime()->typeOf(*num)); 259 return !typeLookupInMroById(thread, *type, ID(__index__)).isErrorNotFound(); 260} 261 262// PyIter_Next 263 264PY_EXPORT PyObject* PyIter_Next(PyObject* iter) { 265 Thread* thread = Thread::current(); 266 HandleScope scope(thread); 267 Object iter_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(iter))); 268 Object next(&scope, thread->invokeMethod1(iter_obj, ID(__next__))); 269 if (thread->clearPendingStopIteration()) { 270 // End of iterable 271 return nullptr; 272 } 273 if (next.isError()) { 274 // Method lookup or call failed 275 if (next.isErrorNotFound()) { 276 thread->raiseWithFmt(LayoutId::kTypeError, 277 "failed to call __next__ on iterable"); 278 } 279 return nullptr; 280 } 281 return ApiHandle::newReference(thread->runtime(), *next); 282} 283 284// Mapping Protocol 285 286PY_EXPORT int PyMapping_Check(PyObject* py_obj) { 287 Thread* thread = Thread::current(); 288 HandleScope scope(thread); 289 Object obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(py_obj))); 290 return thread->runtime()->isMapping(thread, obj); 291} 292 293PY_EXPORT int PyMapping_DelItemString(PyObject* obj, const char* attr_name) { 294 return PyObject_DelItemString(obj, attr_name); 295} 296 297PY_EXPORT int PyMapping_DelItem(PyObject* obj, PyObject* attr_name) { 298 return PyObject_DelItem(obj, attr_name); 299} 300 301PY_EXPORT PyObject* PyMapping_GetItemString(PyObject* obj, const char* key) { 302 Thread* thread = Thread::current(); 303 if (obj == nullptr || key == nullptr) { 304 return nullError(thread); 305 } 306 HandleScope scope(thread); 307 Runtime* runtime = thread->runtime(); 308 Object object(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 309 Object key_obj(&scope, runtime->newStrFromCStr(key)); 310 Object result(&scope, objectGetItem(thread, object, key_obj)); 311 if (result.isErrorException()) return nullptr; 312 return ApiHandle::newReference(runtime, *result); 313} 314 315PY_EXPORT int PyMapping_HasKey(PyObject* obj, PyObject* key) { 316 PyObject* v = PyObject_GetItem(obj, key); 317 if (v != nullptr) { 318 Py_DECREF(v); 319 return 1; 320 } 321 PyErr_Clear(); 322 return 0; 323} 324 325PY_EXPORT int PyMapping_HasKeyString(PyObject* obj, const char* key) { 326 PyObject* v = PyMapping_GetItemString(obj, key); 327 if (v != nullptr) { 328 Py_DECREF(v); 329 return 1; 330 } 331 PyErr_Clear(); 332 return 0; 333} 334 335PY_EXPORT PyObject* PyMapping_Items(PyObject* mapping) { 336 if (PyDict_CheckExact(mapping)) { 337 return PyDict_Items(mapping); 338 } 339 PyObject* items = PyObject_CallMethod(mapping, "items", nullptr); 340 if (items == nullptr) { 341 return nullptr; 342 } 343 PyObject* fast = PySequence_Fast(items, "mapping.items() are not iterable"); 344 Py_DECREF(items); 345 return fast; 346} 347 348PY_EXPORT PyObject* PyMapping_Keys(PyObject* mapping) { 349 DCHECK(mapping != nullptr, "mapping was null"); 350 if (PyDict_CheckExact(mapping)) { 351 return PyDict_Keys(mapping); 352 } 353 PyObject* keys = PyObject_CallMethod(mapping, "keys", nullptr); 354 if (keys == nullptr) { 355 return nullptr; 356 } 357 PyObject* fast = PySequence_Fast(keys, "mapping.keys() are not iterable"); 358 Py_DECREF(keys); 359 return fast; 360} 361 362PY_EXPORT Py_ssize_t PyMapping_Length(PyObject* pyobj) { 363 return objectLength(pyobj); 364} 365 366PY_EXPORT int PyMapping_SetItemString(PyObject* obj, const char* key, 367 PyObject* value) { 368 if (key == nullptr) { 369 nullError(Thread::current()); 370 return -1; 371 } 372 PyObject* key_obj = PyUnicode_FromString(key); 373 if (key_obj == nullptr) { 374 return -1; 375 } 376 int r = PyObject_SetItem(obj, key_obj, value); 377 Py_DECREF(key_obj); 378 return r; 379} 380 381PY_EXPORT Py_ssize_t PyMapping_Size(PyObject* pyobj) { 382 return objectLength(pyobj); 383} 384 385PY_EXPORT PyObject* PyMapping_Values(PyObject* mapping) { 386 if (PyDict_CheckExact(mapping)) { 387 return PyDict_Values(mapping); 388 } 389 PyObject* values = PyObject_CallMethod(mapping, "values", nullptr); 390 if (values == nullptr) { 391 return nullptr; 392 } 393 PyObject* fast = PySequence_Fast(values, "mapping.values() are not iterable"); 394 Py_DECREF(values); 395 return fast; 396} 397 398// Number Protocol 399 400PY_EXPORT PyObject* PyNumber_Absolute(PyObject* obj) { 401 return doUnaryOp(ID(abs), obj); 402} 403 404static PyObject* smallIntAdd(PyObject* left, PyObject* right) { 405 RawObject left_obj = ApiHandle::asObject(ApiHandle::fromPyObject(left)); 406 RawObject right_obj = ApiHandle::asObject(ApiHandle::fromPyObject(right)); 407 if (left_obj.isSmallInt() && right_obj.isSmallInt()) { 408 Runtime* runtime = Thread::current()->runtime(); 409 return ApiHandle::newReference( 410 runtime, runtime->newInt(SmallInt::cast(left_obj).value() + 411 SmallInt::cast(right_obj).value())); 412 } 413 return nullptr; 414} 415 416PY_EXPORT PyObject* PyNumber_Add(PyObject* left, PyObject* right) { 417 PyObject* result = smallIntAdd(left, right); 418 if (result != nullptr) { 419 // Fast path: smallint + smallint. 420 return result; 421 } 422 return doBinaryOp(ID(add), left, right); 423} 424 425PY_EXPORT PyObject* PyNumber_And(PyObject* left, PyObject* right) { 426 return doBinaryOp(ID(and_), left, right); 427} 428 429PY_EXPORT Py_ssize_t PyNumber_AsSsize_t(PyObject* obj, PyObject* overflow_err) { 430 Thread* thread = Thread::current(); 431 if (obj == nullptr) { 432 nullError(thread); 433 return -1; 434 } 435 HandleScope scope(thread); 436 Object index(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 437 Object num(&scope, intFromIndex(thread, index)); 438 if (num.isError()) return -1; 439 Int number(&scope, intUnderlying(*num)); 440 if (overflow_err == nullptr || number.numDigits() == 1) { 441 // Overflows should be clipped, or value is already in range. 442 return number.asWordSaturated(); 443 } 444 // Value overflows, raise an exception. 445 thread->setPendingExceptionType( 446 ApiHandle::asObject(ApiHandle::fromPyObject(overflow_err))); 447 thread->setPendingExceptionValue(thread->runtime()->newStrFromFmt( 448 "cannot fit '%T' into an index-sized integer", &index)); 449 return -1; 450} 451 452PY_EXPORT int PyNumber_Check(PyObject* obj) { 453 if (obj == nullptr) { 454 return false; 455 } 456 457 Thread* thread = Thread::current(); 458 HandleScope scope(thread); 459 Object num(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 460 Type type(&scope, thread->runtime()->typeOf(*num)); 461 if (!typeLookupInMroById(thread, *type, ID(__int__)).isErrorNotFound()) { 462 return true; 463 } 464 if (!typeLookupInMroById(thread, *type, ID(__float__)).isErrorNotFound()) { 465 return true; 466 } 467 return false; 468} 469 470PY_EXPORT PyObject* PyNumber_Divmod(PyObject* left, PyObject* right) { 471 return doBinaryOp(ID(divmod), left, right); 472} 473 474PY_EXPORT PyObject* PyNumber_Float(PyObject* obj) { 475 Thread* thread = Thread::current(); 476 if (obj == nullptr) { 477 return nullError(thread); 478 } 479 HandleScope scope(thread); 480 Object object(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 481 Object flt(&scope, thread->invokeFunction1(ID(builtins), ID(float), object)); 482 return flt.isError() ? nullptr 483 : ApiHandle::newReference(thread->runtime(), *flt); 484} 485 486PY_EXPORT PyObject* PyNumber_FloorDivide(PyObject* left, PyObject* right) { 487 return doBinaryOp(ID(floordiv), left, right); 488} 489 490PY_EXPORT PyObject* PyNumber_Index(PyObject* item) { 491 Thread* thread = Thread::current(); 492 if (item == nullptr) { 493 return nullError(thread); 494 } 495 496 HandleScope scope(thread); 497 Object obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(item))); 498 Object index(&scope, intFromIndex(thread, obj)); 499 return index.isError() ? nullptr 500 : ApiHandle::newReference(thread->runtime(), *index); 501} 502 503PY_EXPORT PyObject* PyNumber_InPlaceAdd(PyObject* left, PyObject* right) { 504 PyObject* result = smallIntAdd(left, right); 505 if (result != nullptr) { 506 // Fast path: smallint + smallint. 507 // In case operands are SmallInts, InPlaceAdd doesn't mutate them. 508 return result; 509 } 510 return doBinaryOp(ID(iadd), left, right); 511} 512 513PY_EXPORT PyObject* PyNumber_InPlaceAnd(PyObject* left, PyObject* right) { 514 return doBinaryOp(ID(iand), left, right); 515} 516 517PY_EXPORT PyObject* PyNumber_InPlaceFloorDivide(PyObject* left, 518 PyObject* right) { 519 return doBinaryOp(ID(ifloordiv), left, right); 520} 521 522PY_EXPORT PyObject* PyNumber_InPlaceLshift(PyObject* left, PyObject* right) { 523 return doBinaryOp(ID(ilshift), left, right); 524} 525 526PY_EXPORT PyObject* PyNumber_InPlaceMatrixMultiply(PyObject* left, 527 PyObject* right) { 528 return doBinaryOp(ID(imatmul), left, right); 529} 530 531PY_EXPORT PyObject* PyNumber_InPlaceMultiply(PyObject* left, PyObject* right) { 532 return doBinaryOp(ID(imul), left, right); 533} 534 535PY_EXPORT PyObject* PyNumber_InPlaceOr(PyObject* left, PyObject* right) { 536 return doBinaryOp(ID(ior), left, right); 537} 538 539PY_EXPORT PyObject* PyNumber_InPlacePower(PyObject* base, PyObject* exponent, 540 PyObject* divisor) { 541 if (divisor == Py_None) { 542 return doBinaryOp(ID(ipow), base, exponent); 543 } 544 UNIMPLEMENTED("ipow(base, exponent, divisor)"); 545} 546 547PY_EXPORT PyObject* PyNumber_InPlaceRemainder(PyObject* left, PyObject* right) { 548 return doBinaryOp(ID(imod), left, right); 549} 550 551PY_EXPORT PyObject* PyNumber_InPlaceRshift(PyObject* left, PyObject* right) { 552 return doBinaryOp(ID(irshift), left, right); 553} 554 555PY_EXPORT PyObject* PyNumber_InPlaceSubtract(PyObject* left, PyObject* right) { 556 return doBinaryOp(ID(isub), left, right); 557} 558 559PY_EXPORT PyObject* PyNumber_InPlaceTrueDivide(PyObject* left, 560 PyObject* right) { 561 return doBinaryOp(ID(itruediv), left, right); 562} 563 564PY_EXPORT PyObject* PyNumber_InPlaceXor(PyObject* left, PyObject* right) { 565 return doBinaryOp(ID(ixor), left, right); 566} 567 568PY_EXPORT PyObject* PyNumber_Invert(PyObject* pyobj) { 569 return doUnaryOp(ID(invert), pyobj); 570} 571 572PY_EXPORT PyObject* PyNumber_Long(PyObject* obj) { 573 Thread* thread = Thread::current(); 574 if (obj == nullptr) { 575 return nullError(thread); 576 } 577 HandleScope scope(thread); 578 Object object(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 579 Object result(&scope, thread->invokeFunction1(ID(builtins), ID(int), object)); 580 if (result.isError()) { 581 return nullptr; 582 } 583 return ApiHandle::newReference(thread->runtime(), *result); 584} 585 586PY_EXPORT PyObject* PyNumber_Lshift(PyObject* left, PyObject* right) { 587 return doBinaryOp(ID(lshift), left, right); 588} 589 590PY_EXPORT PyObject* PyNumber_MatrixMultiply(PyObject* left, PyObject* right) { 591 return doBinaryOp(ID(matmul), left, right); 592} 593 594PY_EXPORT PyObject* PyNumber_Multiply(PyObject* left, PyObject* right) { 595 return doBinaryOp(ID(mul), left, right); 596} 597 598PY_EXPORT PyObject* PyNumber_Negative(PyObject* pyobj) { 599 return doUnaryOp(ID(neg), pyobj); 600} 601 602PY_EXPORT PyObject* PyNumber_Or(PyObject* left, PyObject* right) { 603 return doBinaryOp(ID(or_), left, right); 604} 605 606PY_EXPORT PyObject* PyNumber_Positive(PyObject* pyobj) { 607 return doUnaryOp(ID(pos), pyobj); 608} 609 610PY_EXPORT PyObject* PyNumber_Power(PyObject* base, PyObject* exponent, 611 PyObject* divisor) { 612 if (divisor == Py_None) { 613 return doBinaryOp(ID(pow), base, exponent); 614 } 615 UNIMPLEMENTED("pow(base, exponent, divisor)"); 616} 617 618PY_EXPORT PyObject* PyNumber_Remainder(PyObject* left, PyObject* right) { 619 return doBinaryOp(ID(mod), left, right); 620} 621 622PY_EXPORT PyObject* PyNumber_Rshift(PyObject* left, PyObject* right) { 623 return doBinaryOp(ID(rshift), left, right); 624} 625 626PY_EXPORT PyObject* PyNumber_Subtract(PyObject* left, PyObject* right) { 627 return doBinaryOp(ID(sub), left, right); 628} 629 630PY_EXPORT PyObject* PyNumber_ToBase(PyObject* n, int base) { 631 Thread* thread = Thread::current(); 632 HandleScope scope(thread); 633 Object n_object(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(n))); 634 n_object = intFromIndex(thread, n_object); 635 if (n_object.isError()) { 636 return nullptr; 637 } 638 Int number(&scope, intUnderlying(*n_object)); 639 Object formatted(&scope, NoneType::object()); 640 switch (base) { 641 case 2: 642 formatted = formatIntBinarySimple(thread, number); 643 break; 644 case 8: 645 formatted = formatIntOctalSimple(thread, number); 646 break; 647 case 10: 648 formatted = formatIntDecimalSimple(thread, number); 649 break; 650 case 16: 651 formatted = formatIntHexadecimalSimple(thread, number); 652 break; 653 default: 654 thread->raiseWithFmt(LayoutId::kSystemError, 655 "PyNumber_ToBase: base must be 2, 8, 10 or 16"); 656 return nullptr; 657 } 658 return ApiHandle::newReference(thread->runtime(), *formatted); 659} 660 661PY_EXPORT PyObject* PyNumber_TrueDivide(PyObject* left, PyObject* right) { 662 return doBinaryOp(ID(truediv), left, right); 663} 664 665PY_EXPORT PyObject* PyNumber_Xor(PyObject* left, PyObject* right) { 666 return doBinaryOp(ID(xor), left, right); 667} 668 669// Object Protocol 670 671PY_EXPORT int PyObject_AsCharBuffer(PyObject* /* j */, 672 const char** /* buffer */, 673 Py_ssize_t* /* n */) { 674 UNIMPLEMENTED("PyObject_AsCharBuffer"); 675} 676 677PY_EXPORT int PyObject_AsReadBuffer(PyObject* /* j */, 678 const void** /* buffer */, 679 Py_ssize_t* /* n */) { 680 UNIMPLEMENTED("PyObject_AsReadBuffer"); 681} 682 683PY_EXPORT int PyObject_AsWriteBuffer(PyObject* /* j */, void** /* buffer */, 684 Py_ssize_t* /* n */) { 685 UNIMPLEMENTED("PyObject_AsWriteBuffer"); 686} 687 688PY_EXPORT PyObject* PyObject_Call(PyObject* callable, PyObject* args, 689 PyObject* kwargs) { 690 Thread* thread = Thread::current(); 691 if (callable == nullptr) { 692 return nullError(thread); 693 } 694 695 DCHECK(!thread->hasPendingException(), 696 "may accidentally clear pending exception"); 697 698 HandleScope scope(thread); 699 Runtime* runtime = thread->runtime(); 700 Object callable_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(callable))); 701 Type callable_type(&scope, runtime->typeOf(*callable_obj)); 702 if (typeHasSlots(callable_type)) { 703 // Attempt to call tp_call directly for native types to avoid 704 // recursive interpreter calls. 705 void* tp_call_value = typeSlotAt(callable_type, Py_tp_call); 706 if (tp_call_value != nullptr) { 707 ternaryfunc call = reinterpret_cast<ternaryfunc>(tp_call_value); 708 return call(callable, args, kwargs); 709 } 710 } 711 thread->stackPush(*callable_obj); 712 713 Object args_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(args))); 714 DCHECK(runtime->isInstanceOfTuple(*args_obj), "args mut be a tuple"); 715 thread->stackPush(*args_obj); 716 717 word flags = 0; 718 if (kwargs != nullptr) { 719 Object kwargs_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(kwargs))); 720 DCHECK(thread->runtime()->isInstanceOfDict(*kwargs_obj), 721 "kwargs must be a dict"); 722 thread->stackPush(*kwargs_obj); 723 flags |= CallFunctionExFlag::VAR_KEYWORDS; 724 } 725 726 // TODO(T30925218): Protect against native stack overflow. 727 728 Object result(&scope, Interpreter::callEx(thread, flags)); 729 if (result.isError()) return nullptr; 730 return ApiHandle::newReference(runtime, *result); 731} 732 733static PyObject* makeInterpreterCall(Thread* thread, word nargs) { 734 HandleScope scope(thread); 735 Object result(&scope, Interpreter::call(thread, nargs)); 736 if (result.isError()) return nullptr; 737 return ApiHandle::newReference(thread->runtime(), *result); 738} 739 740static PyObject* callWithVarArgs(Thread* thread, const Object& callable, 741 const char* format, std::va_list* va, 742 int build_value_flags) { 743 thread->stackPush(*callable); 744 745 if (format == nullptr) { 746 return makeInterpreterCall(thread, /*nargs=*/0); 747 } 748 749 word nargs = countFormat(format, '\0'); 750 if (nargs == 1) { 751 PyObject* value = makeValueFromFormat(&format, va, build_value_flags); 752 if (!PyTuple_Check(value)) { 753 thread->stackPush(ApiHandle::stealReference(value)); 754 return makeInterpreterCall(thread, nargs); 755 } 756 // If the only argument passed is a tuple, splat the tuple as positional 757 // arguments 758 nargs = PyTuple_Size(value); 759 for (word i = 0; i < nargs; i++) { 760 PyObject* arg = PyTuple_GetItem(value, i); 761 thread->stackPush(ApiHandle::asObject(ApiHandle::fromPyObject(arg))); 762 } 763 return makeInterpreterCall(thread, nargs); 764 } 765 for (const char* f = format; *f != '\0';) { 766 PyObject* value = makeValueFromFormat(&f, va, build_value_flags); 767 if (value == nullptr) break; 768 thread->stackPush(ApiHandle::stealReference(value)); 769 } 770 771 return makeInterpreterCall(thread, nargs); 772} 773 774static PyObject* callFunction(PyObject* callable, const char* format, 775 std::va_list* va) { 776 Thread* thread = Thread::current(); 777 if (callable == nullptr) { 778 return nullError(thread); 779 } 780 781 HandleScope scope(thread); 782 Object callable_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(callable))); 783 PyObject* result = callWithVarArgs(thread, callable_obj, format, va, 0); 784 return result; 785} 786 787PY_EXPORT PyObject* PyObject_CallFunction(PyObject* callable, 788 const char* format, ...) { 789 va_list va; 790 va_start(va, format); 791 PyObject* result = callFunction(callable, format, &va); 792 va_end(va); 793 return result; 794} 795 796PY_EXPORT PyObject* PyEval_CallFunction(PyObject* callable, const char* format, 797 ...) { 798 va_list va; 799 va_start(va, format); 800 PyObject* result = callFunction(callable, format, &va); 801 va_end(va); 802 return result; 803} 804 805static PyObject* callWithObjArgs(Thread* thread, const Object& callable, 806 std::va_list va) { 807 DCHECK(!thread->hasPendingException(), 808 "may accidentally clear pending exception"); 809 810 thread->stackPush(*callable); 811 word nargs = 0; 812 for (PyObject* arg; (arg = va_arg(va, PyObject*)) != nullptr; nargs++) { 813 thread->stackPush(ApiHandle::asObject(ApiHandle::fromPyObject(arg))); 814 } 815 816 // TODO(T30925218): CPython tracks recursive calls before calling the function 817 // through Py_EnterRecursiveCall, and we should probably do the same 818 HandleScope scope(thread); 819 Object result(&scope, Interpreter::call(thread, nargs)); 820 if (result.isError()) return nullptr; 821 return ApiHandle::newReference(thread->runtime(), *result); 822} 823 824PY_EXPORT PyObject* PyObject_CallFunctionObjArgs(PyObject* callable, ...) { 825 Thread* thread = Thread::current(); 826 if (callable == nullptr) { 827 return nullError(thread); 828 } 829 HandleScope scope(thread); 830 Object callable_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(callable))); 831 va_list va; 832 va_start(va, callable); 833 PyObject* result = callWithObjArgs(thread, callable_obj, va); 834 va_end(va); 835 return result; 836} 837 838PY_EXPORT PyObject* _PyObject_CallFunction_SizeT(PyObject* callable, 839 const char* format, ...) { 840 Thread* thread = Thread::current(); 841 if (callable == nullptr) { 842 return nullError(thread); 843 } 844 845 HandleScope scope(thread); 846 Object callable_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(callable))); 847 va_list va; 848 va_start(va, format); 849 PyObject* result = 850 callWithVarArgs(thread, callable_obj, format, &va, kFlagSizeT); 851 va_end(va); 852 return result; 853} 854 855static PyObject* callMethod(PyObject* pyobj, const char* name, 856 const char* format, std::va_list* va) { 857 Thread* thread = Thread::current(); 858 if (pyobj == nullptr) { 859 return nullError(thread); 860 } 861 862 HandleScope scope(thread); 863 Runtime* runtime = thread->runtime(); 864 Object obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(pyobj))); 865 Object callable(&scope, runtime->attributeAtByCStr(thread, obj, name)); 866 if (callable.isError()) return nullptr; 867 868 PyObject* result = callWithVarArgs(thread, callable, format, va, 0); 869 return result; 870} 871 872PY_EXPORT PyObject* PyObject_CallMethod(PyObject* pyobj, const char* name, 873 const char* format, ...) { 874 va_list va; 875 va_start(va, format); 876 PyObject* result = callMethod(pyobj, name, format, &va); 877 va_end(va); 878 return result; 879} 880 881PY_EXPORT PyObject* PyEval_CallMethod(PyObject* pyobj, const char* name, 882 const char* format, ...) { 883 va_list va; 884 va_start(va, format); 885 PyObject* result = callMethod(pyobj, name, format, &va); 886 va_end(va); 887 return result; 888} 889 890PY_EXPORT PyObject* PyObject_CallMethodObjArgs(PyObject* pyobj, 891 PyObject* py_method_name, ...) { 892 Thread* thread = Thread::current(); 893 if (pyobj == nullptr || py_method_name == nullptr) { 894 return nullError(thread); 895 } 896 HandleScope scope(thread); 897 Object obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(pyobj))); 898 Object name(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(py_method_name))); 899 name = attributeName(thread, name); 900 if (name.isErrorException()) return nullptr; 901 Object callable(&scope, thread->runtime()->attributeAt(thread, obj, name)); 902 if (callable.isError()) return nullptr; 903 904 va_list va; 905 va_start(va, py_method_name); 906 PyObject* result = callWithObjArgs(thread, callable, va); 907 va_end(va); 908 return result; 909} 910 911PY_EXPORT PyObject* _PyObject_CallMethod_SizeT(PyObject* pyobj, 912 const char* name, 913 const char* format, ...) { 914 Thread* thread = Thread::current(); 915 if (pyobj == nullptr) { 916 return nullError(thread); 917 } 918 919 HandleScope scope(thread); 920 Runtime* runtime = thread->runtime(); 921 Object obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(pyobj))); 922 Object callable(&scope, runtime->attributeAtByCStr(thread, obj, name)); 923 if (callable.isError()) return nullptr; 924 925 va_list va; 926 va_start(va, format); 927 PyObject* result = callWithVarArgs(thread, callable, format, &va, kFlagSizeT); 928 va_end(va); 929 return result; 930} 931 932PY_EXPORT PyObject* PyObject_CallObject(PyObject* callable, PyObject* args) { 933 Thread* thread = Thread::current(); 934 if (callable == nullptr) { 935 return nullError(thread); 936 } 937 DCHECK(!thread->hasPendingException(), 938 "may accidentally clear pending exception"); 939 HandleScope scope(thread); 940 thread->stackPush(ApiHandle::asObject(ApiHandle::fromPyObject(callable))); 941 Object result(&scope, NoneType::object()); 942 Runtime* runtime = thread->runtime(); 943 if (args != nullptr) { 944 Object args_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(args))); 945 if (!runtime->isInstanceOfTuple(*args_obj)) { 946 thread->raiseWithFmt(LayoutId::kTypeError, 947 "argument list must be a tuple"); 948 return nullptr; 949 } 950 thread->stackPush(*args_obj); 951 // TODO(T30925218): Protect against native stack overflow. 952 result = Interpreter::callEx(thread, 0); 953 } else { 954 result = Interpreter::call(thread, 0); 955 } 956 if (result.isError()) return nullptr; 957 return ApiHandle::newReference(runtime, *result); 958} 959 960PY_EXPORT int PyObject_CheckBuffer_Func(PyObject* pyobj) { 961 // TODO(T38246066): Collapse all the cases into Runtime::isByteslike and make 962 // this function a small wrapper around that 963 Thread* thread = Thread::current(); 964 HandleScope scope(thread); 965 Object obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(pyobj))); 966 Runtime* runtime = thread->runtime(); 967 if (runtime->isInstanceOfBytes(*obj) || 968 runtime->isInstanceOfBytearray(*obj)) { 969 return true; 970 } 971 if (runtime->isByteslike(*obj)) { 972 UNIMPLEMENTED("PyObject_CheckBuffer with builtin byteslike"); 973 } 974 Type type(&scope, runtime->typeOf(*obj)); 975 if (type.isBuiltin()) return false; 976 if (!typeHasSlots(type)) return false; 977 return typeSlotAt(type, Py_bf_getbuffer) != nullptr; 978} 979 980PY_EXPORT int PyObject_CheckReadBuffer(PyObject* /* j */) { 981 UNIMPLEMENTED("PyObject_CheckReadBuffer"); 982} 983 984PY_EXPORT int PyObject_DelItem(PyObject* obj, PyObject* key) { 985 Thread* thread = Thread::current(); 986 if (obj == nullptr || key == nullptr) { 987 nullError(thread); 988 return -1; 989 } 990 HandleScope scope(thread); 991 Object object(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 992 Object key_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(key))); 993 Object result(&scope, objectDelItem(thread, object, key_obj)); 994 if (result.isErrorException()) { 995 return -1; 996 } 997 return 0; 998} 999 1000PY_EXPORT int PyObject_DelItemString(PyObject* obj, const char* key) { 1001 Thread* thread = Thread::current(); 1002 if (obj == nullptr || key == nullptr) { 1003 nullError(thread); 1004 return -1; 1005 } 1006 HandleScope scope(thread); 1007 Runtime* runtime = thread->runtime(); 1008 Object object(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 1009 Object key_obj(&scope, runtime->newStrFromCStr(key)); 1010 Object result(&scope, objectDelItem(thread, object, key_obj)); 1011 if (result.isErrorException()) { 1012 return -1; 1013 } 1014 return 0; 1015} 1016 1017PY_EXPORT PyObject* _PyObject_CallNoArg(PyObject* callable) { 1018 return _PyObject_FastCall(callable, nullptr, 0); 1019} 1020 1021PY_EXPORT PyObject* _PyObject_FastCall(PyObject* callable, PyObject** pyargs, 1022 Py_ssize_t n_args) { 1023 return _PyObject_FastCallDict(callable, pyargs, n_args, nullptr); 1024} 1025 1026PY_EXPORT PyObject* _PyObject_FastCallDict(PyObject* callable, 1027 PyObject** pyargs, Py_ssize_t n_args, 1028 PyObject* kwargs) { 1029 DCHECK(callable != nullptr, "callable must not be nullptr"); 1030 Thread* thread = Thread::current(); 1031 DCHECK(!thread->hasPendingException(), 1032 "may accidentally clear pending exception"); 1033 DCHECK(n_args >= 0, "n_args must not be negative"); 1034 1035 HandleScope scope(thread); 1036 thread->stackPush(ApiHandle::asObject(ApiHandle::fromPyObject(callable))); 1037 DCHECK(n_args == 0 || pyargs != nullptr, "Args array must not be nullptr"); 1038 Object result(&scope, NoneType::object()); 1039 Runtime* runtime = thread->runtime(); 1040 if (kwargs != nullptr) { 1041 Object args_obj(&scope, NoneType::object()); 1042 if (n_args > 0) { 1043 MutableTuple args(&scope, runtime->newMutableTuple(n_args)); 1044 for (Py_ssize_t i = 0; i < n_args; i++) { 1045 args.atPut(i, ApiHandle::asObject(ApiHandle::fromPyObject(pyargs[i]))); 1046 } 1047 args_obj = args.becomeImmutable(); 1048 } else { 1049 args_obj = runtime->emptyTuple(); 1050 } 1051 thread->stackPush(*args_obj); 1052 Object kwargs_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(kwargs))); 1053 DCHECK(runtime->isInstanceOfDict(*kwargs_obj), "kwargs must be a dict"); 1054 thread->stackPush(*kwargs_obj); 1055 // TODO(T30925218): Protect against native stack overflow. 1056 result = Interpreter::callEx(thread, CallFunctionExFlag::VAR_KEYWORDS); 1057 } else { 1058 for (Py_ssize_t i = 0; i < n_args; i++) { 1059 thread->stackPush(ApiHandle::asObject(ApiHandle::fromPyObject(pyargs[i]))); 1060 } 1061 // TODO(T30925218): Protect against native stack overflow. 1062 result = Interpreter::call(thread, n_args); 1063 } 1064 if (result.isError()) return nullptr; 1065 return ApiHandle::newReference(runtime, *result); 1066} 1067 1068PY_EXPORT PyObject* _PyObject_FastCallKeywords(PyObject* /* e */, 1069 PyObject** /* k */, 1070 Py_ssize_t /* s */, 1071 PyObject* /* s */) { 1072 UNIMPLEMENTED("_PyObject_FastCallKeywords"); 1073} 1074 1075PY_EXPORT PyObject* PyObject_Format(PyObject* obj, PyObject* format_spec) { 1076 DCHECK(obj != nullptr, "obj should not be null"); 1077 Thread* thread = Thread::current(); 1078 HandleScope scope(thread); 1079 Object object(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 1080 Object format_spec_obj( 1081 &scope, format_spec == nullptr 1082 ? Str::empty() 1083 : ApiHandle::asObject(ApiHandle::fromPyObject(format_spec))); 1084 Object result(&scope, thread->invokeFunction2(ID(builtins), ID(format), 1085 object, format_spec_obj)); 1086 if (result.isError()) { 1087 return nullptr; 1088 } 1089 return ApiHandle::newReference(thread->runtime(), *result); 1090} 1091 1092PY_EXPORT int PyObject_GetBuffer(PyObject* obj, Py_buffer* view, int flags) { 1093 DCHECK(obj != nullptr, "obj must not be nullptr"); 1094 1095 Thread* thread = Thread::current(); 1096 ApiHandle* handle = ApiHandle::fromPyObject(obj); 1097 HandleScope scope(thread); 1098 Object obj_obj(&scope, ApiHandle::asObject(handle)); 1099 Runtime* runtime = thread->runtime(); 1100 if (runtime->isInstanceOfBytes(*obj_obj)) { 1101 Bytes bytes(&scope, bytesUnderlying(*obj_obj)); 1102 char* buffer = bytesAsString(runtime, handle, bytes); 1103 if (buffer == nullptr) { 1104 return -1; 1105 } 1106 return PyBuffer_FillInfo(view, handle, buffer, bytes.length(), 1107 /*readonly=*/1, flags); 1108 } 1109 if (runtime->isInstanceOfBytearray(*obj_obj)) { 1110 // TODO(T54579154): This creates a copy of the object which does not stay 1111 // in sync. We should have a way to pin the memory to allow direct access. 1112 Bytearray array(&scope, *obj_obj); 1113 char* buffer = bytearrayAsString(runtime, handle, array); 1114 if (buffer == nullptr) { 1115 return -1; 1116 } 1117 return PyBuffer_FillInfo(view, handle, buffer, array.numItems(), 1118 /*readonly=*/1, flags); 1119 } 1120 if (obj_obj.isMemoryView()) { 1121 MemoryView memoryview(&scope, *obj_obj); 1122 Object buffer(&scope, memoryview.buffer()); 1123 // A MemoryView's underlying buffer is either a bytes object or a raw 1124 // pointer. 1125 if (runtime->isInstanceOfBytes(*buffer)) { 1126 Bytes bytes(&scope, bytesUnderlying(*obj_obj)); 1127 // We use the memoryview handle's cache directly to store the buffer. 1128 char* underlying_buffer = bytesAsString(runtime, handle, bytes); 1129 if (underlying_buffer == nullptr) { 1130 return -1; 1131 } 1132 return PyBuffer_FillInfo(view, handle, underlying_buffer, 1133 memoryview.length(), 1134 /*readonly=*/1, flags); 1135 } 1136 1137 Pointer underlying_pointer(&scope, *buffer); 1138 char* underlying_buffer = 1139 reinterpret_cast<char*>(underlying_pointer.cptr()); 1140 return PyBuffer_FillInfo(view, handle, underlying_buffer, 1141 memoryview.length(), 1142 /*readonly=*/1, flags); 1143 } 1144 if (runtime->isInstanceOfArray(*obj_obj)) { 1145 Array array(&scope, *obj_obj); 1146 word length = arrayByteLength(*array); 1147 // We create a copy of the array's buffer and place it in the API handle's 1148 // cache to ensure it gets reaped. 1149 if (void* cache = ApiHandle::cache(runtime, handle)) { 1150 std::free(cache); 1151 } 1152 byte* buffer = static_cast<byte*>(std::malloc(length + 1)); 1153 if (buffer == nullptr) { 1154 return -1; 1155 } 1156 MutableBytes::cast(array.buffer()).copyTo(buffer, length); 1157 ApiHandle::setCache(runtime, handle, buffer); 1158 1159 return PyBuffer_FillInfo(view, handle, reinterpret_cast<char*>(buffer), 1160 length, 1161 /*readonly=*/1, flags); 1162 } 1163 // We must be dealing with a buffer protocol or an incompatible type. 1164 Type type(&scope, runtime->typeOf(*obj_obj)); 1165 if (type.isBuiltin()) { 1166 raiseBufferError(thread, obj_obj); 1167 return -1; 1168 } 1169 if (!typeHasSlots(type)) { 1170 raiseBufferError(thread, obj_obj); 1171 return -1; 1172 } 1173 void* slot = typeSlotAt(type, Py_bf_getbuffer); 1174 if (slot == nullptr) { 1175 raiseBufferError(thread, obj_obj); 1176 return -1; 1177 } 1178 return reinterpret_cast<getbufferproc>(slot)(handle, view, flags); 1179} 1180 1181PY_EXPORT PyObject* PyObject_GetItem(PyObject* obj, PyObject* key) { 1182 Thread* thread = Thread::current(); 1183 if (obj == nullptr || key == nullptr) { 1184 return nullError(thread); 1185 } 1186 HandleScope scope(thread); 1187 Object object(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 1188 Object key_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(key))); 1189 Object result(&scope, objectGetItem(thread, object, key_obj)); 1190 if (result.isErrorException()) return nullptr; 1191 return ApiHandle::newReference(thread->runtime(), *result); 1192} 1193 1194PY_EXPORT PyObject* PyObject_GetIter(PyObject* pyobj) { 1195 Thread* thread = Thread::current(); 1196 HandleScope scope(thread); 1197 Object obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(pyobj))); 1198 Object result(&scope, Interpreter::createIterator(thread, obj)); 1199 if (result.isError()) { 1200 return nullptr; 1201 } 1202 return ApiHandle::newReference(thread->runtime(), *result); 1203} 1204 1205PY_EXPORT int PyObject_IsInstance(PyObject* instance, PyObject* cls) { 1206 Thread* thread = Thread::current(); 1207 HandleScope scope(thread); 1208 Object object(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(instance))); 1209 Object classinfo(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(cls))); 1210 Object result(&scope, thread->invokeFunction2(ID(builtins), ID(isinstance), 1211 object, classinfo)); 1212 return result.isError() ? -1 : Bool::cast(*result).value(); 1213} 1214 1215PY_EXPORT int PyObject_IsSubclass(PyObject* derived, PyObject* cls) { 1216 Thread* thread = Thread::current(); 1217 HandleScope scope(thread); 1218 Object subclass(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(derived))); 1219 Object classinfo(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(cls))); 1220 Object result(&scope, thread->invokeFunction2(ID(builtins), ID(issubclass), 1221 subclass, classinfo)); 1222 return result.isError() ? -1 : Bool::cast(*result).value(); 1223} 1224 1225PY_EXPORT Py_ssize_t PyObject_Length(PyObject* pyobj) { 1226 return objectLength(pyobj); 1227} 1228 1229PY_EXPORT Py_ssize_t PyObject_LengthHint(PyObject* obj, 1230 Py_ssize_t default_value) { 1231 Py_ssize_t res = objectLength(obj); 1232 Thread* thread = Thread::current(); 1233 Runtime* runtime = thread->runtime(); 1234 HandleScope scope(thread); 1235 if (res < 0 && thread->hasPendingException()) { 1236 Object given_obj(&scope, thread->pendingExceptionType()); 1237 Object exc_obj(&scope, runtime->typeAt(LayoutId::kTypeError)); 1238 if (!givenExceptionMatches(thread, given_obj, exc_obj)) { 1239 return -1; 1240 } 1241 // Catch TypeError when obj does not have __len__. 1242 thread->clearPendingException(); 1243 } else { 1244 return res; 1245 } 1246 1247 Object object(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 1248 Object length_hint(&scope, 1249 thread->invokeMethod1(object, ID(__length_hint__))); 1250 if (length_hint.isErrorNotFound() || length_hint.isNotImplementedType()) { 1251 return default_value; 1252 } 1253 if (length_hint.isError()) { 1254 return -1; 1255 } 1256 if (!thread->runtime()->isInstanceOfInt(*length_hint)) { 1257 thread->raiseWithFmt(LayoutId::kTypeError, 1258 "__length_hint__ must be an integer, not %T", 1259 &length_hint); 1260 return -1; 1261 } 1262 Int index(&scope, intUnderlying(*length_hint)); 1263 if (!index.isSmallInt()) { 1264 thread->raiseWithFmt(LayoutId::kOverflowError, 1265 "cannot fit '%T' into an index-sized integer", 1266 &length_hint); 1267 return -1; 1268 } 1269 if (index.isNegative()) { 1270 thread->raiseWithFmt(LayoutId::kValueError, "__len__() should return >= 0"); 1271 return -1; 1272 } 1273 return index.asWord(); 1274} 1275 1276PY_EXPORT int PyObject_SetItem(PyObject* obj, PyObject* key, PyObject* value) { 1277 Thread* thread = Thread::current(); 1278 if (obj == nullptr || key == nullptr || value == nullptr) { 1279 nullError(thread); 1280 return -1; 1281 } 1282 HandleScope scope(thread); 1283 Object object(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 1284 Object key_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(key))); 1285 Object value_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(value))); 1286 Object result(&scope, objectSetItem(thread, object, key_obj, value_obj)); 1287 return result.isErrorException() ? -1 : 0; 1288} 1289 1290PY_EXPORT Py_ssize_t PyObject_Size(PyObject* pyobj) { 1291 return objectLength(pyobj); 1292} 1293 1294PY_EXPORT PyTypeObject* Py_TYPE_Func(PyObject* pyobj) { 1295 Thread* thread = Thread::current(); 1296 if (pyobj == nullptr) { 1297 nullError(thread); 1298 return nullptr; 1299 } 1300 1301 Runtime* runtime = thread->runtime(); 1302 return reinterpret_cast<PyTypeObject*>(ApiHandle::borrowedReference( 1303 runtime, runtime->typeOf(ApiHandle::asObject(ApiHandle::fromPyObject(pyobj))))); 1304} 1305 1306PY_EXPORT void Py_SET_TYPE_Func(PyObject* obj, PyTypeObject* type) { 1307 DCHECK(obj != nullptr, "obj must be non-null"); 1308 DCHECK(type != nullptr, "type must be non-null"); 1309 Thread* thread = Thread::current(); 1310 HandleScope scope(thread); 1311 Object self(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 1312 Type new_type(&scope, ApiHandle::asObject(ApiHandle::fromPyTypeObject(type))); 1313 Object result(&scope, typeSetDunderClass(thread, self, new_type)); 1314 if (result.isError()) { 1315 UNIMPLEMENTED("unhandled case in __class__ setter"); 1316 } 1317} 1318 1319PY_EXPORT PyObject* PyObject_Type(PyObject* pyobj) { 1320 Thread* thread = Thread::current(); 1321 if (pyobj == nullptr) { 1322 return nullError(thread); 1323 } 1324 1325 Runtime* runtime = thread->runtime(); 1326 return ApiHandle::newReference( 1327 runtime, runtime->typeOf(ApiHandle::asObject(ApiHandle::fromPyObject(pyobj)))); 1328} 1329 1330PY_EXPORT const char* PyObject_TypeName(PyObject* /* obj */) { 1331 UNIMPLEMENTED("PyObject_TypeName"); 1332} 1333 1334// Sequence Protocol 1335 1336PY_EXPORT void _Py_FreeCharPArray(char* const array[]) { 1337 for (Py_ssize_t i = 0; array[i] != nullptr; ++i) { 1338 PyMem_Free(array[i]); 1339 } 1340 PyMem_Free(const_cast<char**>(array)); 1341} 1342 1343PY_EXPORT char* const* _PySequence_BytesToCharpArray(PyObject* self) { 1344 Py_ssize_t argc = PySequence_Size(self); 1345 if (argc < 0) { 1346 DCHECK(argc == -1, "size cannot be negative (-1 denotes an error)"); 1347 return nullptr; 1348 } 1349 1350 if (argc > (kMaxWord / kPointerSize) - 1) { 1351 PyErr_NoMemory(); 1352 return nullptr; 1353 } 1354 1355 char** result = static_cast<char**>(PyMem_Malloc((argc + 1) * kPointerSize)); 1356 if (result == nullptr) { 1357 PyErr_NoMemory(); 1358 return nullptr; 1359 } 1360 1361 for (Py_ssize_t i = 0; i < argc; ++i) { 1362 PyObject* item = PySequence_GetItem(self, i); 1363 if (item == nullptr) { 1364 // NULL terminate before freeing. 1365 result[i] = nullptr; 1366 _Py_FreeCharPArray(result); 1367 return nullptr; 1368 } 1369 char* data; 1370 if (PyBytes_AsStringAndSize(item, &data, nullptr) < 0) { 1371 // NULL terminate before freeing. 1372 result[i] = nullptr; 1373 Py_DECREF(item); 1374 _Py_FreeCharPArray(result); 1375 return nullptr; 1376 } 1377 Py_ssize_t size = PyBytes_GET_SIZE(item) + 1; 1378 result[i] = static_cast<char*>(PyMem_Malloc(size)); 1379 if (result[i] == nullptr) { 1380 PyErr_NoMemory(); 1381 Py_DECREF(item); 1382 _Py_FreeCharPArray(result); 1383 return nullptr; 1384 } 1385 std::memcpy(result[i], data, size); 1386 Py_DECREF(item); 1387 } 1388 1389 result[argc] = nullptr; 1390 return result; 1391} 1392 1393PY_EXPORT int PySequence_Check(PyObject* py_obj) { 1394 Thread* thread = Thread::current(); 1395 HandleScope scope(thread); 1396 Object obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(py_obj))); 1397 return thread->runtime()->isSequence(thread, obj); 1398} 1399 1400PY_EXPORT PyObject* PySequence_Concat(PyObject* left, PyObject* right) { 1401 Thread* thread = Thread::current(); 1402 if (left == nullptr || right == nullptr) { 1403 return nullError(thread); 1404 } 1405 if (!PySequence_Check(left) || !PySequence_Check(right)) { 1406 thread->raiseWithFmt(LayoutId::kTypeError, 1407 "objects cannot be concatenated"); 1408 return nullptr; 1409 } 1410 return PyNumber_Add(left, right); 1411} 1412 1413PY_EXPORT int PySequence_Contains(PyObject* seq, PyObject* obj) { 1414 Thread* thread = Thread::current(); 1415 if (seq == nullptr || obj == nullptr) { 1416 nullError(thread); 1417 return -1; 1418 } 1419 HandleScope scope(thread); 1420 Object seq_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(seq))); 1421 Object object(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 1422 Object result(&scope, thread->invokeFunction2(ID(operator), ID(contains), 1423 seq_obj, object)); 1424 if (result.isError()) { 1425 return -1; 1426 } 1427 return Bool::cast(*result).value() ? 1 : 0; 1428} 1429 1430PY_EXPORT Py_ssize_t PySequence_Count(PyObject* seq, PyObject* obj) { 1431 Thread* thread = Thread::current(); 1432 if (seq == nullptr || obj == nullptr) { 1433 nullError(thread); 1434 return -1; 1435 } 1436 HandleScope scope(thread); 1437 Object seq_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(seq))); 1438 Object object(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 1439 Object result(&scope, thread->invokeFunction2(ID(operator), ID(countOf), 1440 seq_obj, object)); 1441 if (result.isError()) { 1442 return -1; 1443 } 1444 return SmallInt::cast(*result).value(); 1445} 1446 1447PY_EXPORT int PySequence_DelItem(PyObject* seq, Py_ssize_t idx) { 1448 Thread* thread = Thread::current(); 1449 if (seq == nullptr) { 1450 return -1; 1451 } 1452 HandleScope scope(thread); 1453 Object seq_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(seq))); 1454 Object idx_obj(&scope, thread->runtime()->newInt(idx)); 1455 Object result(&scope, 1456 thread->invokeMethod2(seq_obj, ID(__delitem__), idx_obj)); 1457 if (result.isError()) { 1458 return -1; 1459 } 1460 return 0; 1461} 1462 1463static RawObject makeSlice(Thread* thread, Py_ssize_t low, Py_ssize_t high) { 1464 HandleScope scope(thread); 1465 Runtime* runtime = thread->runtime(); 1466 Object start(&scope, runtime->newInt(low)); 1467 Object stop(&scope, runtime->newInt(high)); 1468 Object step(&scope, NoneType::object()); 1469 return runtime->newSlice(start, stop, step); 1470} 1471 1472PY_EXPORT int PySequence_DelSlice(PyObject* seq, Py_ssize_t low, 1473 Py_ssize_t high) { 1474 Thread* thread = Thread::current(); 1475 if (seq == nullptr) { 1476 nullError(thread); 1477 return -1; 1478 } 1479 HandleScope scope(thread); 1480 Object slice(&scope, makeSlice(thread, low, high)); 1481 Object seq_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(seq))); 1482 Object result(&scope, thread->invokeMethod2(seq_obj, ID(__delitem__), slice)); 1483 if (result.isError()) { 1484 if (result.isErrorNotFound()) { 1485 thread->raiseWithFmt(LayoutId::kTypeError, 1486 "object does not support slice deletion"); 1487 } 1488 return -1; 1489 } 1490 return 0; 1491} 1492 1493PY_EXPORT PyObject* PySequence_Fast(PyObject* seq, const char* msg) { 1494 Thread* thread = Thread::current(); 1495 if (seq == nullptr) { 1496 return nullError(thread); 1497 } 1498 HandleScope scope(thread); 1499 Object seq_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(seq))); 1500 1501 Runtime* runtime = thread->runtime(); 1502 if (seq_obj.isList() || seq_obj.isTuple()) { 1503 return ApiHandle::newReference(runtime, *seq_obj); 1504 } 1505 Object iter(&scope, Interpreter::createIterator(thread, seq_obj)); 1506 if (iter.isError()) { 1507 Object given(&scope, thread->pendingExceptionType()); 1508 Object exc(&scope, runtime->typeAt(LayoutId::kTypeError)); 1509 if (givenExceptionMatches(thread, given, exc)) { 1510 thread->setPendingExceptionValue(runtime->newStrFromCStr(msg)); 1511 } 1512 return nullptr; 1513 } 1514 1515 Object result(&scope, 1516 thread->invokeFunction1(ID(builtins), ID(list), seq_obj)); 1517 if (result.isError()) { 1518 return nullptr; 1519 } 1520 return ApiHandle::newReference(runtime, *result); 1521} 1522 1523PY_EXPORT Py_ssize_t PySequence_Fast_GET_SIZE_Func(PyObject* seq) { 1524 return PyList_Check(seq) ? PyList_GET_SIZE(seq) : PyTuple_GET_SIZE(seq); 1525} 1526 1527PY_EXPORT PyObject* PySequence_Fast_GET_ITEM_Func(PyObject* seq, 1528 Py_ssize_t idx) { 1529 return PyList_Check(seq) ? PyList_GET_ITEM(seq, idx) 1530 : PyTuple_GET_ITEM(seq, idx); 1531} 1532 1533PY_EXPORT PyObject* PySequence_GetItem(PyObject* seq, Py_ssize_t idx) { 1534 Thread* thread = Thread::current(); 1535 if (seq == nullptr) { 1536 return nullError(thread); 1537 } 1538 HandleScope scope(thread); 1539 Runtime* runtime = thread->runtime(); 1540 Object seq_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(seq))); 1541 if (seq_obj.isTuple()) { 1542 // Fast path: return `tuple`'s element directly. 1543 RawTuple tuple = Tuple::cast(*seq_obj); 1544 if (0 <= idx && idx < tuple.length()) { 1545 return ApiHandle::newReference(runtime, tuple.at(idx)); 1546 } 1547 } else if (seq_obj.isList()) { 1548 // Fast path: return `list`'s element directly. 1549 RawList list = List::cast(*seq_obj); 1550 if (0 <= idx && idx < list.numItems()) { 1551 return ApiHandle::newReference(runtime, list.at(idx)); 1552 } 1553 } 1554 Object idx_obj(&scope, thread->runtime()->newInt(idx)); 1555 Object result(&scope, 1556 thread->invokeMethod2(seq_obj, ID(__getitem__), idx_obj)); 1557 if (result.isError()) { 1558 if (result.isErrorNotFound()) { 1559 thread->raiseWithFmt(LayoutId::kTypeError, "could not call __getitem__"); 1560 } 1561 return nullptr; 1562 } 1563 return ApiHandle::newReference(runtime, *result); 1564} 1565 1566PY_EXPORT PyObject* PySequence_ITEM_Func(PyObject* seq, Py_ssize_t i) { 1567 DCHECK(seq != nullptr, "sequence must not be nullptr"); 1568 DCHECK(i >= 0, "index can't be negative"); 1569 Thread* thread = Thread::current(); 1570 HandleScope scope(thread); 1571 Object seq_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(seq))); 1572 Runtime* runtime = thread->runtime(); 1573 DCHECK(runtime->isSequence(thread, seq_obj), "seq must be a sequence"); 1574 Object idx(&scope, runtime->newInt(i)); 1575 Object result(&scope, thread->invokeMethod2(seq_obj, ID(__getitem__), idx)); 1576 if (result.isError()) return nullptr; 1577 return ApiHandle::newReference(runtime, *result); 1578} 1579 1580PY_EXPORT PyObject* PySequence_GetSlice(PyObject* seq, Py_ssize_t low, 1581 Py_ssize_t high) { 1582 Thread* thread = Thread::current(); 1583 if (seq == nullptr) { 1584 return nullError(thread); 1585 } 1586 HandleScope scope(thread); 1587 Object slice(&scope, makeSlice(thread, low, high)); 1588 Object seq_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(seq))); 1589 Object result(&scope, thread->invokeMethod2(seq_obj, ID(__getitem__), slice)); 1590 if (result.isError()) { 1591 if (result.isErrorNotFound()) { 1592 thread->raiseWithFmt(LayoutId::kTypeError, "could not call __getitem__"); 1593 } 1594 return nullptr; 1595 } 1596 return ApiHandle::newReference(thread->runtime(), *result); 1597} 1598 1599PY_EXPORT int PySequence_In(PyObject* pyseq, PyObject* pyobj) { 1600 return PySequence_Contains(pyseq, pyobj); 1601} 1602 1603PY_EXPORT Py_ssize_t PySequence_Index(PyObject* seq, PyObject* obj) { 1604 Thread* thread = Thread::current(); 1605 if (seq == nullptr || obj == nullptr) { 1606 nullError(thread); 1607 return -1; 1608 } 1609 HandleScope scope(thread); 1610 Object seq_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(seq))); 1611 Object object(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 1612 Object result(&scope, thread->invokeFunction2(ID(operator), ID(indexOf), 1613 seq_obj, object)); 1614 if (result.isError()) { 1615 return -1; 1616 } 1617 return SmallInt::cast(*result).value(); 1618} 1619 1620PY_EXPORT PyObject* PySequence_InPlaceConcat(PyObject* left, PyObject* right) { 1621 Thread* thread = Thread::current(); 1622 if (left == nullptr || right == nullptr) { 1623 return nullError(thread); 1624 } 1625 HandleScope scope(thread); 1626 Object left_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(left))); 1627 Object right_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(right))); 1628 Object result(&scope, thread->invokeFunction2(ID(operator), ID(iconcat), 1629 left_obj, right_obj)); 1630 return result.isError() ? nullptr 1631 : ApiHandle::newReference(thread->runtime(), *result); 1632} 1633 1634PY_EXPORT PyObject* PySequence_InPlaceRepeat(PyObject* seq, Py_ssize_t count) { 1635 Thread* thread = Thread::current(); 1636 if (seq == nullptr) { 1637 return nullError(thread); 1638 } 1639 HandleScope scope(thread); 1640 Runtime* runtime = thread->runtime(); 1641 Object sequence(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(seq))); 1642 Object count_obj(&scope, runtime->newInt(count)); 1643 Object result(&scope, thread->invokeFunction2(ID(operator), ID(irepeat), 1644 sequence, count_obj)); 1645 return result.isError() ? nullptr : ApiHandle::newReference(runtime, *result); 1646} 1647 1648PY_EXPORT Py_ssize_t PySequence_Length(PyObject* pyobj) { 1649 return objectLength(pyobj); 1650} 1651 1652PY_EXPORT PyObject* PySequence_List(PyObject* seq) { 1653 Thread* thread = Thread::current(); 1654 if (seq == nullptr) { 1655 return nullError(thread); 1656 } 1657 HandleScope scope(thread); 1658 Object seq_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(seq))); 1659 RawObject result = thread->invokeFunction1(ID(builtins), ID(list), seq_obj); 1660 return result.isError() ? nullptr 1661 : ApiHandle::newReference(thread->runtime(), result); 1662} 1663 1664PY_EXPORT PyObject* PySequence_Repeat(PyObject* pyseq, Py_ssize_t count) { 1665 Thread* thread = Thread::current(); 1666 if (pyseq == nullptr) { 1667 return nullError(thread); 1668 } 1669 if (!PySequence_Check(pyseq)) { 1670 thread->raiseWithFmt(LayoutId::kTypeError, "object cannot be repeated"); 1671 return nullptr; 1672 } 1673 PyObject* count_obj(PyLong_FromSsize_t(count)); 1674 PyObject* result = PyNumber_Multiply(pyseq, count_obj); 1675 Py_DECREF(count_obj); 1676 return result; 1677} 1678 1679PY_EXPORT int PySequence_SetItem(PyObject* seq, Py_ssize_t idx, PyObject* obj) { 1680 Thread* thread = Thread::current(); 1681 if (seq == nullptr) { 1682 nullError(thread); 1683 return -1; 1684 } 1685 HandleScope scope(thread); 1686 Object seq_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(seq))); 1687 Object idx_obj(&scope, thread->runtime()->newInt(idx)); 1688 Object result(&scope, NoneType::object()); 1689 if (obj == nullptr) { 1690 // Equivalent to PySequence_DelItem 1691 result = thread->invokeMethod2(seq_obj, ID(__delitem__), idx_obj); 1692 } else { 1693 Object object(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 1694 result = thread->invokeMethod3(seq_obj, ID(__setitem__), idx_obj, object); 1695 } 1696 if (result.isError()) { 1697 if (result.isErrorNotFound()) { 1698 thread->raiseWithFmt(LayoutId::kTypeError, "object is not subscriptable"); 1699 } 1700 return -1; 1701 } 1702 return 0; 1703} 1704 1705PY_EXPORT int PySequence_SetSlice(PyObject* seq, Py_ssize_t low, 1706 Py_ssize_t high, PyObject* obj) { 1707 Thread* thread = Thread::current(); 1708 if (seq == nullptr) { 1709 nullError(thread); 1710 return -1; 1711 } 1712 HandleScope scope(thread); 1713 Object slice(&scope, makeSlice(thread, low, high)); 1714 Object seq_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(seq))); 1715 Object result(&scope, NoneType::object()); 1716 if (obj == nullptr) { 1717 result = thread->invokeMethod2(seq_obj, ID(__delitem__), slice); 1718 } else { 1719 Object object(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj))); 1720 result = thread->invokeMethod3(seq_obj, ID(__setitem__), slice, object); 1721 } 1722 if (result.isError()) { 1723 if (result.isErrorNotFound()) { 1724 thread->raiseWithFmt(LayoutId::kTypeError, 1725 "object does not support slice assignment"); 1726 } 1727 return -1; 1728 } 1729 return 0; 1730} 1731 1732PY_EXPORT Py_ssize_t PySequence_Size(PyObject* pyobj) { 1733 return objectLength(pyobj); 1734} 1735 1736PY_EXPORT PyObject* PySequence_Tuple(PyObject* seq) { 1737 Thread* thread = Thread::current(); 1738 if (seq == nullptr) { 1739 return nullError(thread); 1740 } 1741 HandleScope scope(thread); 1742 Object seq_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(seq))); 1743 Runtime* runtime = thread->runtime(); 1744 if (seq_obj.isTuple()) { 1745 return ApiHandle::newReference(runtime, *seq_obj); 1746 } 1747 Object result(&scope, 1748 thread->invokeFunction1(ID(builtins), ID(tuple), seq_obj)); 1749 if (result.isError()) { 1750 return nullptr; 1751 } 1752 return ApiHandle::newReference(runtime, *result); 1753} 1754 1755} // namespace py