Skip to content

Commit

Permalink
[update vm] update class and thread's frame.
Browse files Browse the repository at this point in the history
  • Loading branch information
asxez committed Mar 26, 2024
1 parent f01030f commit 8b9a2ab
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 1 deletion.
29 changes: 29 additions & 0 deletions objectAndClass/include/class.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "obj_range.h"
#include "../../vm/core.h"
#include "../../vm/vm.h"
#include "../../compiler/compiler.h"

DEFINE_BUFFER_METHOD(Method)

Expand Down Expand Up @@ -55,6 +56,34 @@ Class *newRawClass(VM *vm, const char *name, uint32_t fieldNum) {
return class;
}

//创建一个类
Class *newClass(VM *vm, ObjString *className, uint32_t fieldNum, Class *superClass) {
//10表示strlen(" metaClass")
#define MAX_METACLASS_LEN (MAX_ID_LEN + 10)
char newClassName[MAX_METACLASS_LEN] = {EOS};
#undef MAX_METACLASS_LEN

memcpy(newClassName, className->value.start, className->value.length);
memcpy(newClassName + className->value.length, " metaClass", 10);

//先创建子类的meta类
Class *metaClass = newRawClass(vm, newClassName, 0);
metaClass->objHeader.class = vm->classOfClass;

//绑定classOfClass为meta类的基类,所有类的meta类的基类都是classOfClass
bindSuperClass(vm, metaClass, vm->classOfClass);

//最后创建类
memcpy(newClassName, className->value.start, className->value.length);
newClassName[className->value.length] = EOS;
Class *class = newRawClass(vm, newClassName, fieldNum);

className->objHeader.class = metaClass;
bindSuperClass(vm, class, superClass);

return class;
}

//数字等Value也被视为对象,因此参数为Value,获得对象obj所属的类
Class *getClassOfObj(VM *vm, Value object) {
switch (object.type) {
Expand Down
1 change: 0 additions & 1 deletion vm/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include <sys/stat.h>
#include "../utils/utils.h"
#include "vm.h"
#include "../objectAndClass/include/class.h"
#include "../compiler/compiler.h"
#include "../objectAndClass/include/obj_thread.h"
#include "coreScript.inc"
Expand Down
3 changes: 3 additions & 0 deletions vm/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define STOVE_CORE_H

#include "vm.h"
#include "../objectAndClass/include/class.h"

extern char *rootDir;
char *readFile(const char *sourceFile);
Expand All @@ -14,5 +15,7 @@ void buildCore(VM *vm);
int getIndexFromSymbolTable(SymbolTable *table, const char *symbol, uint32_t length);
int addSymbol(VM *vm, SymbolTable *table, const char *symbol, uint32_t length);
int ensureSymbolExist(VM *vm, SymbolTable *table, const char *symbol, uint32_t length);
void bindMethod(VM *vm, Class *class, uint32_t index, Method method);
void bindSuperClass(VM *vm, Class *subClass, Class *superClass);

#endif //STOVE_CORE_H
60 changes: 60 additions & 0 deletions vm/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <stdlib.h>
#include "../utils/utils.h"
#include "core.h"
#include "../objectAndClass/include/obj_thread.h"

//初始化虚拟机
void initVM(VM *vm) {
Expand All @@ -24,3 +25,62 @@ VM *newVM(void) {
buildCore(vm);
return vm;
}

//确保stack有效
void ensureStack(VM *vm, ObjThread *objThread, uint32_t neededSlots) {
if (objThread->stackCapacity >= neededSlots)
return;

uint32_t newStackCapacity = ceilToPowerOf2(neededSlots);
ASSERT(newStackCapacity > objThread->stackCapacity, "newStackCapacity error.");

//记录原栈底以用于下面判断扩容后的栈是否是原地扩容
Value *oldStackBottom = objThread->stack;

uint32_t slotSize = sizeof(Value);
objThread->stack = (Value *) memManager(vm, objThread->stack, objThread->stackCapacity * slotSize,
newStackCapacity * slotSize);
objThread->stackCapacity = newStackCapacity;

//判断是否是原地扩容
long offset = objThread->stack - oldStackBottom;

//说明os无法在原地满足内存需求,重新分配了起始地址,下面要调整
if (offset != 0) {
//调整各堆栈框架的地址
uint32_t idx = 0;
while (idx < objThread->usedFrameNum)
objThread->frames[idx++].stackStart += offset;

//调整open Upvalue
ObjUpvalue *upvalue = objThread->openUpvalues;
while (upvalue != NULL) {
upvalue->localVarPtr += offset;
upvalue = upvalue->next;
}

//更新栈顶
objThread->esp += offset;
}
}

//为objClosure在objThread中创建运行时栈
static void createFrame(VM *vm, ObjThread *objThread, ObjClosure *objClosure, int argNum) {
if (objThread->usedFrameNum + 1 > objThread->frameCapacity) {
uint32_t newCapacity = objThread->frameCapacity * 2;
uint32_t frameSize = sizeof(Frame);
objThread->frames = (Frame *) memManager(vm, objThread->frames, frameSize * objThread->frameCapacity,
frameSize * newCapacity);
objThread->frameCapacity = newCapacity;
}

//栈大小等于栈顶减去栈底
uint32_t stackSlots = (uint32_t) (objThread->esp - objThread->stack);
//总共需要的栈大小
uint32_t neededSlots = stackSlots + objClosure->fun->maxStackSlotUsedNum;

ensureStack(vm, objThread, neededSlots);

//准备上CPU
prepareFrame(objThread, objClosure, objThread->esp - argNum);
}

0 comments on commit 8b9a2ab

Please sign in to comment.