this repo has no description
at trunk 860 lines 29 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "builtins-module.h" 3 4#include <cerrno> 5#include <cmath> 6#include <csignal> 7 8#include "attributedict.h" 9#include "builtins.h" 10#include "bytes-builtins.h" 11#include "capi.h" 12#include "dict-builtins.h" 13#include "exception-builtins.h" 14#include "formatter.h" 15#include "int-builtins.h" 16#include "list-builtins.h" 17#include "marshal.h" 18#include "module-builtins.h" 19#include "modules.h" 20#include "object-builtins.h" 21#include "objects.h" 22#include "range-builtins.h" 23#include "runtime.h" 24#include "set-builtins.h" 25#include "str-builtins.h" 26#include "tuple-builtins.h" 27#include "type-builtins.h" 28 29namespace py { 30 31RawObject delAttribute(Thread* thread, const Object& object, 32 const Object& name) { 33 HandleScope scope(thread); 34 Object interned(&scope, attributeName(thread, name)); 35 if (interned.isErrorException()) return *interned; 36 Object result(&scope, 37 thread->runtime()->attributeDel(thread, object, interned)); 38 if (result.isErrorException()) return *result; 39 return NoneType::object(); 40} 41 42RawObject getAttribute(Thread* thread, const Object& object, 43 const Object& name) { 44 HandleScope scope(thread); 45 Object interned(&scope, attributeName(thread, name)); 46 if (interned.isErrorException()) return *interned; 47 return thread->runtime()->attributeAt(thread, object, interned); 48} 49 50static RawObject getAttributeWithDefault(Thread* thread, const Object& object, 51 const Object& name) { 52 HandleScope scope(thread); 53 Object interned(&scope, attributeName(thread, name)); 54 if (interned.isErrorException()) return *interned; 55 LoadAttrKind kind; 56 Object location(&scope, Unbound::object()); 57 return thread->runtime()->attributeAtSetLocation(thread, object, interned, 58 &kind, &location); 59} 60 61RawObject hasAttribute(Thread* thread, const Object& object, 62 const Object& name) { 63 HandleScope scope(thread); 64 Object interned(&scope, attributeName(thread, name)); 65 if (interned.isErrorException()) return *interned; 66 67 LoadAttrKind kind; 68 Object location(&scope, Unbound::object()); 69 Object result(&scope, thread->runtime()->attributeAtSetLocation( 70 thread, object, interned, &kind, &location)); 71 if (result.isErrorNotFound()) { 72 return Bool::falseObj(); 73 } 74 if (!result.isErrorException()) { 75 return Bool::trueObj(); 76 } 77 if (!thread->pendingExceptionMatches(LayoutId::kAttributeError)) { 78 return *result; 79 } 80 thread->clearPendingException(); 81 return Bool::falseObj(); 82} 83 84RawObject setAttribute(Thread* thread, const Object& object, const Object& name, 85 const Object& value) { 86 HandleScope scope(thread); 87 Object interned(&scope, attributeName(thread, name)); 88 if (interned.isErrorException()) return *interned; 89 90 Object result( 91 &scope, thread->invokeMethod3(object, ID(__setattr__), interned, value)); 92 if (result.isErrorException()) return *result; 93 return NoneType::object(); 94} 95 96bool FUNC(builtins, _index_intrinsic)(Thread* thread) { 97 RawObject value = thread->stackTop(); 98 if (thread->runtime()->isInstanceOfInt(value)) { 99 thread->stackPop(); 100 thread->stackSetTop(value); 101 return true; 102 } 103 return false; 104} 105 106bool FUNC(builtins, _index_or_int_intrinsic)(Thread* thread) { 107 RawObject value = thread->stackTop(); 108 if (value.isBool()) { 109 thread->stackPop(); 110 thread->stackSetTop(convertBoolToInt(value)); 111 return true; 112 } 113 if (value.isSmallInt() || value.isLargeInt()) { 114 thread->stackPop(); 115 thread->stackSetTop(value); 116 } 117 return false; 118} 119 120bool FUNC(builtins, _obj_as_int_intrinsic)(Thread* thread) { 121 RawObject value = thread->stackTop(); 122 if (value.isBool()) { 123 thread->stackPop(); 124 thread->stackSetTop(convertBoolToInt(value)); 125 return true; 126 } 127 if (thread->runtime()->isInstanceOfInt(value)) { 128 thread->stackPop(); 129 thread->stackSetTop(intUnderlying(value)); 130 return true; 131 } 132 return false; 133} 134 135bool FUNC(builtins, abs_intrinsic)(Thread* thread) { 136 RawObject obj = thread->stackTop(); 137 if (obj.isSmallInt()) { 138 thread->stackPop(); 139 word value = SmallInt::cast(obj).value(); 140 if (value < 0) { 141 obj = SmallInt::fromWord(-value); 142 } 143 thread->stackSetTop(obj); 144 return true; 145 } 146 if (obj.isFloat()) { 147 thread->stackPop(); 148 double value = Float::cast(obj).value(); 149 thread->stackSetTop(thread->runtime()->newFloat(std::fabs(value))); 150 return true; 151 } 152 return false; 153} 154 155bool FUNC(builtins, next_intrinsic)(Thread* thread) { 156 RawObject value = thread->stackTop(); 157 switch (value.layoutId()) { 158 case LayoutId::kDictKeyIterator: { 159 HandleScope scope(thread); 160 DictKeyIterator iter(&scope, value); 161 RawObject result = dictKeyIteratorNext(thread, iter); 162 if (result.isErrorNoMoreItems()) { 163 return false; 164 } 165 thread->stackPop(); 166 thread->stackSetTop(result); 167 return true; 168 } 169 case LayoutId::kListIterator: { 170 HandleScope scope(thread); 171 ListIterator list_iterator(&scope, value); 172 RawObject result = listIteratorNext(thread, list_iterator); 173 if (result.isErrorOutOfBounds()) { 174 return false; 175 } 176 thread->stackPop(); 177 thread->stackSetTop(result); 178 return true; 179 } 180 case LayoutId::kRangeIterator: { 181 HandleScope scope(thread); 182 RangeIterator iter(&scope, value); 183 RawObject result = rangeIteratorNext(iter); 184 if (result.isErrorNoMoreItems()) { 185 return false; 186 } 187 thread->stackPop(); 188 thread->stackSetTop(result); 189 return true; 190 } 191 case LayoutId::kSetIterator: { 192 HandleScope scope(thread); 193 SetIterator set_iterator(&scope, value); 194 RawObject result = setIteratorNext(thread, set_iterator); 195 if (result.isErrorNoMoreItems()) { 196 return false; 197 } 198 thread->stackPop(); 199 thread->stackSetTop(result); 200 return true; 201 } 202 case LayoutId::kStrIterator: { 203 HandleScope scope(thread); 204 StrIterator str_iterator(&scope, value); 205 RawObject result = strIteratorNext(thread, str_iterator); 206 if (result.isErrorNoMoreItems()) { 207 return false; 208 } 209 thread->stackPop(); 210 thread->stackSetTop(result); 211 return true; 212 } 213 case LayoutId::kTupleIterator: { 214 HandleScope scope(thread); 215 TupleIterator tuple_iterator(&scope, value); 216 RawObject result = tupleIteratorNext(thread, tuple_iterator); 217 if (result.isErrorNoMoreItems()) { 218 return false; 219 } 220 thread->stackPop(); 221 thread->stackSetTop(result); 222 return true; 223 } 224 default: { 225 return false; 226 } 227 } 228} 229 230bool FUNC(builtins, _number_check_intrinsic)(Thread* thread) { 231 Runtime* runtime = thread->runtime(); 232 RawObject arg = thread->stackTop(); 233 if (runtime->isInstanceOfInt(arg) || runtime->isInstanceOfFloat(arg)) { 234 thread->stackPop(); 235 thread->stackSetTop(Bool::trueObj()); 236 return true; 237 } 238 return false; 239} 240 241bool FUNC(builtins, _slice_index_intrinsic)(Thread* thread) { 242 RawObject value = thread->stackPeek(0); 243 if (value.isNoneType() || thread->runtime()->isInstanceOfInt(value)) { 244 thread->stackPop(); 245 thread->stackSetTop(value); 246 return true; 247 } 248 return false; 249} 250 251bool FUNC(builtins, _slice_index_not_none_intrinsic)(Thread* thread) { 252 RawObject value = thread->stackTop(); 253 if (thread->runtime()->isInstanceOfInt(value)) { 254 thread->stackPop(); 255 thread->stackSetTop(value); 256 return true; 257 } 258 return false; 259} 260 261bool FUNC(builtins, isinstance_intrinsic)(Thread* thread) { 262 RawObject obj = thread->stackPeek(1); 263 RawObject type = thread->stackPeek(0); 264 Runtime* runtime = thread->runtime(); 265 RawType obj_type = runtime->typeOf(obj); 266 if (obj_type == type) { 267 thread->stackDrop(2); 268 thread->stackSetTop(Bool::trueObj()); 269 return true; 270 } 271 if (type.isType()) { 272 if (typeIsSubclass(obj_type, type)) { 273 thread->stackDrop(2); 274 thread->stackSetTop(Bool::trueObj()); 275 return true; 276 } 277 if (obj_type.hasFlag(Type::Flag::kHasObjectDunderClass)) { 278 // obj_type.__class__ is object.__class__, so type(obj) is guaranteed to 279 // be obj_type. See _object_class_set implementation. 280 thread->stackDrop(2); 281 thread->stackSetTop(Bool::falseObj()); 282 return true; 283 } 284 } else if (type.isTuple()) { 285 RawTuple types = Tuple::cast(type); 286 word length = types.length(); 287 for (word i = 0; i < length; i++) { 288 RawObject item = types.at(i); 289 if (!item.isType()) { 290 return false; 291 } 292 if (typeIsSubclass(obj_type, item)) { 293 thread->stackDrop(2); 294 thread->stackSetTop(Bool::trueObj()); 295 return true; 296 } 297 } 298 } 299 return false; 300} 301 302bool FUNC(builtins, len_intrinsic)(Thread* thread) { 303 RawObject arg = thread->stackTop(); 304 word length; 305 switch (arg.layoutId()) { 306 case LayoutId::kBytearray: 307 length = Bytearray::cast(arg).numItems(); 308 break; 309 case LayoutId::kDict: 310 length = Dict::cast(arg).numItems(); 311 break; 312 case LayoutId::kFrozenSet: 313 length = FrozenSet::cast(arg).numItems(); 314 break; 315 case LayoutId::kLargeBytes: 316 length = LargeBytes::cast(arg).length(); 317 break; 318 case LayoutId::kLargeStr: 319 length = LargeStr::cast(arg).codePointLength(); 320 break; 321 case LayoutId::kList: 322 length = List::cast(arg).numItems(); 323 break; 324 case LayoutId::kSet: 325 length = Set::cast(arg).numItems(); 326 break; 327 case LayoutId::kSmallBytes: 328 length = SmallBytes::cast(arg).length(); 329 break; 330 case LayoutId::kSmallStr: 331 length = SmallStr::cast(arg).codePointLength(); 332 break; 333 case LayoutId::kTuple: 334 length = Tuple::cast(arg).length(); 335 break; 336 default: 337 return false; 338 } 339 thread->stackPop(); 340 thread->stackSetTop(SmallInt::fromWord(length)); 341 return true; 342} 343 344void FUNC(builtins, __init_module__)(Thread* thread, const Module& module, 345 View<byte> bytecode) { 346 Runtime* runtime = thread->runtime(); 347 runtime->setBuiltinsModuleId(module.id()); 348 runtime->cacheBuildClass(thread, module); 349 HandleScope scope(thread); 350 351 // Add module variables 352 { 353 Object dunder_debug(&scope, Bool::falseObj()); 354 moduleAtPutById(thread, module, ID(__debug__), dunder_debug); 355 356 Object false_obj(&scope, Bool::falseObj()); 357 moduleAtPutById(thread, module, ID(False), false_obj); 358 359 Object none(&scope, NoneType::object()); 360 moduleAtPutById(thread, module, ID(None), none); 361 362 Object not_implemented(&scope, NotImplementedType::object()); 363 moduleAtPutById(thread, module, ID(NotImplemented), not_implemented); 364 365 Object true_obj(&scope, Bool::trueObj()); 366 moduleAtPutById(thread, module, ID(True), true_obj); 367 } 368 369 executeFrozenModule(thread, module, bytecode); 370} 371 372static RawObject calculateMetaclass(Thread* thread, const Type& metaclass_type, 373 const Tuple& bases) { 374 Runtime* runtime = thread->runtime(); 375 RawObject result = *metaclass_type; 376 for (word i = 0, num_bases = bases.length(); i < num_bases; i++) { 377 RawObject base_type = runtime->typeOf(bases.at(i)); 378 if (typeIsSubclass(base_type, result)) { 379 result = base_type; 380 } else if (!typeIsSubclass(result, base_type)) { 381 return thread->raiseWithFmt( 382 LayoutId::kTypeError, 383 "metaclass conflict: the metaclass of a derived class must be a " 384 "(non-strict) subclass of the metaclasses of all its bases"); 385 } 386 } 387 return result; 388} 389 390RawObject FUNC(builtins, bin)(Thread* thread, Arguments args) { 391 HandleScope scope(thread); 392 Object number(&scope, args.get(0)); 393 number = intFromIndex(thread, number); 394 if (number.isError()) { 395 return *number; 396 } 397 Int number_int(&scope, intUnderlying(*number)); 398 return formatIntBinarySimple(thread, number_int); 399} 400 401RawObject FUNC(builtins, delattr)(Thread* thread, Arguments args) { 402 HandleScope scope(thread); 403 Object self(&scope, args.get(0)); 404 Object name(&scope, args.get(1)); 405 Object result(&scope, delAttribute(thread, self, name)); 406 return *result; 407} 408 409static RawObject replaceNonTypeBases(Thread* thread, const Tuple& bases) { 410 Runtime* runtime = thread->runtime(); 411 word num_bases = bases.length(); 412 bool has_nontype_base = false; 413 for (word i = 0; i < num_bases; i++) { 414 if (!runtime->isInstanceOfType(bases.at(i))) { 415 has_nontype_base = true; 416 break; 417 } 418 } 419 if (!has_nontype_base) { 420 return *bases; 421 } 422 HandleScope scope(thread); 423 List new_bases(&scope, runtime->newList()); 424 Object base(&scope, NoneType::object()); 425 Object replacements(&scope, NoneType::object()); 426 Tuple entries(&scope, runtime->emptyTuple()); 427 for (word i = 0; i < num_bases; i++) { 428 base = bases.at(i); 429 if (runtime->isInstanceOfType(*base)) { 430 runtime->listAdd(thread, new_bases, base); 431 continue; 432 } 433 replacements = thread->invokeMethod2(base, ID(__mro_entries__), bases); 434 if (replacements.isErrorException()) return *replacements; 435 if (replacements.isErrorNotFound()) { 436 runtime->listAdd(thread, new_bases, base); 437 continue; 438 } 439 if (!replacements.isTuple()) { 440 return thread->raiseWithFmt(LayoutId::kTypeError, 441 "__mro_entries__ must return a tuple"); 442 } 443 entries = *replacements; 444 listExtend(thread, new_bases, entries, entries.length()); 445 } 446 Tuple new_bases_items(&scope, new_bases.items()); 447 return runtime->tupleSubseq(thread, new_bases_items, 0, new_bases.numItems()); 448} 449 450static void pickBuiltinTypeCtorFunction(Thread* thread, const Type& type) { 451 HandleScope scope(thread); 452 Object ctor(&scope, NoneType::object()); 453 LayoutId layout_id = type.instanceLayoutId(); 454 Runtime* runtime = thread->runtime(); 455 switch (layout_id) { 456 case LayoutId::kInt: { 457 Module under_builtins(&scope, runtime->findModuleById(ID(_builtins))); 458 ctor = moduleAtById(thread, under_builtins, ID(_int_ctor)); 459 break; 460 } 461 case LayoutId::kList: { 462 Module under_builtins(&scope, runtime->findModuleById(ID(_builtins))); 463 ctor = moduleAtById(thread, under_builtins, ID(_list_ctor)); 464 break; 465 } 466 case LayoutId::kRange: { 467 // range args are messy. Use __new__ as the default ctor but cache a 468 // specialized version in the interpreter if possible at a given 469 // callsite. 470 ctor = typeAtById(thread, type, ID(__new__)); 471 DCHECK(ctor.isStaticMethod(), "expected staticmethod"); 472 ctor = StaticMethod::cast(*ctor).function(); 473 break; 474 } 475 case LayoutId::kSet: { 476 Module under_builtins(&scope, runtime->findModuleById(ID(_builtins))); 477 ctor = moduleAtById(thread, under_builtins, ID(_set_ctor)); 478 break; 479 } 480 case LayoutId::kStr: { 481 Module under_builtins(&scope, runtime->findModuleById(ID(_builtins))); 482 ctor = moduleAtById(thread, under_builtins, ID(_str_ctor)); 483 break; 484 } 485 case LayoutId::kStopIteration: { 486 Module under_builtins(&scope, runtime->findModuleById(ID(_builtins))); 487 ctor = moduleAtById(thread, under_builtins, ID(_stop_iteration_ctor)); 488 break; 489 } 490 case LayoutId::kStrArray: { 491 Module under_builtins(&scope, runtime->findModuleById(ID(_builtins))); 492 ctor = moduleAtById(thread, under_builtins, ID(_str_array_ctor)); 493 break; 494 } 495 case LayoutId::kSuper: { 496 Module under_builtins(&scope, runtime->findModuleById(ID(_builtins))); 497 ctor = moduleAtById(thread, under_builtins, ID(_super_ctor)); 498 break; 499 } 500 default: { 501 if (typeAtById(thread, type, ID(__init__)).isErrorNotFound()) { 502 // Use __new__ as _ctor if __init__ is undefined. 503 Object dunder_new(&scope, typeAtById(thread, type, ID(__new__))); 504 if (!dunder_new.isErrorNotFound()) { 505 ctor = StaticMethod::cast(*dunder_new).function(); 506 } 507 } 508 } 509 } 510 if (ctor.isNoneType()) { 511 ctor = runtime->lookupNameInModule(thread, ID(_builtins), 512 ID(_type_dunder_call)); 513 } 514 CHECK(ctor.isFunction(), "ctor is expected to be a function"); 515 type.setCtor(*ctor); 516} 517 518RawObject FUNC(builtins, __build_class__)(Thread* thread, Arguments args) { 519 Runtime* runtime = thread->runtime(); 520 HandleScope scope(thread); 521 Object body_obj(&scope, args.get(0)); 522 if (!body_obj.isFunction()) { 523 return thread->raiseWithFmt(LayoutId::kTypeError, 524 "__build_class__: func must be a function"); 525 } 526 Function body(&scope, *body_obj); 527 Object name(&scope, args.get(1)); 528 if (!runtime->isInstanceOfStr(*name)) { 529 return thread->raiseWithFmt(LayoutId::kTypeError, 530 "__build_class__: name is not a string"); 531 } 532 Object metaclass(&scope, args.get(2)); 533 Object bootstrap(&scope, args.get(3)); 534 Tuple orig_bases(&scope, args.get(4)); 535 Tuple bases(&scope, *orig_bases); 536 Dict kwargs(&scope, args.get(5)); 537 538 if (bootstrap == Bool::trueObj()) { 539 CHECK(name.isStr(), "bootstrap class names must not be str subclass"); 540 name = Runtime::internStr(thread, name); 541 Object type_obj(&scope, findBuiltinTypeWithName(thread, name)); 542 CHECK(!type_obj.isErrorNotFound(), "Unknown builtin type"); 543 Type type(&scope, *type_obj); 544 545 if (bases.length() == 0 && name != runtime->symbols()->at(ID(object))) { 546 bases = runtime->implicitBases(); 547 } 548 Tuple builtin_bases(&scope, type.bases()); 549 word bases_length = bases.length(); 550 CHECK(builtin_bases.length() == bases_length, "mismatching bases for '%s'", 551 Str::cast(*name).toCStr()); 552 for (word i = 0; i < bases_length; i++) { 553 CHECK(builtin_bases.at(i) == bases.at(i), "mismatching bases for '%s'", 554 Str::cast(*name).toCStr()); 555 } 556 557 if (type.mro().isNoneType()) { 558 Type superclass(&scope, bases.at(0)); 559 DCHECK(!superclass.mro().isNoneType(), "superclass not initialized yet"); 560 Tuple superclass_mro(&scope, superclass.mro()); 561 word mro_length = superclass_mro.length() + 1; 562 MutableTuple mro(&scope, runtime->newMutableTuple(mro_length)); 563 mro.atPut(0, *type); 564 mro.replaceFromWith(1, *superclass_mro, mro_length - 1); 565 type.setMro(mro.becomeImmutable()); 566 } 567 568 Dict type_dict(&scope, runtime->newDict()); 569 Object result(&scope, 570 thread->callFunctionWithImplicitGlobals(body, type_dict)); 571 if (result.isError()) return *result; 572 CHECK(!typeAssignFromDict(thread, type, type_dict).isErrorException(), 573 "error while assigning bootstrap type dict"); 574 // TODO(T53997177): Centralize type initialization 575 Object module_name(&scope, typeAtById(thread, type, ID(__module__))); 576 // non-heap-types in CPython have no `__module__` unless there is a 577 // "." in `tp_name`. Remove the attribute when it equals "builtins". 578 if (module_name.isStr() && 579 Str::cast(*module_name).equals(runtime->symbols()->at(ID(builtins)))) { 580 typeRemoveById(thread, type, ID(__module__)); 581 } 582 583 Object qualname(&scope, NoneType::object()); 584 if (type.instanceLayoutId() == LayoutId::kType) { 585 qualname = *name; 586 // Note: `type` is the only type allowed to have a descriptor instead of 587 // a string for `__qualname__`. 588 } else { 589 qualname = typeRemoveById(thread, type, ID(__qualname__)); 590 DCHECK(qualname.isStr() && Str::cast(*qualname).equals(Str::cast(*name)), 591 "unexpected __qualname__ attribute"); 592 } 593 type.setQualname(*qualname); 594 typeAddDocstring(thread, type); 595 596 if (Layout::cast(type.instanceLayout()).hasTupleOverflow() && 597 typeAtById(thread, type, ID(__dict__)).isErrorNotFound()) { 598 typeAddInstanceDict(thread, type); 599 } 600 601 if (DCHECK_IS_ON()) { 602 Object dunder_new(&scope, typeAtById(thread, type, ID(__new__))); 603 if (!dunder_new.isStaticMethod()) { 604 if (!(dunder_new.isNoneType() || dunder_new.isErrorNotFound())) { 605 DCHECK(false, "__new__ for %s should be a staticmethod", 606 Str::cast(*name).toCStr()); 607 } 608 } 609 } 610 611 pickBuiltinTypeCtorFunction(thread, type); 612 runtime->builtinTypeCreated(thread, type); 613 return *type; 614 } 615 616 Object updated_bases(&scope, replaceNonTypeBases(thread, bases)); 617 if (updated_bases.isErrorException()) { 618 return *updated_bases; 619 } 620 bases = *updated_bases; 621 bool metaclass_is_class; 622 if (metaclass.isUnbound()) { 623 metaclass_is_class = true; 624 if (bases.length() == 0) { 625 metaclass = runtime->typeAt(LayoutId::kType); 626 } else { 627 metaclass = runtime->typeOf(bases.at(0)); 628 } 629 } else { 630 metaclass_is_class = runtime->isInstanceOfType(*metaclass); 631 } 632 633 if (metaclass_is_class) { 634 Type metaclass_type(&scope, *metaclass); 635 metaclass = calculateMetaclass(thread, metaclass_type, bases); 636 if (metaclass.isError()) return *metaclass; 637 } 638 639 Object dict_obj(&scope, NoneType::object()); 640 Object prepare_method( 641 &scope, runtime->attributeAtById(thread, metaclass, ID(__prepare__))); 642 if (prepare_method.isError()) { 643 Object given(&scope, thread->pendingExceptionType()); 644 Object exc(&scope, runtime->typeAt(LayoutId::kAttributeError)); 645 if (!givenExceptionMatches(thread, given, exc)) { 646 return *prepare_method; 647 } 648 thread->clearPendingException(); 649 dict_obj = runtime->newDict(); 650 } else { 651 thread->stackPush(*prepare_method); 652 Tuple pargs(&scope, runtime->newTupleWith2(name, bases)); 653 thread->stackPush(*pargs); 654 thread->stackPush(*kwargs); 655 dict_obj = Interpreter::callEx(thread, CallFunctionExFlag::VAR_KEYWORDS); 656 if (dict_obj.isError()) return *dict_obj; 657 } 658 if (!runtime->isMapping(thread, dict_obj)) { 659 if (metaclass_is_class) { 660 Type metaclass_type(&scope, *metaclass); 661 Str metaclass_type_name(&scope, metaclass_type.name()); 662 return thread->raiseWithFmt( 663 LayoutId::kTypeError, 664 "%S.__prepare__() must return a mapping, not %T", 665 &metaclass_type_name, &dict_obj); 666 } 667 return thread->raiseWithFmt( 668 LayoutId::kTypeError, 669 "<metaclass>.__prepare__() must return a mapping, not %T", &dict_obj); 670 } 671 Dict type_dict(&scope, *dict_obj); 672 673 // TODO(cshapiro): might need to do some kind of callback here and we want 674 // backtraces to work correctly. The key to doing that would be to put some 675 // state on the stack in between the the incoming arguments from the builtin 676 // caller and the on-stack state for the class body function call. 677 Object body_result(&scope, 678 thread->callFunctionWithImplicitGlobals(body, type_dict)); 679 if (body_result.isError()) return *body_result; 680 681 if (bases != orig_bases) { 682 dictAtPutById(thread, type_dict, ID(__orig_bases__), orig_bases); 683 } 684 685 thread->stackPush(*metaclass); 686 Tuple pargs(&scope, runtime->newTupleWith3(name, bases, type_dict)); 687 thread->stackPush(*pargs); 688 thread->stackPush(*kwargs); 689 return Interpreter::callEx(thread, CallFunctionExFlag::VAR_KEYWORDS); 690} 691 692RawObject FUNC(builtins, callable)(Thread* thread, Arguments args) { 693 HandleScope scope(thread); 694 Object arg(&scope, args.get(0)); 695 return Bool::fromBool(thread->runtime()->isCallable(thread, arg)); 696} 697 698RawObject FUNC(builtins, chr)(Thread* thread, Arguments args) { 699 HandleScope scope(thread); 700 Object arg(&scope, args.get(0)); 701 Runtime* runtime = thread->runtime(); 702 if (!runtime->isInstanceOfInt(*arg)) { 703 return thread->raiseWithFmt(LayoutId::kTypeError, 704 "an integer is required (got type %T)", &arg); 705 } 706 Int num(&scope, intUnderlying(*arg)); 707 if (!num.isSmallInt()) { 708 return thread->raiseWithFmt(LayoutId::kOverflowError, 709 "Python int too large to convert to C int"); 710 } 711 word code_point = num.asWord(); 712 if (code_point < 0 || code_point > kMaxUnicode) { 713 return thread->raiseWithFmt(LayoutId::kValueError, 714 "chr() arg not in range(0x110000)"); 715 } 716 return SmallStr::fromCodePoint(static_cast<int32_t>(code_point)); 717} 718 719RawObject FUNC(builtins, id)(Thread* thread, Arguments args) { 720 // NOTE: This pins a handle until the runtime exits. 721 // TODO(emacs): Either determine that this function is used so little that it 722 // does not matter or add a section to the GC to clean up handles created by 723 // id(). 724 Runtime* runtime = thread->runtime(); 725 return runtime->newIntFromCPtr(objectNewReference(runtime, args.get(0))); 726} 727 728RawObject FUNC(builtins, oct)(Thread* thread, Arguments args) { 729 HandleScope scope(thread); 730 Object number(&scope, args.get(0)); 731 number = intFromIndex(thread, number); 732 if (number.isError()) { 733 return *number; 734 } 735 Int number_int(&scope, intUnderlying(*number)); 736 return formatIntOctalSimple(thread, number_int); 737} 738 739RawObject FUNC(builtins, ord)(Thread* thread, Arguments args) { 740 HandleScope scope(thread); 741 Object obj(&scope, args.get(0)); 742 Runtime* runtime = thread->runtime(); 743 if (runtime->isInstanceOfBytes(*obj)) { 744 Bytes bytes(&scope, bytesUnderlying(*obj)); 745 if (bytes.length() == 1) { 746 int32_t code_point = bytes.byteAt(0); 747 return SmallInt::fromWord(code_point); 748 } 749 } else if (runtime->isInstanceOfStr(*obj)) { 750 Str str(&scope, strUnderlying(*obj)); 751 if (str.isSmallStr() && *str != Str::empty()) { 752 word num_bytes; 753 int32_t code_point = str.codePointAt(0, &num_bytes); 754 if (num_bytes == str.length()) { 755 return SmallInt::fromWord(code_point); 756 } 757 } 758 } else if (runtime->isInstanceOfBytearray(*obj)) { 759 Bytearray byte_array(&scope, *obj); 760 if (byte_array.numItems() == 1) { 761 int32_t code_point = byte_array.byteAt(0); 762 return SmallInt::fromWord(code_point); 763 } 764 } else { 765 return thread->raiseWithFmt(LayoutId::kTypeError, 766 "Unsupported type in builtin 'ord'"); 767 } 768 return thread->raiseWithFmt(LayoutId::kTypeError, 769 "Builtin 'ord' expects string of length 1"); 770} 771 772RawObject FUNC(builtins, __import__)(Thread* thread, Arguments args) { 773 // Note that this is a simplified __import__ implementation that is used 774 // during early bootstrap; it is replaced by importlib.__import__ once 775 // import lib is fully initialized. 776 HandleScope scope(thread); 777 Str name(&scope, args.get(0)); 778 name = Runtime::internStr(thread, name); 779 // We ignore arg1, arg2, arg3. 780 DCHECK(args.get(4) == SmallInt::fromWord(0), "only supports level=0"); 781 Runtime* runtime = thread->runtime(); 782 Object module(&scope, ensureBuiltinModule(thread, name)); 783 if (module.isErrorNotFound() || !runtime->isInstanceOfModule(*module)) { 784 return thread->raiseWithFmt(LayoutId::kImportError, 785 "failed to import %S (bootstrap importer)", 786 &name); 787 } 788 return *module; 789} 790 791RawObject FUNC(builtins, _debug_break)(Thread*, Arguments) { 792#if __has_builtin(__builtin_debugtrap) 793 __builtin_debugtrap(); 794#elif defined(__i386__) || defined(__x86_64__) 795 __asm__ volatile("int $0x03"); 796#else 797 std::raise(SIGTRAP); 798#endif 799 return NoneType::object(); 800} 801 802// TODO(T39322942): Turn this into the Range constructor (__init__ or __new__) 803RawObject FUNC(builtins, getattr)(Thread* thread, Arguments args) { 804 HandleScope scope(thread); 805 Object self(&scope, args.get(0)); 806 Object name(&scope, args.get(1)); 807 Object default_obj(&scope, args.get(2)); 808 if (!default_obj.isUnbound()) { 809 Object result(&scope, getAttributeWithDefault(thread, self, name)); 810 if (result.isErrorNotFound()) { 811 return *default_obj; 812 } 813 if (result.isError()) { 814 Type given(&scope, thread->pendingExceptionType()); 815 Runtime* runtime = thread->runtime(); 816 Type exc(&scope, runtime->typeAt(LayoutId::kAttributeError)); 817 if (givenExceptionMatches(thread, given, exc)) { 818 thread->clearPendingException(); 819 return *default_obj; 820 } 821 return *result; 822 } 823 return *result; 824 } 825 return getAttribute(thread, self, name); 826} 827 828RawObject FUNC(builtins, hasattr)(Thread* thread, Arguments args) { 829 HandleScope scope(thread); 830 Object self(&scope, args.get(0)); 831 Object name(&scope, args.get(1)); 832 return hasAttribute(thread, self, name); 833} 834 835RawObject FUNC(builtins, hash)(Thread* thread, Arguments args) { 836 HandleScope scope(thread); 837 Object object(&scope, args.get(0)); 838 return Interpreter::hash(thread, object); 839} 840 841RawObject FUNC(builtins, hex)(Thread* thread, Arguments args) { 842 HandleScope scope(thread); 843 Object number(&scope, args.get(0)); 844 number = intFromIndex(thread, number); 845 if (number.isError()) { 846 return *number; 847 } 848 Int number_int(&scope, intUnderlying(*number)); 849 return formatIntHexadecimalSimple(thread, number_int); 850} 851 852RawObject FUNC(builtins, setattr)(Thread* thread, Arguments args) { 853 HandleScope scope(thread); 854 Object self(&scope, args.get(0)); 855 Object name(&scope, args.get(1)); 856 Object value(&scope, args.get(2)); 857 return setAttribute(thread, self, name, value); 858} 859 860} // namespace py