void Interpreter::doSuperSend(long bytecodeIndex) { VMSymbol* signature = static_cast<VMSymbol*>(method->GetConstant(bytecodeIndex)); VMFrame* ctxt = GetFrame()->GetOuterContext(); VMMethod* realMethod = ctxt->GetMethod(); VMClass* holder = realMethod->GetHolder(); VMClass* super = holder->GetSuperClass(); VMInvokable* invokable = static_cast<VMInvokable*>(super->LookupInvokable(signature)); if (invokable != nullptr) (*invokable)(GetFrame()); else { long numOfArgs = Signature::GetNumberOfArguments(signature); vm_oop_t receiver = GetFrame()->GetStackElement(numOfArgs - 1); VMArray* argumentsArray = GetUniverse()->NewArray(numOfArgs); for (long i = numOfArgs - 1; i >= 0; --i) { vm_oop_t o = GetFrame()->Pop(); argumentsArray->SetIndexableField(i, o); } vm_oop_t arguments[] = {signature, argumentsArray}; AS_OBJ(receiver)->Send(doesNotUnderstand, arguments, 2); } }
void Interpreter::popFrameAndPushResult(vm_oop_t result) { VMFrame* prevFrame = popFrame(); VMMethod* method = prevFrame->GetMethod(); long numberOfArgs = method->GetNumberOfArguments(); for (long i = 0; i < numberOfArgs; ++i) GetFrame()->Pop(); GetFrame()->Push(result); }
VMFrame* Interpreter::popFrame() { VMFrame* result = GetFrame(); SetFrame(GetFrame()->GetPreviousFrame()); result->ClearPreviousFrame(); #ifdef UNSAFE_FRAME_OPTIMIZATION //remember this frame as free frame result->GetMethod()->SetCachedFrame(result); #endif return result; }
void CloneObjectsTest::testCloneFrame() { VMSymbol* methodSymbol = GetUniverse()->NewSymbol("frameMethod"); VMMethod* method = GetUniverse()->NewMethod(methodSymbol, 0, 0); VMFrame* orig = GetUniverse()->NewFrame(nullptr, method); VMFrame* context = orig->Clone(); orig->SetContext(context); VMInteger* dummyArg = GetUniverse()->NewInteger(1111); orig->SetArgument(0, 0, dummyArg); VMFrame* clone = orig->Clone(); CPPUNIT_ASSERT((intptr_t)orig != (intptr_t)clone); CPPUNIT_ASSERT_EQUAL_MESSAGE("class differs!!", orig->clazz, clone->clazz); CPPUNIT_ASSERT_EQUAL_MESSAGE("objectSize differs!!", orig->objectSize, clone->objectSize); CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfFields differs!!", orig->numberOfFields, clone->numberOfFields); CPPUNIT_ASSERT_EQUAL_MESSAGE("GetPreviousFrame differs!!", orig->GetPreviousFrame(), clone->GetPreviousFrame()); CPPUNIT_ASSERT_EQUAL_MESSAGE("GetContext differs!!", orig->GetContext(), clone->GetContext()); CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOGetMethodfFields differs!!", orig->GetMethod(), clone->GetMethod()); //CPPUNIT_ASSERT_EQUAL_MESSAGE("GetStackPointer differs!!", orig->GetStackPointer(), clone->GetStackPointer()); CPPUNIT_ASSERT_EQUAL_MESSAGE("bytecodeIndex differs!!", orig->bytecodeIndex, clone->bytecodeIndex); }