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 AbstractVMObject::Send(Interpreter* interp, StdString selectorString, vm_oop_t* arguments, long argc) { VMFrame* frame = interp->GetFrame(); VMSymbol* selector = GetUniverse()->SymbolFor(selectorString); frame->Push(this); for (long i = 0; i < argc; ++i) { frame->Push(arguments[i]); } VMClass* cl = GetClass(); VMInvokable* invokable = cl->LookupInvokable(selector); invokable->Invoke(interp, frame); }