Skip to content

Commit

Permalink
Refactor send for better compilation (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
smarr authored Jul 7, 2024
2 parents 7f26c0b + 36d0342 commit 3576572
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 52 deletions.
51 changes: 28 additions & 23 deletions src/interpreter/Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,34 +137,37 @@ void Interpreter::send(VMSymbol* signature, VMClass* receiverClass) {
invokable->Invoke(this, GetFrame());
bytecodeIndexGlobal = GetFrame()->GetBytecodeIndex();
} else {
//doesNotUnderstand
long numberOfArgs = Signature::GetNumberOfArguments(signature);
triggerDoesNotUnderstand(signature);
}
}

vm_oop_t receiver = GetFrame()->GetStackElement(numberOfArgs-1);
void Interpreter::triggerDoesNotUnderstand(VMSymbol* signature) {
long numberOfArgs = Signature::GetNumberOfArguments(signature);

VMArray* argumentsArray = GetUniverse()->NewArray(numberOfArgs - 1); // without receiver
vm_oop_t receiver = GetFrame()->GetStackElement(numberOfArgs - 1);

// the receiver should not go into the argumentsArray
// so, numberOfArgs - 2
for (long i = numberOfArgs - 2; i >= 0; --i) {
vm_oop_t o = GetFrame()->Pop();
argumentsArray->SetIndexableField(i, o);
}
vm_oop_t arguments[] = {signature, argumentsArray};

GetFrame()->Pop(); // pop the receiver
VMArray* argumentsArray = GetUniverse()->NewArray(numberOfArgs - 1); // without receiver

//check if current frame is big enough for this unplanned Send
//doesNotUnderstand: needs 3 slots, one for this, one for method name, one for args
long additionalStackSlots = 3 - GetFrame()->RemainingStackSize();
if (additionalStackSlots > 0) {
GetFrame()->SetBytecodeIndex(bytecodeIndexGlobal);
//copy current frame into a bigger one and replace the current frame
SetFrame(VMFrame::EmergencyFrameFrom(GetFrame(), additionalStackSlots));
}
// the receiver should not go into the argumentsArray
// so, numberOfArgs - 2
for (long i = numberOfArgs - 2; i >= 0; --i) {
vm_oop_t o = GetFrame()->Pop();
argumentsArray->SetIndexableField(i, o);
}
vm_oop_t arguments[] = {signature, argumentsArray};

GetFrame()->Pop(); // pop the receiver

AS_OBJ(receiver)->Send(this, doesNotUnderstand, arguments, 2);
//check if current frame is big enough for this unplanned Send
//doesNotUnderstand: needs 3 slots, one for this, one for method name, one for args
long additionalStackSlots = 3 - GetFrame()->RemainingStackSize();
if (additionalStackSlots > 0) {
GetFrame()->SetBytecodeIndex(bytecodeIndexGlobal);
//copy current frame into a bigger one and replace the current frame
SetFrame(VMFrame::EmergencyFrameFrom(GetFrame(), additionalStackSlots));
}

AS_OBJ(receiver)->Send(this, doesNotUnderstand, arguments, 2);
}

void Interpreter::doDup() {
Expand Down Expand Up @@ -278,8 +281,10 @@ void Interpreter::doSend(long bytecodeIndex) {
int numOfArgs = Signature::GetNumberOfArguments(signature);

vm_oop_t receiver = GetFrame()->GetStackElement(numOfArgs-1);

assert(IsValidObject(receiver));
assert(dynamic_cast<VMClass*>(CLASS_OF(receiver)) != nullptr); // make sure it is really a class
// make sure it is really a class
assert(dynamic_cast<VMClass*>(CLASS_OF(receiver)) != nullptr);

VMClass* receiverClass = CLASS_OF(receiver);

Expand Down
3 changes: 3 additions & 0 deletions src/interpreter/Interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ class Interpreter {

VMFrame* popFrame();
void popFrameAndPushResult(vm_oop_t result);

void send(VMSymbol* signature, VMClass* receiverClass);

void triggerDoesNotUnderstand(VMSymbol* signature);

void doDup();
void doPushLocal(long bytecodeIndex);
Expand Down
2 changes: 1 addition & 1 deletion src/vm/IsValidObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ void obtain_vtables_of_known_classes(VMSymbol* className) {
VMInteger* i = new (GetHeap<HEAP_CLS>()) VMInteger(0);
vt_integer = *(void**) i;

VMMethod* mth = new (GetHeap<HEAP_CLS>()) VMMethod(0, 0, 0);
VMMethod* mth = new (GetHeap<HEAP_CLS>()) VMMethod(0, 0);
vt_method = *(void**) mth;
vt_object = *(void**) nilObject;

Expand Down
4 changes: 0 additions & 4 deletions src/vmobjects/Signature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@
#include "Signature.h"
#include "VMSymbol.h"

int Signature::GetNumberOfArguments(VMSymbol* sig) {
return sig->numberOfArgumentsOfSignature;
}

bool Signature::IsBinary(VMSymbol* sig) {
return sig->numberOfArgumentsOfSignature == 2;
}
Expand Down
7 changes: 5 additions & 2 deletions src/vmobjects/Signature.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@

#include <stddef.h>
#include <vmobjects/ObjectFormats.h>
#include <vmobjects/VMSymbol.h>

class Signature {
public:
static int GetNumberOfArguments(VMSymbol* sig);
inline static int GetNumberOfArguments(VMSymbol* sig) {
return sig->numberOfArgumentsOfSignature;
}

static bool IsBinary(VMSymbol* sig);

static int DetermineNumberOfArguments(const char* sig, const size_t length);
static bool IsBinary(const char* sig, const size_t length);

};
8 changes: 0 additions & 8 deletions src/vmobjects/VMFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,14 +227,6 @@ void VMFrame::PrintStack() const {
}
}

void VMFrame::ResetStackPointer() {
// arguments are stored in front of local variables
VMMethod* meth = GetMethod();
locals = arguments + meth->GetNumberOfArguments();
// Set the stack pointer to its initial value thereby clearing the stack
stack_ptr = locals + meth->GetNumberOfLocals() - 1;
}

void VMFrame::SetLocal(long index, long contextLevel, vm_oop_t value) {
VMFrame* context = GetContextLevel(contextLevel);
context->SetLocal(index, value);
Expand Down
10 changes: 9 additions & 1 deletion src/vmobjects/VMFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
*/

#include <vmobjects/VMArray.h>
#include <vmobjects/VMMethod.h>

class Universe;

Expand Down Expand Up @@ -64,7 +65,14 @@ class VMFrame: public VMObject {
store_ptr(*stack_ptr, obj);
}

void ResetStackPointer();
void ResetStackPointer() {
// arguments are stored in front of local variables
VMMethod* meth = GetMethod();
locals = arguments + meth->GetNumberOfArguments();
// Set the stack pointer to its initial value thereby clearing the stack
stack_ptr = locals + meth->GetNumberOfLocals() - 1;
}

inline long GetBytecodeIndex() const;
inline void SetBytecodeIndex(long);

Expand Down
4 changes: 2 additions & 2 deletions src/vmobjects/VMMethod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ const long VMMethod::VMMethodNumberOfFields = 8;
const long VMMethod::VMMethodNumberOfFields = 7;
#endif

VMMethod::VMMethod(long bcCount, long numberOfConstants, long nof) :
VMInvokable(nof + VMMethodNumberOfFields) {
VMMethod::VMMethod(long bcCount, long numberOfConstants) :
VMInvokable(VMMethodNumberOfFields) {
#ifdef UNSAFE_FRAME_OPTIMIZATION
cachedFrame = nullptr;
#endif
Expand Down
21 changes: 10 additions & 11 deletions src/vmobjects/VMMethod.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,20 @@ class VMMethod: public VMInvokable {
public:
typedef GCMethod Stored;

VMMethod(long bcCount, long numberOfConstants, long nof = 0);
VMMethod(long bcCount, long numberOfConstants);

inline long GetNumberOfLocals() const;
inline long GetNumberOfLocals() const {
return INT_VAL(load_ptr(numberOfLocals));
}

void SetNumberOfLocals(long nol);
long GetMaximumNumberOfStackElements() const;
void SetMaximumNumberOfStackElements(long stel);
inline long GetNumberOfArguments() const;

inline long GetNumberOfArguments() const {
return INT_VAL(load_ptr(numberOfArguments));
}

void SetNumberOfArguments(long);
long GetNumberOfBytecodes() const;
virtual void SetHolder(VMClass* hld);
Expand Down Expand Up @@ -111,14 +118,6 @@ class VMMethod: public VMInvokable {
static const long VMMethodNumberOfFields;
};

inline long VMMethod::GetNumberOfLocals() const {
return INT_VAL(load_ptr(numberOfLocals));
}

inline long VMMethod::GetNumberOfArguments() const {
return INT_VAL(load_ptr(numberOfArguments));
}

void VMMethod::SetIndexableField(long idx, vm_oop_t item) {
store_ptr(indexableFields[idx], item);
}
Expand Down

0 comments on commit 3576572

Please sign in to comment.