this repo has no description
at trunk 2119 lines 68 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "thread.h" 3 4#include <memory> 5 6#include "gtest/gtest.h" 7 8#include "builtins-module.h" 9#include "bytecode.h" 10#include "compile-utils.h" 11#include "dict-builtins.h" 12#include "frame.h" 13#include "globals.h" 14#include "interpreter.h" 15#include "marshal.h" 16#include "module-builtins.h" 17#include "modules.h" 18#include "runtime.h" 19#include "test-utils.h" 20#include "type-builtins.h" 21 22namespace py { 23namespace testing { 24 25using BuildSlice = RuntimeFixture; 26using BuildString = RuntimeFixture; 27using FormatTest = RuntimeFixture; 28using ListAppendTest = RuntimeFixture; 29using ListInsertTest = RuntimeFixture; 30using ListIterTest = RuntimeFixture; 31using ThreadTest = RuntimeFixture; 32using UnpackList = RuntimeFixture; 33using UnpackSeq = RuntimeFixture; 34 35TEST_F(ThreadTest, CheckMainThreadRuntime) { 36 ASSERT_EQ(thread_->runtime(), runtime_); 37} 38 39TEST_F(ThreadTest, RunEmptyFunction) { 40 HandleScope scope(thread_); 41 42 Object none(&scope, NoneType::object()); 43 Tuple consts(&scope, runtime_->newTupleWith1(none)); 44 const byte bytecode[] = {LOAD_CONST, 0, RETURN_VALUE, 0}; 45 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 46 47 Thread thread2(runtime_, 1 * kKiB); 48 runtime_->interpreter()->setupThread(&thread2); 49 Thread::setCurrentThread(&thread2); 50 EXPECT_TRUE(runCode(code).isNoneType()); 51 52 // Avoid assertion in runtime destructor. 53 Thread::setCurrentThread(thread_); 54} 55 56TEST_F(ThreadTest, ModuleBodyCallsHelloWorldFunction) { 57 ASSERT_FALSE(runFromCStr(runtime_, R"( 58def hello(): 59 return 'hello, world' 60result = hello() 61)") 62 .isError()); 63 EXPECT_TRUE( 64 isStrEqualsCStr(mainModuleAt(runtime_, "result"), "hello, world")); 65} 66 67TEST_F(ThreadTest, DunderCallInstance) { 68 HandleScope scope(thread_); 69 70 const char* src = R"( 71class C: 72 def __init__(self, x, y): 73 self.value = x + y 74 def __call__(self, y): 75 return self.value * y 76c = C(10, 2) 77g = c(3) 78)"; 79 80 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 81 82 Object global(&scope, mainModuleAt(runtime_, "g")); 83 EXPECT_TRUE(isIntEqualsWord(*global, 36)); 84} 85 86TEST_F(ThreadTest, DunderCallInstanceWithDescriptor) { 87 HandleScope scope(thread_); 88 const char* src = R"( 89result = None 90 91def stage2(x): 92 global result 93 result = x 94 95class Stage1: 96 def __get__(self, instance, owner): 97 return stage2 98 99class Stage0: 100 __call__ = Stage1() 101 102c = Stage0() 103c(1111) 104)"; 105 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 106 Object result(&scope, mainModuleAt(runtime_, "result")); 107 EXPECT_TRUE(isIntEqualsWord(*result, 1111)); 108} 109 110TEST_F(ThreadTest, DunderCallInstanceKw) { 111 HandleScope scope(thread_); 112 const char* src = R"( 113class C: 114 def __init__(self): 115 self.value = None 116 117 def __call__(self, y): 118 return y 119 120c = C() 121result = c(y=3) 122)"; 123 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 124 125 Object result(&scope, mainModuleAt(runtime_, "result")); 126 EXPECT_TRUE(isIntEqualsWord(*result, 3)); 127} 128 129TEST_F(ThreadTest, DunderCallInstanceSplatArgs) { 130 HandleScope scope(thread_); 131 const char* src = R"( 132class C: 133 def __call__(self, y): 134 return y 135 136c = C() 137args = (3,) 138result = c(*args) 139)"; 140 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 141 142 Object result(&scope, mainModuleAt(runtime_, "result")); 143 EXPECT_TRUE(isIntEqualsWord(*result, 3)); 144} 145 146TEST_F(ThreadTest, DunderCallInstanceSplatKw) { 147 HandleScope scope(thread_); 148 const char* src = R"( 149class C: 150 def __call__(self, y): 151 return y 152 153c = C() 154kwargs = {'y': 3} 155result = c(**kwargs) 156)"; 157 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 158 159 Object result(&scope, mainModuleAt(runtime_, "result")); 160 EXPECT_TRUE(isIntEqualsWord(*result, 3)); 161} 162 163TEST_F(ThreadTest, DunderCallInstanceSplatArgsAndKw) { 164 HandleScope scope(thread_); 165 const char* src = R"( 166result_x = None 167result_y = None 168class C: 169 def __call__(self, x, y): 170 global result_x 171 global result_y 172 result_x = x 173 result_y = y 174 175c = C() 176args = (1,) 177kwargs = {'y': 3} 178c(*args, **kwargs) 179)"; 180 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 181 182 Object result_x(&scope, mainModuleAt(runtime_, "result_x")); 183 EXPECT_TRUE(isIntEqualsWord(*result_x, 1)); 184 Object result_y(&scope, mainModuleAt(runtime_, "result_y")); 185 EXPECT_TRUE(isIntEqualsWord(*result_y, 3)); 186} 187 188TEST_F(ThreadTest, OverlappingFrames) { 189 HandleScope scope(thread_); 190 191 // Push a frame for a code object with space for 3 items on the value stack 192 Object name(&scope, Str::empty()); 193 Code caller_code(&scope, newCodeWithBytes(View<byte>(nullptr, 0))); 194 caller_code.setStacksize(3); 195 196 Module module(&scope, findMainModule(runtime_)); 197 Function caller(&scope, runtime_->newFunctionWithCode(thread_, name, 198 caller_code, module)); 199 200 thread_->stackPush(*caller); 201 thread_->pushCallFrame(*caller); 202 203 // Push a frame for a code object that expects 3 arguments and needs space 204 // for 3 local variables 205 Locals locals; 206 locals.argcount = 3; 207 Tuple consts(&scope, runtime_->emptyTuple()); 208 Tuple names(&scope, runtime_->emptyTuple()); 209 Code code(&scope, newCodeWithBytesConstsNamesLocals(View<byte>(nullptr, 0), 210 consts, names, &locals)); 211 212 Function function(&scope, 213 runtime_->newFunctionWithCode(thread_, name, code, module)); 214 215 // Push args on the stack in the sequence generated by CPython 216 thread_->stackPush(*function); 217 thread_->stackPush(runtime_->newInt(1111)); 218 thread_->stackPush(runtime_->newInt(2222)); 219 thread_->stackPush(runtime_->newInt(3333)); 220 Frame* frame = thread_->pushCallFrame(*function); 221 222 // Make sure we can read the args from the frame 223 EXPECT_TRUE(isIntEqualsWord(frame->local(0), 1111)); 224 EXPECT_TRUE(isIntEqualsWord(frame->local(1), 2222)); 225 EXPECT_TRUE(isIntEqualsWord(frame->local(2), 3333)); 226} 227 228TEST_F(ThreadTest, EncodeTryBlock) { 229 TryBlock block(TryBlock::kExceptHandler, 200, 300); 230 EXPECT_EQ(block.kind(), TryBlock::kExceptHandler); 231 EXPECT_EQ(block.handler(), 200); 232 EXPECT_EQ(block.level(), 300); 233 234 TryBlock decoded(block.asSmallInt()); 235 EXPECT_EQ(decoded.kind(), block.kind()); 236 EXPECT_EQ(decoded.handler(), block.handler()); 237 EXPECT_EQ(decoded.level(), block.level()); 238} 239 240TEST_F(ThreadTest, PushPopFrame) { 241 HandleScope scope(thread_); 242 243 Tuple consts(&scope, runtime_->emptyTuple()); 244 Tuple names(&scope, runtime_->emptyTuple()); 245 Locals locals; 246 locals.varcount = 2; 247 Code code(&scope, newCodeWithBytesConstsNamesLocals(View<byte>(nullptr, 0), 248 consts, names, &locals)); 249 250 Module module(&scope, findMainModule(runtime_)); 251 Object name(&scope, Str::empty()); 252 Function function(&scope, 253 runtime_->newFunctionWithCode(thread_, name, code, module)); 254 255 RawObject* prev_sp = thread_->stackPointer(); 256 thread_->stackPush(*function); 257 Frame* frame = thread_->pushCallFrame(*function); 258 259 // Verify frame invariants post-push 260 EXPECT_TRUE(frame->previousFrame()->isSentinel()); 261 EXPECT_EQ(thread_->stackPointer(), reinterpret_cast<RawObject*>(frame)); 262 EXPECT_EQ(thread_->valueStackBase(), thread_->stackPointer()); 263 264 // Make sure we restore the thread's stack pointer back to its previous 265 // location 266 thread_->popFrame(); 267 EXPECT_EQ(thread_->stackPointer(), prev_sp); 268} 269 270TEST_F(ThreadTest, PushFrameWithNoCellVars) { 271 HandleScope scope(thread_); 272 273 Code code(&scope, newCodeWithBytes(View<byte>(nullptr, 0))); 274 Module module(&scope, findMainModule(runtime_)); 275 Object name(&scope, Str::empty()); 276 Function function(&scope, 277 runtime_->newFunctionWithCode(thread_, name, code, module)); 278 thread_->stackPush(*function); 279 byte* prev_sp = reinterpret_cast<byte*>(thread_->stackPointer()); 280 thread_->pushCallFrame(*function); 281 282 EXPECT_EQ(reinterpret_cast<byte*>(thread_->stackPointer()), 283 prev_sp - Frame::kSize); 284} 285 286TEST_F(ThreadTest, PushFrameWithNoFreeVars) { 287 HandleScope scope(thread_); 288 289 Code code(&scope, newCodeWithBytes(View<byte>(nullptr, 0))); 290 Module module(&scope, findMainModule(runtime_)); 291 Object name(&scope, Str::empty()); 292 Function function(&scope, 293 runtime_->newFunctionWithCode(thread_, name, code, module)); 294 thread_->stackPush(*function); 295 byte* prev_sp = reinterpret_cast<byte*>(thread_->stackPointer()); 296 thread_->pushCallFrame(*function); 297 298 EXPECT_EQ(reinterpret_cast<byte*>(thread_->stackPointer()), 299 prev_sp - Frame::kSize); 300} 301 302TEST_F(ThreadTest, ManipulateValueStack) { 303 // Push 3 items on the value stack 304 RawObject* sp = thread_->stackPointer(); 305 *--sp = SmallInt::fromWord(1111); 306 *--sp = SmallInt::fromWord(2222); 307 *--sp = SmallInt::fromWord(3333); 308 thread_->setStackPointer(sp); 309 ASSERT_EQ(thread_->stackPointer(), sp); 310 311 // Verify the value stack is laid out as we expect 312 EXPECT_TRUE(isIntEqualsWord(thread_->stackPeek(0), 3333)); 313 EXPECT_TRUE(isIntEqualsWord(thread_->stackPeek(1), 2222)); 314 EXPECT_TRUE(isIntEqualsWord(thread_->stackPeek(2), 1111)); 315 316 // Pop 2 items off the stack and check the stack is still as we expect 317 thread_->setStackPointer(sp + 2); 318 EXPECT_TRUE(isIntEqualsWord(thread_->stackPeek(0), 1111)); 319} 320 321TEST_F(ThreadTest, ManipulateBlockStack) { 322 Frame* frame = thread_->currentFrame(); 323 324 TryBlock pushed1(TryBlock::kFinally, 100, 10); 325 frame->blockStackPush(pushed1); 326 327 TryBlock pushed2(TryBlock::kExceptHandler, 200, 20); 328 frame->blockStackPush(pushed2); 329 330 TryBlock popped2 = frame->blockStackPop(); 331 EXPECT_EQ(popped2.kind(), pushed2.kind()); 332 EXPECT_EQ(popped2.handler(), pushed2.handler()); 333 EXPECT_EQ(popped2.level(), pushed2.level()); 334 335 TryBlock popped1 = frame->blockStackPop(); 336 EXPECT_EQ(popped1.kind(), pushed1.kind()); 337 EXPECT_EQ(popped1.handler(), pushed1.handler()); 338 EXPECT_EQ(popped1.level(), pushed1.level()); 339} 340 341TEST_F(ThreadTest, CallFunction) { 342 HandleScope scope(thread_); 343 344 // Build the code object for the following function 345 // 346 // def noop(arg0, arg1): 347 // return 2222 348 // 349 Locals locals; 350 locals.argcount = 2; 351 Object obj(&scope, runtime_->newInt(2222)); 352 Tuple callee_consts(&scope, runtime_->newTupleWith1(obj)); 353 Tuple names(&scope, runtime_->emptyTuple()); 354 const byte callee_bytecode[] = {LOAD_CONST, 0, RETURN_VALUE, 0}; 355 Code callee_code(&scope, newCodeWithBytesConstsNamesLocals( 356 callee_bytecode, callee_consts, names, &locals)); 357 358 // Create the function object and bind it to the code object 359 Object qualname(&scope, Str::empty()); 360 Module module(&scope, findMainModule(runtime_)); 361 Function callee(&scope, runtime_->newFunctionWithCode(thread_, qualname, 362 callee_code, module)); 363 364 // Build a code object to call the function defined above 365 Object obj1(&scope, SmallInt::fromWord(1111)); 366 Object obj2(&scope, SmallInt::fromWord(2222)); 367 Tuple caller_consts(&scope, runtime_->newTupleWith3(callee, obj1, obj2)); 368 const byte caller_bytecode[] = {LOAD_CONST, 0, LOAD_CONST, 1, 369 LOAD_CONST, 2, CALL_FUNCTION, 2, 370 RETURN_VALUE, 0}; 371 Code caller_code(&scope, 372 newCodeWithBytesConsts(caller_bytecode, caller_consts)); 373 374 // Execute the caller and make sure we get back the expected result 375 EXPECT_TRUE(isIntEqualsWord(runCode(caller_code), 2222)); 376} 377 378TEST_F(ThreadTest, ExtendedArg) { 379 HandleScope scope(thread_); 380 381 const word num_consts = 258; 382 const byte bytecode[] = {EXTENDED_ARG, 1, LOAD_CONST, 1, RETURN_VALUE, 0}; 383 384 MutableTuple constants(&scope, runtime_->newMutableTuple(num_consts)); 385 386 auto zero = SmallInt::fromWord(0); 387 auto non_zero = SmallInt::fromWord(0xDEADBEEF); 388 for (word i = 0; i < num_consts - 2; i++) { 389 constants.atPut(i, zero); 390 } 391 constants.atPut(num_consts - 1, non_zero); 392 Tuple consts(&scope, constants.becomeImmutable()); 393 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 394 395 EXPECT_TRUE(isIntEqualsWord(runCode(code), 0xDEADBEEF)); 396} 397 398TEST_F(ThreadTest, ExecuteDupTop) { 399 HandleScope scope(thread_); 400 401 Object obj(&scope, SmallInt::fromWord(1111)); 402 Tuple consts(&scope, runtime_->newTupleWith1(obj)); 403 const byte bytecode[] = {LOAD_CONST, 0, DUP_TOP, 0, RETURN_VALUE, 0}; 404 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 405 406 EXPECT_TRUE(isIntEqualsWord(runCode(code), 1111)); 407} 408 409TEST_F(ThreadTest, ExecuteDupTopTwo) { 410 HandleScope scope(thread_); 411 412 Object obj1(&scope, SmallInt::fromWord(1111)); 413 Object obj2(&scope, SmallInt::fromWord(2222)); 414 Tuple consts(&scope, runtime_->newTupleWith2(obj1, obj2)); 415 const byte bytecode[] = {LOAD_CONST, 0, LOAD_CONST, 1, 416 DUP_TOP_TWO, 0, RETURN_VALUE, 0}; 417 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 418 419 EXPECT_TRUE(isIntEqualsWord(runCode(code), 2222)); 420} 421 422TEST_F(ThreadTest, ExecuteRotTwo) { 423 HandleScope scope(thread_); 424 425 Object obj1(&scope, SmallInt::fromWord(1111)); 426 Object obj2(&scope, SmallInt::fromWord(2222)); 427 Tuple consts(&scope, runtime_->newTupleWith2(obj1, obj2)); 428 const byte bytecode[] = {LOAD_CONST, 0, LOAD_CONST, 1, 429 ROT_TWO, 0, RETURN_VALUE, 0}; 430 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 431 432 EXPECT_TRUE(isIntEqualsWord(runCode(code), 1111)); 433} 434 435TEST_F(ThreadTest, ExecuteRotThree) { 436 HandleScope scope(thread_); 437 438 Object obj1(&scope, SmallInt::fromWord(1111)); 439 Object obj2(&scope, SmallInt::fromWord(2222)); 440 Object obj3(&scope, SmallInt::fromWord(3333)); 441 Tuple consts(&scope, runtime_->newTupleWith3(obj1, obj2, obj3)); 442 const byte bytecode[] = {LOAD_CONST, 0, LOAD_CONST, 1, LOAD_CONST, 2, 443 ROT_THREE, 0, RETURN_VALUE, 0}; 444 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 445 446 EXPECT_TRUE(isIntEqualsWord(runCode(code), 2222)); 447} 448 449TEST_F(ThreadTest, ExecuteRotFour) { 450 HandleScope scope(thread_); 451 452 Object obj1(&scope, SmallInt::fromWord(1111)); 453 Object obj2(&scope, SmallInt::fromWord(2222)); 454 Object obj3(&scope, SmallInt::fromWord(3333)); 455 Object obj4(&scope, SmallInt::fromWord(4444)); 456 Tuple consts(&scope, runtime_->newTupleWith4(obj1, obj2, obj3, obj4)); 457 const byte bytecode[] = {LOAD_CONST, 0, LOAD_CONST, 1, LOAD_CONST, 2, 458 LOAD_CONST, 3, ROT_FOUR, 0, RETURN_VALUE, 0}; 459 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 460 461 EXPECT_TRUE(isIntEqualsWord(runCode(code), 3333)); 462} 463 464TEST_F(ThreadTest, ExecuteJumpAbsolute) { 465 HandleScope scope(thread_); 466 467 Object obj1(&scope, SmallInt::fromWord(1111)); 468 Object obj2(&scope, SmallInt::fromWord(2222)); 469 Tuple consts(&scope, runtime_->newTupleWith2(obj1, obj2)); 470 const byte bytecode[] = {JUMP_ABSOLUTE, 4, LOAD_CONST, 0, 471 LOAD_CONST, 1, RETURN_VALUE, 0}; 472 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 473 474 EXPECT_TRUE(isIntEqualsWord(runCode(code), 2222)); 475} 476 477TEST_F(ThreadTest, ExecuteJumpForward) { 478 HandleScope scope(thread_); 479 480 Object obj1(&scope, SmallInt::fromWord(1111)); 481 Object obj2(&scope, SmallInt::fromWord(2222)); 482 Tuple consts(&scope, runtime_->newTupleWith2(obj1, obj2)); 483 const byte bytecode[] = {JUMP_FORWARD, 2, LOAD_CONST, 0, 484 LOAD_CONST, 1, RETURN_VALUE, 0}; 485 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 486 487 EXPECT_TRUE(isIntEqualsWord(runCode(code), 2222)); 488} 489 490TEST_F(ThreadTest, ExecuteStoreLoadFast) { 491 HandleScope scope(thread_); 492 493 Object obj(&scope, SmallInt::fromWord(1111)); 494 Tuple consts(&scope, runtime_->newTupleWith1(obj)); 495 Tuple names(&scope, runtime_->emptyTuple()); 496 Locals locals; 497 locals.varcount = 2; 498 const byte bytecode[] = {LOAD_CONST, 0, STORE_FAST, 1, 499 LOAD_FAST, 1, RETURN_VALUE, 0}; 500 Code code(&scope, newCodeWithBytesConstsNamesLocals(bytecode, consts, names, 501 &locals)); 502 503 EXPECT_TRUE(isIntEqualsWord(runCode(code), 1111)); 504} 505 506TEST_F(ThreadTest, LoadGlobal) { 507 HandleScope scope(thread_); 508 509 Object name(&scope, Runtime::internStrFromCStr(thread_, "foo")); 510 Tuple names(&scope, runtime_->newTupleWith1(name)); 511 Tuple consts(&scope, runtime_->emptyTuple()); 512 const byte bytecode[] = {LOAD_GLOBAL, 0, RETURN_VALUE, 0}; 513 Code code(&scope, 514 newCodeWithBytesConstsNamesFlags(bytecode, consts, names, 0)); 515 516 Module module(&scope, findMainModule(runtime_)); 517 Object value(&scope, runtime_->newInt(1234)); 518 moduleAtPut(thread_, module, name, value); 519 520 Object none(&scope, NoneType::object()); 521 EXPECT_TRUE(isIntEqualsWord(thread_->exec(code, module, none), 1234)); 522} 523 524TEST_F(ThreadTest, StoreGlobalCreateValueCell) { 525 HandleScope scope(thread_); 526 527 Object obj(&scope, SmallInt::fromWord(42)); 528 Tuple consts(&scope, runtime_->newTupleWith1(obj)); 529 Object name(&scope, Runtime::internStrFromCStr(thread_, "foo")); 530 Tuple names(&scope, runtime_->newTupleWith1(name)); 531 const byte bytecode[] = {LOAD_CONST, 0, STORE_GLOBAL, 0, 532 LOAD_CONST, 0, RETURN_VALUE, 0}; 533 Code code(&scope, 534 newCodeWithBytesConstsNamesFlags(bytecode, consts, names, 0)); 535 536 Module module(&scope, findMainModule(runtime_)); 537 Object none(&scope, NoneType::object()); 538 EXPECT_TRUE(isIntEqualsWord(thread_->exec(code, module, none), 42)); 539 EXPECT_TRUE(isIntEqualsWord(moduleAt(module, name), 42)); 540} 541 542TEST_F(ThreadTest, StoreGlobalReuseValueCell) { 543 HandleScope scope(thread_); 544 545 Object obj(&scope, SmallInt::fromWord(42)); 546 Tuple consts(&scope, runtime_->newTupleWith1(obj)); 547 Object name(&scope, Runtime::internStrFromCStr(thread_, "foo")); 548 Tuple names(&scope, runtime_->newTupleWith1(name)); 549 const byte bytecode[] = {LOAD_CONST, 0, STORE_GLOBAL, 0, 550 LOAD_CONST, 0, RETURN_VALUE, 0}; 551 Code code(&scope, 552 newCodeWithBytesConstsNamesFlags(bytecode, consts, names, 0)); 553 554 Module module(&scope, findMainModule(runtime_)); 555 Object value(&scope, runtime_->newInt(99)); 556 moduleAtPut(thread_, module, name, value); 557 Object none(&scope, NoneType::object()); 558 EXPECT_TRUE(isIntEqualsWord(thread_->exec(code, module, none), 42)); 559 EXPECT_TRUE(isIntEqualsWord(moduleAt(module, name), 42)); 560} 561 562TEST_F(ThreadTest, LoadNameInModuleBodyFromBuiltins) { 563 HandleScope scope(thread_); 564 565 Tuple consts(&scope, runtime_->emptyTuple()); 566 Object name(&scope, Runtime::internStrFromCStr(thread_, "foo")); 567 Tuple names(&scope, runtime_->newTupleWith1(name)); 568 const byte bytecode[] = {LOAD_NAME, 0, RETURN_VALUE, 0}; 569 Code code(&scope, 570 newCodeWithBytesConstsNamesFlags(bytecode, consts, names, 0)); 571 572 Object builtins_name(&scope, runtime_->symbols()->at(ID(builtins))); 573 Module builtins(&scope, runtime_->newModule(builtins_name)); 574 Module module(&scope, findMainModule(runtime_)); 575 moduleAtPutById(thread_, module, ID(__builtins__), builtins); 576 Object value(&scope, runtime_->newInt(123)); 577 moduleAtPut(thread_, builtins, name, value); 578 Dict locals(&scope, runtime_->newDict()); 579 EXPECT_TRUE(isIntEqualsWord(thread_->exec(code, module, locals), 123)); 580} 581 582TEST_F(ThreadTest, LoadNameFromGlobals) { 583 HandleScope scope(thread_); 584 585 Tuple consts(&scope, runtime_->emptyTuple()); 586 Object name(&scope, Runtime::internStrFromCStr(thread_, "foo")); 587 Tuple names(&scope, runtime_->newTupleWith1(name)); 588 const byte bytecode[] = {LOAD_NAME, 0, RETURN_VALUE, 0}; 589 Code code(&scope, 590 newCodeWithBytesConstsNamesFlags(bytecode, consts, names, 0)); 591 592 Module module(&scope, findMainModule(runtime_)); 593 Object value(&scope, runtime_->newInt(321)); 594 moduleAtPut(thread_, module, name, value); 595 Dict locals(&scope, runtime_->newDict()); 596 597 EXPECT_TRUE(isIntEqualsWord(thread_->exec(code, module, locals), 321)); 598} 599 600TEST_F(ThreadTest, LoadNameFromLocals) { 601 HandleScope scope(thread_); 602 603 Tuple consts(&scope, runtime_->emptyTuple()); 604 Object name(&scope, Runtime::internStrFromCStr(thread_, "foo")); 605 Tuple names(&scope, runtime_->newTupleWith1(name)); 606 const byte bytecode[] = {LOAD_NAME, 0, RETURN_VALUE, 0}; 607 Code code(&scope, 608 newCodeWithBytesConstsNamesFlags(bytecode, consts, names, 0)); 609 610 Module module(&scope, findMainModule(runtime_)); 611 Object globals_value(&scope, runtime_->newInt(456)); 612 moduleAtPut(thread_, module, name, globals_value); 613 Dict locals(&scope, runtime_->newDict()); 614 Object locals_value(&scope, runtime_->newInt(654)); 615 dictAtPutByStr(thread_, locals, name, locals_value); 616 EXPECT_TRUE(isIntEqualsWord(thread_->exec(code, module, locals), 654)); 617} 618 619TEST_F(ThreadTest, MakeFunction) { 620 HandleScope scope(thread_); 621 622 Code func_code(&scope, newCodeWithBytes(View<byte>(nullptr, 0))); 623 func_code.setName(runtime_->newStrFromCStr("hello")); 624 625 Object obj1(&scope, runtime_->newStrFromCStr("hello_qualname")); 626 Object obj2(&scope, NoneType::object()); 627 Tuple consts(&scope, runtime_->newTupleWith3(func_code, obj1, obj2)); 628 629 Object name(&scope, runtime_->newStrFromCStr("hello")); 630 Tuple names(&scope, runtime_->newTupleWith1(name)); 631 632 const byte bytecode[] = {LOAD_CONST, 0, LOAD_CONST, 1, MAKE_FUNCTION, 0, 633 STORE_NAME, 0, LOAD_CONST, 2, RETURN_VALUE, 0}; 634 Code code(&scope, 635 newCodeWithBytesConstsNamesFlags(bytecode, consts, names, 0)); 636 637 Module module(&scope, findMainModule(runtime_)); 638 Dict locals(&scope, runtime_->newDict()); 639 ASSERT_TRUE(thread_->exec(code, module, locals).isNoneType()); 640 641 Object function_obj(&scope, dictAtByStr(thread_, locals, name)); 642 ASSERT_TRUE(function_obj.isFunction()); 643 Function function(&scope, *function_obj); 644 EXPECT_EQ(function.code(), func_code); 645 EXPECT_TRUE(isStrEqualsCStr(function.name(), "hello")); 646 EXPECT_TRUE(isStrEqualsCStr(function.qualname(), "hello_qualname")); 647 EXPECT_EQ(function.entry(), &interpreterTrampoline); 648} 649 650TEST_F(ThreadTest, BuildList) { 651 HandleScope scope(thread_); 652 653 Object obj1(&scope, SmallInt::fromWord(111)); 654 Object obj2(&scope, runtime_->newStrFromCStr("qqq")); 655 Object obj3(&scope, NoneType::object()); 656 Tuple consts(&scope, runtime_->newTupleWith3(obj1, obj2, obj3)); 657 658 const byte bytecode[] = {LOAD_CONST, 0, LOAD_CONST, 1, LOAD_CONST, 2, 659 BUILD_LIST, 3, RETURN_VALUE, 0}; 660 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 661 662 Object result_obj(&scope, runCode(code)); 663 ASSERT_TRUE(result_obj.isList()); 664 List list(&scope, *result_obj); 665 EXPECT_EQ(list.numItems(), 3); 666 EXPECT_TRUE(isIntEqualsWord(list.at(0), 111)); 667 EXPECT_TRUE(isStrEqualsCStr(list.at(1), "qqq")); 668 EXPECT_TRUE(list.at(2).isNoneType()); 669} 670 671TEST_F(ThreadTest, BuildSetEmpty) { 672 HandleScope scope(thread_); 673 674 const byte bytecode[] = {BUILD_SET, 0, RETURN_VALUE, 0}; 675 Code code(&scope, newCodeWithBytes(bytecode)); 676 677 Object result_obj(&scope, runCode(code)); 678 ASSERT_TRUE(result_obj.isSet()); 679 Set result(&scope, *result_obj); 680 EXPECT_EQ(result.numItems(), 0); 681} 682 683TEST_F(ThreadTest, BuildSetWithOneItem) { 684 HandleScope scope(thread_); 685 686 Object obj(&scope, runtime_->newInt(111)); 687 Tuple consts(&scope, runtime_->newTupleWith2(obj, obj)); // dup 688 const byte bytecode[] = {LOAD_CONST, 0, LOAD_CONST, 1, 689 BUILD_SET, 2, RETURN_VALUE, 0}; 690 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 691 692 Object result_obj(&scope, runCode(code)); 693 ASSERT_TRUE(result_obj.isSet()); 694 Set result(&scope, *result_obj); 695 EXPECT_EQ(result.numItems(), 1); 696 Object int_val(&scope, SmallInt::fromWord(111)); 697 EXPECT_TRUE(setIncludes(thread_, result, int_val)); 698} 699 700TEST_F(ThreadTest, BuildSet) { 701 HandleScope scope(thread_); 702 703 Object obj1(&scope, runtime_->newInt(111)); 704 Object obj2(&scope, runtime_->newStrFromCStr("qqq")); 705 Object obj3(&scope, NoneType::object()); 706 Tuple consts(&scope, runtime_->newTupleWith4(obj1, obj1, obj2, obj3)); // dup 707 const byte bytecode[] = {LOAD_CONST, 0, LOAD_CONST, 1, LOAD_CONST, 2, 708 LOAD_CONST, 3, BUILD_SET, 4, RETURN_VALUE, 0}; 709 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 710 711 Object result_obj(&scope, runCode(code)); 712 ASSERT_TRUE(result_obj.isSet()); 713 Set result(&scope, *result_obj); 714 EXPECT_EQ(result.numItems(), 3); 715 Object int_val(&scope, runtime_->newInt(111)); 716 EXPECT_TRUE(setIncludes(thread_, result, int_val)); 717 Object str(&scope, runtime_->newStrFromCStr("qqq")); 718 EXPECT_TRUE(setIncludes(thread_, result, str)); 719 Object none(&scope, NoneType::object()); 720 EXPECT_TRUE(setIncludes(thread_, result, none)); 721} 722 723TEST_F(ThreadTest, PopJumpIfFalseWithTruthy) { 724 HandleScope scope(thread_); 725 726 Object obj1(&scope, Bool::trueObj()); 727 Object obj2(&scope, SmallInt::fromWord(1111)); 728 Object obj3(&scope, SmallInt::fromWord(2222)); 729 Tuple consts(&scope, runtime_->newTupleWith3(obj1, obj2, obj3)); 730 // Bytecode for the snippet: 731 // if x: 732 // return 1111 733 // return 2222 734 const byte bytecode[] = {LOAD_CONST, 0, POP_JUMP_IF_FALSE, 8, 735 LOAD_CONST, 1, RETURN_VALUE, 0, 736 LOAD_CONST, 2, RETURN_VALUE, 0}; 737 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 738 739 EXPECT_TRUE(isIntEqualsWord(runCode(code), 1111)); 740} 741 742TEST_F(ThreadTest, PopJumpIfFalseWithFalsey) { 743 HandleScope scope(thread_); 744 745 Object obj1(&scope, Bool::falseObj()); 746 Object obj2(&scope, SmallInt::fromWord(1111)); 747 Object obj3(&scope, SmallInt::fromWord(2222)); 748 Tuple consts(&scope, runtime_->newTupleWith3(obj1, obj2, obj3)); 749 // Bytecode for the snippet: 750 // if x: 751 // return 1111 752 // return 2222 753 const byte bytecode[] = {LOAD_CONST, 0, POP_JUMP_IF_FALSE, 8, 754 LOAD_CONST, 1, RETURN_VALUE, 0, 755 LOAD_CONST, 2, RETURN_VALUE, 0}; 756 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 757 758 EXPECT_TRUE(isIntEqualsWord(runCode(code), 2222)); 759} 760 761TEST_F(ThreadTest, PopJumpIfTrueWithFalsey) { 762 HandleScope scope(thread_); 763 764 Object obj1(&scope, Bool::falseObj()); 765 Object obj2(&scope, SmallInt::fromWord(1111)); 766 Object obj3(&scope, SmallInt::fromWord(2222)); 767 Tuple consts(&scope, runtime_->newTupleWith3(obj1, obj2, obj3)); 768 // Bytecode for the snippet: 769 // if not x: 770 // return 1111 771 // return 2222 772 const byte bytecode[] = {LOAD_CONST, 0, POP_JUMP_IF_TRUE, 8, 773 LOAD_CONST, 1, RETURN_VALUE, 0, 774 LOAD_CONST, 2, RETURN_VALUE, 0}; 775 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 776 777 EXPECT_TRUE(isIntEqualsWord(runCode(code), 1111)); 778} 779 780TEST_F(ThreadTest, PopJumpIfTrueWithTruthy) { 781 HandleScope scope(thread_); 782 783 Object obj1(&scope, Bool::trueObj()); 784 Object obj2(&scope, SmallInt::fromWord(1111)); 785 Object obj3(&scope, SmallInt::fromWord(2222)); 786 Tuple consts(&scope, runtime_->newTupleWith3(obj1, obj2, obj3)); 787 // Bytecode for the snippet: 788 // if not x: 789 // return 1111 790 // return 2222 791 const byte bytecode[] = {LOAD_CONST, 0, POP_JUMP_IF_TRUE, 8, 792 LOAD_CONST, 1, RETURN_VALUE, 0, 793 LOAD_CONST, 2, RETURN_VALUE, 0}; 794 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 795 796 EXPECT_TRUE(isIntEqualsWord(runCode(code), 2222)); 797} 798 799TEST_F(ThreadTest, JumpIfFalseOrPopWithFalsey) { 800 HandleScope scope(thread_); 801 802 Object obj1(&scope, Bool::falseObj()); 803 Object obj2(&scope, SmallInt::fromWord(1111)); 804 Tuple consts(&scope, runtime_->newTupleWith2(obj1, obj2)); 805 const byte bytecode[] = {LOAD_CONST, 0, JUMP_IF_FALSE_OR_POP, 6, 806 LOAD_CONST, 1, RETURN_VALUE, 0}; 807 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 808 809 // If the condition is false, we should return the top of the stack, which is 810 // the condition itself 811 EXPECT_EQ(runCode(code), Bool::falseObj()); 812} 813 814TEST_F(ThreadTest, JumpIfFalseOrPopWithTruthy) { 815 HandleScope scope(thread_); 816 817 Object obj1(&scope, Bool::trueObj()); 818 Object obj2(&scope, SmallInt::fromWord(1111)); 819 Tuple consts(&scope, runtime_->newTupleWith2(obj1, obj2)); 820 const byte bytecode[] = {LOAD_CONST, 0, JUMP_IF_FALSE_OR_POP, 6, 821 LOAD_CONST, 1, RETURN_VALUE, 0}; 822 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 823 824 // If the condition is true, we should pop the top of the stack (the 825 // condition) and continue execution. In our case that loads a const and 826 // returns it. 827 EXPECT_TRUE(isIntEqualsWord(runCode(code), 1111)); 828} 829 830TEST_F(ThreadTest, JumpIfTrueOrPopWithTruthy) { 831 HandleScope scope(thread_); 832 833 Object obj1(&scope, Bool::trueObj()); 834 Object obj2(&scope, SmallInt::fromWord(1111)); 835 Tuple consts(&scope, runtime_->newTupleWith2(obj1, obj2)); 836 const byte bytecode[] = {LOAD_CONST, 0, JUMP_IF_TRUE_OR_POP, 6, 837 LOAD_CONST, 1, RETURN_VALUE, 0}; 838 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 839 840 // If the condition is true, we should return the top of the stack, which is 841 // the condition itself 842 EXPECT_EQ(runCode(code), Bool::trueObj()); 843} 844 845TEST_F(ThreadTest, JumpIfTrueOrPopWithFalsey) { 846 HandleScope scope(thread_); 847 848 Object obj1(&scope, Bool::falseObj()); 849 Object obj2(&scope, SmallInt::fromWord(1111)); 850 Tuple consts(&scope, runtime_->newTupleWith2(obj1, obj2)); 851 const byte bytecode[] = {LOAD_CONST, 0, JUMP_IF_TRUE_OR_POP, 6, 852 LOAD_CONST, 1, RETURN_VALUE, 0}; 853 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 854 855 // If the condition is false, we should pop the top of the stack (the 856 // condition) and continue execution. In our case that loads a const and 857 // returns it. 858 EXPECT_TRUE(isIntEqualsWord(runCode(code), 1111)); 859} 860 861TEST_F(ThreadTest, UnaryNotWithTruthy) { 862 HandleScope scope(thread_); 863 864 Object obj(&scope, Bool::trueObj()); 865 Tuple consts(&scope, runtime_->newTupleWith1(obj)); 866 // Bytecode for the snippet: 867 // return not x 868 const byte bytecode[] = {LOAD_CONST, 0, UNARY_NOT, 0, RETURN_VALUE, 0}; 869 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 870 871 // If the condition is true, we should return false 872 EXPECT_EQ(runCode(code), Bool::falseObj()); 873} 874 875TEST_F(ThreadTest, UnaryNotWithFalsey) { 876 HandleScope scope(thread_); 877 878 Object obj(&scope, Bool::falseObj()); 879 Tuple consts(&scope, runtime_->newTupleWith1(obj)); 880 // Bytecode for the snippet: 881 // return not x 882 const byte bytecode[] = {LOAD_CONST, 0, UNARY_NOT, 0, RETURN_VALUE, 0}; 883 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 884 885 // If the condition is false, we should return true 886 EXPECT_EQ(runCode(code), Bool::trueObj()); 887} 888 889TEST_F(ThreadTest, LoadBuildTypeEmptyType) { 890 HandleScope scope(thread_); 891 892 ASSERT_FALSE(runFromCStr(runtime_, R"( 893class C: 894 pass 895)") 896 .isError()); 897 898 Type cls(&scope, mainModuleAt(runtime_, "C")); 899 ASSERT_TRUE(cls.name().isSmallStr()); 900 EXPECT_EQ(cls.name(), SmallStr::fromCStr("C")); 901 902 Tuple mro(&scope, cls.mro()); 903 EXPECT_EQ(mro.length(), 2); 904 EXPECT_EQ(mro.at(0), *cls); 905 EXPECT_EQ(mro.at(1), runtime_->typeAt(LayoutId::kObject)); 906} 907 908TEST_F(ThreadTest, LoadBuildTypeTypeWithInit) { 909 HandleScope scope(thread_); 910 911 ASSERT_FALSE(runFromCStr(runtime_, R"( 912class C: 913 def __init__(self): 914 pass 915)") 916 .isError()); 917 918 Module mod(&scope, findMainModule(runtime_)); 919 ASSERT_TRUE(mod.isModule()); 920 921 Str cls_name(&scope, Runtime::internStrFromCStr(thread_, "C")); 922 Object value(&scope, moduleAt(mod, cls_name)); 923 ASSERT_TRUE(value.isType()); 924 Type cls(&scope, *value); 925 926 // Check class MRO 927 Tuple mro(&scope, cls.mro()); 928 EXPECT_EQ(mro.length(), 2); 929 EXPECT_EQ(mro.at(0), *cls); 930 EXPECT_EQ(mro.at(1), runtime_->typeAt(LayoutId::kObject)); 931 932 // Check class name 933 ASSERT_TRUE(cls.name().isSmallStr()); 934 EXPECT_EQ(cls.name(), SmallStr::fromCStr("C")); 935 936 // Check for the __init__ method name in the dict 937 value = typeAtById(thread_, cls, ID(__init__)); 938 ASSERT_FALSE(value.isError()); 939 EXPECT_TRUE(value.isFunction()); 940} 941 942static ALIGN_16 RawObject nativeExceptionTest(Thread* thread, Arguments) { 943 HandleScope scope(thread); 944 Str msg(&scope, 945 Str::cast(thread->runtime()->newStrFromCStr("test exception"))); 946 return thread->raise(LayoutId::kRuntimeError, *msg); 947} 948 949TEST_F(ThreadTest, NativeExceptions) { 950 HandleScope scope(thread_); 951 952 Object name(&scope, runtime_->newStrFromCStr("fn")); 953 Object empty_tuple(&scope, runtime_->emptyTuple()); 954 Code fn_code(&scope, runtime_->newBuiltinCode( 955 /*argcount=*/0, /*posonlyargcount=*/0, 956 /*kwonlyargcount=*/0, /*flags=*/0, 957 nativeExceptionTest, empty_tuple, name)); 958 Module module(&scope, findMainModule(runtime_)); 959 Function fn(&scope, 960 runtime_->newFunctionWithCode(thread_, name, fn_code, module)); 961 962 Tuple consts(&scope, runtime_->newTupleWith1(fn)); 963 // Call the native fn and check that a pending exception is left in the 964 // Thread. 965 const byte bytecode[] = {LOAD_CONST, 0, CALL_FUNCTION, 0, RETURN_VALUE, 0}; 966 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 967 968 EXPECT_TRUE(raised(runCode(code), LayoutId::kRuntimeError)); 969 Object value(&scope, thread_->pendingExceptionValue()); 970 ASSERT_TRUE(value.isStr()); 971 Str str(&scope, *value); 972 EXPECT_TRUE(str.equalsCStr("test exception")); 973} 974 975TEST_F(ThreadTest, PendingStopIterationValueInspectsTuple) { 976 HandleScope scope(thread_); 977 978 Object obj1(&scope, runtime_->newInt(123)); 979 Object obj2(&scope, runtime_->newInt(456)); 980 Tuple tuple(&scope, runtime_->newTupleWith2(obj1, obj2)); 981 thread_->raise(LayoutId::kStopIteration, *tuple); 982 983 ASSERT_TRUE(thread_->hasPendingStopIteration()); 984 EXPECT_TRUE(isIntEqualsWord(thread_->pendingStopIterationValue(), 123)); 985} 986 987TEST_F(ThreadTest, 988 RaiseStopIterationWithTupleReturnedByPendingStopIterationValue) { 989 HandleScope scope(thread_); 990 991 Object obj1(&scope, runtime_->newInt(123)); 992 Object obj2(&scope, runtime_->newInt(456)); 993 Tuple tuple(&scope, runtime_->newTupleWith2(obj1, obj2)); 994 thread_->raiseStopIterationWithValue(tuple); 995 996 ASSERT_TRUE(thread_->hasPendingStopIteration()); 997 EXPECT_EQ(thread_->pendingStopIterationValue(), tuple); 998} 999 1000TEST_F(ThreadTest, 1001 RaiseStopIterationWithStopIterationReturnedByPendingStopIterationValue) { 1002 HandleScope scope(thread_); 1003 1004 Object obj1(&scope, runtime_->newInt(123)); 1005 Type stop_iteration_type(&scope, runtime_->typeAt(LayoutId::kStopIteration)); 1006 Object stop_iteration(&scope, 1007 Interpreter::call1(thread_, stop_iteration_type, obj1)); 1008 thread_->raiseStopIterationWithValue(stop_iteration); 1009 1010 ASSERT_TRUE(thread_->hasPendingStopIteration()); 1011 EXPECT_EQ(thread_->pendingStopIterationValue(), stop_iteration); 1012} 1013 1014TEST_F(ThreadTest, 1015 RaiseStopIterationWithIntReturnedByPendingStopIterationValue) { 1016 HandleScope scope(thread_); 1017 1018 Object obj1(&scope, runtime_->newInt(123)); 1019 thread_->raiseStopIterationWithValue(obj1); 1020 1021 ASSERT_TRUE(thread_->hasPendingStopIteration()); 1022 EXPECT_EQ(thread_->pendingStopIterationValue(), obj1); 1023} 1024 1025TEST_F(ThreadTest, RaiseWithTypePreservesTraceback) { 1026 HandleScope scope(thread_); 1027 Layout layout(&scope, runtime_->layoutAt(LayoutId::kBaseException)); 1028 BaseException exc(&scope, runtime_->newInstance(layout)); 1029 Object tb(&scope, runtime_->newTraceback()); 1030 exc.setTraceback(*tb); 1031 thread_->raiseWithType(runtime_->typeOf(*exc), *exc); 1032 Object pending_exc_tb(&scope, thread_->pendingExceptionTraceback()); 1033 EXPECT_EQ(tb, pending_exc_tb); 1034} 1035 1036// MRO tests 1037 1038TEST_F(ThreadTest, LoadBuildTypeVerifyMro) { 1039 HandleScope scope(thread_); 1040 1041 ASSERT_FALSE(runFromCStr(runtime_, R"( 1042class A: pass 1043class B: pass 1044class C(A,B): pass 1045)") 1046 .isError()); 1047 1048 Object a(&scope, mainModuleAt(runtime_, "A")); 1049 Object b(&scope, mainModuleAt(runtime_, "B")); 1050 Type c(&scope, mainModuleAt(runtime_, "C")); 1051 Object object(&scope, moduleAtByCStr(runtime_, "builtins", "object")); 1052 Tuple mro(&scope, c.mro()); 1053 ASSERT_EQ(mro.length(), 4); 1054 EXPECT_EQ(mro.at(0), c); 1055 EXPECT_EQ(mro.at(1), a); 1056 EXPECT_EQ(mro.at(2), b); 1057 EXPECT_EQ(mro.at(3), object); 1058} 1059 1060TEST_F(ThreadTest, LoadBuildTypeVerifyMroInheritance) { 1061 HandleScope scope(thread_); 1062 1063 ASSERT_FALSE(runFromCStr(runtime_, R"( 1064class A: pass 1065class B(A): pass 1066class C(B): pass 1067)") 1068 .isError()); 1069 1070 Object a(&scope, mainModuleAt(runtime_, "A")); 1071 Object b(&scope, mainModuleAt(runtime_, "B")); 1072 Type c(&scope, mainModuleAt(runtime_, "C")); 1073 Object object(&scope, moduleAtByCStr(runtime_, "builtins", "object")); 1074 Tuple mro(&scope, c.mro()); 1075 ASSERT_EQ(mro.length(), 4); 1076 EXPECT_EQ(mro.at(0), c); 1077 EXPECT_EQ(mro.at(1), b); 1078 EXPECT_EQ(mro.at(2), a); 1079 EXPECT_EQ(mro.at(3), object); 1080} 1081 1082TEST_F(ThreadTest, LoadBuildTypeVerifyMroMultiInheritance) { 1083 HandleScope scope(thread_); 1084 1085 ASSERT_FALSE(runFromCStr(runtime_, R"( 1086class A: pass 1087class B(A): pass 1088class C: pass 1089class D(B,C): pass 1090)") 1091 .isError()); 1092 1093 Object a(&scope, mainModuleAt(runtime_, "A")); 1094 Object b(&scope, mainModuleAt(runtime_, "B")); 1095 Object c(&scope, mainModuleAt(runtime_, "C")); 1096 Type d(&scope, mainModuleAt(runtime_, "D")); 1097 Object object(&scope, moduleAtByCStr(runtime_, "builtins", "object")); 1098 Tuple mro(&scope, d.mro()); 1099 ASSERT_EQ(mro.length(), 5); 1100 EXPECT_EQ(mro.at(0), d); 1101 EXPECT_EQ(mro.at(1), b); 1102 EXPECT_EQ(mro.at(2), a); 1103 EXPECT_EQ(mro.at(3), c); 1104 EXPECT_EQ(mro.at(4), object); 1105} 1106 1107TEST_F(ThreadTest, LoadBuildTypeVerifyMroDiamond) { 1108 HandleScope scope(thread_); 1109 1110 ASSERT_FALSE(runFromCStr(runtime_, R"( 1111class A: pass 1112class B(A): pass 1113class C(A): pass 1114class D(B,C): pass 1115)") 1116 .isError()); 1117 1118 Object a(&scope, mainModuleAt(runtime_, "A")); 1119 Object b(&scope, mainModuleAt(runtime_, "B")); 1120 Object c(&scope, mainModuleAt(runtime_, "C")); 1121 Type d(&scope, mainModuleAt(runtime_, "D")); 1122 Object object(&scope, moduleAtByCStr(runtime_, "builtins", "object")); 1123 Tuple mro(&scope, d.mro()); 1124 ASSERT_EQ(mro.length(), 5); 1125 EXPECT_EQ(mro.at(0), d); 1126 EXPECT_EQ(mro.at(1), b); 1127 EXPECT_EQ(mro.at(2), c); 1128 EXPECT_EQ(mro.at(3), a); 1129 EXPECT_EQ(mro.at(4), object); 1130} 1131 1132TEST_F(ThreadTest, LoadBuildTypeVerifyMroError) { 1133 const char* src = R"( 1134class A: pass 1135class B(A): pass 1136class C(A, B): pass 1137)"; 1138 1139 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, src), LayoutId::kTypeError, 1140 "Cannot create a consistent method resolution " 1141 "order (MRO) for bases A, B")); 1142} 1143 1144// iteration 1145 1146TEST_F(ThreadTest, RaiseVarargs) { 1147 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "raise 1"), 1148 LayoutId::kTypeError, 1149 "exceptions must derive from BaseException")); 1150} 1151 1152TEST_F(ThreadTest, InheritFromObject) { 1153 HandleScope scope(thread_); 1154 const char* src = R"( 1155class Foo(object): 1156 pass 1157)"; 1158 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1159 1160 // Look up the class Foo 1161 Object main_obj(&scope, findMainModule(runtime_)); 1162 ASSERT_TRUE(main_obj.isModule()); 1163 Object foo_obj(&scope, mainModuleAt(runtime_, "Foo")); 1164 ASSERT_TRUE(foo_obj.isType()); 1165 Type foo(&scope, *foo_obj); 1166 1167 // Check that its MRO is itself and object 1168 ASSERT_TRUE(foo.mro().isTuple()); 1169 Tuple mro(&scope, foo.mro()); 1170 ASSERT_EQ(mro.length(), 2); 1171 EXPECT_EQ(mro.at(0), *foo); 1172 EXPECT_EQ(mro.at(1), runtime_->typeAt(LayoutId::kObject)); 1173} 1174 1175// imports 1176 1177TEST_F(ThreadTest, ImportTest) { 1178 HandleScope scope(thread_); 1179 Object module_src(&scope, runtime_->newStrFromCStr(R"( 1180def say_hello(): 1181 return "hello" 1182)")); 1183 Object filename(&scope, runtime_->newStrFromCStr("<test string>")); 1184 const char* main_src = R"( 1185import hello 1186result = hello.say_hello() 1187)"; 1188 1189 // Pre-load the hello module so is cached. 1190 Code code(&scope, compile(thread_, module_src, filename, ID(exec), 1191 /*flags=*/0, /*optimize=*/0)); 1192 Object name(&scope, runtime_->newStrFromCStr("hello")); 1193 ASSERT_FALSE(executeModuleFromCode(thread_, code, name).isError()); 1194 ASSERT_FALSE(runFromCStr(runtime_, main_src).isError()); 1195 EXPECT_TRUE(isStrEqualsCStr(mainModuleAt(runtime_, "result"), "hello")); 1196} 1197 1198TEST_F(ThreadTest, FailedImportTest) { 1199 const char* main_src = R"( 1200import hello 1201hello.say_hello() 1202)"; 1203 1204 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, main_src), 1205 LayoutId::kModuleNotFoundError, 1206 "No module named 'hello'")); 1207} 1208 1209TEST_F(ThreadTest, ImportMissingAttributeTest) { 1210 HandleScope scope(thread_); 1211 Object module_src(&scope, runtime_->newStrFromCStr(R"( 1212def say_hello(): 1213 print("hello"); 1214)")); 1215 Object filename(&scope, runtime_->newStrFromCStr("<test string>")); 1216 const char* main_src = R"( 1217import hello 1218hello.foo() 1219)"; 1220 1221 // Pre-load the hello module so is cached. 1222 Code code(&scope, compile(thread_, module_src, filename, ID(exec), 1223 /*flags=*/0, /*optimize=*/0)); 1224 Object name(&scope, runtime_->newStrFromCStr("hello")); 1225 ASSERT_FALSE(executeModuleFromCode(thread_, code, name).isError()); 1226 1227 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, main_src), 1228 LayoutId::kAttributeError, 1229 "module 'hello' has no attribute 'foo'")); 1230} 1231 1232TEST_F(ThreadTest, ModuleSetAttrTest) { 1233 HandleScope scope(thread_); 1234 Object module_src(&scope, runtime_->newStrFromCStr(R"( 1235def say_hello(): 1236 return "hello" 1237)")); 1238 Object filename(&scope, runtime_->newStrFromCStr("<test string>")); 1239 const char* main_src = R"( 1240import hello 1241def goodbye(): 1242 return "goodbye" 1243hello.say_hello = goodbye 1244result = hello.say_hello() 1245)"; 1246 1247 // Pre-load the hello module so is cached. 1248 Code code(&scope, compile(thread_, module_src, filename, ID(exec), 1249 /*flags=*/0, /*optimize=*/0)); 1250 Object name(&scope, runtime_->newStrFromCStr("hello")); 1251 ASSERT_FALSE(executeModuleFromCode(thread_, code, name).isError()); 1252 ASSERT_FALSE(runFromCStr(runtime_, main_src).isError()); 1253 EXPECT_TRUE(isStrEqualsCStr(mainModuleAt(runtime_, "result"), "goodbye")); 1254} 1255 1256TEST_F(ThreadTest, StoreFastStackEffect) { 1257 const char* src = R"( 1258def printit(x, y, z): 1259 return (x, y, z) 1260 1261def test(): 1262 x = 1 1263 y = 2 1264 z = 3 1265 return printit(x, y, z) 1266 1267result = test() 1268)"; 1269 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1270 HandleScope scope(thread_); 1271 Object result(&scope, mainModuleAt(runtime_, "result")); 1272 ASSERT_TRUE(result.isTuple()); 1273 Tuple tuple(&scope, *result); 1274 ASSERT_EQ(tuple.length(), 3); 1275 EXPECT_TRUE(isIntEqualsWord(tuple.at(0), 1)); 1276 EXPECT_TRUE(isIntEqualsWord(tuple.at(1), 2)); 1277 EXPECT_TRUE(isIntEqualsWord(tuple.at(2), 3)); 1278} 1279 1280TEST_F(ThreadTest, Closure) { 1281 const char* src = R"( 1282result = [] 1283def f(): 1284 a = 1 1285 def g(): 1286 b = 2 1287 def h(): 1288 result.append(b) 1289 result.append(a) 1290 h() 1291 b = 3 1292 h() 1293 g() 1294f() 1295)"; 1296 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1297 HandleScope scope(thread_); 1298 Object result(&scope, mainModuleAt(runtime_, "result")); 1299 EXPECT_PYLIST_EQ(result, {1, 2, 3}); 1300} 1301 1302TEST_F(ThreadTest, StackOverflowRaisesRecursionError) { 1303 // TODO(T59724033): Not using binop doesn't raise RecursionError, which 1304 // signifies that our recursion depth checking is problematic. 1305 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"( 1306def foo(x): 1307 return foo(x + 1) 1308 1309foo(1.0) 1310)"), 1311 LayoutId::kRecursionError, 1312 "maximum recursion depth exceeded")); 1313} 1314 1315TEST_F(FormatTest, NoConvEmpty) { 1316 const char* src = R"( 1317result = f'' 1318)"; 1319 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1320 EXPECT_TRUE(isStrEqualsCStr(mainModuleAt(runtime_, "result"), "")); 1321} 1322 1323TEST_F(FormatTest, NoConvOneElement) { 1324 const char* src = R"( 1325a = "hello" 1326result = f'a={a}' 1327)"; 1328 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1329 EXPECT_TRUE(isStrEqualsCStr(mainModuleAt(runtime_, "result"), "a=hello")); 1330} 1331 1332TEST_F(FormatTest, NoConvMultiElements) { 1333 const char* src = R"( 1334a = "hello" 1335b = "world" 1336c = "python" 1337result = f'{a} {b} {c}' 1338)"; 1339 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1340 EXPECT_TRUE( 1341 isStrEqualsCStr(mainModuleAt(runtime_, "result"), "hello world python")); 1342} 1343 1344TEST_F(FormatTest, NoConvMultiElementsLarge) { 1345 const char* src = R"( 1346a = "Python" 1347b = "is" 1348c = "an interpreted high-level programming language for general-purpose programming." 1349result = f'{a} {b} {c}' 1350)"; 1351 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1352 EXPECT_TRUE(isStrEqualsCStr( 1353 mainModuleAt(runtime_, "result"), 1354 "Python is an interpreted high-level programming language for " 1355 "general-purpose programming.")); 1356} 1357 1358TEST_F(ThreadTest, BuildTupleUnpack) { 1359 HandleScope scope(thread_); 1360 const char* src = R"( 1361t = (*[0], *[1, 2], *[], *[3, 4, 5]) 1362t1 = (*(0,), *(1, 2), *(), *(3, 4, 5)) 1363)"; 1364 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1365 1366 Object t(&scope, mainModuleAt(runtime_, "t")); 1367 EXPECT_TRUE(t.isTuple()); 1368 Tuple tuple_t(&scope, *t); 1369 EXPECT_EQ(tuple_t.length(), 6); 1370 for (word i = 0; i < tuple_t.length(); i++) { 1371 EXPECT_TRUE(isIntEqualsWord(tuple_t.at(i), i)); 1372 } 1373 1374 Object t1(&scope, mainModuleAt(runtime_, "t1")); 1375 EXPECT_TRUE(t1.isTuple()); 1376 Tuple tuple_t1(&scope, *t1); 1377 EXPECT_EQ(tuple_t1.length(), 6); 1378 EXPECT_TRUE(isIntEqualsWord(tuple_t1.at(0), 0)); 1379 EXPECT_TRUE(isIntEqualsWord(tuple_t1.at(1), 1)); 1380 EXPECT_TRUE(isIntEqualsWord(tuple_t1.at(2), 2)); 1381 EXPECT_TRUE(isIntEqualsWord(tuple_t1.at(3), 3)); 1382 EXPECT_TRUE(isIntEqualsWord(tuple_t1.at(4), 4)); 1383 EXPECT_TRUE(isIntEqualsWord(tuple_t1.at(5), 5)); 1384} 1385 1386TEST_F(ThreadTest, BuildListUnpack) { 1387 HandleScope scope(thread_); 1388 const char* src = R"( 1389l = [*[0], *[1, 2], *[], *[3, 4, 5]] 1390)"; 1391 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1392 1393 Object l(&scope, mainModuleAt(runtime_, "l")); 1394 EXPECT_TRUE(l.isList()); 1395 List list_l(&scope, *l); 1396 EXPECT_EQ(list_l.numItems(), 6); 1397 EXPECT_TRUE(isIntEqualsWord(list_l.at(0), 0)); 1398 EXPECT_TRUE(isIntEqualsWord(list_l.at(1), 1)); 1399 EXPECT_TRUE(isIntEqualsWord(list_l.at(2), 2)); 1400 EXPECT_TRUE(isIntEqualsWord(list_l.at(3), 3)); 1401 EXPECT_TRUE(isIntEqualsWord(list_l.at(4), 4)); 1402 EXPECT_TRUE(isIntEqualsWord(list_l.at(5), 5)); 1403} 1404 1405TEST_F(ThreadTest, BuildSetUnpack) { 1406 HandleScope scope(thread_); 1407 const char* src = R"( 1408s = {*[0, 1], *{2, 3}, *(4, 5), *[]} 1409)"; 1410 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1411 1412 Object s(&scope, mainModuleAt(runtime_, "s")); 1413 EXPECT_TRUE(s.isSet()); 1414 Set set_s(&scope, *s); 1415 EXPECT_EQ(set_s.numItems(), 6); 1416 Object small_int(&scope, SmallInt::fromWord(0)); 1417 EXPECT_TRUE(setIncludes(thread_, set_s, small_int)); 1418 small_int = SmallInt::fromWord(1); 1419 EXPECT_TRUE(setIncludes(thread_, set_s, small_int)); 1420 small_int = SmallInt::fromWord(2); 1421 EXPECT_TRUE(setIncludes(thread_, set_s, small_int)); 1422 small_int = SmallInt::fromWord(3); 1423 EXPECT_TRUE(setIncludes(thread_, set_s, small_int)); 1424 small_int = SmallInt::fromWord(4); 1425 EXPECT_TRUE(setIncludes(thread_, set_s, small_int)); 1426 small_int = SmallInt::fromWord(5); 1427 EXPECT_TRUE(setIncludes(thread_, set_s, small_int)); 1428} 1429 1430TEST_F(BuildString, BuildStringEmpty) { 1431 HandleScope scope(thread_); 1432 1433 const byte bytecode[] = {BUILD_STRING, 0, RETURN_VALUE, 0}; 1434 Code code(&scope, newCodeWithBytes(bytecode)); 1435 1436 EXPECT_TRUE(isStrEqualsCStr(runCode(code), "")); 1437} 1438 1439TEST_F(BuildString, BuildStringSingle) { 1440 HandleScope scope(thread_); 1441 Object str(&scope, SmallStr::fromCStr("foo")); 1442 Tuple consts(&scope, runtime_->newTupleWith1(str)); 1443 const byte bytecode[] = {LOAD_CONST, 0, BUILD_STRING, 1, RETURN_VALUE, 0}; 1444 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 1445 1446 EXPECT_TRUE(isStrEqualsCStr(runCode(code), "foo")); 1447} 1448 1449TEST_F(BuildString, BuildStringMultiSmall) { 1450 HandleScope scope(thread_); 1451 Object str(&scope, SmallStr::fromCStr("foo")); 1452 Object str1(&scope, SmallStr::fromCStr("bar")); 1453 Tuple consts(&scope, runtime_->newTupleWith2(str, str1)); 1454 const byte bytecode[] = {LOAD_CONST, 0, LOAD_CONST, 1, 1455 BUILD_STRING, 2, RETURN_VALUE, 0}; 1456 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 1457 1458 EXPECT_TRUE(isStrEqualsCStr(runCode(code), "foobar")); 1459} 1460 1461TEST_F(BuildString, BuildStringMultiLarge) { 1462 HandleScope scope(thread_); 1463 Object str(&scope, SmallStr::fromCStr("hello")); 1464 Object str1(&scope, SmallStr::fromCStr("world")); 1465 Object str2(&scope, SmallStr::fromCStr("python")); 1466 Tuple consts(&scope, runtime_->newTupleWith3(str, str1, str2)); 1467 const byte bytecode[] = {LOAD_CONST, 0, LOAD_CONST, 1, LOAD_CONST, 2, 1468 BUILD_STRING, 3, RETURN_VALUE, 0}; 1469 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 1470 1471 EXPECT_TRUE(isStrEqualsCStr(runCode(code), "helloworldpython")); 1472} 1473 1474TEST_F(UnpackSeq, UnpackRange) { 1475 const char* src = R"( 1476[a ,b, c] = range(2, 5) 1477)"; 1478 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1479 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "a"), 2)); 1480 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "b"), 3)); 1481 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "c"), 4)); 1482} 1483 1484// LIST_APPEND(listAdd) in list_comp, followed by unpack 1485// TODO(rkng): list support in BINARY_ADD 1486TEST_F(UnpackList, UnpackListCompAppend) { 1487 const char* src = R"( 1488a = [1, 2, 3] 1489b = [x for x in a] 1490b1, b2, b3 = b 1491)"; 1492 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1493 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "b1"), 1)); 1494 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "b2"), 2)); 1495 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "b3"), 3)); 1496} 1497 1498TEST_F(ThreadTest, SetAdd) { 1499 HandleScope scope(thread_); 1500 const char* src = R"( 1501a = [1, 2, 3] 1502b = {x for x in a} 1503)"; 1504 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1505 Object b(&scope, mainModuleAt(runtime_, "b")); 1506 ASSERT_TRUE(b.isSet()); 1507 Set set_b(&scope, *b); 1508 EXPECT_EQ(set_b.numItems(), 3); 1509} 1510 1511TEST_F(ThreadTest, MapAdd) { 1512 HandleScope scope(thread_); 1513 const char* src = R"( 1514a = ['a', 'b', 'c'] 1515b = {x:x for x in a} 1516)"; 1517 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1518 Object b(&scope, mainModuleAt(runtime_, "b")); 1519 EXPECT_EQ(b.isDict(), true); 1520 Dict dict_b(&scope, *b); 1521 EXPECT_EQ(dict_b.numItems(), 3); 1522} 1523 1524TEST_F(UnpackList, UnpackNestedLists) { 1525 const char* src = R"( 1526b = [[1,2], [3,4,5]] 1527b1, b2 = b 1528b11, b12 = b1 1529b21, b22, b23 = b2 1530)"; 1531 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1532 HandleScope scope(thread_); 1533 List b(&scope, mainModuleAt(runtime_, "b")); 1534 EXPECT_EQ(b.numItems(), 2); 1535 List b1(&scope, mainModuleAt(runtime_, "b1")); 1536 EXPECT_EQ(b1.numItems(), 2); 1537 List b2(&scope, mainModuleAt(runtime_, "b2")); 1538 EXPECT_EQ(b2.numItems(), 3); 1539 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "b11"), 1)); 1540 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "b12"), 2)); 1541 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "b21"), 3)); 1542 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "b22"), 4)); 1543 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "b23"), 5)); 1544} 1545 1546TEST_F(UnpackSeq, UnpackRangeStep) { 1547 const char* src = R"( 1548[a ,b, c, d] = range(2, 10, 2) 1549)"; 1550 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1551 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "a"), 2)); 1552 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "b"), 4)); 1553 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "c"), 6)); 1554 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "d"), 8)); 1555} 1556 1557TEST_F(UnpackSeq, UnpackRangeNeg) { 1558 const char* src = R"( 1559[a ,b, c, d, e] = range(-10, 0, 2) 1560)"; 1561 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1562 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "a"), -10)); 1563 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "b"), -8)); 1564 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "c"), -6)); 1565 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "d"), -4)); 1566 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "e"), -2)); 1567} 1568 1569TEST_F(ListIterTest, Build) { 1570 const char* src = R"( 1571a = [1, 2, 3] 1572result = [] 1573for x in a: 1574 result.append(x) 1575)"; 1576 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1577 HandleScope scope(thread_); 1578 Object result(&scope, mainModuleAt(runtime_, "result")); 1579 EXPECT_PYLIST_EQ(result, {1, 2, 3}); 1580} 1581 1582TEST_F(ListAppendTest, BuildAndUnpack) { 1583 const char* src = R"( 1584a = [1, 2] 1585b = [x for x in [a] * 3] 1586b1, b2, b3 = b 1587b11, b12 = b1 1588)"; 1589 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1590 HandleScope scope(thread_); 1591 List b(&scope, mainModuleAt(runtime_, "b")); 1592 EXPECT_EQ(b.numItems(), 3); 1593 List b1(&scope, mainModuleAt(runtime_, "b1")); 1594 EXPECT_EQ(b1.numItems(), 2); 1595 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "b11"), 1)); 1596 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "b12"), 2)); 1597} 1598 1599TEST_F(ListInsertTest, InsertToList) { 1600 HandleScope scope(thread_); 1601 const char* src = R"( 1602l = [] 1603for i in range(16): 1604 if i == 2 or i == 12: 1605 continue 1606 l.append(i) 1607 1608a, b = l[2], l[12] 1609 1610l.insert(2, 2) 1611l.insert(12, 12) 1612 1613s = 0 1614for el in l: 1615 s += el 1616)"; 1617 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1618 Object a(&scope, mainModuleAt(runtime_, "a")); 1619 Object b(&scope, mainModuleAt(runtime_, "b")); 1620 Object l(&scope, mainModuleAt(runtime_, "l")); 1621 Object s(&scope, mainModuleAt(runtime_, "s")); 1622 1623 EXPECT_FALSE(isIntEqualsWord(*a, 2)); 1624 EXPECT_FALSE(isIntEqualsWord(*b, 12)); 1625 1626 List list_l(&scope, *l); 1627 ASSERT_EQ(list_l.numItems(), 16); 1628 EXPECT_TRUE(isIntEqualsWord(list_l.at(2), 2)); 1629 EXPECT_TRUE(isIntEqualsWord(list_l.at(12), 12)); 1630 1631 // sum(0..16) = 120 1632 EXPECT_TRUE(isIntEqualsWord(*s, 120)); 1633} 1634 1635TEST_F(ListInsertTest, InsertToListBounds) { 1636 HandleScope scope(thread_); 1637 const char* src = R"( 1638l = [x for x in range(1, 5)] 1639l.insert(100, 5) 1640l.insert(400, 6) 1641l.insert(-100, 0) 1642)"; 1643 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1644 Object l(&scope, mainModuleAt(runtime_, "l")); 1645 List list_l(&scope, *l); 1646 EXPECT_TRUE(isIntEqualsWord(list_l.at(0), 0)); 1647 EXPECT_TRUE(isIntEqualsWord(list_l.at(1), 1)); 1648 EXPECT_TRUE(isIntEqualsWord(list_l.at(2), 2)); 1649 EXPECT_TRUE(isIntEqualsWord(list_l.at(3), 3)); 1650 EXPECT_TRUE(isIntEqualsWord(list_l.at(4), 4)); 1651 EXPECT_TRUE(isIntEqualsWord(list_l.at(5), 5)); 1652 EXPECT_TRUE(isIntEqualsWord(list_l.at(6), 6)); 1653} 1654 1655TEST_F(ListInsertTest, InsertToNegativeIndex) { 1656 HandleScope scope(thread_); 1657 const char* src = R"( 1658l = [0, 2, 4] 1659l.insert(-2, 1) 1660l.insert(-1, 3) 1661)"; 1662 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1663 Object l(&scope, mainModuleAt(runtime_, "l")); 1664 List list_l(&scope, *l); 1665 ASSERT_EQ(list_l.numItems(), 5); 1666 EXPECT_TRUE(isIntEqualsWord(list_l.at(0), 0)); 1667 EXPECT_TRUE(isIntEqualsWord(list_l.at(1), 1)); 1668 EXPECT_TRUE(isIntEqualsWord(list_l.at(2), 2)); 1669 EXPECT_TRUE(isIntEqualsWord(list_l.at(3), 3)); 1670 EXPECT_TRUE(isIntEqualsWord(list_l.at(4), 4)); 1671} 1672 1673TEST_F(ThreadTest, BaseTypeConflict) { 1674 const char* src = R"( 1675class Foo(list, dict): pass 1676)"; 1677 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, src), LayoutId::kTypeError, 1678 "multiple bases have instance lay-out conflict")); 1679} 1680 1681TEST_F(ThreadTest, BreakLoopWhileLoop) { 1682 const char* src = R"( 1683a = 0 1684result = [] 1685while 1: 1686 a = a + 1 1687 result.append(a) 1688 if a == 3: 1689 break 1690)"; 1691 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1692 HandleScope scope(thread_); 1693 Object result(&scope, mainModuleAt(runtime_, "result")); 1694 EXPECT_PYLIST_EQ(result, {1, 2, 3}); 1695} 1696 1697TEST_F(ThreadTest, BreakLoopWhileLoop1) { 1698 const char* src = R"( 1699a = 0 1700result = [] 1701while 1: 1702 a = a + 1 1703 result.append(a) 1704 if a == 3: 1705 break 1706)"; 1707 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1708 HandleScope scope(thread_); 1709 Object result(&scope, mainModuleAt(runtime_, "result")); 1710 EXPECT_PYLIST_EQ(result, {1, 2, 3}); 1711 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "a"), 3)); 1712} 1713 1714TEST_F(ThreadTest, BreakLoopRangeLoop) { 1715 const char* src = R"( 1716result = [] 1717for x in range(1,6): 1718 if x == 3: 1719 break; 1720 result.append(x) 1721)"; 1722 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1723 HandleScope scope(thread_); 1724 Object result(&scope, mainModuleAt(runtime_, "result")); 1725 EXPECT_PYLIST_EQ(result, {1, 2}); 1726} 1727 1728TEST_F(ThreadTest, ContinueLoopRangeLoop) { 1729 HandleScope scope(thread_); 1730 const char* src = R"( 1731l = [] 1732 1733for x in range(4): 1734 if x == 3: 1735 try: 1736 continue 1737 except: 1738 # This is to prevent the peephole optimizer 1739 # from turning the CONTINUE_LOOP op 1740 # into a JUMP_ABSOLUTE op 1741 pass 1742 l.append(x) 1743)"; 1744 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1745 Object l(&scope, mainModuleAt(runtime_, "l")); 1746 EXPECT_TRUE(l.isList()); 1747 List list_l(&scope, *l); 1748 ASSERT_GE(list_l.numItems(), 3); 1749 EXPECT_EQ(list_l.at(0), SmallInt::fromWord(0)); 1750 EXPECT_EQ(list_l.at(1), SmallInt::fromWord(1)); 1751 EXPECT_EQ(list_l.at(2), SmallInt::fromWord(2)); 1752} 1753 1754TEST_F(ThreadTest, Func2TestPyStone) { // mimic pystone.py Func2 1755 const char* src = R"( 1756def f1(x, y): 1757 return x + y 1758def f2(): 1759 return f1(1, 2) 1760result = f2() 1761)"; 1762 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1763 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "result"), 3)); 1764} 1765 1766TEST_F(ThreadTest, BinSubscrString) { // pystone dependency 1767 const char* src = R"( 1768a = 'Hello' 1769r0 = a[0] 1770r1 = a[1] 1771r2 = a[2] 1772r3 = a[3] 1773r4 = a[4] 1774)"; 1775 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1776 EXPECT_TRUE(isStrEqualsCStr(mainModuleAt(runtime_, "r0"), "H")); 1777 EXPECT_TRUE(isStrEqualsCStr(mainModuleAt(runtime_, "r1"), "e")); 1778 EXPECT_TRUE(isStrEqualsCStr(mainModuleAt(runtime_, "r2"), "l")); 1779 EXPECT_TRUE(isStrEqualsCStr(mainModuleAt(runtime_, "r3"), "l")); 1780 EXPECT_TRUE(isStrEqualsCStr(mainModuleAt(runtime_, "r4"), "o")); 1781} 1782 1783TEST_F(ThreadTest, SetupExceptNoOp) { // pystone dependency 1784 const char* src = R"( 1785def f(x): 1786 try: 1787 return x 1788 except ValueError: 1789 return "Invalid Argument" 1790result = f(100) 1791)"; 1792 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1793 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "result"), 100)); 1794} 1795 1796TEST_F(ThreadTest, BuildTypeWithMetaclass) { 1797 HandleScope scope(thread_); 1798 const char* src = R"( 1799class Foo(metaclass=type): 1800 pass 1801a = Foo() 1802)"; 1803 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1804 Object foo(&scope, mainModuleAt(runtime_, "Foo")); 1805 EXPECT_TRUE(foo.isType()); 1806 Object a(&scope, mainModuleAt(runtime_, "a")); 1807 EXPECT_TRUE(runtime_->typeOf(*a) == *foo); 1808} 1809 1810TEST_F(ThreadTest, BuildTypeWithMetaclass2) { 1811 HandleScope scope(thread_); 1812 const char* src = R"( 1813class Foo(type): 1814 def __new__(mcls, name, bases, dict): 1815 cls = super(Foo, mcls).__new__(mcls, name, bases, dict) 1816 cls.lalala = 123 1817 return cls 1818class Bar(metaclass=Foo): 1819 def __init__(self): 1820 self.hahaha = 456 1821b = Bar.lalala 1822a = Bar() 1823c = a.hahaha 1824)"; 1825 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1826 Object bar(&scope, mainModuleAt(runtime_, "Bar")); 1827 EXPECT_TRUE(runtime_->isInstanceOfType(*bar)); 1828 Object a(&scope, mainModuleAt(runtime_, "a")); 1829 EXPECT_TRUE(runtime_->typeOf(*a) == *bar); 1830 Object b(&scope, mainModuleAt(runtime_, "b")); 1831 EXPECT_TRUE(isIntEqualsWord(*b, 123)); 1832 Object c(&scope, mainModuleAt(runtime_, "c")); 1833 EXPECT_TRUE(isIntEqualsWord(*c, 456)); 1834} 1835 1836TEST_F(ThreadTest, NameLookupInTypeBodyFindsImplicitGlobal) { 1837 HandleScope scope(thread_); 1838 const char* src = R"( 1839a = 0 1840b = 0 1841class C: 1842 global a 1843 global b 1844 PI = 3 1845 a = PI 1846 PIPI = PI * 2 1847 b = PIPI 1848)"; 1849 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1850 Object a(&scope, mainModuleAt(runtime_, "a")); 1851 EXPECT_TRUE(isIntEqualsWord(*a, 3)); 1852 Object b(&scope, mainModuleAt(runtime_, "b")); 1853 EXPECT_TRUE(isIntEqualsWord(*b, 6)); 1854} 1855 1856TEST_F(ThreadTest, NameLookupInTypeBodyFindsGlobal) { 1857 HandleScope scope(thread_); 1858 const char* src = R"( 1859var = 1 1860class C: 1861 global one 1862 global two 1863 one = var 1864 var = 2 1865 two = var 1866)"; 1867 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1868 Object one(&scope, mainModuleAt(runtime_, "one")); 1869 EXPECT_TRUE(isIntEqualsWord(*one, 1)); 1870 Object two(&scope, mainModuleAt(runtime_, "two")); 1871 EXPECT_TRUE(isIntEqualsWord(*two, 2)); 1872} 1873 1874TEST_F(ThreadTest, ExecuteDeleteName) { 1875 HandleScope scope(thread_); 1876 const char* src = R"( 1877var = 1 1878del var 1879)"; 1880 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1881 Object var(&scope, mainModuleAt(runtime_, "var")); 1882 EXPECT_TRUE(var.isError()); 1883} 1884 1885TEST_F(ThreadTest, SetupFinally) { 1886 HandleScope scope(thread_); 1887 const char* src = R"( 1888x = 1 1889try: 1890 pass 1891finally: 1892 x = 2 1893)"; 1894 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1895 Object x(&scope, mainModuleAt(runtime_, "x")); 1896 EXPECT_EQ(*x, SmallInt::fromWord(2)); 1897} 1898 1899TEST_F(ThreadTest, SetupAnnotationsAndStoreAnnotations) { 1900 HandleScope scope(thread_); 1901 const char* src = R"( 1902global_with_annotation: int = 1 1903class ClassWithAnnotation: 1904 attribute_with_annotation: int = 2 1905class_anno_dict = ClassWithAnnotation.__annotations__ 1906)"; 1907 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1908 Dict module_anno_dict(&scope, mainModuleAt(runtime_, "__annotations__")); 1909 Str m_key(&scope, runtime_->newStrFromCStr("global_with_annotation")); 1910 Object m_value(&scope, dictAtByStr(thread_, module_anno_dict, m_key)); 1911 EXPECT_EQ(*m_value, runtime_->typeAt(LayoutId::kInt)); 1912 1913 Dict class_anno_dict(&scope, mainModuleAt(runtime_, "class_anno_dict")); 1914 Str c_key(&scope, runtime_->newStrFromCStr("attribute_with_annotation")); 1915 Object c_value(&scope, dictAtByStr(thread_, class_anno_dict, c_key)); 1916 EXPECT_EQ(*c_value, runtime_->typeAt(LayoutId::kInt)); 1917} 1918 1919TEST_F(ThreadTest, DeleteFastRaisesUnboundLocalError) { 1920 const char* src = R"( 1921def foo(a, b, c): 1922 del a 1923 return a 1924foo(1, 2, 3) 1925)"; 1926 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, src), 1927 LayoutId::kUnboundLocalError, 1928 "local variable 'a' referenced before assignment")); 1929} 1930 1931TEST_F(ThreadTest, DeleteFast) { 1932 HandleScope scope(thread_); 1933 const char* src = R"( 1934def foo(a, b, c): 1935 del a 1936 return b 1937x = foo(1, 2, 3) 1938)"; 1939 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1940 Object x(&scope, mainModuleAt(runtime_, "x")); 1941 EXPECT_EQ(*x, SmallInt::fromWord(2)); 1942} 1943 1944TEST_F(ThreadTest, ConstructInstanceWithKwargs) { 1945 HandleScope scope(thread_); 1946 const char* src = R"( 1947result_a = None 1948result_b = None 1949result_c = None 1950 1951class Foo: 1952 def __init__(self, a, b=None, c=None): 1953 global result_a, result_b, result_c 1954 result_a = a 1955 result_b = b 1956 result_c = c 1957 1958foo = Foo(1111, b=2222, c=3333) 1959)"; 1960 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1961 1962 Object result_a(&scope, mainModuleAt(runtime_, "result_a")); 1963 EXPECT_TRUE(isIntEqualsWord(*result_a, 1111)); 1964 1965 Object result_b(&scope, mainModuleAt(runtime_, "result_b")); 1966 EXPECT_TRUE(isIntEqualsWord(*result_b, 2222)); 1967 1968 Object result_c(&scope, mainModuleAt(runtime_, "result_c")); 1969 EXPECT_TRUE(isIntEqualsWord(*result_c, 3333)); 1970} 1971 1972TEST_F(ThreadTest, LoadTypeDeref) { 1973 HandleScope scope(thread_); 1974 const char* src = R"( 1975def foo(): 1976 a = 1 1977 class Foo: 1978 b = a 1979 return Foo.b 1980x = foo() 1981)"; 1982 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 1983 Object x(&scope, mainModuleAt(runtime_, "x")); 1984 EXPECT_EQ(*x, SmallInt::fromWord(1)); 1985} 1986 1987TEST_F(ThreadTest, LoadTypeDerefFromLocal) { 1988 HandleScope scope(thread_); 1989 Object obj1(&scope, SmallInt::fromWord(1111)); 1990 Tuple consts(&scope, runtime_->newTupleWith1(obj1)); 1991 Object obj3(&scope, Runtime::internStrFromCStr(thread_, "lalala")); 1992 Tuple names(&scope, runtime_->newTupleWith1(obj3)); 1993 const byte bytecode[] = {LOAD_CONST, 0, STORE_NAME, 0, 1994 LOAD_CLASSDEREF, 0, RETURN_VALUE, 0}; 1995 Code code(&scope, 1996 newCodeWithBytesConstsNamesFlags(bytecode, consts, names, 0)); 1997 Object obj2(&scope, Runtime::internStrFromCStr(thread_, "lalala")); 1998 Tuple freevars(&scope, runtime_->newTupleWith1(obj2)); 1999 code.setFreevars(*freevars); 2000 Object name(&scope, Runtime::internStrFromCStr(thread_, "foo")); 2001 Module module(&scope, findMainModule(runtime_)); 2002 2003 Function function(&scope, 2004 runtime_->newFunctionWithCode(thread_, name, code, module)); 2005 Tuple closure(&scope, runtime_->newTupleWith1(obj3)); 2006 function.setClosure(*closure); 2007 2008 Dict locals(&scope, runtime_->newDict()); 2009 EXPECT_TRUE(isIntEqualsWord( 2010 thread_->callFunctionWithImplicitGlobals(function, locals), 1111)); 2011} 2012 2013TEST_F(ThreadTest, PushCallFrameWithSameGlobalsPropagatesBuiltins) { 2014 HandleScope scope(thread_); 2015 Code code(&scope, newCodeWithBytes(View<byte>(nullptr, 0))); 2016 2017 Object qualname(&scope, runtime_->newStrFromCStr("<anonymous>")); 2018 Module module(&scope, findMainModule(runtime_)); 2019 Function function( 2020 &scope, runtime_->newFunctionWithCode(thread_, qualname, code, module)); 2021 2022 Frame* frame = thread_->currentFrame(); 2023 thread_->stackPush(*function); 2024 Frame* new_frame = thread_->pushCallFrame(*function); 2025 EXPECT_NE(new_frame, frame); 2026} 2027 2028TEST_F(ThreadTest, ExecSetsMissingDunderBuiltins) { 2029 HandleScope scope(thread_); 2030 Object obj(&scope, NoneType::object()); 2031 Tuple consts(&scope, runtime_->newTupleWith1(obj)); 2032 const byte bytecode[] = {LOAD_CONST, 0, RETURN_VALUE, 0}; 2033 Code code(&scope, newCodeWithBytesConsts(bytecode, consts)); 2034 code.setFlags(0); 2035 2036 Object name(&scope, runtime_->newStrFromCStr("<test module>")); 2037 Module module(&scope, runtime_->newModule(name)); 2038 Object none(&scope, NoneType::object()); 2039 2040 ASSERT_TRUE(thread_->exec(code, module, none).isNoneType()); 2041 2042 Module builtins_module(&scope, runtime_->findModuleById(ID(builtins))); 2043 Object proxy(&scope, builtins_module.moduleProxy()); 2044 EXPECT_EQ(moduleAtById(thread_, module, ID(__builtins__)), proxy); 2045} 2046 2047TEST_F(ThreadTest, CallFunctionInDifferentModule) { 2048 HandleScope scope(thread_); 2049 ASSERT_FALSE(runFromCStr(runtime_, R"( 2050def a(): 2051 def inner_a(): 2052 return object 2053 return inner_a 2054result0 = a()() 2055)") 2056 .isError()); 2057 // Object a(&scope, mainModuleAt(runtime_, "a")); 2058 Object result0(&scope, mainModuleAt(runtime_, "result0")); 2059 Object object(&scope, moduleAtByCStr(runtime_, "builtins", "object")); 2060 EXPECT_EQ(result0, object); 2061} 2062 2063TEST_F(ThreadTest, RaiseWithFmtFormatsString) { 2064 EXPECT_TRUE(raisedWithStr( 2065 thread_->raiseWithFmt(LayoutId::kTypeError, "hello %Y", ID(dict)), 2066 LayoutId::kTypeError, "hello dict")); 2067} 2068 2069TEST_F(ThreadTest, RaiseOSErrorFromErrnoWithInvalidErrnoReturnsOSError) { 2070 EXPECT_TRUE(raised(thread_->raiseOSErrorFromErrno(-5), LayoutId::kOSError)); 2071} 2072 2073TEST_F(ThreadTest, RaiseOSErrorFromErrnoPicksOSErrorSubclass) { 2074 EXPECT_TRUE(raised(thread_->raiseOSErrorFromErrno(EACCES), 2075 LayoutId::kPermissionError)); 2076} 2077 2078TEST_F(ThreadTest, StrOffsetWithNegativeReturnsNegativeOne) { 2079 HandleScope scope(thread_); 2080 Str str(&scope, SmallStr::fromCStr("foo")); 2081 EXPECT_EQ(thread_->strOffset(str, -10), -1); 2082} 2083 2084TEST_F(ThreadTest, StrOffsetWithLargeNumberReturnsLength) { 2085 HandleScope scope(thread_); 2086 Str str(&scope, SmallStr::fromCStr("foo")); 2087 EXPECT_EQ(thread_->strOffset(str, 5), 3); 2088} 2089 2090TEST_F(ThreadTest, StrOffsetWithIndexReturnsOffset) { 2091 HandleScope scope(thread_); 2092 Str str(&scope, SmallStr::fromCStr("\u00e9tude")); 2093 EXPECT_EQ(thread_->strOffset(str, 2), 3); 2094} 2095 2096TEST_F(ThreadTest, StrOffsetWithCacheHitReturnsCorrectOffsets) { 2097 HandleScope scope(thread_); 2098 Str str(&scope, runtime_->newStrFromCStr("\u00e9l\u00e9gie")); 2099 EXPECT_EQ(thread_->strOffset(str, 2), 3); 2100 EXPECT_EQ(thread_->strOffset(str, 4), 6); 2101 EXPECT_EQ(thread_->strOffset(str, 1), 2); 2102} 2103 2104TEST_F(ThreadTest, StrOffsetWithCacheMissReturnsCorrectOffsets) { 2105 HandleScope scope(thread_); 2106 Str str(&scope, runtime_->newStrFromCStr("\u00e9l\u00e9gie")); 2107 EXPECT_EQ(thread_->strOffset(str, 2), 3); 2108 2109 // out of bounds 2110 EXPECT_EQ(thread_->strOffset(str, 10), 8); 2111 EXPECT_EQ(thread_->strOffset(str, 1), 2); 2112 2113 // new string 2114 str = runtime_->newStrFromCStr("foo"); 2115 EXPECT_EQ(thread_->strOffset(str, 2), 2); 2116} 2117 2118} // namespace testing 2119} // namespace py