├── README.md ├── cli ├── cli.c └── cli.h ├── compiler ├── compiler.c ├── compiler.h ├── debug.c └── debug.h ├── employee.sp ├── gc ├── gc.c └── gc.h ├── include ├── common.h ├── unicodeUtf8.c ├── unicodeUtf8.h ├── utils.c └── utils.h ├── makefile ├── makefile.debug ├── manager.sp ├── object ├── class.c ├── class.h ├── header_obj.c ├── header_obj.h ├── meta_obj.c ├── meta_obj.h ├── obj_fn.c ├── obj_fn.h ├── obj_list.c ├── obj_list.h ├── obj_map.c ├── obj_map.h ├── obj_range.c ├── obj_range.h ├── obj_string.c ├── obj_string.h ├── obj_thread.c └── obj_thread.h ├── parser ├── parser.c └── parser.h └── vm ├── core.c ├── core.h ├── core.script.inc ├── opcode.inc ├── vm.c └── vm.h /README.md: -------------------------------------------------------------------------------- 1 | # DIYProgramLanguage
2 | **代码来自 《基于c语言自制编程语言》作者:郑钢**
3 | 使用方法:直接在根目录打开命令行并且输入make
4 | 若想查看gc垃圾回收过程,请在命令行输入make -f makefile.debug 来在编译的时候加入DEBUG宏
5 | -------------------------------------------------------------------------------- /cli/cli.c: -------------------------------------------------------------------------------- 1 | #include "cli.h" 2 | #include 3 | #include 4 | #include "parser.h" 5 | #include "vm.h" 6 | #include "core.h" 7 | 8 | //执行脚本文件 9 | static void runFile(const char* path) { 10 | const char* lastSlash = strrchr(path, '/'); 11 | if (lastSlash != NULL) { 12 | char* root = (char*)malloc(lastSlash - path + 2); 13 | memcpy(root, path, lastSlash - path + 1); 14 | root[lastSlash - path + 1] = '\0'; 15 | rootDir = root; 16 | } 17 | 18 | VM* vm = newVM(); 19 | const char* sourceCode = readFile(path); 20 | executeModule(vm, OBJ_TO_VALUE(newObjString(vm, path, strlen(path))), sourceCode); 21 | freeVM(vm); 22 | } 23 | 24 | //运行命令行 25 | static void runCli(void) { 26 | VM* vm = newVM(); 27 | char sourceLine[MAX_LINE_LEN]; 28 | printf("maque Version: 0.1\n"); 29 | while (true) { 30 | printf(">>> "); 31 | 32 | //若读取失败或者键入quit就退出循环 33 | if (!fgets(sourceLine, MAX_LINE_LEN, stdin) || 34 | memcmp(sourceLine, "quit", 4) == 0) { 35 | break; 36 | } 37 | executeModule(vm, OBJ_TO_VALUE(newObjString(vm, "cli", 3)), sourceLine); 38 | } 39 | freeVM(vm); 40 | } 41 | 42 | int main(int argc, const char** argv) { 43 | if (argc == 1) { 44 | runCli(); 45 | } else { 46 | runFile(argv[1]); 47 | } 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /cli/cli.h: -------------------------------------------------------------------------------- 1 | #ifndef _CLI_CLI_H 2 | #define _CLI_CLI_H 3 | 4 | #define VERSION 0.1.0 5 | #define MAX_LINE_LEN 1024 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /compiler/compiler.h: -------------------------------------------------------------------------------- 1 | #ifndef _COMPILER_COMPILER_H 2 | #define _COMPILER_COMPILER_H 3 | #include "obj_fn.h" 4 | 5 | #define MAX_LOCAL_VAR_NUM 128 6 | #define MAX_UPVALUE_NUM 128 7 | #define MAX_ID_LEN 128 //变量名最大长度 8 | 9 | #define MAX_METHOD_NAME_LEN MAX_ID_LEN 10 | #define MAX_ARG_NUM 16 11 | 12 | //函数名长度+'('+n个参数+(n-1)个参数分隔符','+')' 13 | #define MAX_SIGN_LEN MAX_METHOD_NAME_LEN + MAX_ARG_NUM * 2 + 1 14 | 15 | #define MAX_FIELD_NUM 128 16 | 17 | typedef struct { 18 | //如果此upvalue是直接外层函数的局部变量就置为true, 19 | //否则置为false 20 | bool isEnclosingLocalVar; 21 | 22 | //外层函数中局部变量的索引或者外层函数中upvalue的索引 23 | //这取决于isEnclosingLocalVar的值 24 | uint32_t index; 25 | } Upvalue; //upvalue结构 26 | 27 | typedef struct { 28 | const char* name; 29 | uint32_t length; 30 | int scopeDepth; //局部变量作用域 31 | 32 | //表示本函数中的局部变量是否是其内层函数所引用的upvalue, 33 | //当其内层函数引用此变量时,由其内层函数来设置此项为true. 34 | bool isUpvalue; 35 | } LocalVar; //局部变量 36 | 37 | typedef enum { 38 | SIGN_CONSTRUCT, //构造函数 39 | SIGN_METHOD, //普通方法 40 | SIGN_GETTER, //getter方法 41 | SIGN_SETTER, //setter方法 42 | SIGN_SUBSCRIPT, //getter形式的下标 43 | SIGN_SUBSCRIPT_SETTER //setter形式的下标 44 | } SignatureType; //方法的签名 45 | 46 | typedef struct { 47 | SignatureType type; //签名类型 48 | const char* name; //签名 49 | uint32_t length; //签名长度 50 | uint32_t argNum; //参数个数 51 | } Signature; //签名 52 | 53 | typedef struct loop { 54 | int condStartIndex; //循环中条件的地址 55 | int bodyStartIndex; //循环体起始地址 56 | int scopeDepth; //循环中若有break,告诉它需要退出的作用域深度 57 | int exitIndex; //循环条件不满足时跳出循环体的目标地址 58 | struct loop* enclosingLoop; //外层循环 59 | } Loop; //loop结构 60 | 61 | typedef struct { 62 | ObjString* name; //类名 63 | SymbolTable fields; //类属性符号表 64 | bool inStatic; //若当前编译静态方法就为真 65 | IntBuffer instantMethods; //实例方法 66 | IntBuffer staticMethods; //静态方法 67 | Signature* signature; //当前正在编译的签名 68 | } ClassBookKeep; //用于记录类编译时的信息 69 | 70 | typedef struct compileUnit CompileUnit; 71 | 72 | int defineModuleVar(VM* vm, ObjModule* objModule, const char* name, uint32_t length, Value value); 73 | 74 | ObjFn* compileModule(VM* vm, ObjModule* objModule, const char* moduleCode); 75 | uint32_t getBytesOfOperands(Byte* instrStream, Value* constants, int ip); 76 | void grayCompileUnit(VM* vm, CompileUnit* cu); 77 | #endif 78 | -------------------------------------------------------------------------------- /compiler/debug.c: -------------------------------------------------------------------------------- 1 | #ifdef DEBUG 2 | #include 3 | #include "debug.h" 4 | #include "vm.h" 5 | #include 6 | 7 | //在fnDebug中绑定函数名 8 | void bindDebugFnName(VM* vm, FnDebug* fnDebug, 9 | const char* name, uint32_t length) { 10 | ASSERT(fnDebug->fnName == NULL, "debug.name has bound!"); 11 | fnDebug->fnName = ALLOCATE_ARRAY(vm, char, length + 1); 12 | memcpy(fnDebug->fnName, name, length); 13 | fnDebug->fnName[length] = '\0'; 14 | } 15 | 16 | //打印栈 17 | void dumpStack(ObjThread* thread) { 18 | printf("(thread %p) stack:%p, esp:%p, slots:%ld ", 19 | thread, thread->stack, thread->esp, thread->esp - thread->stack); 20 | Value* slot = thread->stack; 21 | while (slot < thread->esp) { 22 | dumpValue(*slot); 23 | printf(" | "); 24 | slot++; 25 | } 26 | printf("\n"); 27 | } 28 | 29 | //打印对象 30 | static void dumpObject(ObjHeader* obj) { 31 | switch (obj->type) { 32 | case OT_CLASS: 33 | printf("[class %s %p]", ((Class*)obj)->name->value.start, obj); 34 | break; 35 | case OT_CLOSURE: 36 | printf("[closure %p]", obj); 37 | break; 38 | case OT_THREAD: 39 | printf("[thread %p]", obj); 40 | break; 41 | case OT_FUNCTION: 42 | printf("[fn %p]", obj); 43 | break; 44 | case OT_INSTANCE: 45 | printf("[instance %p]", obj); 46 | break; 47 | case OT_LIST: 48 | printf("[list %p]", obj); 49 | break; 50 | case OT_MAP: 51 | printf("[map %p]", obj); 52 | break; 53 | case OT_MODULE: 54 | printf("[module %p]", obj); 55 | break; 56 | case OT_RANGE: 57 | printf("[range %p]", obj); 58 | break; 59 | case OT_STRING: 60 | printf("%s", ((ObjString*)obj)->value.start); 61 | break; 62 | case OT_UPVALUE : 63 | printf("[upvalue %p]", obj); 64 | break; 65 | default: 66 | printf("[unknown object %d]", obj->type); 67 | break; 68 | } 69 | } 70 | 71 | //打印value 72 | void dumpValue(Value value) { 73 | switch (value.type) { 74 | case VT_FALSE: printf("false"); break; 75 | case VT_NULL: printf("null"); break; 76 | case VT_NUM: printf("%.14g", VALUE_TO_NUM(value)); break; 77 | case VT_TRUE: printf("true"); break; 78 | case VT_OBJ: dumpObject(VALUE_TO_OBJ(value)); break; 79 | case VT_UNDEFINED: NOT_REACHED(); 80 | } 81 | } 82 | 83 | //打印一条指令 84 | static int dumpOneInstruction(VM* vm, ObjFn* fn, int i, int* lastLine) { 85 | int start = i; 86 | uint8_t* bytecode = fn->instrStream.datas; 87 | OpCode opCode = (OpCode)bytecode[i]; 88 | 89 | int lineNo = fn->debug->lineNo.datas[i]; 90 | 91 | if (lastLine == NULL || *lastLine != lineNo) { 92 | printf("%4d:", lineNo); //输出源码行号 93 | if (lastLine != NULL) { 94 | *lastLine = lineNo; 95 | } 96 | } else { 97 | //不用输出源码行了,还是输出的lastLine行的指令流,空出行号的位置即可 98 | printf(" "); 99 | } 100 | 101 | printf(" %04d ", i++); //输出指令流中的位置 102 | 103 | #define READ_BYTE() (bytecode[i++]) 104 | #define READ_SHORT() (i += 2, (bytecode[i - 2] << 8) | bytecode[i - 1]) 105 | 106 | #define BYTE_INSTRUCTION(name) \ 107 | printf("%-16s %5d\n", name, READ_BYTE()); \ 108 | break; \ 109 | 110 | switch (opCode) { 111 | case OPCODE_LOAD_CONSTANT: { 112 | int constant = READ_SHORT(); 113 | printf("%-16s %5d '", "LOAD_CONSTANT", constant); 114 | dumpValue(fn->constants.datas[constant]); 115 | printf("'\n"); 116 | break; 117 | } 118 | 119 | case OPCODE_PUSH_NULL: printf("PUSH_NULL\n"); break; 120 | case OPCODE_PUSH_FALSE: printf("PUSH_FALSE\n"); break; 121 | case OPCODE_PUSH_TRUE: printf("PUSH_TRUE\n"); break; 122 | 123 | case OPCODE_LOAD_LOCAL_VAR: BYTE_INSTRUCTION("LOAD_LOCAL_VAR"); 124 | case OPCODE_STORE_LOCAL_VAR: BYTE_INSTRUCTION("STORE_LOCAL_VAR"); 125 | case OPCODE_LOAD_UPVALUE: BYTE_INSTRUCTION("LOAD_UPVALUE"); 126 | case OPCODE_STORE_UPVALUE: BYTE_INSTRUCTION("STORE_UPVALUE"); 127 | 128 | case OPCODE_LOAD_MODULE_VAR: { 129 | int slot = READ_SHORT(); 130 | printf("%-16s %5d '%s'\n", "LOAD_MODULE_VAR", slot, 131 | fn->module->moduleVarName.datas[slot].str); 132 | break; 133 | } 134 | 135 | case OPCODE_STORE_MODULE_VAR: { 136 | int slot = READ_SHORT(); 137 | printf("%-16s %5d '%s'\n", "STORE_MODULE_VAR", slot, 138 | fn->module->moduleVarName.datas[slot].str); 139 | break; 140 | } 141 | 142 | case OPCODE_LOAD_THIS_FIELD: BYTE_INSTRUCTION("LOAD_THIS_FIELD"); 143 | case OPCODE_STORE_THIS_FIELD: BYTE_INSTRUCTION("STORE_THIS_FIELD"); 144 | case OPCODE_LOAD_FIELD: BYTE_INSTRUCTION("LOAD_FIELD"); 145 | case OPCODE_STORE_FIELD: BYTE_INSTRUCTION("STORE_FIELD"); 146 | 147 | case OPCODE_POP: printf("POP\n"); break; 148 | 149 | case OPCODE_CALL0: 150 | case OPCODE_CALL1: 151 | case OPCODE_CALL2: 152 | case OPCODE_CALL3: 153 | case OPCODE_CALL4: 154 | case OPCODE_CALL5: 155 | case OPCODE_CALL6: 156 | case OPCODE_CALL7: 157 | case OPCODE_CALL8: 158 | case OPCODE_CALL9: 159 | case OPCODE_CALL10: 160 | case OPCODE_CALL11: 161 | case OPCODE_CALL12: 162 | case OPCODE_CALL13: 163 | case OPCODE_CALL14: 164 | case OPCODE_CALL15: 165 | case OPCODE_CALL16: { 166 | int numArgs = bytecode[i - 1] - OPCODE_CALL0; 167 | int symbol = READ_SHORT(); 168 | printf("CALL%-11d %5d '%s'\n", numArgs, symbol, 169 | vm->allMethodNames.datas[symbol].str); 170 | break; 171 | } 172 | 173 | case OPCODE_SUPER0: 174 | case OPCODE_SUPER1: 175 | case OPCODE_SUPER2: 176 | case OPCODE_SUPER3: 177 | case OPCODE_SUPER4: 178 | case OPCODE_SUPER5: 179 | case OPCODE_SUPER6: 180 | case OPCODE_SUPER7: 181 | case OPCODE_SUPER8: 182 | case OPCODE_SUPER9: 183 | case OPCODE_SUPER10: 184 | case OPCODE_SUPER11: 185 | case OPCODE_SUPER12: 186 | case OPCODE_SUPER13: 187 | case OPCODE_SUPER14: 188 | case OPCODE_SUPER15: 189 | case OPCODE_SUPER16: { 190 | int numArgs = bytecode[i - 1] - OPCODE_SUPER0; 191 | int symbol = READ_SHORT(); 192 | int superclass = READ_SHORT(); 193 | printf("SUPER%-10d %5d '%s' %5d\n", numArgs, symbol, 194 | vm->allMethodNames.datas[symbol].str, superclass); 195 | break; 196 | } 197 | 198 | case OPCODE_JUMP: { 199 | int offset = READ_SHORT(); 200 | printf("%-16s offset:%-5d abs:%d\n", "JUMP", offset, i + offset); 201 | break; 202 | } 203 | 204 | case OPCODE_LOOP: { 205 | int offset = READ_SHORT(); 206 | printf("%-16s offset:%-5d abs:%d\n", "LOOP", offset, i - offset); 207 | break; 208 | } 209 | 210 | case OPCODE_JUMP_IF_FALSE: { 211 | int offset = READ_SHORT(); 212 | printf("%-16s offset:%-5d abs:%d\n", "JUMP_IF_FALSE", offset, i + offset); 213 | break; 214 | } 215 | 216 | case OPCODE_AND: { 217 | int offset = READ_SHORT(); 218 | printf("%-16s offset:%-5d abs:%d\n", "AND", offset, i + offset); 219 | break; 220 | } 221 | 222 | case OPCODE_OR: { 223 | int offset = READ_SHORT(); 224 | printf("%-16s offset:%-5d abs:%d\n", "OR", offset, i + offset); 225 | break; 226 | } 227 | 228 | case OPCODE_CLOSE_UPVALUE: 229 | printf("CLOSE_UPVALUE\n"); 230 | break; 231 | 232 | case OPCODE_RETURN: 233 | printf("RETURN\n"); 234 | break; 235 | 236 | case OPCODE_CREATE_CLOSURE: { 237 | int constant = READ_SHORT(); 238 | printf("%-16s %5d ", "CREATE_CLOSURE", constant); 239 | dumpValue(fn->constants.datas[constant]); 240 | printf(" "); 241 | ObjFn* loadedFn = VALUE_TO_OBJFN(fn->constants.datas[constant]); 242 | uint32_t j; 243 | for (j = 0; j < loadedFn->upvalueNum; j++) { 244 | int isLocal = READ_BYTE(); 245 | int index = READ_BYTE(); 246 | if (j > 0) printf(", "); 247 | printf("%s %d", isLocal ? "local" : "upvalue", index); 248 | } 249 | printf("\n"); 250 | break; 251 | } 252 | 253 | case OPCODE_CONSTRUCT: 254 | printf("CONSTRUCT\n"); 255 | break; 256 | 257 | case OPCODE_CREATE_CLASS: { 258 | int numFields = READ_BYTE(); 259 | printf("%-16s %5d fields\n", "CREATE_CLASS", numFields); 260 | break; 261 | } 262 | 263 | case OPCODE_INSTANCE_METHOD: { 264 | int symbol = READ_SHORT(); 265 | printf("%-16s %5d '%s'\n", "INSTANCE_METHOD", symbol, 266 | vm->allMethodNames.datas[symbol].str); 267 | break; 268 | } 269 | 270 | case OPCODE_STATIC_METHOD: { 271 | int symbol = READ_SHORT(); 272 | printf("%-16s %5d '%s'\n", "STATIC_METHOD", symbol, 273 | vm->allMethodNames.datas[symbol].str); 274 | break; 275 | } 276 | 277 | case OPCODE_END: 278 | printf("END\n"); 279 | break; 280 | 281 | default: 282 | printf("UKNOWN! [%d]\n", bytecode[i - 1]); 283 | break; 284 | } 285 | 286 | //返回指令占用的字节数 287 | if (opCode == OPCODE_END) { 288 | return -1; 289 | } 290 | return i - start; 291 | 292 | #undef READ_BYTE 293 | #undef READ_SHORT 294 | } 295 | 296 | //打印指令 297 | void dumpInstructions(VM* vm, ObjFn* fn) { 298 | printf("module:[%s]\tfunction:[%s]\n", 299 | fn->module->name == NULL ? "" : fn->module->name->value.start, 300 | fn->debug->fnName); 301 | 302 | int i = 0; 303 | int lastLine = -1; 304 | while (true) { 305 | int offset = dumpOneInstruction(vm, fn, i, &lastLine); 306 | if (offset == -1) break; 307 | i += offset; 308 | } 309 | printf("\n"); 310 | } 311 | 312 | #endif 313 | -------------------------------------------------------------------------------- /compiler/debug.h: -------------------------------------------------------------------------------- 1 | #ifdef DEBUG 2 | #ifndef _COMPILER_DEBUG_H 3 | #define _COMPILER_DEBUG_H 4 | #include "utils.h" 5 | #include "obj_fn.h" 6 | #include "obj_thread.h" 7 | 8 | void bindDebugFnName(VM* vm, FnDebug* fnDebug, 9 | const char* name, uint32_t length); 10 | void dumpValue(Value value); 11 | void dumpInstructions(VM* vm, ObjFn* fn); 12 | void dumpStack(ObjThread* thread); 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /employee.sp: -------------------------------------------------------------------------------- 1 | class Employee { 2 | var name 3 | var gender 4 | var age 5 | var salary 6 | static var employeeNum = 0 7 | new(n, g, a, s) { 8 | name = n 9 | gender = g 10 | age = a 11 | salary = s 12 | employeeNum = employeeNum + 1 13 | } 14 | 15 | sayHi() { 16 | System.print("My name is " + 17 | name + ", I am a " + gender + 18 | ", " + age.toString + "years old") 19 | } 20 | 21 | salary { 22 | return salary 23 | } 24 | 25 | static employeeNum { 26 | return employeeNum 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /gc/gc.c: -------------------------------------------------------------------------------- 1 | #include "gc.h" 2 | #include "compiler.h" 3 | #include "obj_list.h" 4 | #include "obj_range.h" 5 | #if DEBUG 6 | #include "debug.h" 7 | #include 8 | #endif 9 | 10 | //标灰obj:即把obj收集到数组vm->grays.grayObjects 11 | void grayObject(VM* vm, ObjHeader* obj) { 12 | //如果isDark为true表示为黑色,说明已经可达,直接返回 13 | if (obj == NULL || obj->isDark) return; 14 | 15 | //标记为可达 16 | obj->isDark = true; 17 | 18 | //若超过了容量就扩容 19 | if (vm->grays.count >= vm->grays.capacity) { 20 | vm->grays.capacity = vm->grays.count * 2; 21 | vm->grays.grayObjects = 22 | (ObjHeader**)realloc(vm->grays.grayObjects, vm->grays.capacity * sizeof(ObjHeader*)); 23 | } 24 | 25 | //把obj添加到数组grayObjects 26 | vm->grays.grayObjects[vm->grays.count++] = obj; 27 | } 28 | 29 | //标灰value 30 | void grayValue(VM* vm, Value value) { 31 | //只有对象才需要标记 32 | if (!VALUE_IS_OBJ(value)) { 33 | return; 34 | } 35 | grayObject(vm, VALUE_TO_OBJ(value)); 36 | } 37 | 38 | //标灰buffer->datas中的value 39 | static void grayBuffer(VM* vm, ValueBuffer* buffer) { 40 | uint32_t idx = 0; 41 | while (idx < buffer->count) { 42 | grayValue(vm, buffer->datas[idx]); 43 | idx++; 44 | } 45 | } 46 | 47 | //标黑class 48 | static void blackClass(VM* vm, Class* class) { 49 | //标灰meta类 50 | grayObject(vm, (ObjHeader*)class->objHeader.class); 51 | 52 | //标灰父类 53 | grayObject(vm, (ObjHeader*)class->superClass); 54 | 55 | //标灰方法 56 | uint32_t idx = 0; 57 | while (idx < class->methods.count) { 58 | if (class->methods.datas[idx].type == MT_SCRIPT) { 59 | grayObject(vm, (ObjHeader*)class->methods.datas[idx].obj); 60 | } 61 | idx++; 62 | } 63 | 64 | //标灰类名 65 | grayObject(vm, (ObjHeader*)class->name); 66 | 67 | //累计类大小 68 | vm->allocatedBytes += sizeof(Class); 69 | vm->allocatedBytes += sizeof(Method) * class->methods.capacity; 70 | } 71 | 72 | //标灰闭包 73 | static void blackClosure(VM* vm, ObjClosure* objClosure) { 74 | //标灰闭包中的函数 75 | grayObject(vm, (ObjHeader*)objClosure->fn); 76 | 77 | //标灰包中的upvalue 78 | uint32_t idx = 0; 79 | while (idx < objClosure->fn->upvalueNum) { 80 | grayObject(vm, (ObjHeader*)objClosure->upvalues[idx]); 81 | idx++; 82 | } 83 | 84 | //累计闭包大小 85 | vm->allocatedBytes += sizeof(ObjClosure); 86 | vm->allocatedBytes += sizeof(ObjUpvalue*) * objClosure->fn->upvalueNum; 87 | } 88 | 89 | //标黑objThread 90 | static void blackThread(VM* vm, ObjThread* objThread) { 91 | //标灰frame 92 | uint32_t idx = 0; 93 | while (idx < objThread->usedFrameNum) { 94 | grayObject(vm, (ObjHeader*)objThread->frames[idx].closure); 95 | idx++; 96 | } 97 | 98 | //标灰运行时栈中每个slot 99 | Value* slot = objThread->stack; 100 | while (slot < objThread->esp) { 101 | grayValue(vm, *slot); 102 | slot++; 103 | } 104 | 105 | //标灰本线程中所有的upvalue 106 | ObjUpvalue* upvalue = objThread->openUpvalues; 107 | while (upvalue != NULL) { 108 | grayObject(vm, (ObjHeader*)upvalue); 109 | upvalue = upvalue->next; 110 | } 111 | 112 | //标灰caller 113 | grayObject(vm, (ObjHeader*)objThread->caller); 114 | grayValue(vm, objThread->errorObj); 115 | 116 | //累计线程大小 117 | vm->allocatedBytes += sizeof(ObjThread); 118 | vm->allocatedBytes += objThread->frameCapacity * sizeof(Frame); 119 | vm->allocatedBytes += objThread->stackCapacity * sizeof(Value); 120 | } 121 | 122 | //标黑fn 123 | static void blackFn(VM* vm, ObjFn* fn) { 124 | //标灰常量 125 | grayBuffer(vm, &fn->constants); 126 | 127 | //累计Objfn的空间 128 | vm->allocatedBytes += sizeof(ObjFn); 129 | vm->allocatedBytes += sizeof(uint8_t) * fn->instrStream.capacity; 130 | vm->allocatedBytes += sizeof(Value) * fn->constants.capacity; 131 | 132 | #if DEBUG 133 | //再加上debug信息占用的内存 134 | vm->allocatedBytes += sizeof(Int) * fn->instrStream.capacity; 135 | #endif 136 | } 137 | 138 | //标黑objInstance 139 | static void blackInstance(VM* vm, ObjInstance* objInstance) { 140 | //标灰元类 141 | grayObject(vm, (ObjHeader*)objInstance->objHeader.class); 142 | 143 | //标灰实例中所有域,域的个数在class->fieldNum 144 | uint32_t idx = 0; 145 | while (idx < objInstance->objHeader.class->fieldNum) { 146 | grayValue(vm, objInstance->fields[idx]); 147 | idx++; 148 | } 149 | 150 | //累计objInstance空间 151 | vm->allocatedBytes += sizeof(ObjInstance); 152 | vm->allocatedBytes += sizeof(Value) * objInstance->objHeader.class->fieldNum; 153 | } 154 | 155 | //标黑objList 156 | static void blackList(VM* vm, ObjList* objList) { 157 | //标灰list的elements 158 | grayBuffer(vm, &objList->elements); 159 | 160 | //累计objList大小 161 | vm->allocatedBytes += sizeof(ObjList); 162 | vm->allocatedBytes += sizeof(Value) * objList->elements.capacity; 163 | } 164 | 165 | //标黑objMap 166 | static void blackMap(VM* vm, ObjMap* objMap) { 167 | //标灰所有entry 168 | uint32_t idx = 0; 169 | while (idx < objMap->capacity) { 170 | Entry* entry = &objMap->entries[idx]; 171 | //跳过无效的entry 172 | if (!VALUE_IS_UNDEFINED(entry->key)) { 173 | grayValue(vm, entry->key); 174 | grayValue(vm, entry->value); 175 | } 176 | idx++; 177 | } 178 | 179 | //累计ObjMap大小 180 | vm->allocatedBytes += sizeof(ObjMap); 181 | vm->allocatedBytes += sizeof(Entry) * objMap->capacity; 182 | } 183 | 184 | //标黑objModule 185 | static void blackModule(VM* vm, ObjModule* objModule) { 186 | //标灰模块中所有模块变量 187 | uint32_t idx = 0; 188 | while (idx < objModule->moduleVarValue.count) { 189 | grayValue(vm, objModule->moduleVarValue.datas[idx]); 190 | idx++; 191 | } 192 | 193 | //标灰模块名 194 | grayObject(vm, (ObjHeader*)objModule->name); 195 | 196 | //累计ObjModule大小 197 | vm->allocatedBytes += sizeof(ObjModule); 198 | vm->allocatedBytes += sizeof(String) * objModule->moduleVarName.capacity; 199 | vm->allocatedBytes += sizeof(Value) * objModule->moduleVarValue.capacity; 200 | } 201 | 202 | //标黑range 203 | static void blackRange(VM* vm) { 204 | //ObjRange中没有大数据,只有from和to, 205 | //其空间属于sizeof(ObjRange),因此不用额外标记 206 | vm->allocatedBytes += sizeof(ObjRange); 207 | } 208 | 209 | //标黑objString 210 | static void blackString(VM* vm, ObjString* objString) { 211 | //累计ObjString空间 +1是结尾的'\0' 212 | vm->allocatedBytes += sizeof(ObjString) + objString->value.length + 1; 213 | } 214 | 215 | //标黑objUpvalue 216 | static void blackUpvalue(VM* vm, ObjUpvalue* objUpvalue) { 217 | //标灰objUpvalue的closedUpvalue 218 | grayValue(vm, objUpvalue->closedUpvalue); 219 | 220 | //累计objUpvalue大小 221 | vm->allocatedBytes += sizeof(ObjUpvalue); 222 | } 223 | 224 | //标黑obj 225 | static void blackObject(VM* vm, ObjHeader* obj) { 226 | #ifdef DEBUG 227 | printf("mark "); 228 | dumpValue(OBJ_TO_VALUE(obj)); 229 | printf(" @ %p\n", obj); 230 | #endif 231 | //根据对象类型分别标黑 232 | switch (obj->type) { 233 | case OT_CLASS: 234 | blackClass(vm, (Class*)obj); 235 | break; 236 | 237 | case OT_CLOSURE: 238 | blackClosure(vm, (ObjClosure*)obj); 239 | break; 240 | 241 | case OT_THREAD: 242 | blackThread(vm, (ObjThread*)obj); 243 | break; 244 | 245 | case OT_FUNCTION: 246 | blackFn(vm, (ObjFn*)obj); 247 | break; 248 | 249 | case OT_INSTANCE: 250 | blackInstance(vm, (ObjInstance*)obj); 251 | break; 252 | 253 | case OT_LIST: 254 | blackList(vm, (ObjList*)obj); 255 | break; 256 | 257 | case OT_MAP: 258 | blackMap(vm, (ObjMap*)obj); 259 | break; 260 | 261 | case OT_MODULE: 262 | blackModule(vm, (ObjModule*)obj); 263 | break; 264 | 265 | case OT_RANGE: 266 | blackRange(vm); 267 | break; 268 | 269 | case OT_STRING: 270 | blackString(vm, (ObjString*)obj); 271 | break; 272 | 273 | case OT_UPVALUE: 274 | blackUpvalue(vm, (ObjUpvalue*)obj); 275 | break; 276 | } 277 | } 278 | 279 | //标黑那些已经标灰的对象,即保留那些标灰的对象 280 | static void blackObjectInGray(VM* vm) { 281 | //所有要保留的对象都已经收集到了vm->grays.grayObjects中, 282 | //现在逐一标黑 283 | while (vm->grays.count > 0) { 284 | ObjHeader* objHeader = vm->grays.grayObjects[--vm->grays.count]; 285 | blackObject(vm, objHeader); 286 | } 287 | } 288 | 289 | //释放obj自身及其占用的内存 290 | void freeObject(VM* vm, ObjHeader* obj) { 291 | #ifdef DEBUG 292 | printf("free "); 293 | dumpValue(OBJ_TO_VALUE(obj)); 294 | printf(" @ %p\n", obj); 295 | #endif 296 | 297 | //根据对象类型分别处理 298 | switch (obj->type) { 299 | case OT_CLASS: 300 | MethodBufferClear(vm, &((Class*)obj)->methods); 301 | break; 302 | 303 | case OT_THREAD: { 304 | ObjThread* objThread = (ObjThread*)obj; 305 | DEALLOCATE(vm, objThread->frames); 306 | DEALLOCATE(vm, objThread->stack); 307 | break; 308 | } 309 | 310 | case OT_FUNCTION: { 311 | ObjFn* fn = (ObjFn*)obj; 312 | ValueBufferClear(vm, &fn->constants); 313 | ByteBufferClear(vm, &fn->instrStream); 314 | #if DEBUG 315 | IntBufferClear(vm, &fn->debug->lineNo); 316 | DEALLOCATE(vm, fn->debug->fnName); 317 | DEALLOCATE(vm, fn->debug); 318 | #endif 319 | break; 320 | } 321 | 322 | case OT_LIST: 323 | ValueBufferClear(vm, &((ObjList*)obj)->elements); 324 | break; 325 | 326 | case OT_MAP: 327 | DEALLOCATE(vm, ((ObjMap*)obj)->entries); 328 | break; 329 | 330 | case OT_MODULE: 331 | StringBufferClear(vm, &((ObjModule*)obj)->moduleVarName); 332 | ValueBufferClear(vm, &((ObjModule*)obj)->moduleVarValue); 333 | break; 334 | 335 | case OT_STRING: 336 | case OT_RANGE: 337 | case OT_CLOSURE: 338 | case OT_INSTANCE: 339 | case OT_UPVALUE: 340 | break; 341 | } 342 | 343 | //最后再释放自己 344 | DEALLOCATE(vm, obj); 345 | } 346 | 347 | //立即运行垃圾回收器去释放未用的内存 348 | void startGC(VM* vm) { 349 | #ifdef DEBUG 350 | double startTime = (double)clock() / CLOCKS_PER_SEC; 351 | uint32_t before = vm->allocatedBytes; 352 | printf("-- gc before:%d nextGC:%d vm:%p --\n", 353 | before, vm->config.nextGC, vm); 354 | #endif 355 | // 一 标记阶段:标记需要保留的对象 356 | 357 | //将allocatedBytes置0便于精确统计回收后的总分配内存大小 358 | vm->allocatedBytes = 0; 359 | 360 | //allModules不能被释放 361 | grayObject(vm, (ObjHeader*)vm->allModules); 362 | 363 | //标灰tmpRoots数组中的对象(不可达但是不想被回收,白名单) 364 | uint32_t idx = 0; 365 | while (idx < vm->tmpRootNum) { 366 | grayObject(vm, vm->tmpRoots[idx]); 367 | idx++; 368 | } 369 | 370 | //标灰当前线程,不能被回收 371 | grayObject(vm, (ObjHeader*)vm->curThread); 372 | 373 | //编译过程中若申请的内存过高就标灰编译单元 374 | if (vm->curParser != NULL) { 375 | ASSERT(vm->curParser->curCompileUnit != NULL, 376 | "grayCompileUnit only be called while compiling!"); 377 | grayCompileUnit(vm, vm->curParser->curCompileUnit); 378 | } 379 | 380 | //置黑所有灰对象(保留的对象) 381 | blackObjectInGray(vm); 382 | 383 | // 二 清扫阶段:回收白对象(垃圾对象) 384 | 385 | ObjHeader** obj = &vm->allObjects; 386 | while (*obj != NULL) { 387 | //回收白对象 388 | if (!((*obj)->isDark)) { 389 | ObjHeader* unreached = *obj; 390 | *obj = unreached->next; 391 | freeObject(vm, unreached); 392 | } else { 393 | //如果已经是黑对象,为了下一次gc重新判定, 394 | //现在将其恢复为未标记状态,避免永远不被回收 395 | (*obj)->isDark = false; 396 | obj = &(*obj)->next; 397 | } 398 | } 399 | 400 | //更新下一次触发gc的阀值 401 | vm->config.nextGC = vm->allocatedBytes * vm->config.heapGrowthFactor; 402 | if (vm->config.nextGC < vm->config.minHeapSize) { 403 | vm->config.nextGC = vm->config.minHeapSize; 404 | } 405 | 406 | #ifdef DEBUG 407 | double elapsed = ((double)clock() / CLOCKS_PER_SEC) - startTime; 408 | printf("GC %lu before, %lu after (%lu collected), next at %lu. take %.3fs.\n", 409 | (unsigned long)before, 410 | (unsigned long)vm->allocatedBytes, 411 | (unsigned long)(before - vm->allocatedBytes), 412 | (unsigned long)vm->config.nextGC, 413 | elapsed); 414 | #endif 415 | } 416 | -------------------------------------------------------------------------------- /gc/gc.h: -------------------------------------------------------------------------------- 1 | #ifndef _GC_GC_H 2 | #define _GC_GC_H 3 | #include "vm.h" 4 | void grayObject(VM* vm, ObjHeader* obj); 5 | void grayValue(VM* vm, Value value); 6 | void freeObject(VM* vm, ObjHeader* obj); 7 | void startGC(VM* vm); 8 | #endif 9 | -------------------------------------------------------------------------------- /include/common.h: -------------------------------------------------------------------------------- 1 | #ifndef _INCLUDE_COMMON_H 2 | #define _INCLUDE_COMMON_H 3 | #include 4 | #include 5 | #include 6 | 7 | typedef struct vm VM; 8 | typedef struct parser Parser; 9 | typedef struct class Class; 10 | 11 | #define bool char 12 | #define true 1 13 | #define false 0 14 | #define UNUSED __attribute__ ((unused)) 15 | 16 | #ifdef DEBUG 17 | #define ASSERT(condition, errMsg) \ 18 | do {\ 19 | if (!(condition)) {\ 20 | fprintf(stderr, "ASSERT failed! %s:%d In function %s(): %s\n", \ 21 | __FILE__, __LINE__, __func__, errMsg); \ 22 | abort();\ 23 | }\ 24 | } while (0); 25 | #else 26 | #define ASSERT(condition, errMsg) ((void)0) 27 | #endif 28 | 29 | #define NOT_REACHED()\ 30 | do {\ 31 | fprintf(stderr, "NOT_REACHED: %s:%d In function %s()\n", \ 32 | __FILE__, __LINE__, __func__);\ 33 | while (1);\ 34 | } while (0); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /include/unicodeUtf8.c: -------------------------------------------------------------------------------- 1 | #include "unicodeUtf8.h" 2 | #include "common.h" 3 | 4 | //返回value按照utf8编码后的字节数 5 | uint32_t getByteNumOfEncodeUtf8(int value) { 6 | ASSERT(value > 0, "Can`t encode negative value!"); 7 | 8 | // 单个ascii字符需要1字节 9 | if (value <= 0x7f) { 10 | return 1; 11 | } 12 | 13 | //此范围内数值编码为utf8需要2字节 14 | if (value <= 0x7ff) { 15 | return 2; 16 | } 17 | 18 | //此范围内数值编码为utf8需要3字节 19 | if (value <= 0xffff) { 20 | return 3; 21 | } 22 | 23 | //此范围内数值编码为utf8需要4字节 24 | if (value <= 0x10ffff) { 25 | return 4; 26 | } 27 | 28 | return 0; //超过范围返回0 29 | } 30 | 31 | //把value编码为utf8后写入缓冲区buf,返回写入的字节数 32 | uint8_t encodeUtf8(uint8_t* buf, int value) { 33 | ASSERT(value > 0, "Can`t encode negative value!"); 34 | 35 | //按照大端字节序写入缓冲区 36 | if (value <= 0x7f) { // 单个ascii字符需要1字节 37 | *buf = value & 0x7f; 38 | return 1; 39 | } else if (value <= 0x7ff) { //此范围内数值编码为utf8需要2字节 40 | //先写入高字节 41 | *buf++ = 0xc0 | ((value & 0x7c0) >> 6); 42 | // 再写入低字节 43 | *buf = 0x80 | (value & 0x3f); 44 | return 2; 45 | } else if (value <= 0xffff) { //此范围内数值编码为utf8需要3字节 46 | // 先写入高字节 47 | *buf++ = 0xe0 | ((value & 0xf000) >> 12); 48 | //再写入中间字节 49 | *buf++ = 0x80 | ((value & 0xfc0) >> 6); 50 | //最后写入低字节 51 | *buf = 0x80 | (value & 0x3f); 52 | return 3; 53 | } else if (value <= 0x10ffff) { //此范围内数值编码为utf8需要4字节 54 | *buf++ = 0xf0 | ((value & 0x1c0000) >> 18); 55 | *buf++ = 0x80 | ((value & 0x3f000) >> 12); 56 | *buf++ = 0x80 | ((value & 0xfc0) >> 6); 57 | *buf = 0x80 | (value & 0x3f); 58 | return 4; 59 | } 60 | 61 | NOT_REACHED(); 62 | return 0; 63 | } 64 | 65 | //返回解码utf8的字节数 66 | uint32_t getByteNumOfDecodeUtf8(uint8_t byte) { 67 | //byte应该是utf8的最高1字节,如果指向了utf8编码后面的低字节部分则返回0 68 | if ((byte & 0xc0) == 0x80) { 69 | return 0; 70 | } 71 | 72 | if ((byte & 0xf8) == 0xf0) { 73 | return 4; 74 | } 75 | 76 | if ((byte & 0xf0) == 0xe0) { 77 | return 3; 78 | } 79 | 80 | if ((byte & 0xe0) == 0xc0) { 81 | return 2; 82 | } 83 | 84 | return 1; //ascii码 85 | } 86 | 87 | //解码以bytePtr为起始地址的UTF-8序列 其最大长度为length 若不是UTF-8序列就返回-1 88 | int decodeUtf8(const uint8_t* bytePtr, uint32_t length) { 89 | //若是1字节的ascii: 0xxxxxxx 90 | if (*bytePtr <= 0x7f) { 91 | return *bytePtr; 92 | } 93 | 94 | int value; 95 | uint32_t remainingBytes; 96 | 97 | //先读取高1字节 98 | //根据高字节的高n位判断相应字节数的utf8编码 99 | if ((*bytePtr & 0xe0) == 0xc0) { 100 | //若是2字节的utf8 101 | value = *bytePtr & 0x1f; 102 | remainingBytes = 1; 103 | } else if ((*bytePtr & 0xf0) == 0xe0) { 104 | //若是3字节的utf8 105 | value = *bytePtr & 0x0f; 106 | remainingBytes = 2; 107 | } else if ((*bytePtr & 0xf8) == 0xf0) { 108 | //若是4字节的utf8 109 | value = *bytePtr & 0x07; 110 | remainingBytes = 3; 111 | } else { //非法编码 112 | return -1; 113 | } 114 | 115 | //如果utf8被斩断了就不再读过去了 116 | if (remainingBytes > length - 1) { 117 | return -1; 118 | } 119 | 120 | //再读取低字节中的数据 121 | while (remainingBytes > 0) { 122 | bytePtr++; 123 | remainingBytes--; 124 | //高2位必须是10 125 | if ((*bytePtr & 0xc0) != 0x80) { 126 | return -1; 127 | } 128 | 129 | //从次高字节往低字节,不断累加各字节的低6位 130 | value = value << 6 | (*bytePtr & 0x3f); 131 | } 132 | return value; 133 | } 134 | -------------------------------------------------------------------------------- /include/unicodeUtf8.h: -------------------------------------------------------------------------------- 1 | #ifndef _INCLUDE_UTF8_H 2 | #define _INCLUDE_UTF8_H 3 | #include 4 | uint32_t getByteNumOfEncodeUtf8(int value); 5 | uint32_t getByteNumOfDecodeUtf8(uint8_t byte); 6 | uint8_t encodeUtf8(uint8_t* buf, int value); 7 | int decodeUtf8(const uint8_t* bytePtr, uint32_t length); 8 | #endif 9 | -------------------------------------------------------------------------------- /include/utils.c: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | #include "vm.h" 3 | #include "parser.h" 4 | #include 5 | #include 6 | #include "gc.h" 7 | 8 | //内存管理三种功能: 9 | // 1 申请内存 10 | // 2 修改空间大小 11 | // 3 释放内存 12 | void* memManager(VM* vm, void* ptr, uint32_t oldSize, uint32_t newSize) { 13 | //累计系统分配的总内存 14 | vm->allocatedBytes += newSize - oldSize; 15 | 16 | //避免realloc(NULL, 0)定义的新地址,此地址不能被释放 17 | if (newSize == 0) { 18 | free(ptr); 19 | return NULL; 20 | } 21 | 22 | //在分配内存时若达到了GC触发的阀值则启动垃圾回收 23 | if (newSize > 0 && vm->allocatedBytes > vm->config.nextGC) { 24 | startGC(vm); 25 | } 26 | 27 | return realloc(ptr, newSize); 28 | } 29 | 30 | // 找出大于等于v最近的2次幂 31 | uint32_t ceilToPowerOf2(uint32_t v) { 32 | v += (v == 0); //修复当v等于0时结果为0的边界情况 33 | v--; 34 | v |= v >> 1; 35 | v |= v >> 2; 36 | v |= v >> 4; 37 | v |= v >> 8; 38 | v |= v >> 16; 39 | v++; 40 | return v; 41 | } 42 | 43 | DEFINE_BUFFER_METHOD(String) 44 | DEFINE_BUFFER_METHOD(Int) 45 | DEFINE_BUFFER_METHOD(Char) 46 | DEFINE_BUFFER_METHOD(Byte) 47 | 48 | void symbolTableClear(VM* vm, SymbolTable* buffer) { 49 | uint32_t idx = 0; 50 | while (idx < buffer->count) { 51 | memManager(vm, buffer->datas[idx++].str, 0, 0); 52 | } 53 | StringBufferClear(vm, buffer); 54 | } 55 | 56 | //通用报错函数 57 | void errorReport(void* parser, 58 | ErrorType errorType, const char* fmt, ...) { 59 | char buffer[DEFAULT_BUfFER_SIZE] = {'\0'}; 60 | va_list ap; 61 | va_start(ap, fmt); 62 | vsnprintf(buffer, DEFAULT_BUfFER_SIZE, fmt, ap); 63 | va_end(ap); 64 | 65 | switch (errorType) { 66 | case ERROR_IO: 67 | case ERROR_MEM: 68 | fprintf(stderr, "%s:%d In function %s():%s\n", 69 | __FILE__, __LINE__, __func__, buffer); 70 | break; 71 | case ERROR_LEX: 72 | case ERROR_COMPILE: 73 | ASSERT(parser != NULL, "parser is null!"); 74 | fprintf(stderr, "%s:%d \"%s\"\n", ((Parser*)parser)->file, 75 | ((Parser*)parser)->preToken.lineNo, buffer); 76 | break; 77 | case ERROR_RUNTIME: 78 | fprintf(stderr, "%s\n", buffer); 79 | break; 80 | default: 81 | NOT_REACHED(); 82 | } 83 | exit(1); 84 | } 85 | -------------------------------------------------------------------------------- /include/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef _INCLUDE_UTILS_H 2 | #define _INCLUDE_UTILS_H 3 | #include "common.h" 4 | 5 | void* memManager(VM* vm, void* ptr, uint32_t oldSize, uint32_t newSize); 6 | 7 | #define ALLOCATE(vmPtr, type) \ 8 | (type*)memManager(vmPtr, NULL, 0, sizeof(type)) 9 | 10 | #define ALLOCATE_EXTRA(vmPtr, mainType, extraSize) \ 11 | (mainType*)memManager(vmPtr, NULL, 0, sizeof(mainType) + extraSize) 12 | 13 | #define ALLOCATE_ARRAY(vmPtr, type, count) \ 14 | (type*)memManager(vmPtr, NULL, 0, sizeof(type) * count) 15 | 16 | #define DEALLOCATE_ARRAY(vmPtr, arrayPtr, count) \ 17 | memManager(vmPtr, arrayPtr, sizeof(arrayPtr[0]) * count, 0) 18 | 19 | #define DEALLOCATE(vmPtr, memPtr) memManager(vmPtr, memPtr, 0, 0) 20 | 21 | uint32_t ceilToPowerOf2(uint32_t v); 22 | 23 | typedef struct { 24 | char* str; 25 | uint32_t length; 26 | } String; 27 | 28 | typedef struct { 29 | uint32_t length; //除结束'\0'之外的字符个数 30 | char start[0]; //类似c99中的柔性数组 31 | } CharValue; //字符串缓冲区 32 | 33 | //声明buffer类型 34 | #define DECLARE_BUFFER_TYPE(type)\ 35 | typedef struct {\ 36 | /* 数据缓冲区 */ \ 37 | type* datas;\ 38 | /*缓冲区中已使用的元素个数*/\ 39 | uint32_t count;\ 40 | /*缓冲区容量用*/\ 41 | uint32_t capacity;\ 42 | } type##Buffer;\ 43 | void type##BufferInit(type##Buffer* buf);\ 44 | void type##BufferFillWrite(VM* vm, \ 45 | type##Buffer* buf, type data, uint32_t fillCount);\ 46 | void type##BufferAdd(VM* vm, type##Buffer* buf, type data);\ 47 | void type##BufferClear(VM* vm, type##Buffer* buf); 48 | 49 | //定义buffer方法 50 | #define DEFINE_BUFFER_METHOD(type)\ 51 | void type##BufferInit(type##Buffer* buf) {\ 52 | buf->datas = NULL;\ 53 | buf->count = buf->capacity = 0;\ 54 | }\ 55 | \ 56 | void type##BufferFillWrite(VM* vm, \ 57 | type##Buffer* buf, type data, uint32_t fillCount) {\ 58 | uint32_t newCounts = buf->count + fillCount;\ 59 | if (newCounts > buf->capacity) {\ 60 | size_t oldSize = buf->capacity * sizeof(type);\ 61 | buf->capacity = ceilToPowerOf2(newCounts);\ 62 | size_t newSize = buf->capacity * sizeof(type);\ 63 | ASSERT(newSize > oldSize, "faint...memory allocate!");\ 64 | buf->datas = (type*)memManager(vm, buf->datas, oldSize, newSize);\ 65 | }\ 66 | uint32_t cnt = 0;\ 67 | while (cnt < fillCount) {\ 68 | buf->datas[buf->count++] = data;\ 69 | cnt++;\ 70 | }\ 71 | }\ 72 | \ 73 | void type##BufferAdd(VM* vm, type##Buffer* buf, type data) {\ 74 | type##BufferFillWrite(vm, buf, data, 1);\ 75 | }\ 76 | \ 77 | void type##BufferClear(VM* vm, type##Buffer* buf) {\ 78 | size_t oldSize = buf->capacity * sizeof(buf->datas[0]);\ 79 | memManager(vm, buf->datas, oldSize, 0);\ 80 | type##BufferInit(buf);\ 81 | } 82 | 83 | DECLARE_BUFFER_TYPE(String) 84 | #define SymbolTable StringBuffer 85 | typedef uint8_t Byte; 86 | typedef char Char; 87 | typedef int Int; 88 | DECLARE_BUFFER_TYPE(Int) 89 | DECLARE_BUFFER_TYPE(Char) 90 | DECLARE_BUFFER_TYPE(Byte) 91 | 92 | typedef enum { 93 | ERROR_IO, 94 | ERROR_MEM, 95 | ERROR_LEX, 96 | ERROR_COMPILE, 97 | ERROR_RUNTIME 98 | } ErrorType; 99 | 100 | void errorReport(void* parser, 101 | ErrorType errorType, const char* fmt, ...); 102 | 103 | void symbolTableClear(VM*, SymbolTable* buffer); 104 | 105 | #define IO_ERROR(...)\ 106 | errorReport(NULL, ERROR_IO, __VA_ARGS__) 107 | 108 | #define MEM_ERROR(...)\ 109 | errorReport(NULL, ERROR_MEM, __VA_ARGS__) 110 | 111 | #define LEX_ERROR(parser, ...)\ 112 | errorReport(parser, ERROR_LEX, __VA_ARGS__) 113 | 114 | #define COMPILE_ERROR(parser, ...)\ 115 | errorReport(parser, ERROR_COMPILE, __VA_ARGS__) 116 | 117 | #define RUN_ERROR(...)\ 118 | errorReport(NULL, ERROR_RUNTIME, __VA_ARGS__) 119 | 120 | #define DEFAULT_BUfFER_SIZE 512 121 | 122 | #endif 123 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | #CFLAGS = -g -DDEBUG -lm -Wall -I object -I vm -I compiler -I parser -I include -I cli -I gc -W -Wstrict-prototypes -Wmissing-prototypes -Wsystem-headers 3 | CFLAGS = -g -lm -Wall -I object -I vm -I compiler -I parser -I include -I cli -I gc -W -Wstrict-prototypes -Wmissing-prototypes -Wsystem-headers 4 | TARGET = spr 5 | DIRS = object include cli compiler parser vm gc 6 | CFILES = $(foreach dir, $(DIRS),$(wildcard $(dir)/*.c)) 7 | OBJS = $(patsubst %.c,%.o,$(CFILES)) 8 | $(TARGET):$(OBJS) 9 | $(CC) -o $(TARGET) $(OBJS) $(CFLAGS) 10 | clean: 11 | -$(RM) $(TARGET) $(OBJS) 12 | r: clean $(TARGET) 13 | -------------------------------------------------------------------------------- /makefile.debug: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -g -DDEBUG -lm -Wall -I object -I vm -I compiler -I parser -I include -I cli -I gc -W -Wstrict-prototypes -Wmissing-prototypes -Wsystem-headers 3 | TARGET = spr 4 | DIRS = object include cli compiler parser vm gc 5 | CFILES = $(foreach dir, $(DIRS),$(wildcard $(dir)/*.c)) 6 | OBJS = $(patsubst %.c,%.o,$(CFILES)) 7 | $(TARGET):$(OBJS) 8 | $(CC) -o $(TARGET) $(OBJS) $(CFLAGS) 9 | clean: 10 | -$(RM) $(TARGET) $(OBJS) 11 | r: clean $(TARGET) 12 | -------------------------------------------------------------------------------- /manager.sp: -------------------------------------------------------------------------------- 1 | /* 2 | 本文件中的代码只为演示语法,无任何意义,不用深究. 3 | 精力有限,这里只演示部分功能,如果读者感兴趣, 4 | 可以参考core.c中后面注册的原生方法和core.script.inc中的脚本方法 5 | 测试有限,难免还会有bug,读过本书后应该有bugfix的能力.看好你,兄弟. 6 | 刚子 7 | 2017.4.12 8 | */ 9 | 10 | import employee for Employee 11 | var xh = Employee.new("xiaohong", "female", 20, 6000) 12 | System.print(xh.salary) 13 | 14 | var xm = Employee.new("xiaoming", "male", 23, 8000) 15 | System.print(xm.salary) 16 | 17 | System.print(Employee.employeeNum) 18 | 19 | class Manager < Employee { 20 | var bonus 21 | bonus=(v) { 22 | bonus = v 23 | } 24 | 25 | new(n, g, a, s, b) { 26 | super(n, g, a, s) 27 | bonus = b 28 | } 29 | 30 | salary { 31 | return super.salary + bonus 32 | } 33 | 34 | } 35 | 36 | fun employeeInfo() { 37 | System.print("number of employee:" + Employee.employeeNum.toString) 38 | var employeeTitle = Map.new() 39 | employeeTitle["xh"] = "rd" 40 | employeeTitle["xm"] = "op" 41 | employeeTitle["lw"] = "manager" 42 | employeeTitle["lz"] = "pm" 43 | 44 | for k (employeeTitle.keys) { 45 | System.print(k + " -> " + employeeTitle[k]) 46 | } 47 | 48 | var employeeHeight = { 49 | "xh": 170, 50 | "xm": 172, 51 | "lw": 168, 52 | "lz": 173 53 | } 54 | var totalHeight = 0 55 | for v (employeeHeight.values) { 56 | totalHeight = totalHeight + v 57 | } 58 | System.print("averageHeight: %(totalHeight / employeeHeight.count)") 59 | 60 | var allEmployee = ["xh", "xm", "lw", "lz"] 61 | for e (allEmployee) { 62 | System.print(e) 63 | } 64 | 65 | allEmployee.add("xl") 66 | System.print("all employee are:%(allEmployee.toString)") 67 | var idx = 0 68 | var count = allEmployee.count 69 | while (idx < count) { 70 | System.print(allEmployee[idx]) 71 | idx = idx + 1 72 | } 73 | 74 | System.gc() //可以手动回收内存 75 | 76 | var a = 3 + 5 > 9 - 3 ? "yes" : "no" 77 | if (a.endsWith("s")) { 78 | System.print(System.clock) 79 | } else { 80 | System.print("error!!!!!") 81 | } 82 | 83 | var str = "hello, world." 84 | System.print(str[-1..0]) 85 | } 86 | 87 | var lw = Manager.new("laowang", "male", 35, 13000, 2000) 88 | System.print(lw.salary) 89 | lw.bonus=3100 90 | System.print(lw.salary) 91 | var lz = Manager.new("laozheng", "male", 36, 15000, 2300) 92 | System.print(lz.salary) 93 | 94 | var thread = Thread.new(employeeInfo) 95 | thread.call() 96 | -------------------------------------------------------------------------------- /object/class.c: -------------------------------------------------------------------------------- 1 | #include "class.h" 2 | #include "common.h" 3 | #include "string.h" 4 | #include "obj_range.h" 5 | #include "core.h" 6 | #include "vm.h" 7 | 8 | DEFINE_BUFFER_METHOD(Method) 9 | 10 | //判断a和b是否相等 11 | bool valueIsEqual(Value a, Value b) { 12 | //类型不同则无须进行后面的比较 13 | if (a.type != b.type) { 14 | return false; 15 | } 16 | 17 | //同为数字,比较数值 18 | if (a.type == VT_NUM) { 19 | return a.num == b.num; 20 | } 21 | 22 | //同为对象,若所指的对象是同一个则返回true 23 | if (a.objHeader == b.objHeader) { 24 | return true; 25 | } 26 | 27 | //对象类型不同无须比较 28 | if (a.objHeader->type != b.objHeader->type) { 29 | return false; 30 | } 31 | 32 | //以下处理类型相同的对象 33 | //若对象同为字符串 34 | if (a.objHeader->type == OT_STRING) { 35 | ObjString* strA = VALUE_TO_OBJSTR(a); 36 | ObjString* strB = VALUE_TO_OBJSTR(b); 37 | return (strA->value.length == strB->value.length && 38 | memcmp(strA->value.start, strB->value.start, strA->value.length) == 0); 39 | } 40 | 41 | //若对象同为range 42 | if (a.objHeader->type == OT_RANGE) { 43 | ObjRange* rgA = VALUE_TO_OBJRANGE(a); 44 | ObjRange* rgB = VALUE_TO_OBJRANGE(b); 45 | return (rgA->from == rgB->from && rgA->to == rgB->to); 46 | } 47 | 48 | return false; //其它对象不可比较 49 | } 50 | 51 | //新建一个裸类 52 | Class* newRawClass(VM* vm, const char* name, uint32_t fieldNum) { 53 | Class* class = ALLOCATE(vm, Class); 54 | 55 | //裸类没有元类 56 | initObjHeader(vm, &class->objHeader, OT_CLASS, NULL); 57 | class->name = newObjString(vm, name, strlen(name)); 58 | class->fieldNum = fieldNum; 59 | class->superClass = NULL; //默认没有基类 60 | 61 | pushTmpRoot(vm, (ObjHeader*)class); 62 | MethodBufferInit(&class->methods); 63 | popTmpRoot(vm); 64 | 65 | return class; 66 | } 67 | 68 | //创建一个类 69 | Class* newClass(VM* vm, ObjString* className, uint32_t fieldNum, Class* superClass) { 70 | //10表示strlen(" metaClass" 71 | #define MAX_METACLASS_LEN MAX_ID_LEN + 10 72 | char newClassName[MAX_METACLASS_LEN] = {'\0'}; 73 | #undef MAX_METACLASS_LEN 74 | 75 | memcpy(newClassName, className->value.start, className->value.length); 76 | memcpy(newClassName + className->value.length, " metaclass", 10); 77 | 78 | //先创建子类的meta类 79 | Class* metaclass = newRawClass(vm, newClassName, 0); 80 | metaclass->objHeader.class = vm->classOfClass; 81 | 82 | pushTmpRoot(vm, (ObjHeader*)metaclass); 83 | //绑定classOfClass为meta类的基类 84 | //所有类的meta类的基类都是classOfClass 85 | bindSuperClass(vm, metaclass, vm->classOfClass); 86 | 87 | //最后再创建类 88 | memcpy(newClassName, className->value.start, className->value.length); 89 | newClassName[className->value.length] = '\0'; 90 | Class* class = newRawClass(vm, newClassName, fieldNum); 91 | pushTmpRoot(vm, (ObjHeader*)class); 92 | 93 | class->objHeader.class = metaclass; 94 | bindSuperClass(vm, class, superClass); 95 | 96 | popTmpRoot(vm); // metaclass 97 | popTmpRoot(vm); // class 98 | 99 | return class; 100 | } 101 | 102 | //数字等Value也被视为对象,因此参数为Value.获得对象obj所属的类 103 | Class* getClassOfObj(VM* vm, Value object) { 104 | switch (object.type) { 105 | case VT_NULL: 106 | return vm->nullClass; 107 | case VT_FALSE: 108 | case VT_TRUE: 109 | return vm->boolClass; 110 | case VT_NUM: 111 | return vm->numClass; 112 | case VT_OBJ: 113 | return VALUE_TO_OBJ(object)->class; 114 | default: 115 | NOT_REACHED(); 116 | } 117 | return NULL; 118 | } 119 | -------------------------------------------------------------------------------- /object/class.h: -------------------------------------------------------------------------------- 1 | #ifndef _OBJECT_CLASS_H 2 | #define _OBJECT_CLASS_H 3 | #include "common.h" 4 | #include "utils.h" 5 | #include "header_obj.h" 6 | #include "obj_string.h" 7 | #include "obj_fn.h" 8 | 9 | typedef enum { 10 | MT_NONE, //空方法类型,并不等同于undefined 11 | MT_PRIMITIVE, //在vm中用c实现的原生方法 12 | MT_SCRIPT, //脚本中定义的方法 13 | MT_FN_CALL, //有关函数对象的调用方法,用来实现函数重载 14 | } MethodType; //方法类型 15 | 16 | #define VT_TO_VALUE(vt) \ 17 | ((Value){vt, {0}}) 18 | 19 | #define BOOL_TO_VALUE(boolean) (boolean ? VT_TO_VALUE(VT_TRUE) : VT_TO_VALUE(VT_FALSE)) 20 | #define VALUE_TO_BOOL(value) ((value).type == VT_TRUE ? true : false) 21 | 22 | #define NUM_TO_VALUE(num) ((Value){VT_NUM, {num}}) 23 | #define VALUE_TO_NUM(value) value.num 24 | 25 | #define OBJ_TO_VALUE(objPtr) ({ \ 26 | Value value; \ 27 | value.type = VT_OBJ; \ 28 | value.objHeader = (ObjHeader*)(objPtr); \ 29 | value; \ 30 | }) 31 | 32 | #define VALUE_TO_OBJ(value) (value.objHeader) 33 | #define VALUE_TO_OBJSTR(value) ((ObjString*)VALUE_TO_OBJ(value)) 34 | #define VALUE_TO_OBJFN(value) ((ObjFn*)VALUE_TO_OBJ(value)) 35 | #define VALUE_TO_OBJRANGE(value) ((ObjRange*)VALUE_TO_OBJ(value)) 36 | #define VALUE_TO_OBJINSTANCE(value) ((ObjInstance*)VALUE_TO_OBJ(value)) 37 | #define VALUE_TO_OBJLIST(value) ((ObjList*)VALUE_TO_OBJ(value)) 38 | #define VALUE_TO_OBJMAP(value) ((ObjMap*)VALUE_TO_OBJ(value)) 39 | #define VALUE_TO_OBJCLOSURE(value) ((ObjClosure*)VALUE_TO_OBJ(value)) 40 | #define VALUE_TO_OBJTHREAD(value) ((ObjThread*)VALUE_TO_OBJ(value)) 41 | #define VALUE_TO_OBJMODULE(value) ((ObjModule*)VALUE_TO_OBJ(value)) 42 | #define VALUE_TO_CLASS(value) ((Class*)VALUE_TO_OBJ(value)) 43 | 44 | #define VALUE_IS_UNDEFINED(value) ((value).type == VT_UNDEFINED) 45 | #define VALUE_IS_NULL(value) ((value).type == VT_NULL) 46 | #define VALUE_IS_TRUE(value) ((value).type == VT_TRUE) 47 | #define VALUE_IS_FALSE(value) ((value).type == VT_FALSE) 48 | #define VALUE_IS_NUM(value) ((value).type == VT_NUM) 49 | #define VALUE_IS_OBJ(value) ((value).type == VT_OBJ) 50 | #define VALUE_IS_CERTAIN_OBJ(value, objType) (VALUE_IS_OBJ(value) && VALUE_TO_OBJ(value)->type == objType) 51 | #define VALUE_IS_OBJSTR(value) (VALUE_IS_CERTAIN_OBJ(value, OT_STRING)) 52 | #define VALUE_IS_OBJINSTANCE(value) (VALUE_IS_CERTAIN_OBJ(value, OT_INSTANCE)) 53 | #define VALUE_IS_OBJCLOSURE(value) (VALUE_IS_CERTAIN_OBJ(value, OT_CLOSURE)) 54 | #define VALUE_IS_OBJRANGE(value) (VALUE_IS_CERTAIN_OBJ(value, OT_RANGE)) 55 | #define VALUE_IS_CLASS(value) (VALUE_IS_CERTAIN_OBJ(value, OT_CLASS)) 56 | #define VALUE_IS_0(value) (VALUE_IS_NUM(value) && (value).num == 0) 57 | 58 | //原生方法指针 59 | typedef bool (*Primitive)(VM* vm, Value* args); 60 | 61 | typedef struct { 62 | MethodType type; //union中的值由type的值决定 63 | union { 64 | //指向脚本方法所关联的c实现 65 | Primitive primFn; 66 | 67 | //指向脚本代码编译后的ObjClosure或ObjFn 68 | ObjClosure* obj; 69 | }; 70 | } Method; 71 | 72 | DECLARE_BUFFER_TYPE(Method) 73 | 74 | //类是对象的模板 75 | struct class { 76 | ObjHeader objHeader; 77 | struct class* superClass; //父类 78 | uint32_t fieldNum; //本类的字段数,包括基类的字段数 79 | MethodBuffer methods; //本类的方法 80 | ObjString* name; //类名 81 | }; //对象类 82 | 83 | typedef union { 84 | uint64_t bits64; 85 | uint32_t bits32[2]; 86 | double num; 87 | } Bits64; 88 | 89 | #define CAPACITY_GROW_FACTOR 4 90 | #define MIN_CAPACITY 64 91 | bool valueIsEqual(Value a, Value b); 92 | Class* newRawClass(VM* vm, const char* name, uint32_t fieldNum); 93 | inline Class* getClassOfObj(VM* vm, Value object); 94 | Class* newClass(VM* vm, ObjString* className, uint32_t fieldNum, Class* superClass); 95 | #endif 96 | -------------------------------------------------------------------------------- /object/header_obj.c: -------------------------------------------------------------------------------- 1 | #include "header_obj.h" 2 | #include "class.h" 3 | #include "vm.h" 4 | 5 | DEFINE_BUFFER_METHOD(Value) 6 | 7 | //初始化对象头 8 | void initObjHeader(VM* vm, ObjHeader* objHeader, ObjType objType, Class* class) { 9 | objHeader->type = objType; 10 | objHeader->isDark = false; 11 | objHeader->class = class; //设置meta类 12 | objHeader->next = vm->allObjects; 13 | vm->allObjects = objHeader; 14 | } 15 | -------------------------------------------------------------------------------- /object/header_obj.h: -------------------------------------------------------------------------------- 1 | #ifndef _OBJECT_HEADER_H 2 | #define _OBJECT_HEADER_H 3 | #include "utils.h" 4 | typedef enum { 5 | OT_CLASS, //此项是class类型,以下都是object类型 6 | OT_LIST, 7 | OT_MAP, 8 | OT_MODULE, 9 | OT_RANGE, 10 | OT_STRING, 11 | OT_UPVALUE, 12 | OT_FUNCTION, 13 | OT_CLOSURE, 14 | OT_INSTANCE, 15 | OT_THREAD 16 | } ObjType; //对象类型 17 | 18 | typedef struct objHeader { 19 | ObjType type; 20 | bool isDark; //对象是否可达 21 | Class* class; //对象所属的类 22 | struct objHeader* next; //用于链接所有已分配对象 23 | } ObjHeader; //对象头,用于记录元信息和垃圾回收 24 | 25 | typedef enum { 26 | VT_UNDEFINED, 27 | VT_NULL, 28 | VT_FALSE, 29 | VT_TRUE, 30 | VT_NUM, 31 | VT_OBJ //值为对象,指向对象头 32 | } ValueType; //value类型 33 | 34 | typedef struct { 35 | ValueType type; 36 | union { 37 | double num; 38 | ObjHeader* objHeader; 39 | }; 40 | } Value; //通用的值结构 41 | 42 | DECLARE_BUFFER_TYPE(Value) 43 | 44 | void initObjHeader(VM* vm, ObjHeader* objHeader, ObjType objType, Class* class); 45 | #endif 46 | -------------------------------------------------------------------------------- /object/meta_obj.c: -------------------------------------------------------------------------------- 1 | #include "obj_fn.h" 2 | #include "class.h" 3 | #include "vm.h" 4 | #include 5 | 6 | //新建模块 7 | ObjModule* newObjModule(VM* vm, const char* modName) { 8 | ObjModule* objModule = ALLOCATE(vm, ObjModule); 9 | if (objModule == NULL) { 10 | MEM_ERROR("allocate ObjModule failed!"); 11 | } 12 | 13 | //ObjModule是元信息对象,不属于任何一个类 14 | initObjHeader(vm, &objModule->objHeader, OT_MODULE, NULL); 15 | 16 | pushTmpRoot(vm, (ObjHeader*)objModule); 17 | StringBufferInit(&objModule->moduleVarName); 18 | ValueBufferInit(&objModule->moduleVarValue); 19 | 20 | objModule->name = NULL; //核心模块名为NULL 21 | if (modName != NULL) { 22 | objModule->name = newObjString(vm, modName, strlen(modName)); 23 | } 24 | popTmpRoot(vm); 25 | 26 | return objModule; 27 | } 28 | 29 | //创建类class的实例 30 | ObjInstance* newObjInstance(VM* vm, Class* class) { 31 | //参数class主要作用是提供类中field的数目 32 | ObjInstance* objInstance = ALLOCATE_EXTRA(vm, 33 | ObjInstance, sizeof(Value) * class->fieldNum); 34 | 35 | //在此关联对象的类为参数class 36 | initObjHeader(vm, &objInstance->objHeader, OT_INSTANCE, class); 37 | 38 | //初始化field为NULL 39 | uint32_t idx = 0; 40 | while (idx < class->fieldNum) { 41 | objInstance->fields[idx++] = VT_TO_VALUE(VT_NULL); 42 | } 43 | return objInstance; 44 | } 45 | -------------------------------------------------------------------------------- /object/meta_obj.h: -------------------------------------------------------------------------------- 1 | #ifndef _OBJECT_METAOBJ_H 2 | #define _OBJECT_METAOBJ_H 3 | #include "obj_string.h" 4 | 5 | typedef struct { 6 | ObjHeader objHeader; 7 | SymbolTable moduleVarName; //模块中的模块变量名 8 | ValueBuffer moduleVarValue; //模块中的模块变量值 9 | ObjString* name; //模块名 10 | } ObjModule; //模块对象 11 | 12 | typedef struct { 13 | ObjHeader objHeader; 14 | //具体的字段 15 | Value fields[0]; 16 | } ObjInstance; //对象实例 17 | 18 | ObjModule* newObjModule(VM* vm, const char* modName); 19 | ObjInstance* newObjInstance(VM* vm, Class* class); 20 | #endif 21 | -------------------------------------------------------------------------------- /object/obj_fn.c: -------------------------------------------------------------------------------- 1 | #include "meta_obj.h" 2 | #include "class.h" 3 | #include "vm.h" 4 | 5 | //创建一个空函数 6 | ObjFn* newObjFn(VM* vm, ObjModule* objModule, uint32_t slotNum) { 7 | ObjFn* objFn = ALLOCATE(vm, ObjFn); 8 | if (objFn == NULL) { 9 | MEM_ERROR("allocate ObjFn failed!"); 10 | } 11 | initObjHeader(vm, &objFn->objHeader, OT_FUNCTION, vm->fnClass); 12 | ByteBufferInit(&objFn->instrStream); 13 | ValueBufferInit(&objFn->constants); 14 | objFn->module = objModule; 15 | objFn->maxStackSlotUsedNum = slotNum; 16 | objFn->upvalueNum = objFn->argNum = 0; 17 | #ifdef DEBUG 18 | objFn->debug = ALLOCATE(vm, FnDebug); 19 | objFn->debug->fnName = NULL; 20 | IntBufferInit(&objFn->debug->lineNo); 21 | #endif 22 | return objFn; 23 | } 24 | 25 | //以函数fn创建一个闭包 26 | ObjClosure* newObjClosure(VM* vm, ObjFn* objFn) { 27 | ObjClosure* objClosure = ALLOCATE_EXTRA(vm, 28 | ObjClosure, sizeof(ObjUpvalue*) * objFn->upvalueNum); 29 | initObjHeader(vm, &objClosure->objHeader, OT_CLOSURE, vm->fnClass); 30 | objClosure->fn = objFn; 31 | 32 | //清除upvalue数组做 以避免在填充upvalue数组之前触发GC 33 | uint32_t idx = 0; 34 | while (idx < objFn->upvalueNum) { 35 | objClosure->upvalues[idx] = NULL; 36 | idx++; 37 | } 38 | 39 | return objClosure; 40 | } 41 | 42 | //创建upvalue对象 43 | ObjUpvalue* newObjUpvalue(VM* vm, Value* localVarPtr) { 44 | ObjUpvalue* objUpvalue = ALLOCATE(vm, ObjUpvalue); 45 | initObjHeader(vm, &objUpvalue->objHeader, OT_UPVALUE, NULL); 46 | objUpvalue->localVarPtr = localVarPtr; 47 | objUpvalue->closedUpvalue = VT_TO_VALUE(VT_NULL); 48 | objUpvalue->next = NULL; 49 | return objUpvalue; 50 | } 51 | -------------------------------------------------------------------------------- /object/obj_fn.h: -------------------------------------------------------------------------------- 1 | #ifndef _OBJECT_FN_H 2 | #define _OBJECT_FN_H 3 | #include "utils.h" 4 | #include "meta_obj.h" 5 | 6 | typedef struct { 7 | char* fnName; //函数名 8 | IntBuffer lineNo; //行号 9 | } FnDebug; //在函数中的调试结构 10 | 11 | typedef struct { 12 | ObjHeader objHeader; 13 | ByteBuffer instrStream; //函数编译后的指令流 14 | ValueBuffer constants; // 函数中的常量表 15 | 16 | ObjModule* module; //本函数所属的模块 17 | 18 | //本函数最多需要的栈空间,是栈使用空间的峰值 19 | uint32_t maxStackSlotUsedNum; 20 | uint32_t upvalueNum; //本函数所涵盖的upvalue数量 21 | uint8_t argNum; //函数期望的参数个数 22 | #if DEBUG 23 | FnDebug* debug; 24 | #endif 25 | } ObjFn; //函数对象 26 | 27 | typedef struct upvalue { 28 | ObjHeader objHeader; 29 | 30 | //栈是个Value类型的数组,localVarPtr指向upvalue所关联的局部变量 31 | Value* localVarPtr; 32 | 33 | //已被关闭的upvalue 34 | Value closedUpvalue; 35 | 36 | struct upvalue* next; //用以链接openUpvalue链表 37 | } ObjUpvalue; //upvalue对象 38 | 39 | typedef struct { 40 | ObjHeader objHeader; 41 | ObjFn* fn; //闭包中所要引用的函数 42 | 43 | ObjUpvalue* upvalues[0]; //用于存储此函数的 "close upvalue" 44 | } ObjClosure; //闭包对象 45 | 46 | typedef struct { 47 | uint8_t* ip; //程序计数器 指向下一个将被执行的指令 48 | 49 | //在本frame中执行的闭包函数 50 | ObjClosure* closure; 51 | 52 | //frame是共享therad.stack 53 | //此项用于指向本frame所在thread运行时栈的起始地址 54 | Value* stackStart; 55 | } Frame; //调用框架 56 | 57 | #define INITIAL_FRAME_NUM 4 58 | 59 | ObjUpvalue* newObjUpvalue(VM* vm, Value* localVarPtr); 60 | ObjClosure* newObjClosure(VM* vm, ObjFn* objFn); 61 | ObjFn* newObjFn(VM* vm, ObjModule* objModule, uint32_t maxStackSlotUsedNum); 62 | #endif 63 | -------------------------------------------------------------------------------- /object/obj_list.c: -------------------------------------------------------------------------------- 1 | #include "obj_list.h" 2 | 3 | //新建list对象,元素个数为elementNum 4 | ObjList* newObjList(VM* vm, uint32_t elementNum) { 5 | //存储list元素的缓冲区 6 | Value* elementArray = NULL; 7 | 8 | //先分配内存,后调用initObjHeader,避免gc无谓的遍历 9 | if (elementNum > 0) { 10 | elementArray = ALLOCATE_ARRAY(vm, Value, elementNum); 11 | } 12 | ObjList* objList = ALLOCATE(vm, ObjList); 13 | 14 | objList->elements.datas = elementArray; 15 | objList->elements.capacity = objList->elements.count = elementNum; 16 | initObjHeader(vm, &objList->objHeader, OT_LIST, vm->listClass); 17 | return objList; 18 | } 19 | 20 | //在objlist中索引为index处插入value, 类似于list[index] = value 21 | void insertElement(VM* vm, ObjList* objList, uint32_t index, Value value) { 22 | if (index > objList->elements.count - 1) { 23 | RUN_ERROR("index out bounded!"); 24 | } 25 | 26 | if (VALUE_IS_OBJ(value)) { 27 | pushTmpRoot(vm, VALUE_TO_OBJ(value)); 28 | } 29 | //准备一个Value的空间以容纳新元素产生的空间波动 30 | //即最后一个元素要后移1个空间 31 | ValueBufferAdd(vm, &objList->elements, VT_TO_VALUE(VT_NULL)); 32 | if (VALUE_IS_OBJ(value)) { 33 | popTmpRoot(vm); 34 | } 35 | 36 | //下面使index后面的元素整体后移一位 37 | uint32_t idx = objList->elements.count - 1; 38 | while (idx > index) { 39 | objList->elements.datas[idx] = objList->elements.datas[idx - 1]; 40 | idx--; 41 | } 42 | 43 | //在index处插入数值 44 | objList->elements.datas[index] = value; 45 | } 46 | 47 | //调整list容量 48 | static void shrinkList(VM* vm, ObjList* objList, uint32_t newCapacity) { 49 | uint32_t oldSize = objList->elements.capacity * sizeof(Value); 50 | uint32_t newSize = newCapacity * sizeof(Value); 51 | memManager(vm, objList->elements.datas, oldSize, newSize); 52 | objList->elements.capacity = newCapacity; 53 | } 54 | 55 | //删除list中索引为index处的元素,即删除list[index] 56 | Value removeElement(VM* vm, ObjList* objList, uint32_t index) { 57 | Value valueRemoved = objList->elements.datas[index]; 58 | 59 | if (VALUE_IS_OBJ(valueRemoved)) { 60 | pushTmpRoot(vm, VALUE_TO_OBJ(valueRemoved)); 61 | } 62 | //使index后面的元素前移一位,覆盖index处的元素 63 | uint32_t idx = index; 64 | while (idx < objList->elements.count) { 65 | objList->elements.datas[idx] = objList->elements.datas[idx + 1]; 66 | idx++; 67 | } 68 | 69 | //若容量利用率过低就减小容量 70 | uint32_t _capacity = objList->elements.capacity / CAPACITY_GROW_FACTOR; 71 | if (_capacity > objList->elements.count) { 72 | shrinkList(vm, objList, _capacity); 73 | } 74 | if (VALUE_IS_OBJ(valueRemoved)) { 75 | popTmpRoot(vm); 76 | } 77 | 78 | objList->elements.count--; 79 | return valueRemoved; 80 | } 81 | -------------------------------------------------------------------------------- /object/obj_list.h: -------------------------------------------------------------------------------- 1 | #ifndef _OBJECT_LIST_H 2 | #define _OBJECT_LIST_H 3 | #include "class.h" 4 | #include "vm.h" 5 | 6 | typedef struct { 7 | ObjHeader objHeader; 8 | ValueBuffer elements; //list中的元素 9 | } ObjList; //list对象 10 | 11 | ObjList* newObjList(VM* vm, uint32_t elementNum); 12 | Value removeElement(VM* vm, ObjList* objList, uint32_t index); 13 | void insertElement(VM* vm, ObjList* objList, uint32_t index, Value value); 14 | #endif 15 | -------------------------------------------------------------------------------- /object/obj_map.c: -------------------------------------------------------------------------------- 1 | #include "obj_map.h" 2 | #include "class.h" 3 | #include "vm.h" 4 | #include "obj_string.h" 5 | #include "obj_range.h" 6 | 7 | //创建新map对象 8 | ObjMap* newObjMap(VM* vm) { 9 | ObjMap* objMap = ALLOCATE(vm, ObjMap); 10 | initObjHeader(vm, &objMap->objHeader, OT_MAP, vm->mapClass); 11 | objMap->capacity = objMap->count = 0; 12 | objMap->entries = NULL; 13 | return objMap; 14 | } 15 | 16 | //计算数字的哈希码 17 | static uint32_t hashNum(double num) { 18 | Bits64 bits64; 19 | bits64.num = num; 20 | return bits64.bits32[0] ^ bits64.bits32[1]; 21 | } 22 | 23 | //计算对象的哈希码 24 | static uint32_t hashObj(ObjHeader* objHeader) { 25 | switch (objHeader->type) { 26 | case OT_CLASS: //计算class的哈希值 27 | return hashString(((Class*)objHeader)->name->value.start, 28 | ((Class*)objHeader)->name->value.length); 29 | 30 | case OT_RANGE: { //计算range对象哈希码 31 | ObjRange* objRange = (ObjRange*)objHeader; 32 | return hashNum(objRange->from) ^ hashNum(objRange->to); 33 | } 34 | case OT_STRING: //对于字符串,直接返回其hashCode 35 | return ((ObjString*)objHeader)->hashCode; 36 | default: 37 | RUN_ERROR("the hashable are objstring, objrange and class."); 38 | } 39 | return 0; 40 | } 41 | 42 | //根据value的类型调用相应的哈希函数 43 | static uint32_t hashValue(Value value) { 44 | switch (value.type) { 45 | case VT_FALSE: 46 | return 0; 47 | case VT_NULL: 48 | return 1; 49 | case VT_NUM: 50 | return hashNum(value.num); 51 | case VT_TRUE: 52 | return 2; 53 | case VT_OBJ: 54 | return hashObj(value.objHeader); 55 | default: 56 | RUN_ERROR("unsupport type hashed!"); 57 | } 58 | return 0; 59 | } 60 | 61 | //在entries中添加entry,如果是新的key则返回true 62 | static bool addEntry(Entry* entries, uint32_t capacity, Value key, Value value) { 63 | uint32_t index = hashValue(key) % capacity; 64 | 65 | //通过开放探测法去找可用的slot 66 | while (true) { 67 | //找到空闲的slot,说明目前没有此key,直接赋值返回 68 | if (entries[index].key.type == VT_UNDEFINED) { 69 | entries[index].key = key; 70 | entries[index].value = value; 71 | return true; //新的key就返回true 72 | } else if (valueIsEqual(entries[index].key, key)) { //key已经存在,仅仅更新值就行 73 | entries[index].value = value; 74 | return false; // 未增加新的key就返回false 75 | } 76 | 77 | //开放探测定址,尝试下一个slot 78 | index = (index + 1) % capacity; 79 | } 80 | } 81 | 82 | //使对象objMap的容量调整到newCapacity 83 | static void resizeMap(VM* vm, ObjMap* objMap, uint32_t newCapacity) { 84 | // 1 先建立个新的entry数组 85 | Entry* newEntries = ALLOCATE_ARRAY(vm, Entry, newCapacity); 86 | uint32_t idx = 0; 87 | while (idx < newCapacity) { 88 | newEntries[idx].key = VT_TO_VALUE(VT_UNDEFINED); 89 | newEntries[idx].value = VT_TO_VALUE(VT_FALSE); 90 | idx++; 91 | } 92 | 93 | // 2 再遍历老的数组,把有值的部分插入到新数组 94 | if (objMap->capacity > 0) { 95 | Entry* entryArr = objMap->entries; 96 | idx = 0; 97 | while (idx < objMap->capacity) { 98 | //该slot有值 99 | if (entryArr[idx].key.type != VT_UNDEFINED) { 100 | addEntry(newEntries, newCapacity, 101 | entryArr[idx].key, entryArr[idx].value); 102 | } 103 | idx++; 104 | } 105 | } 106 | 107 | // 3 将老entry数组空间回收 108 | DEALLOCATE_ARRAY(vm, objMap->entries, objMap->count); 109 | objMap->entries = newEntries; //更新指针为新的entry数组 110 | objMap->capacity = newCapacity; //更新容量 111 | } 112 | 113 | //在objMap中查找key对应的entry 114 | static Entry* findEntry(ObjMap* objMap, Value key) { 115 | //objMap为空则返回null 116 | if (objMap->capacity == 0) { 117 | return NULL; 118 | } 119 | 120 | //以下开放定址探测 121 | //用哈希值对容量取模计算槽位(slot) 122 | uint32_t index = hashValue(key) % objMap->capacity; 123 | Entry* entry; 124 | while (true) { 125 | entry = &objMap->entries[index]; 126 | 127 | //若该slot中的entry正好是该key的entry,找到返回 128 | if (valueIsEqual(entry->key, key)) { 129 | return entry; 130 | } 131 | 132 | //key为VT_UNDEFINED且value为VT_TRUE表示探测链未断,可继续探测. 133 | //key为VT_UNDEFINED且value为VT_FALSE表示探测链结束,探测结束. 134 | if (VALUE_IS_UNDEFINED(entry->key) && VALUE_IS_FALSE(entry->value)) { 135 | return NULL; //未找到 136 | } 137 | 138 | //继续向下探测 139 | index = (index + 1) % objMap->capacity; 140 | } 141 | } 142 | 143 | //在objMap中实现key与value的关联:objMap[key]=value 144 | void mapSet(VM* vm, ObjMap* objMap, Value key, Value value) { 145 | //当容量利用率达到80%时扩容 146 | if (objMap->count + 1 > objMap->capacity * MAP_LOAD_PERCENT) { 147 | uint32_t newCapacity = objMap->capacity * CAPACITY_GROW_FACTOR; 148 | if (newCapacity < MIN_CAPACITY) { 149 | newCapacity = MIN_CAPACITY; 150 | } 151 | resizeMap(vm, objMap, newCapacity); 152 | } 153 | 154 | //若创建了新的key则使objMap->count加1 155 | if (addEntry(objMap->entries, objMap->capacity, key, value)) { 156 | objMap->count++; 157 | } 158 | } 159 | 160 | //从map中查找key对应的value: map[key] 161 | Value mapGet(ObjMap* objMap, Value key) { 162 | Entry* entry = findEntry(objMap, key); 163 | if (entry == NULL) { 164 | return VT_TO_VALUE(VT_UNDEFINED); 165 | } 166 | return entry->value; 167 | } 168 | 169 | //回收objMap.entries占用的空间 170 | void clearMap(VM* vm, ObjMap* objMap) { 171 | DEALLOCATE_ARRAY(vm, objMap->entries, objMap->count); 172 | objMap->entries = NULL; 173 | objMap->capacity = objMap->count = 0; 174 | } 175 | 176 | //删除objMap中的key,返回map[key] 177 | Value removeKey(VM* vm, ObjMap* objMap, Value key) { 178 | Entry* entry = findEntry(objMap, key); 179 | 180 | if (entry == NULL) { 181 | return VT_TO_VALUE(VT_NULL); 182 | } 183 | 184 | //设置开放定址的伪删除 185 | Value value = entry->value; 186 | entry->key = VT_TO_VALUE(VT_UNDEFINED); 187 | entry->value = VT_TO_VALUE(VT_TRUE); //值为真,伪删除 188 | 189 | if (VALUE_IS_OBJ(value)) { 190 | pushTmpRoot(vm, VALUE_TO_OBJ(value)); 191 | } 192 | objMap->count--; 193 | if (objMap->count == 0) { //若删除该entry后map为空就回收该空间 194 | clearMap(vm, objMap); 195 | } else if (objMap->count < objMap->capacity / (CAPACITY_GROW_FACTOR) * MAP_LOAD_PERCENT && 196 | objMap->count > MIN_CAPACITY) { //若map容量利用率太低,就缩小map空间 197 | uint32_t newCapacity = objMap->capacity / CAPACITY_GROW_FACTOR; 198 | if (newCapacity < MIN_CAPACITY) { 199 | newCapacity = MIN_CAPACITY; 200 | } 201 | resizeMap(vm, objMap, newCapacity); 202 | } 203 | if (VALUE_IS_OBJ(value)) { 204 | popTmpRoot(vm); 205 | } 206 | 207 | return value; 208 | } 209 | -------------------------------------------------------------------------------- /object/obj_map.h: -------------------------------------------------------------------------------- 1 | #ifndef _OBJECT_MAP_H 2 | #define _OBJECT_MAP_H 3 | #include "header_obj.h" 4 | 5 | #define MAP_LOAD_PERCENT 0.8 6 | 7 | typedef struct { 8 | Value key; 9 | Value value; 10 | } Entry; //key->value对儿 11 | 12 | typedef struct { 13 | ObjHeader objHeader; 14 | uint32_t capacity; //Entry的容量(即总数),包括已使用和未使用Entry的数量 15 | uint32_t count; //map中使用的Entry的数量 16 | Entry* entries; //Entry数组 17 | } ObjMap; 18 | 19 | ObjMap* newObjMap(VM* vm); 20 | 21 | void mapSet(VM* vm, ObjMap* objMap, Value key, Value value); 22 | Value mapGet(ObjMap* objMap, Value key); 23 | void clearMap(VM* vm, ObjMap* objMap); 24 | Value removeKey(VM* vm, ObjMap* objMap, Value key); 25 | #endif 26 | -------------------------------------------------------------------------------- /object/obj_range.c: -------------------------------------------------------------------------------- 1 | #include "obj_range.h" 2 | #include "utils.h" 3 | #include "class.h" 4 | #include "vm.h" 5 | 6 | //新建range对象 7 | ObjRange* newObjRange(VM* vm, int from, int to) { 8 | ObjRange* objRange = ALLOCATE(vm, ObjRange); 9 | initObjHeader(vm, &objRange->objHeader, OT_RANGE, vm->rangeClass); 10 | objRange->from = from; 11 | objRange->to = to; 12 | return objRange; 13 | } 14 | -------------------------------------------------------------------------------- /object/obj_range.h: -------------------------------------------------------------------------------- 1 | #ifndef _OBJECT_RANGE_H 2 | #define _OBJECT_RANGE_H 3 | #include "class.h" 4 | 5 | typedef struct { 6 | ObjHeader objHeader; 7 | int from; //范围的起始 8 | int to; //范围的结束 9 | } ObjRange; //range对象 10 | 11 | ObjRange* newObjRange(VM* vm, int from, int to); 12 | #endif 13 | -------------------------------------------------------------------------------- /object/obj_string.c: -------------------------------------------------------------------------------- 1 | #include "obj_string.h" 2 | #include 3 | #include "vm.h" 4 | #include "utils.h" 5 | #include "common.h" 6 | #include 7 | 8 | //fnv-1a算法 9 | uint32_t hashString(char* str, uint32_t length) { 10 | uint32_t hashCode = 2166136261, idx = 0; 11 | while (idx < length) { 12 | hashCode ^= str[idx]; 13 | hashCode *= 16777619; 14 | idx++; 15 | } 16 | return hashCode; 17 | } 18 | 19 | //为string计算哈希码并将值存储到string->hash 20 | void hashObjString(ObjString* objString) { 21 | objString->hashCode = 22 | hashString(objString->value.start, objString->value.length); 23 | } 24 | 25 | //以str字符串创建ObjString对象,允许空串"" 26 | ObjString* newObjString(VM* vm, const char* str, uint32_t length) { 27 | //length为0时str必为NULL length不为0时str不为NULL 28 | ASSERT(length == 0 || str != NULL, "str length don`t match str!"); 29 | 30 | //+1是为了结尾的'\0' 31 | ObjString* objString = ALLOCATE_EXTRA(vm, ObjString, length + 1); 32 | 33 | if (objString != NULL) { 34 | initObjHeader(vm, &objString->objHeader, OT_STRING, vm->stringClass); 35 | objString->value.length = length; 36 | 37 | //支持空字符串: str为null,length为0 38 | //如果非空则复制其内容 39 | if (length > 0) { 40 | memcpy(objString->value.start, str, length); 41 | } 42 | objString->value.start[length] = '\0'; 43 | hashObjString(objString); 44 | } else { 45 | MEM_ERROR("Allocating ObjString failed!"); 46 | } 47 | return objString; 48 | } 49 | -------------------------------------------------------------------------------- /object/obj_string.h: -------------------------------------------------------------------------------- 1 | #ifndef _OBJECT_STRING_H 2 | #define _OBJECT_STRING_H 3 | #include "header_obj.h" 4 | 5 | typedef struct { 6 | ObjHeader objHeader; 7 | uint32_t hashCode; //字符串的哈希值 8 | CharValue value; 9 | } ObjString; 10 | 11 | uint32_t hashString(char* str, uint32_t length); 12 | void hashObjString(ObjString* objString); 13 | ObjString* newObjString(VM* vm, const char* str, uint32_t length); 14 | #endif 15 | -------------------------------------------------------------------------------- /object/obj_thread.c: -------------------------------------------------------------------------------- 1 | #include "obj_thread.h" 2 | #include "vm.h" 3 | 4 | //为运行函数准备桢栈 5 | void prepareFrame(ObjThread* objThread, ObjClosure* objClosure, Value* stackStart) { 6 | ASSERT(objThread->frameCapacity > objThread->usedFrameNum, "frame not enough!!"); 7 | //objThread->usedFrameNum是最新可用的frame 8 | Frame* frame = &(objThread->frames[objThread->usedFrameNum++]); 9 | 10 | //thread中的各个frame是共享thread的stack 11 | //frame用frame->stackStart指向各自frame在thread->stack中的起始地址 12 | frame->stackStart = stackStart; 13 | frame->closure = objClosure; 14 | frame->ip = objClosure->fn->instrStream.datas; 15 | } 16 | 17 | //重置thread 18 | void resetThread(ObjThread* objThread, ObjClosure* objClosure) { 19 | objThread->esp = objThread->stack; 20 | objThread->openUpvalues = NULL; 21 | objThread->caller = NULL; 22 | objThread->errorObj = VT_TO_VALUE(VT_NULL); 23 | objThread->usedFrameNum = 0; 24 | 25 | ASSERT(objClosure != NULL, "objClosure is NULL in function resetThread"); 26 | prepareFrame(objThread, objClosure, objThread->stack); 27 | } 28 | 29 | //新建线程 30 | ObjThread* newObjThread(VM* vm, ObjClosure* objClosure) { 31 | ASSERT(objClosure != NULL, "objClosure is NULL!"); 32 | 33 | Frame* frames = ALLOCATE_ARRAY(vm, Frame, INITIAL_FRAME_NUM); 34 | 35 | //加1是为接收者的slot 36 | uint32_t stackCapacity = ceilToPowerOf2(objClosure->fn->maxStackSlotUsedNum + 1); 37 | Value* newStack = ALLOCATE_ARRAY(vm, Value, stackCapacity); 38 | 39 | ObjThread* objThread = ALLOCATE(vm, ObjThread); 40 | initObjHeader(vm, &objThread->objHeader, OT_THREAD, vm->threadClass); 41 | 42 | objThread->frames = frames; 43 | objThread->frameCapacity = INITIAL_FRAME_NUM; 44 | objThread->stack = newStack; 45 | objThread->stackCapacity = stackCapacity; 46 | 47 | resetThread(objThread, objClosure); 48 | return objThread; 49 | } 50 | -------------------------------------------------------------------------------- /object/obj_thread.h: -------------------------------------------------------------------------------- 1 | #ifndef _OBJECT_THREAD_H 2 | #define _OBJECT_THREAD_H 3 | #include "obj_fn.h" 4 | 5 | typedef struct objThread { 6 | ObjHeader objHeader; 7 | 8 | Value* stack; //运行时栈的栈底 9 | Value* esp; //运行时栈的栈顶 10 | uint32_t stackCapacity; //栈容量 11 | 12 | Frame* frames; //调用框架 13 | uint32_t usedFrameNum; //已使用的frame数量 14 | uint32_t frameCapacity; //frame容量 15 | 16 | //"打开的upvalue"的链表首结点 17 | ObjUpvalue* openUpvalues; 18 | 19 | //当前thread的调用者 20 | struct objThread* caller; 21 | 22 | //导致运行时错误的对象会放在此处,否则为空 23 | Value errorObj; 24 | } ObjThread; //线程对象 25 | 26 | void prepareFrame(ObjThread* objThread, ObjClosure* objClosure, Value* stackStart); 27 | ObjThread* newObjThread(VM* vm, ObjClosure* objClosure); 28 | void resetThread(ObjThread* objThread, ObjClosure* objClosure); 29 | #endif 30 | -------------------------------------------------------------------------------- /parser/parser.c: -------------------------------------------------------------------------------- 1 | #include "parser.h" 2 | #include 3 | #include 4 | #include "common.h" 5 | #include "utils.h" 6 | #include "unicodeUtf8.h" 7 | #include 8 | #include "obj_string.h" 9 | #include 10 | 11 | struct keywordToken { 12 | char* keyword; 13 | uint8_t length; 14 | TokenType token; 15 | }; //关键字(保留字)结构 16 | 17 | //关键字查找表 18 | struct keywordToken keywordsToken[] = { 19 | {"var", 3, TOKEN_VAR}, 20 | {"fun", 3, TOKEN_FUN}, 21 | {"if", 2, TOKEN_IF}, 22 | {"else", 4, TOKEN_ELSE}, 23 | {"true", 4, TOKEN_TRUE}, 24 | {"false", 5, TOKEN_FALSE}, 25 | {"while", 5, TOKEN_WHILE}, 26 | {"for", 3, TOKEN_FOR}, 27 | {"break", 5, TOKEN_BREAK}, 28 | {"continue", 8, TOKEN_CONTINUE}, 29 | {"return", 6, TOKEN_RETURN}, 30 | {"null", 4, TOKEN_NULL}, 31 | {"class", 5, TOKEN_CLASS}, 32 | {"is", 2, TOKEN_IS}, 33 | {"static", 6, TOKEN_STATIC}, 34 | {"this", 4, TOKEN_THIS}, 35 | {"super", 5, TOKEN_SUPER}, 36 | {"import", 6, TOKEN_IMPORT}, 37 | {NULL, 0, TOKEN_UNKNOWN} 38 | }; 39 | 40 | // 判断start是否为关键字并返回相应的token 41 | static TokenType idOrkeyword(const char* start, uint32_t length) { 42 | uint32_t idx = 0; 43 | while (keywordsToken[idx].keyword != NULL) { 44 | if (keywordsToken[idx].length == length && \ 45 | memcmp(keywordsToken[idx].keyword, start, length) == 0) { 46 | return keywordsToken[idx].token; 47 | } 48 | idx++; 49 | } 50 | return TOKEN_ID; 51 | } 52 | 53 | // 向前看一个字符 54 | char lookAheadChar(Parser* parser) { 55 | return *parser->nextCharPtr; 56 | } 57 | 58 | //获取下一字符 59 | static void getNextChar(Parser* parser) { 60 | parser->curChar = *parser->nextCharPtr++; 61 | } 62 | 63 | //查看下一个字符是否为期望的,如果是就读进来,返回true,否则返回false 64 | static bool matchNextChar(Parser* parser, char expectedChar) { 65 | if (lookAheadChar(parser) == expectedChar) { 66 | getNextChar(parser); 67 | return true; 68 | } 69 | return false; 70 | } 71 | 72 | // 跳过连续的空白字符 73 | static void skipBlanks(Parser* parser) { 74 | while (isspace(parser->curChar)) { 75 | if (parser->curChar == '\n') { 76 | parser->curToken.lineNo++; 77 | } 78 | getNextChar(parser); 79 | } 80 | } 81 | 82 | //解析标识符 83 | static void parseId(Parser* parser, TokenType type) { 84 | while (isalnum(parser->curChar) || parser->curChar == '_') { 85 | getNextChar(parser); 86 | } 87 | 88 | //nextCharPtr会指向第1个不合法字符的下一个字符,因此-1 89 | uint32_t length = (uint32_t)(parser->nextCharPtr - parser->curToken.start - 1); 90 | if (type != TOKEN_UNKNOWN) { 91 | parser->curToken.type = type; 92 | } else { 93 | parser->curToken.type = idOrkeyword(parser->curToken.start, length); 94 | } 95 | parser->curToken.length = length; 96 | } 97 | 98 | //解析十六进制数字 99 | static void parseHexNum(Parser* parser) { 100 | while (isxdigit(parser->curChar)) { 101 | getNextChar(parser); 102 | } 103 | } 104 | 105 | //解析十进制数字 106 | static void parseDecNum(Parser* parser) { 107 | while (isdigit(parser->curChar)) { 108 | getNextChar(parser); 109 | } 110 | 111 | //若有小数点 112 | if (parser->curChar == '.' && isdigit(lookAheadChar(parser))) { 113 | getNextChar(parser); 114 | while (isdigit(parser->curChar)) { //解析小数点之后的数字 115 | getNextChar(parser); 116 | } 117 | } 118 | } 119 | 120 | //解析八进制 121 | static void parseOctNum(Parser* parser) { 122 | while(parser->curChar >= '0' && parser->curChar < '8') { 123 | getNextChar(parser); 124 | } 125 | } 126 | 127 | //解析八进制 十进制 十六进制 仅支持前缀形式,后缀形式不支持 128 | static void parseNum(Parser* parser) { 129 | //十六进制的0x前缀 130 | if (parser->curChar == '0' && matchNextChar(parser, 'x')) { 131 | getNextChar(parser); //跳过'x' 132 | parseHexNum(parser); //解析十六进制数字 133 | parser->curToken.value = 134 | NUM_TO_VALUE(strtol(parser->curToken.start, NULL, 16)); 135 | } else if (parser->curChar == '0' 136 | && isdigit(lookAheadChar(parser))) { // 八进制 137 | parseOctNum(parser); 138 | parser->curToken.value = 139 | NUM_TO_VALUE(strtol(parser->curToken.start, NULL, 8)); 140 | } else { //解析十进制 141 | parseDecNum(parser); 142 | parser->curToken.value = NUM_TO_VALUE(strtod(parser->curToken.start, NULL)); 143 | } 144 | //nextCharPtr会指向第1个不合法字符的下一个字符,因此-1 145 | parser->curToken.length = 146 | (uint32_t)(parser->nextCharPtr - parser->curToken.start - 1); 147 | parser->curToken.type = TOKEN_NUM; 148 | } 149 | 150 | //解析unicode码点 151 | static void parseUnicodeCodePoint(Parser* parser, ByteBuffer* buf) { 152 | uint32_t idx = 0; 153 | int value = 0; 154 | uint8_t digit = 0; 155 | 156 | //获取数值,u后面跟着4位十六进制数字 157 | while(idx++ < 4) { 158 | getNextChar(parser); 159 | if (parser->curChar == '\0') { 160 | LEX_ERROR(parser, "unterminated unicode!"); 161 | } 162 | if (parser->curChar >= '0' && parser->curChar <= '9') { 163 | digit = parser->curChar - '0'; 164 | } else if (parser->curChar >= 'a' && parser->curChar <= 'f') { 165 | digit = parser->curChar - 'a' + 10; 166 | } else if (parser->curChar >= 'A' && parser->curChar <= 'F') { 167 | digit = parser->curChar - 'A' + 10; 168 | } else { 169 | LEX_ERROR(parser, "invalid unicode!"); 170 | } 171 | value = value * 16 | digit; 172 | } 173 | 174 | uint32_t byteNum = getByteNumOfEncodeUtf8(value); 175 | ASSERT(byteNum != 0, "utf8 encode bytes should be between 1 and 4!"); 176 | 177 | //为代码通用, 下面会直接写buf->datas,在此先写入byteNum个0,以保证事先有byteNum个空间 178 | ByteBufferFillWrite(parser->vm, buf, 0, byteNum); 179 | 180 | //把value编码为utf8后写入缓冲区buf 181 | encodeUtf8(buf->datas + buf->count - byteNum, value); 182 | } 183 | 184 | //解析字符串 185 | static void parseString(Parser* parser) { 186 | ByteBuffer str; 187 | ByteBufferInit(&str); 188 | while (true) { 189 | getNextChar(parser); 190 | 191 | if (parser->curChar == '\0') { 192 | LEX_ERROR(parser, "unterminated string!"); 193 | } 194 | 195 | if (parser->curChar == '"') { 196 | parser->curToken.type = TOKEN_STRING; 197 | break; 198 | } 199 | 200 | if (parser->curChar == '%') { 201 | if (!matchNextChar(parser, '(')) { 202 | LEX_ERROR(parser, "'%' should followed by '('!"); 203 | } 204 | if (parser->interpolationExpectRightParenNum > 0) { 205 | COMPILE_ERROR(parser, "sorry, I don`t support nest interpolate expression!"); 206 | } 207 | parser->interpolationExpectRightParenNum = 1; 208 | parser->curToken.type = TOKEN_INTERPOLATION; 209 | break; 210 | } 211 | 212 | if (parser->curChar == '\\') { //处理转义字符 213 | getNextChar(parser); 214 | switch (parser->curChar) { 215 | case '0': 216 | ByteBufferAdd(parser->vm, &str, '\0'); 217 | break; 218 | case 'a': 219 | ByteBufferAdd(parser->vm, &str, '\a'); 220 | break; 221 | case 'b': 222 | ByteBufferAdd(parser->vm, &str, '\b'); 223 | break; 224 | case 'f': 225 | ByteBufferAdd(parser->vm, &str, '\f'); 226 | break; 227 | case 'n': 228 | ByteBufferAdd(parser->vm, &str, '\n'); 229 | break; 230 | case 'r': 231 | ByteBufferAdd(parser->vm, &str, '\r'); 232 | break; 233 | case 't': 234 | ByteBufferAdd(parser->vm, &str, '\t'); 235 | break; 236 | case 'u': 237 | parseUnicodeCodePoint(parser, &str); 238 | break; 239 | case '"': 240 | ByteBufferAdd(parser->vm, &str, '"'); 241 | break; 242 | case '\\': 243 | ByteBufferAdd(parser->vm, &str, '\\'); 244 | break; 245 | default: 246 | LEX_ERROR(parser, "unsupport escape \\%c", parser->curChar); 247 | break; 248 | } 249 | } else { //普通字符 250 | ByteBufferAdd(parser->vm, &str, parser->curChar); 251 | } 252 | } 253 | 254 | //用识别到的字符串新建字符串对象存储到curToken的value中 255 | ObjString* objString = newObjString(parser->vm, (const char*)str.datas, str.count); 256 | parser->curToken.value = OBJ_TO_VALUE(objString); 257 | ByteBufferClear(parser->vm, &str); 258 | } 259 | 260 | // 跳过一行 261 | static void skipAline(Parser* parser) { 262 | getNextChar(parser); 263 | while (parser->curChar != '\0') { 264 | if (parser->curChar == '\n') { 265 | parser->curToken.lineNo++; 266 | getNextChar(parser); 267 | break; 268 | } 269 | getNextChar(parser); 270 | } 271 | } 272 | 273 | //跳过行注释或区块注释 274 | static void skipComment(Parser* parser) { 275 | char nextChar = lookAheadChar(parser); 276 | if (parser->curChar == '/') { // 行注释 277 | skipAline(parser); 278 | } else { // 区块注释 279 | while (nextChar != '*' && nextChar != '\0') { 280 | getNextChar(parser); 281 | if (parser->curChar == '\n') { 282 | parser->curToken.lineNo++; 283 | } 284 | nextChar = lookAheadChar(parser); 285 | } 286 | if (matchNextChar(parser, '*')) { 287 | if (!matchNextChar(parser, '/')) { //匹配*/ 288 | LEX_ERROR(parser, "expect '/' after '*'!"); 289 | } 290 | getNextChar(parser); 291 | } else { 292 | LEX_ERROR(parser, "expect '*/' before file end!"); 293 | } 294 | } 295 | skipBlanks(parser); //注释之后有可能会有空白字符 296 | } 297 | 298 | //获得下一个token 299 | void getNextToken(Parser* parser) { 300 | parser->preToken = parser->curToken; 301 | skipBlanks(parser); // 跳过待识别单词之前的空格 302 | parser->curToken.type = TOKEN_EOF; 303 | parser->curToken.length = 0; 304 | parser->curToken.start = parser->nextCharPtr - 1; 305 | parser->curToken.value = VT_TO_VALUE(VT_UNDEFINED); 306 | while (parser->curChar != '\0') { 307 | switch (parser->curChar) { 308 | case ',': 309 | parser->curToken.type = TOKEN_COMMA; 310 | break; 311 | case ':': 312 | parser->curToken.type = TOKEN_COLON; 313 | break; 314 | case '(': 315 | if (parser->interpolationExpectRightParenNum > 0) { 316 | parser->interpolationExpectRightParenNum++; 317 | } 318 | parser->curToken.type = TOKEN_LEFT_PAREN; 319 | break; 320 | case ')': 321 | if (parser->interpolationExpectRightParenNum > 0) { 322 | parser->interpolationExpectRightParenNum--; 323 | if (parser->interpolationExpectRightParenNum == 0) { 324 | parseString(parser); 325 | break; 326 | } 327 | } 328 | parser->curToken.type = TOKEN_RIGHT_PAREN; 329 | break; 330 | case '[': 331 | parser->curToken.type = TOKEN_LEFT_BRACKET; 332 | break; 333 | case ']': 334 | parser->curToken.type = TOKEN_RIGHT_BRACKET; 335 | break; 336 | case '{': 337 | parser->curToken.type = TOKEN_LEFT_BRACE; 338 | break; 339 | case '}': 340 | parser->curToken.type = TOKEN_RIGHT_BRACE; 341 | break; 342 | case '.': 343 | if (matchNextChar(parser, '.')) { 344 | parser->curToken.type = TOKEN_DOT_DOT; 345 | } else { 346 | parser->curToken.type = TOKEN_DOT; 347 | } 348 | break; 349 | case '=': 350 | if (matchNextChar(parser, '=')) { 351 | parser->curToken.type = TOKEN_EQUAL; 352 | } else { 353 | parser->curToken.type = TOKEN_ASSIGN; 354 | } 355 | break; 356 | case '+': 357 | parser->curToken.type = TOKEN_ADD; 358 | break; 359 | case '-': 360 | parser->curToken.type = TOKEN_SUB; 361 | break; 362 | case '*': 363 | parser->curToken.type = TOKEN_MUL; 364 | break; 365 | case '/': 366 | //跳过注释'//'或'/*' 367 | if (matchNextChar(parser, '/') || matchNextChar(parser, '*')) { //跳过注释'//'或'/*' 368 | skipComment(parser); 369 | 370 | //重置下一个token起始地址 371 | parser->curToken.start = parser->nextCharPtr - 1; 372 | continue; 373 | } else { // '/' 374 | parser->curToken.type = TOKEN_DIV; 375 | } 376 | break; 377 | case '%': 378 | parser->curToken.type = TOKEN_MOD; 379 | break; 380 | case '&': 381 | if (matchNextChar(parser, '&')) { 382 | parser->curToken.type = TOKEN_LOGIC_AND; 383 | } else { 384 | parser->curToken.type = TOKEN_BIT_AND; 385 | } 386 | break; 387 | case '|': 388 | if (matchNextChar(parser, '|')) { 389 | parser->curToken.type = TOKEN_LOGIC_OR; 390 | } else { 391 | parser->curToken.type = TOKEN_BIT_OR; 392 | } 393 | break; 394 | case '~': 395 | parser->curToken.type = TOKEN_BIT_NOT; 396 | break; 397 | case '?': 398 | parser->curToken.type = TOKEN_QUESTION; 399 | break; 400 | case '>': 401 | if (matchNextChar(parser, '=')) { 402 | parser->curToken.type = TOKEN_GREATE_EQUAL; 403 | } else if (matchNextChar(parser, '>')) { 404 | parser->curToken.type = TOKEN_BIT_SHIFT_RIGHT; 405 | } else { 406 | parser->curToken.type = TOKEN_GREATE; 407 | } 408 | break; 409 | case '<': 410 | if (matchNextChar(parser, '=')) { 411 | parser->curToken.type = TOKEN_LESS_EQUAL; 412 | } else if (matchNextChar(parser, '<')) { 413 | parser->curToken.type = TOKEN_BIT_SHIFT_LEFT; 414 | } else { 415 | parser->curToken.type = TOKEN_LESS; 416 | } 417 | break; 418 | case '!': 419 | if (matchNextChar(parser, '=')) { 420 | parser->curToken.type = TOKEN_NOT_EQUAL; 421 | } else { 422 | parser->curToken.type = TOKEN_LOGIC_NOT; 423 | } 424 | break; 425 | 426 | case '"': 427 | parseString(parser); 428 | break; 429 | 430 | default: 431 | //处理变量名及数字 432 | //进入此分支的字符肯定是数字或变量名的首字符 433 | //后面会调用相应函数把其余字符一并解析 434 | 435 | //首字符是字母或'_'则是变量名 436 | if (isalpha(parser->curChar) || parser->curChar == '_') { 437 | parseId(parser, TOKEN_UNKNOWN); //解析变量名其余的部分 438 | } else if (isdigit(parser->curChar)) { //数字 439 | parseNum(parser); 440 | } else { 441 | if (parser->curChar == '#' && matchNextChar(parser, '!')) { 442 | skipAline(parser); 443 | parser->curToken.start = parser->nextCharPtr - 1; //重置下一个token起始地址 444 | continue; 445 | } 446 | LEX_ERROR(parser, "unsupport char: \'%c\', quit.", parser->curChar); 447 | } 448 | return; 449 | } 450 | //大部分case的出口 451 | parser->curToken.length = (uint32_t)(parser->nextCharPtr - parser->curToken.start); 452 | getNextChar(parser); 453 | return; 454 | } 455 | } 456 | 457 | //若当前token为expected则读入下一个token并返回true, 458 | //否则不读入token且返回false 459 | bool matchToken(Parser* parser, TokenType expected) { 460 | if (parser->curToken.type == expected) { 461 | getNextToken(parser); 462 | return true; 463 | } 464 | return false; 465 | } 466 | 467 | //断言当前token为expected并读入下一token,否则报错errMsg 468 | void consumeCurToken(Parser* parser, TokenType expected, const char* errMsg) { 469 | if (parser->curToken.type != expected) { 470 | COMPILE_ERROR(parser, errMsg); 471 | } 472 | getNextToken(parser); 473 | } 474 | 475 | //断言下一个token为expected,否则报错errMsg 476 | void consumeNextToken(Parser* parser, TokenType expected, const char* errMsg) { 477 | getNextToken(parser); 478 | if (parser->curToken.type != expected) { 479 | COMPILE_ERROR(parser, errMsg); 480 | } 481 | } 482 | 483 | //由于sourceCode未必来自于文件file,有可能只是个字符串, 484 | //file仅用作跟踪待编译的代码的标识,方便报错 485 | void initParser(VM* vm, Parser* parser, const char* file, 486 | const char* sourceCode, ObjModule* objModule) { 487 | parser->file = file; 488 | parser->sourceCode = sourceCode; 489 | parser->curChar = *parser->sourceCode; 490 | parser->nextCharPtr = parser->sourceCode + 1; 491 | parser->curToken.lineNo = 1; 492 | parser->curToken.type = TOKEN_UNKNOWN; 493 | parser->curToken.start = NULL; 494 | parser->curToken.length = 0; 495 | parser->preToken = parser->curToken; 496 | parser->interpolationExpectRightParenNum = 0; 497 | parser->vm = vm; 498 | parser->curModule = objModule; 499 | } 500 | -------------------------------------------------------------------------------- /parser/parser.h: -------------------------------------------------------------------------------- 1 | #ifndef _PARSER_PARSER_H 2 | #define _PARSER_PARSER_H 3 | #include "common.h" 4 | #include "vm.h" 5 | #include "class.h" 6 | #include "compiler.h" 7 | 8 | typedef enum { 9 | TOKEN_UNKNOWN, 10 | // 数据类型 11 | TOKEN_NUM, //数字 12 | TOKEN_STRING, //字符串 13 | TOKEN_ID, //变量名 14 | TOKEN_INTERPOLATION, //内嵌表达式 15 | 16 | // 关键字(系统保留字) 17 | TOKEN_VAR, //'var' 18 | TOKEN_FUN, //'fun' 19 | TOKEN_IF, //'if' 20 | TOKEN_ELSE, //'else' 21 | TOKEN_TRUE, //'true' 22 | TOKEN_FALSE, //'false' 23 | TOKEN_WHILE, //'while' 24 | TOKEN_FOR, //'for' 25 | TOKEN_BREAK, //'break' 26 | TOKEN_CONTINUE, //'continue' 27 | TOKEN_RETURN, //'return' 28 | TOKEN_NULL, //'null' 29 | 30 | //以下是关于类和模块导入的token 31 | TOKEN_CLASS, //'class' 32 | TOKEN_THIS, //'this' 33 | TOKEN_STATIC, //'static' 34 | TOKEN_IS, // 'is' 35 | TOKEN_SUPER, //'super' 36 | TOKEN_IMPORT, //'import' 37 | 38 | //分隔符 39 | TOKEN_COMMA, //',' 40 | TOKEN_COLON, //':' 41 | TOKEN_LEFT_PAREN, //'(' 42 | TOKEN_RIGHT_PAREN, //')' 43 | TOKEN_LEFT_BRACKET, //'[' 44 | TOKEN_RIGHT_BRACKET, //']' 45 | TOKEN_LEFT_BRACE, //'{' 46 | TOKEN_RIGHT_BRACE, //'}' 47 | TOKEN_DOT, //'.' 48 | TOKEN_DOT_DOT, //'..' 49 | 50 | //简单双目运算符 51 | TOKEN_ADD, //'+' 52 | TOKEN_SUB, //'-' 53 | TOKEN_MUL, //'*' 54 | TOKEN_DIV, //'/' 55 | TOKEN_MOD, //'%' 56 | 57 | //赋值运算符 58 | TOKEN_ASSIGN, //'=' 59 | 60 | // 位运算符 61 | TOKEN_BIT_AND, //'&' 62 | TOKEN_BIT_OR, //'|' 63 | TOKEN_BIT_NOT, //'~' 64 | TOKEN_BIT_SHIFT_RIGHT, //'>>' 65 | TOKEN_BIT_SHIFT_LEFT, //'<<' 66 | 67 | // 逻辑运算符 68 | TOKEN_LOGIC_AND, //'&&' 69 | TOKEN_LOGIC_OR, //'||' 70 | TOKEN_LOGIC_NOT, //'!' 71 | 72 | //关系操作符 73 | TOKEN_EQUAL, //'==' 74 | TOKEN_NOT_EQUAL, //'!=' 75 | TOKEN_GREATE, //'>' 76 | TOKEN_GREATE_EQUAL, //'>=' 77 | TOKEN_LESS, //'<' 78 | TOKEN_LESS_EQUAL, //'<=' 79 | 80 | TOKEN_QUESTION, //'?' 81 | 82 | //文件结束标记,仅词法分析时使用 83 | TOKEN_EOF //'EOF' 84 | } TokenType; 85 | 86 | typedef struct { 87 | TokenType type; 88 | const char* start; 89 | uint32_t length; 90 | uint32_t lineNo; 91 | Value value; 92 | } Token; 93 | 94 | struct parser { 95 | const char* file; 96 | const char* sourceCode; 97 | const char* nextCharPtr; 98 | char curChar; 99 | Token curToken; 100 | Token preToken; 101 | ObjModule* curModule; // 当前正在编译的模块 102 | CompileUnit* curCompileUnit; // 当前编译单元 103 | 104 | //处于内嵌表达式之中时,期望的右括号数量. 105 | //用于跟踪小括号对儿的嵌套 106 | int interpolationExpectRightParenNum; 107 | struct parser* parent; //指向父parser 108 | VM* vm; 109 | }; 110 | 111 | #define PEEK_TOKEN(parserPtr) parserPtr->curToken.type 112 | 113 | char lookAheadChar(Parser* parser); 114 | void getNextToken(Parser* parser); 115 | bool matchToken(Parser* parser, TokenType expected); 116 | void consumeCurToken(Parser* parser, TokenType expected, const char* errMsg); 117 | void consumeNextToken(Parser* parser, TokenType expected, const char* errMsg); 118 | uint32_t getByteNumOfEncodeUtf8(int value); 119 | uint8_t encodeUtf8(uint8_t* buf, int value); 120 | void initParser(VM* vm, Parser* parser, const char* file, const char* sourceCode, ObjModule* objModule); 121 | #endif 122 | -------------------------------------------------------------------------------- /vm/core.c: -------------------------------------------------------------------------------- 1 | #include "core.h" 2 | #include 3 | #include 4 | #include "utils.h" 5 | #include "vm.h" 6 | #include "obj_thread.h" 7 | #include "compiler.h" 8 | #include "core.script.inc" 9 | #include 10 | #include "obj_range.h" 11 | #include "obj_list.h" 12 | #include "obj_map.h" 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "unicodeUtf8.h" 18 | #include "gc.h" 19 | #include "class.h" 20 | 21 | char* rootDir = NULL; //根目录 22 | 23 | #define CORE_MODULE VT_TO_VALUE(VT_NULL) 24 | 25 | //返回值类型是Value类型,且是放在args[0], args是Value数组 26 | //RET_VALUE的参数就是Value类型,无须转换直接赋值. 27 | //它是后面"RET_其它类型"的基础 28 | #define RET_VALUE(value)\ 29 | do {\ 30 | args[0] = value;\ 31 | return true;\ 32 | } while(0); 33 | 34 | //将obj转换为Value后做为返回值 35 | #define RET_OBJ(objPtr) RET_VALUE(OBJ_TO_VALUE(objPtr)) 36 | 37 | //将各种值转为Value后做为返回值 38 | #define RET_BOOL(boolean) RET_VALUE(BOOL_TO_VALUE(boolean)) 39 | #define RET_NUM(num) RET_VALUE(NUM_TO_VALUE(num)) 40 | #define RET_NULL RET_VALUE(VT_TO_VALUE(VT_NULL)) 41 | #define RET_TRUE RET_VALUE(VT_TO_VALUE(VT_TRUE)) 42 | #define RET_FALSE RET_VALUE(VT_TO_VALUE(VT_FALSE)) 43 | 44 | //设置线程报错 45 | #define SET_ERROR_FALSE(vmPtr, errMsg) \ 46 | do {\ 47 | vmPtr->curThread->errorObj = \ 48 | OBJ_TO_VALUE(newObjString(vmPtr, errMsg, strlen(errMsg)));\ 49 | return false;\ 50 | } while(0); 51 | 52 | //绑定方法func到classPtr指向的类 53 | #define PRIM_METHOD_BIND(classPtr, methodName, func) {\ 54 | uint32_t length = strlen(methodName);\ 55 | int globalIdx = getIndexFromSymbolTable(&vm->allMethodNames, methodName, length);\ 56 | if (globalIdx == -1) {\ 57 | globalIdx = addSymbol(vm, &vm->allMethodNames, methodName, length);\ 58 | }\ 59 | Method method;\ 60 | method.type = MT_PRIMITIVE;\ 61 | method.primFn = func;\ 62 | bindMethod(vm, classPtr, (uint32_t)globalIdx, method);\ 63 | } 64 | 65 | //读取源代码文件 66 | char* readFile(const char* path) { 67 | FILE* file = fopen(path, "r"); 68 | if (file == NULL) { 69 | IO_ERROR("Could`t open file \"%s\".\n", path); 70 | } 71 | 72 | struct stat fileStat; 73 | stat(path, &fileStat); 74 | size_t fileSize = fileStat.st_size; 75 | char* fileContent = (char*)malloc(fileSize + 1); 76 | if (fileContent == NULL) { 77 | MEM_ERROR("Could`t allocate memory for reading file \"%s\".\n", path); 78 | } 79 | 80 | size_t numRead = fread(fileContent, sizeof(char), fileSize, file); 81 | if (numRead < fileSize) { 82 | IO_ERROR("Could`t read file \"%s\".\n", path); 83 | } 84 | fileContent[fileSize] = '\0'; 85 | 86 | fclose(file); 87 | return fileContent; 88 | } 89 | 90 | //将数字转换为字符串 91 | static ObjString* num2str(VM* vm, double num) { 92 | //nan不是一个确定的值,因此nan和nan是不相等的 93 | if (num != num) { 94 | return newObjString(vm, "nan", 3); 95 | } 96 | 97 | if (num == INFINITY) { 98 | return newObjString(vm, "infinity", 8); 99 | } 100 | 101 | if (num == -INFINITY) { 102 | return newObjString(vm, "-infinity", 9); 103 | } 104 | 105 | //以下24字节的缓冲区足以容纳双精度到字符串的转换 106 | char buf[24] = {'\0'}; 107 | int len = sprintf(buf, "%.14g", num); 108 | return newObjString(vm, buf, len); 109 | } 110 | 111 | //校验arg是否为函数 112 | static bool validateFn(VM* vm, Value arg) { 113 | if (VALUE_TO_OBJCLOSURE(arg)) { 114 | return true; 115 | } 116 | vm->curThread->errorObj = 117 | OBJ_TO_VALUE(newObjString(vm, "argument must be a function!", 28)); 118 | return false; 119 | } 120 | 121 | //判断arg是否为字符串 122 | static bool validateString(VM* vm, Value arg) { 123 | if (VALUE_IS_OBJSTR(arg)) { 124 | return true; 125 | } 126 | SET_ERROR_FALSE(vm, "argument must be string!"); 127 | } 128 | 129 | //判断arg是否为数字 130 | static bool validateNum(VM* vm, Value arg) { 131 | if (VALUE_IS_NUM(arg)) { 132 | return true; 133 | } 134 | SET_ERROR_FALSE(vm, "argument must be number!"); 135 | } 136 | 137 | //确认value是否为整数 138 | static bool validateIntValue(VM* vm, double value) { 139 | if (trunc(value) == value) { 140 | return true; 141 | } 142 | SET_ERROR_FALSE(vm, "argument must be integer!"); 143 | } 144 | 145 | //校验arg是否为整数 146 | static bool validateInt(VM* vm, Value arg) { 147 | //首先得是数字 148 | if (!validateNum(vm, arg)) { 149 | return false; 150 | } 151 | 152 | //再校验数值 153 | return validateIntValue(vm, VALUE_TO_NUM(arg)); 154 | } 155 | 156 | //校验参数index是否是落在"[0, length)"之间的整数 157 | static uint32_t validateIndexValue(VM* vm, double index, uint32_t length) { 158 | //索引必须是数字 159 | if (!validateIntValue(vm, index)) { 160 | return UINT32_MAX; 161 | } 162 | 163 | //支持负数索引,负数是从后往前索引 164 | //转换其对应的正数索引.如果校验失败则返回UINT32_MAX 165 | if (index < 0) { 166 | index += length; 167 | } 168 | 169 | //索引应该落在[0,length) 170 | if (index >= 0 && index < length) { 171 | return (uint32_t)index; 172 | } 173 | 174 | //执行到此说明超出范围 175 | vm->curThread->errorObj = 176 | OBJ_TO_VALUE(newObjString(vm, "index out of bound!", 19)); 177 | return UINT32_MAX; 178 | } 179 | 180 | //验证index有效性 181 | static uint32_t validateIndex(VM* vm, Value index, uint32_t length) { 182 | if (!validateNum(vm, index)) { 183 | return UINT32_MAX; 184 | } 185 | return validateIndexValue(vm, VALUE_TO_NUM(index), length); 186 | } 187 | 188 | //校验key合法性 189 | static bool validateKey(VM* vm, Value arg) { 190 | if (VALUE_IS_TRUE(arg) || 191 | VALUE_IS_FALSE(arg) || 192 | VALUE_IS_NULL(arg) || 193 | VALUE_IS_NUM(arg) || 194 | VALUE_IS_OBJSTR(arg) || 195 | VALUE_IS_OBJRANGE(arg) || 196 | VALUE_IS_CLASS(arg)) { 197 | return true; 198 | } 199 | SET_ERROR_FALSE(vm, "key must be value type!"); 200 | } 201 | 202 | //从码点value创建字符串 203 | static Value makeStringFromCodePoint(VM* vm, int value) { 204 | uint32_t byteNum = getByteNumOfEncodeUtf8(value); 205 | ASSERT(byteNum != 0, "utf8 encode bytes should be between 1 and 4!"); 206 | 207 | //+1是为了结尾的'\0' 208 | ObjString* objString = ALLOCATE_EXTRA(vm, ObjString, byteNum + 1); 209 | 210 | if (objString == NULL) { 211 | MEM_ERROR("allocate memory failed in runtime!"); 212 | } 213 | 214 | initObjHeader(vm, &objString->objHeader, OT_STRING, vm->stringClass); 215 | objString->value.length = byteNum; 216 | objString->value.start[byteNum] = '\0'; 217 | encodeUtf8((uint8_t*)objString->value.start, value); 218 | hashObjString(objString); 219 | return OBJ_TO_VALUE(objString); 220 | } 221 | 222 | //用索引index处的字符创建字符串对象 223 | static Value stringCodePointAt(VM* vm, ObjString* objString, uint32_t index) { 224 | ASSERT(index < objString->value.length, "index out of bound!"); 225 | int codePoint = decodeUtf8((uint8_t*)objString->value.start + index, 226 | objString->value.length - index); 227 | 228 | //若不是有效的utf8序列,将其处理为单个裸字符 229 | if (codePoint == -1) { 230 | return OBJ_TO_VALUE(newObjString(vm, &objString->value.start[index], 1)); 231 | } 232 | 233 | return makeStringFromCodePoint(vm, codePoint); 234 | } 235 | 236 | //计算objRange中元素的起始索引及索引方向 237 | static uint32_t calculateRange(VM* vm, 238 | ObjRange* objRange, uint32_t* countPtr, int* directionPtr) { 239 | 240 | uint32_t from = validateIndexValue(vm, objRange->from, *countPtr); 241 | if (from == UINT32_MAX) { 242 | return UINT32_MAX; 243 | } 244 | 245 | uint32_t to = validateIndexValue(vm, objRange->to, *countPtr); 246 | if (to == UINT32_MAX) { 247 | return UINT32_MAX; 248 | } 249 | 250 | //如果from和to为负值,经过validateIndexValue已经变成了相应的正索引 251 | *directionPtr = from < to ? 1 : -1; 252 | *countPtr = abs((int)(from - to)) + 1; 253 | return from; 254 | } 255 | 256 | //以utf8编码从source中起始为startIndex,方向为direction的count个字符创建字符串 257 | static ObjString* newObjStringFromSub(VM* vm, ObjString* sourceStr, 258 | int startIndex, uint32_t count, int direction) { 259 | 260 | uint8_t* source = (uint8_t*)sourceStr->value.start; 261 | uint32_t totalLength = 0, idx = 0; 262 | 263 | //计算count个utf8编码的字符总共需要的字节数,后面好申请空间 264 | while (idx < count) { 265 | totalLength += getByteNumOfDecodeUtf8(source[startIndex + idx * direction]); 266 | idx++; 267 | } 268 | 269 | //+1是为了结尾的'\0' 270 | ObjString* result = ALLOCATE_EXTRA(vm, ObjString, totalLength + 1); 271 | 272 | if (result == NULL) { 273 | MEM_ERROR("allocate memory failed in runtime!"); 274 | } 275 | initObjHeader(vm, &result->objHeader, OT_STRING, vm->stringClass); 276 | result->value.start[totalLength] = '\0'; 277 | result->value.length = totalLength; 278 | 279 | uint8_t* dest = (uint8_t*)result->value.start; 280 | idx = 0; 281 | while (idx < count) { 282 | int index = startIndex + idx * direction; 283 | //解码,获取字符数据 284 | int codePoint = decodeUtf8(source + index, sourceStr->value.length - index); 285 | if (codePoint != -1) { 286 | //再将数据按照utf8编码,写入result 287 | dest += encodeUtf8(dest, codePoint); 288 | } 289 | idx++; 290 | } 291 | 292 | hashObjString(result); 293 | return result; 294 | } 295 | 296 | //使用Boyer-Moore-Horspool字符串匹配算法在haystack中查找needle,大海捞针 297 | static int findString(ObjString* haystack, ObjString* needle) { 298 | //如果待查找的patten为空则为找到 299 | if (needle->value.length == 0) { 300 | return 0; //返回起始下标0 301 | } 302 | 303 | //若待搜索的字符串比原串还长 肯定搜不到 304 | if (needle->value.length > haystack->value.length) { 305 | return -1; 306 | } 307 | 308 | //构建"bad-character shift表"以确定窗口滑动的距离 309 | //数组shift的值便是滑动距离 310 | uint32_t shift[UINT8_MAX]; 311 | //needle中最后一个字符的下标 312 | uint32_t needleEnd = needle->value.length - 1; 313 | 314 | //一、 先假定"bad character"不属于needle(即pattern), 315 | //对于这种情况,滑动窗口跨过整个needle 316 | uint32_t idx = 0; 317 | while (idx < UINT8_MAX) { 318 | // 默认为滑过整个needle的长度 319 | shift[idx] = needle->value.length; 320 | idx++; 321 | } 322 | 323 | //二、假定haystack中与needle不匹配的字符在needle中之前已匹配过的位置出现过 324 | //就滑动窗口以使该字符与在needle中匹配该字符的最末位置对齐。 325 | //这里预先确定需要滑动的距离 326 | idx = 0; 327 | while (idx < needleEnd) { 328 | char c = needle->value.start[idx]; 329 | //idx从前往后遍历needle,当needle中有重复的字符c时, 330 | //后面的字符c会覆盖前面的同名字符c,这保证了数组shilf中字符是needle中最末位置的字符, 331 | //从而保证了shilf[c]的值是needle中最末端同名字符与needle末端的偏移量 332 | shift[(uint8_t)c] = needleEnd - idx; 333 | idx++; 334 | } 335 | 336 | //Boyer-Moore-Horspool是从后往前比较,这是处理bad-character高效的地方, 337 | //因此获取needle中最后一个字符,用于同haystack的窗口中最后一个字符比较 338 | char lastChar = needle->value.start[needleEnd]; 339 | 340 | //长度差便是滑动窗口的滑动范围 341 | uint32_t range = haystack->value.length - needle->value.length; 342 | 343 | //从haystack中扫描needle,寻找第1个匹配的字符 如果遍历完了就停止 344 | idx = 0; 345 | while (idx <= range) { 346 | //拿needle中最后一个字符同haystack窗口的最后一个字符比较 347 | //(因为Boyer-Moore-Horspool是从后往前比较), 如果匹配,看整个needle是否匹配 348 | char c = haystack->value.start[idx + needleEnd]; 349 | if (lastChar == c && 350 | memcmp(haystack->value.start + idx, needle->value.start, needleEnd) == 0) { 351 | //找到了就返回匹配的位置 352 | return idx; 353 | } 354 | 355 | //否则就向前滑动继续下一伦比较 356 | idx += shift[(uint8_t)c]; 357 | } 358 | 359 | //未找到就返回-1 360 | return -1; 361 | } 362 | 363 | //返回核心类name的value结构 364 | static Value getCoreClassValue(ObjModule* objModule, const char* name) { 365 | int index = getIndexFromSymbolTable(&objModule->moduleVarName, name, strlen(name)); 366 | if (index == -1) { 367 | char id[MAX_ID_LEN] = {'\0'}; 368 | memcpy(id, name, strlen(name)); 369 | RUN_ERROR("something wrong occur: missing core class \"%s\"!", id); 370 | } 371 | return objModule->moduleVarValue.datas[index]; 372 | } 373 | 374 | //从modules中获取名为moduleName的模块 375 | static ObjModule* getModule(VM* vm, Value moduleName) { 376 | Value value = mapGet(vm->allModules, moduleName); 377 | if (value.type == VT_UNDEFINED) { 378 | return NULL; 379 | } 380 | return (ObjModule*)(value.objHeader); 381 | } 382 | 383 | //载入模块moduleName并编译 384 | static ObjThread* loadModule(VM* vm, Value moduleName, const char* moduleCode) { 385 | //确保模块已经载入到 vm->allModules 386 | //先查看是否已经导入了该模块,避免重新导入 387 | ObjModule* module = getModule(vm, moduleName); 388 | 389 | //若该模块未加载先将其载入,并继承核心模块中的变量 390 | if (module == NULL) { 391 | //创建模块并添加到vm->allModules 392 | ObjString* modName = VALUE_TO_OBJSTR(moduleName); 393 | ASSERT(modName->value.start[modName->value.length] == '\0', "string.value.start is not terminated!"); 394 | 395 | module = newObjModule(vm, modName->value.start); 396 | 397 | pushTmpRoot(vm, (ObjHeader*)module); 398 | mapSet(vm, vm->allModules, moduleName, OBJ_TO_VALUE(module)); 399 | popTmpRoot(vm); 400 | 401 | //继承核心模块中的变量 402 | ObjModule* coreModule = getModule(vm, CORE_MODULE); 403 | uint32_t idx = 0; 404 | while (idx < coreModule->moduleVarName.count) { 405 | defineModuleVar(vm, module, 406 | coreModule->moduleVarName.datas[idx].str, 407 | strlen(coreModule->moduleVarName.datas[idx].str), 408 | coreModule->moduleVarValue.datas[idx]); 409 | idx++; 410 | } 411 | } 412 | 413 | ObjFn* fn = compileModule(vm, module, moduleCode); 414 | pushTmpRoot(vm, (ObjHeader*)fn); 415 | ObjClosure* objClosure = newObjClosure(vm, fn); 416 | pushTmpRoot(vm, (ObjHeader*)objClosure); 417 | ObjThread* moduleThread = newObjThread(vm, objClosure); 418 | popTmpRoot(vm); // objClosure 419 | popTmpRoot(vm); // fn 420 | 421 | return moduleThread; 422 | } 423 | 424 | //获取文件全路径 425 | static char* getFilePath(const char* moduleName) { 426 | uint32_t rootDirLength = rootDir == NULL ? 0 : strlen(rootDir); 427 | uint32_t nameLength = strlen(moduleName); 428 | uint32_t pathLength = rootDirLength + nameLength + strlen(".sp"); 429 | char* path = (char*)malloc(pathLength + 1); 430 | 431 | if (rootDir != NULL) { 432 | memmove(path, rootDir, rootDirLength); 433 | } 434 | 435 | memmove(path + rootDirLength, moduleName, nameLength); 436 | memmove(path + rootDirLength + nameLength, ".sp", 3); 437 | path[pathLength] = '\0'; 438 | 439 | return path; 440 | } 441 | 442 | //读取模块 443 | static char* readModule(const char* moduleName) { 444 | //1 读取内建模块 先放着 445 | 446 | //2 读取自定义模块 447 | char* modulePath = getFilePath(moduleName); 448 | char* moduleCode = readFile(modulePath); 449 | free(modulePath); 450 | 451 | return moduleCode; //由主调函数将来free此空间 452 | } 453 | 454 | //输出字符串 455 | static void printString(const char* str) { 456 | //输出到缓冲区后立即刷新 457 | printf("%s", str); 458 | fflush(stdout); 459 | } 460 | 461 | //导入模块moduleName,主要是把编译模块并加载到vm->allModules 462 | static Value importModule(VM* vm, Value moduleName) { 463 | //若已经导入则返回NULL_VAL 464 | if (!VALUE_IS_UNDEFINED(mapGet(vm->allModules, moduleName))) { 465 | return VT_TO_VALUE(VT_NULL); 466 | } 467 | ObjString* objString = VALUE_TO_OBJSTR(moduleName); 468 | const char* sourceCode = readModule(objString->value.start); 469 | 470 | ObjThread* moduleThread = loadModule(vm, moduleName, sourceCode); 471 | return OBJ_TO_VALUE(moduleThread); 472 | } 473 | 474 | //在模块moduleName中获取模块变量variableName 475 | static Value getModuleVariable(VM* vm, Value moduleName, Value variableName) { 476 | //调用本函数前模块已经被加载了 477 | ObjModule* objModule = getModule(vm, moduleName); 478 | if (objModule == NULL) { 479 | ObjString* modName = VALUE_TO_OBJSTR(moduleName); 480 | 481 | //24是下面sprintf中fmt中除%s的字符个数 482 | ASSERT(modName->value.length < 512 - 24, "id`s buffer not big enough!"); 483 | char id[512] = {'\0'}; 484 | int len = sprintf(id, "module \'%s\' is not loaded!", modName->value.start); 485 | vm->curThread->errorObj = OBJ_TO_VALUE(newObjString(vm, id, len)); 486 | return VT_TO_VALUE(VT_NULL); 487 | } 488 | 489 | ObjString* varName = VALUE_TO_OBJSTR(variableName); 490 | 491 | //从moduleVarName中获得待导入的模块变量 492 | int index = getIndexFromSymbolTable(&objModule->moduleVarName, 493 | varName->value.start, varName->value.length); 494 | 495 | if (index == -1) { 496 | //32是下面sprintf中fmt中除%s的字符个数 497 | ASSERT(varName->value.length < 512 - 32, "id`s buffer not big enough!"); 498 | ObjString* modName = VALUE_TO_OBJSTR(moduleName); 499 | char id[512] = {'\0'}; 500 | int len = sprintf(id, "variable \'%s\' is not in module \'%s\'!", 501 | varName->value.start, modName->value.start); 502 | vm->curThread->errorObj = OBJ_TO_VALUE(newObjString(vm, id, len)); 503 | return VT_TO_VALUE(VT_NULL); 504 | } 505 | 506 | //直接返回对应的模块变量 507 | return objModule->moduleVarValue.datas[index]; 508 | } 509 | 510 | //!object: object取反,结果为false 511 | static bool primObjectNot(VM* vm UNUSED, Value* args) { 512 | RET_VALUE(VT_TO_VALUE(VT_FALSE)); 513 | } 514 | 515 | //args[0] == args[1]: 返回object是否相等 516 | static bool primObjectEqual(VM* vm UNUSED, Value* args) { 517 | Value boolValue = BOOL_TO_VALUE(valueIsEqual(args[0], args[1])); 518 | RET_VALUE(boolValue); 519 | } 520 | 521 | //args[0] != args[1]: 返回object是否不等 522 | static bool primObjectNotEqual(VM* vm UNUSED, Value* args) { 523 | Value boolValue = BOOL_TO_VALUE(!valueIsEqual(args[0], args[1])); 524 | RET_VALUE(boolValue); 525 | } 526 | 527 | //args[0] is args[1]:类args[0]是否为类args[1]的子类 528 | static bool primObjectIs(VM* vm, Value* args) { 529 | //args[1]必须是class 530 | if (!VALUE_IS_CLASS(args[1])) { 531 | RUN_ERROR("argument must be class!"); 532 | } 533 | 534 | Class* thisClass = getClassOfObj(vm, args[0]); 535 | Class* baseClass = (Class*)(args[1].objHeader); 536 | 537 | //有可能是多级继承,因此自下而上遍历基类链 538 | while (baseClass != NULL) { 539 | 540 | //在某一级基类找到匹配就设置返回值为VT_TRUE并返回 541 | if (thisClass == baseClass) { 542 | RET_VALUE(VT_TO_VALUE(VT_TRUE)); 543 | } 544 | baseClass = baseClass->superClass; 545 | } 546 | 547 | //若未找到基类,说明不具备is_a关系 548 | RET_VALUE(VT_TO_VALUE(VT_FALSE)); 549 | } 550 | 551 | //args[0].tostring: 返回args[0]所属class的名字 552 | static bool primObjectToString(VM* vm UNUSED, Value* args) { 553 | Class* class = args[0].objHeader->class; 554 | Value nameValue = OBJ_TO_VALUE(class->name); 555 | RET_VALUE(nameValue); 556 | } 557 | 558 | //args[0].type:返回对象args[0]的类 559 | static bool primObjectType(VM* vm, Value* args) { 560 | Class* class = getClassOfObj(vm, args[0]); 561 | RET_OBJ(class); 562 | } 563 | 564 | //args[0].name: 返回类名 565 | static bool primClassName(VM* vm UNUSED, Value* args) { 566 | RET_OBJ(VALUE_TO_CLASS(args[0])->name); 567 | } 568 | 569 | //args[0].supertype: 返回args[0]的基类 570 | static bool primClassSupertype(VM* vm UNUSED, Value* args) { 571 | Class* class = VALUE_TO_CLASS(args[0]); 572 | if (class->superClass != NULL) { 573 | RET_OBJ(class->superClass); 574 | } 575 | RET_VALUE(VT_TO_VALUE(VT_NULL)); 576 | } 577 | 578 | //args[0].toString: 返回类名 579 | static bool primClassToString(VM* vm UNUSED, Value* args) { 580 | RET_OBJ(VALUE_TO_CLASS(args[0])->name); 581 | } 582 | 583 | //args[0].same(args[1], args[2]): 返回args[1]和args[2]是否相等 584 | static bool primObjectmetaSame(VM* vm UNUSED, Value* args) { 585 | Value boolValue = BOOL_TO_VALUE(valueIsEqual(args[1], args[2])); 586 | RET_VALUE(boolValue); 587 | } 588 | 589 | //返回bool的字符串形式:"true"或"false" 590 | static bool primBoolToString(VM* vm, Value* args) { 591 | ObjString* objString; 592 | if (VALUE_TO_BOOL(args[0])) { //若为VT_TRUE 593 | objString = newObjString(vm, "true", 4); 594 | } else { 595 | objString = newObjString(vm, "false", 5); 596 | } 597 | RET_OBJ(objString); 598 | } 599 | 600 | //bool值取反 601 | static bool primBoolNot(VM* vm UNUSED, Value* args) { 602 | RET_BOOL(!VALUE_TO_BOOL(args[0])); 603 | } 604 | 605 | //以下以大写字符开头的为类名,表示类(静态)方法调用 606 | 607 | //Thread.new(func):创建一个thread实例 608 | static bool primThreadNew(VM* vm, Value* args) { 609 | //代码块为参数必为闭包 610 | if (!validateFn(vm, args[1])) { 611 | return false; 612 | } 613 | 614 | ObjThread* objThread = newObjThread(vm, VALUE_TO_OBJCLOSURE(args[1])); 615 | 616 | //使stack[0]为接收者,保持栈平衡 617 | objThread->stack[0] = VT_TO_VALUE(VT_NULL); 618 | objThread->esp++; 619 | RET_OBJ(objThread); 620 | } 621 | 622 | //Thread.abort(err):以错误信息err为参数退出线程 623 | static bool primThreadAbort(VM* vm, Value* args) { 624 | //此函数后续未处理,暂时放着 625 | vm->curThread->errorObj = args[1]; //保存退出参数 626 | return VALUE_IS_NULL(args[1]); 627 | } 628 | 629 | //Thread.current:返回当前的线程 630 | static bool primThreadCurrent(VM* vm, Value* args UNUSED) { 631 | RET_OBJ(vm->curThread); 632 | } 633 | 634 | //Thread.suspend():挂起线程,退出解析器 635 | static bool primThreadSuspend(VM* vm, Value* args UNUSED) { 636 | //目前suspend操作只会退出虚拟机, 637 | //使curThread为NULL,虚拟机将退出 638 | vm->curThread = NULL; 639 | return false; 640 | } 641 | 642 | //Thread.yield(arg)带参数让出cpu 643 | static bool primThreadYieldWithArg(VM* vm, Value* args) { 644 | ObjThread* curThread = vm->curThread; 645 | vm->curThread = curThread->caller; //使cpu控制权回到主调方 646 | 647 | curThread->caller = NULL; //与调用者断开联系 648 | 649 | if (vm->curThread != NULL) { 650 | //如果当前线程有主调方,就将当前线程的返回值放在主调方的栈顶 651 | vm->curThread->esp[-1] = args[1]; 652 | 653 | //对于"thread.yield(arg)"来说, 回收arg的空间, 654 | //保留thread参数所在的空间,将来唤醒时用于存储yield结果 655 | curThread->esp--; 656 | } 657 | return false; 658 | } 659 | 660 | //Thread.yield() 无参数让出cpu 661 | static bool primThreadYieldWithoutArg(VM* vm, Value* args UNUSED) { 662 | ObjThread* curThread = vm->curThread; 663 | vm->curThread = curThread->caller; //使cpu控制权回到主调方 664 | 665 | curThread->caller = NULL; //与调用者断开联系 666 | 667 | if (vm->curThread != NULL) { 668 | //为保持通用的栈结构,如果当前线程有主调方, 669 | //就将空值做为返回值放在主调方的栈顶 670 | vm->curThread->esp[-1] = VT_TO_VALUE(VT_NULL) ; 671 | } 672 | return false; 673 | } 674 | 675 | //切换到下一个线程nextThread 676 | static bool switchThread(VM* vm, 677 | ObjThread* nextThread, Value* args, bool withArg) { 678 | //在下一线程nextThread执行之前,其主调线程应该为空 679 | if (nextThread->caller != NULL) { 680 | RUN_ERROR("thread has been called!"); 681 | } 682 | nextThread->caller = vm->curThread; 683 | 684 | if (nextThread->usedFrameNum == 0) { 685 | //只有已经运行完毕的thread的usedFrameNum才为0 686 | SET_ERROR_FALSE(vm, "a finished thread can`t be switched to!"); 687 | } 688 | 689 | if (!VALUE_IS_NULL(nextThread->errorObj)) { 690 | //Thread.abort(arg)会设置errorObj, 不能切换到abort的线程 691 | SET_ERROR_FALSE(vm, "a aborted thread can`t be switched to!"); 692 | } 693 | 694 | //如果call有参数,回收参数的空间, 695 | //只保留次栈顶用于存储nextThread返回后的结果 696 | if (withArg) { 697 | vm->curThread->esp--; 698 | } 699 | 700 | ASSERT(nextThread->esp > nextThread->stack, "esp should be greater than stack!"); 701 | //nextThread.call(arg)中的arg做为nextThread.yield的返回值 702 | //存储到nextThread的栈顶,否则压入null保持栈平衡 703 | nextThread->esp[-1] = withArg ? args[1] : VT_TO_VALUE(VT_NULL); 704 | 705 | //使当前线程指向nextThread,使之成为就绪 706 | vm->curThread = nextThread; 707 | 708 | //返回false以进入vm中的切换线程流程 709 | return false; 710 | } 711 | 712 | //objThread.call() 713 | static bool primThreadCallWithoutArg(VM* vm, Value* args) { 714 | return switchThread(vm, VALUE_TO_OBJTHREAD(args[0]), args, false); 715 | } 716 | 717 | //objThread.call(arg) 718 | static bool primThreadCallWithArg(VM* vm, Value* args) { 719 | return switchThread(vm, VALUE_TO_OBJTHREAD(args[0]), args, true); 720 | } 721 | 722 | //objThread.isDone返回线程是否运行完成 723 | static bool primThreadIsDone(VM* vm UNUSED, Value* args) { 724 | //获取.isDone的调用者 725 | ObjThread* objThread = VALUE_TO_OBJTHREAD(args[0]); 726 | RET_BOOL(objThread->usedFrameNum == 0 || !VALUE_IS_NULL(objThread->errorObj)); 727 | } 728 | 729 | //Fn.new(_):新建一个函数对象 730 | static bool primFnNew(VM* vm, Value* args) { 731 | //代码块为参数必为闭包 732 | if (!validateFn(vm, args[1])) return false; 733 | 734 | //直接返回函数闭包 735 | RET_VALUE(args[1]); 736 | } 737 | 738 | //null取非 739 | static bool primNullNot(VM* vm UNUSED, Value* args UNUSED) { 740 | RET_VALUE(BOOL_TO_VALUE(true)); 741 | } 742 | 743 | //null的字符串化 744 | static bool primNullToString(VM* vm, Value* args UNUSED) { 745 | ObjString* objString = newObjString(vm, "null", 4); 746 | RET_OBJ(objString); 747 | } 748 | 749 | //将字符串转换为数字 750 | static bool primNumFromString(VM* vm, Value* args) { 751 | if (!validateString(vm, args[1])) { 752 | return false; 753 | } 754 | 755 | ObjString* objString = VALUE_TO_OBJSTR(args[1]); 756 | 757 | //空字符串返回RETURN_NULL 758 | if (objString->value.length == 0) { 759 | RET_NULL; 760 | } 761 | 762 | ASSERT(objString->value.start[objString->value.length] == '\0', "objString don`t teminate!"); 763 | 764 | errno = 0; 765 | char* endPtr; 766 | 767 | //将字符串转换为double型, 它会自动跳过前面的空白 768 | double num = strtod(objString->value.start, &endPtr); 769 | 770 | //以endPtr是否等于start+length来判断不能转换的字符之后是否全是空白 771 | while (*endPtr != '\0' && isspace((unsigned char)*endPtr)) { 772 | endPtr++; 773 | } 774 | 775 | if (errno == ERANGE) { 776 | RUN_ERROR("string too large!"); 777 | } 778 | 779 | //如果字符串中不能转换的字符不全是空白,字符串非法,返回NULL 780 | if (endPtr < objString->value.start + objString->value.length) { 781 | RET_NULL; 782 | } 783 | 784 | //至此,检查通过,返回正确结果 785 | RET_NUM(num); 786 | } 787 | 788 | //返回圆周率 789 | static bool primNumPi(VM* vm UNUSED, Value* args UNUSED) { 790 | RET_NUM(3.14159265358979323846); 791 | } 792 | 793 | #define PRIM_NUM_INFIX(name, operator, type) \ 794 | static bool name(VM* vm, Value* args) {\ 795 | if (!validateNum(vm, args[1])) {\ 796 | return false; \ 797 | }\ 798 | RET_##type(VALUE_TO_NUM(args[0]) operator VALUE_TO_NUM(args[1]));\ 799 | } 800 | 801 | PRIM_NUM_INFIX(primNumPlus, +, NUM); 802 | PRIM_NUM_INFIX(primNumMinus, -, NUM); 803 | PRIM_NUM_INFIX(primNumMul, *, NUM); 804 | PRIM_NUM_INFIX(primNumDiv, /, NUM); 805 | PRIM_NUM_INFIX(primNumGt, >, BOOL); 806 | PRIM_NUM_INFIX(primNumGe, >=, BOOL); 807 | PRIM_NUM_INFIX(primNumLt, <, BOOL); 808 | PRIM_NUM_INFIX(primNumLe, <=, BOOL); 809 | #undef PRIM_NUM_INFIX 810 | 811 | #define PRIM_NUM_BIT(name, operator) \ 812 | static bool name(VM* vm UNUSED, Value* args) {\ 813 | if (!validateNum(vm, args[1])) {\ 814 | return false;\ 815 | }\ 816 | uint32_t leftOperand = VALUE_TO_NUM(args[0]); \ 817 | uint32_t rightOperand = VALUE_TO_NUM(args[1]); \ 818 | RET_NUM(leftOperand operator rightOperand);\ 819 | } 820 | 821 | PRIM_NUM_BIT(primNumBitAnd, &); 822 | PRIM_NUM_BIT(primNumBitOr, |); 823 | PRIM_NUM_BIT(primNumBitShiftRight, >>); 824 | PRIM_NUM_BIT(primNumBitShiftLeft, <<); 825 | #undef PRIM_NUM_BIT 826 | 827 | //使用数学库函数 828 | #define PRIM_NUM_MATH_FN(name, mathFn) \ 829 | static bool name(VM* vm UNUSED, Value* args) {\ 830 | RET_NUM(mathFn(VALUE_TO_NUM(args[0]))); \ 831 | } 832 | 833 | PRIM_NUM_MATH_FN(primNumAbs, fabs); 834 | PRIM_NUM_MATH_FN(primNumAcos, acos); 835 | PRIM_NUM_MATH_FN(primNumAsin, asin); 836 | PRIM_NUM_MATH_FN(primNumAtan, atan); 837 | PRIM_NUM_MATH_FN(primNumCeil, ceil); 838 | PRIM_NUM_MATH_FN(primNumCos, cos); 839 | PRIM_NUM_MATH_FN(primNumFloor, floor); 840 | PRIM_NUM_MATH_FN(primNumNegate, -); 841 | PRIM_NUM_MATH_FN(primNumSin, sin); 842 | PRIM_NUM_MATH_FN(primNumSqrt, sqrt); //开方 843 | PRIM_NUM_MATH_FN(primNumTan, tan); 844 | #undef PRIM_NUM_MATH_FN 845 | 846 | //这里用fmod实现浮点取模 847 | static bool primNumMod(VM* vm UNUSED, Value* args) { 848 | if (!validateNum(vm, args[1])) { 849 | return false; 850 | } 851 | RET_NUM(fmod(VALUE_TO_NUM(args[0]), VALUE_TO_NUM(args[1]))); 852 | } 853 | 854 | //数字取反 855 | static bool primNumBitNot(VM* vm UNUSED, Value* args) { 856 | RET_NUM(~(uint32_t)VALUE_TO_NUM(args[0])); 857 | } 858 | 859 | //[数字from..数字to] 860 | static bool primNumRange(VM* vm UNUSED, Value* args) { 861 | if (!validateNum(vm, args[1])) { 862 | return false; 863 | } 864 | 865 | double from = VALUE_TO_NUM(args[0]); 866 | double to = VALUE_TO_NUM(args[1]); 867 | RET_OBJ(newObjRange(vm, from, to)); 868 | } 869 | 870 | //atan2(args[1]) 871 | static bool primNumAtan2(VM* vm UNUSED, Value* args) { 872 | if (!validateNum(vm, args[1])) { 873 | return false; 874 | } 875 | 876 | RET_NUM(atan2(VALUE_TO_NUM(args[0]), VALUE_TO_NUM(args[1]))); 877 | } 878 | 879 | //返回小数部分 880 | static bool primNumFraction(VM* vm UNUSED, Value* args) { 881 | double dummyInteger; 882 | RET_NUM(modf(VALUE_TO_NUM(args[0]), &dummyInteger)); 883 | } 884 | 885 | //判断数字是否无穷大,不区分正负无穷大 886 | static bool primNumIsInfinity(VM* vm UNUSED, Value* args) { 887 | RET_BOOL(isinf(VALUE_TO_NUM(args[0]))); 888 | } 889 | 890 | //判断是否为数字 891 | static bool primNumIsInteger(VM* vm UNUSED, Value* args) { 892 | double num = VALUE_TO_NUM(args[0]); 893 | //如果是nan(不是一个数字)或无限大的数字就返回false 894 | if (isnan(num) || isinf(num)) { 895 | RET_FALSE; 896 | } 897 | RET_BOOL(trunc(num) == num); 898 | } 899 | 900 | //判断数字是否为nan 901 | static bool primNumIsNan(VM* vm UNUSED, Value* args) { 902 | RET_BOOL(isnan(VALUE_TO_NUM(args[0]))); 903 | } 904 | 905 | //数字转换为字符串 906 | static bool primNumToString(VM* vm UNUSED, Value* args) { 907 | RET_OBJ(num2str(vm, VALUE_TO_NUM(args[0]))); 908 | } 909 | 910 | //取数字的整数部分 911 | static bool primNumTruncate(VM* vm UNUSED, Value* args) { 912 | double integer; 913 | modf(VALUE_TO_NUM(args[0]), &integer); 914 | RET_NUM(integer); 915 | } 916 | 917 | //判断两个数字是否相等 918 | static bool primNumEqual(VM* vm UNUSED, Value* args) { 919 | if (!validateNum(vm, args[1])) { 920 | RET_FALSE; 921 | } 922 | 923 | RET_BOOL(VALUE_TO_NUM(args[0]) == VALUE_TO_NUM(args[1])); 924 | } 925 | 926 | //判断两个数字是否不等 927 | static bool primNumNotEqual(VM* vm UNUSED, Value* args) { 928 | if (!validateNum(vm, args[1])) { 929 | RET_TRUE; 930 | } 931 | RET_BOOL(VALUE_TO_NUM(args[0]) != VALUE_TO_NUM(args[1])); 932 | } 933 | 934 | //objString.fromCodePoint(_):从码点建立字符串 935 | static bool primStringFromCodePoint(VM* vm, Value* args) { 936 | 937 | if (!validateInt(vm, args[1])) { 938 | return false; 939 | } 940 | 941 | int codePoint = (int)VALUE_TO_NUM(args[1]); 942 | if (codePoint < 0) { 943 | SET_ERROR_FALSE(vm, "code point can`t be negetive!"); 944 | } 945 | 946 | if (codePoint > 0x10ffff) { 947 | SET_ERROR_FALSE(vm, "code point must be between 0 and 0x10ffff!"); 948 | } 949 | 950 | RET_VALUE(makeStringFromCodePoint(vm, codePoint)); 951 | } 952 | 953 | //objString+objString: 字符串相加 954 | static bool primStringPlus(VM* vm, Value* args) { 955 | if (!validateString(vm, args[1])) { 956 | return false; 957 | } 958 | 959 | ObjString* left = VALUE_TO_OBJSTR(args[0]); 960 | ObjString* right = VALUE_TO_OBJSTR(args[1]); 961 | 962 | uint32_t totalLength = strlen(left->value.start) + strlen(right->value.start); 963 | //+1是为了结尾的'\0' 964 | ObjString* result = ALLOCATE_EXTRA(vm, ObjString, totalLength + 1); 965 | if (result == NULL) { 966 | MEM_ERROR("allocate memory failed in runtime!"); 967 | } 968 | initObjHeader(vm, &result->objHeader, OT_STRING, vm->stringClass); 969 | memcpy(result->value.start, left->value.start, strlen(left->value.start)); 970 | memcpy(result->value.start + strlen(left->value.start), 971 | right->value.start, strlen(right->value.start)); 972 | result->value.start[totalLength] = '\0'; 973 | result->value.length = totalLength; 974 | hashObjString(result); 975 | 976 | RET_OBJ(result); 977 | } 978 | 979 | //objString[_]:用数字或objRange对象做字符串的subscript 980 | static bool primStringSubscript(VM* vm, Value* args) { 981 | ObjString* objString = VALUE_TO_OBJSTR(args[0]); 982 | //数字和objRange都可以做索引,分别判断 983 | //若索引是数字,就直接索引1个字符,这是最简单的subscript 984 | if (VALUE_IS_NUM(args[1])) { 985 | uint32_t index = validateIndex(vm, args[1], objString->value.length); 986 | if (index == UINT32_MAX) { 987 | return false; 988 | } 989 | RET_VALUE(stringCodePointAt(vm, objString, index)); 990 | } 991 | 992 | //索引要么为数字要么为ObjRange,若不是数字就应该为objRange 993 | if (!VALUE_IS_OBJRANGE(args[1])) { 994 | SET_ERROR_FALSE(vm, "subscript should be integer or range!"); 995 | } 996 | 997 | //direction是索引的方向, 998 | //1表示正方向,从前往后.-1表示反方向,从后往前. 999 | //from若比to大,即从后往前检索字符,direction则为-1 1000 | int direction; 1001 | 1002 | uint32_t count = objString->value.length; 1003 | //返回的startIndex是objRange.from在objString.value.start中的下标 1004 | uint32_t startIndex = calculateRange(vm, VALUE_TO_OBJRANGE(args[1]), &count, &direction); 1005 | if (startIndex == UINT32_MAX) { 1006 | return false; 1007 | } 1008 | 1009 | RET_OBJ(newObjStringFromSub(vm, objString, startIndex, count, direction)); 1010 | } 1011 | 1012 | //objString.byteAt_():返回指定索引的字节 1013 | static bool primStringByteAt(VM* vm UNUSED, Value* args) { 1014 | ObjString* objString = VALUE_TO_OBJSTR(args[0]); 1015 | uint32_t index = validateIndex(vm, args[1], objString->value.length); 1016 | if (index == UINT32_MAX) { 1017 | return false; 1018 | } 1019 | //故转换为数字返回 1020 | RET_NUM((uint8_t)objString->value.start[index]); 1021 | } 1022 | 1023 | //objString.byteCount_:返回字节数 1024 | static bool primStringByteCount(VM* vm UNUSED, Value* args) { 1025 | RET_NUM(VALUE_TO_OBJSTR(args[0])->value.length); 1026 | } 1027 | 1028 | //objString.codePointAt_(_):返回指定的CodePoint 1029 | static bool primStringCodePointAt(VM* vm UNUSED, Value* args) { 1030 | ObjString* objString = VALUE_TO_OBJSTR(args[0]); 1031 | uint32_t index = validateIndex(vm, args[1], objString->value.length); 1032 | if (index == UINT32_MAX) { 1033 | return false; 1034 | } 1035 | 1036 | const uint8_t* bytes = (uint8_t*)objString->value.start; 1037 | if ((bytes[index] & 0xc0) == 0x80) { 1038 | //如果index指向的并不是utf8编码的最高字节 1039 | //而是后面的低字节,返回-1提示用户 1040 | RET_NUM(-1); 1041 | } 1042 | 1043 | //返回解码 1044 | RET_NUM(decodeUtf8((uint8_t*)objString->value.start + index, 1045 | objString->value.length - index)); 1046 | } 1047 | 1048 | //objString.contains(_):判断字符串args[0]中是否包含子字符串args[1] 1049 | static bool primStringContains(VM* vm UNUSED, Value* args) { 1050 | if (!validateString(vm, args[1])) { 1051 | return false; 1052 | } 1053 | 1054 | ObjString* objString = VALUE_TO_OBJSTR(args[0]); 1055 | ObjString* pattern = VALUE_TO_OBJSTR(args[1]); 1056 | RET_BOOL(findString(objString, pattern) != -1); 1057 | } 1058 | 1059 | //objString.endsWith(_): 返回字符串是否以args[1]为结束 1060 | static bool primStringEndsWith(VM* vm UNUSED, Value* args) { 1061 | if (!validateString(vm, args[1])) { 1062 | return false; 1063 | } 1064 | 1065 | ObjString* objString = VALUE_TO_OBJSTR(args[0]); 1066 | ObjString* pattern = VALUE_TO_OBJSTR(args[1]); 1067 | 1068 | //若pattern比源串还长,源串必然不包括pattern 1069 | if (pattern->value.length > objString->value.length) { 1070 | RET_FALSE; 1071 | } 1072 | 1073 | char* cmpIdx = objString->value.start + 1074 | objString->value.length - pattern->value.length; 1075 | RET_BOOL(memcmp(cmpIdx, pattern->value.start, pattern->value.length) == 0); 1076 | } 1077 | 1078 | //objString.indexOf(_):检索字符串args[0]中子串args[1]的起始下标 1079 | static bool primStringIndexOf(VM* vm UNUSED, Value* args) { 1080 | if (!validateString(vm, args[1])) { 1081 | return false; 1082 | } 1083 | 1084 | ObjString* objString = VALUE_TO_OBJSTR(args[0]); 1085 | ObjString* pattern = VALUE_TO_OBJSTR(args[1]); 1086 | 1087 | //若pattern比源串还长,源串必然不包括pattern 1088 | if (pattern->value.length > objString->value.length) { 1089 | RET_FALSE; 1090 | } 1091 | 1092 | int index = findString(objString, pattern); 1093 | RET_NUM(index); 1094 | } 1095 | 1096 | //objString.iterate(_):返回下一个utf8字符(不是字节)的迭代器 1097 | static bool primStringIterate(VM* vm UNUSED, Value* args) { 1098 | ObjString* objString = VALUE_TO_OBJSTR(args[0]); 1099 | 1100 | //如果是第一次迭代 迭代索引肯定为空 1101 | if (VALUE_IS_NULL(args[1])) { 1102 | if (objString->value.length == 0) { 1103 | RET_FALSE; 1104 | } 1105 | RET_NUM(0); 1106 | } 1107 | 1108 | //迭代器必须是正整数 1109 | if (!validateInt(vm, args[1])){ 1110 | return false; 1111 | } 1112 | 1113 | double iter = VALUE_TO_NUM(args[1]); 1114 | if (iter < 0) { 1115 | RET_FALSE; 1116 | } 1117 | 1118 | uint32_t index = (uint32_t)iter; 1119 | do { 1120 | index++; 1121 | 1122 | //到了结尾就返回false,表示迭代完毕 1123 | if (index >= objString->value.length) RET_FALSE; 1124 | 1125 | //读取连续的数据字节,直到下一个Utf8的高字节 1126 | } while ((objString->value.start[index] & 0xc0) == 0x80); 1127 | 1128 | RET_NUM(index); 1129 | } 1130 | 1131 | //objString.iterateByte_(_): 迭代索引,内部使用 1132 | static bool primStringIterateByte(VM* vm UNUSED, Value* args) { 1133 | ObjString* objString = VALUE_TO_OBJSTR(args[0]); 1134 | 1135 | //如果是第一次迭代 迭代索引肯定为空 直接返回索引0 1136 | if (VALUE_IS_NULL(args[1])) { 1137 | if (objString->value.length == 0) { 1138 | RET_FALSE; 1139 | } 1140 | RET_NUM(0); 1141 | } 1142 | 1143 | //迭代器必须是正整数 1144 | if (!validateInt(vm, args[1])) { 1145 | return false; 1146 | } 1147 | 1148 | double iter = VALUE_TO_NUM(args[1]); 1149 | 1150 | if (iter < 0) { 1151 | RET_FALSE; 1152 | } 1153 | 1154 | uint32_t index = (uint32_t)iter; 1155 | index++; //移进到下一个字节的索引 1156 | if (index >= objString->value.length) { 1157 | RET_FALSE; 1158 | } 1159 | 1160 | RET_NUM(index); 1161 | } 1162 | 1163 | //objString.iteratorValue(_):返回迭代器对应的value 1164 | static bool primStringIteratorValue(VM* vm, Value* args) { 1165 | ObjString* objString = VALUE_TO_OBJSTR(args[0]); 1166 | uint32_t index = validateIndex(vm, args[1], objString->value.length); 1167 | if (index == UINT32_MAX) { 1168 | return false; 1169 | } 1170 | RET_VALUE(stringCodePointAt(vm, objString, index)); 1171 | } 1172 | 1173 | //objString.startsWith(_): 返回args[0]是否以args[1]为起始 1174 | static bool primStringStartsWith(VM* vm UNUSED, Value* args) { 1175 | if (!validateString(vm, args[1])) { 1176 | return false; 1177 | } 1178 | 1179 | ObjString* objString = VALUE_TO_OBJSTR(args[0]); 1180 | ObjString* pattern = VALUE_TO_OBJSTR(args[1]); 1181 | 1182 | //若pattern比源串还长,源串必然不包括pattern, 1183 | //因此不可能以pattern为起始 1184 | if (pattern->value.length > objString->value.length) { 1185 | RET_FALSE; 1186 | } 1187 | 1188 | RET_BOOL(memcmp(objString->value.start, 1189 | pattern->value.start, pattern->value.length) == 0); 1190 | } 1191 | 1192 | //objString.toString:获得自己的字符串 1193 | static bool primStringToString(VM* vm UNUSED, Value* args) { 1194 | RET_VALUE(args[0]); 1195 | } 1196 | 1197 | //objList.new():创建1个新的liist 1198 | static bool primListNew(VM* vm, Value* args UNUSED) { 1199 | RET_OBJ(newObjList(vm, 0)); 1200 | } 1201 | 1202 | //objList[_]:索引list元素 1203 | static bool primListSubscript(VM* vm, Value* args) { 1204 | ObjList* objList = VALUE_TO_OBJLIST(args[0]); 1205 | 1206 | //数字和objRange都可以做索引,分别判断 1207 | //若索引是数字,就直接索引1个字符,这是最简单的subscript 1208 | if (VALUE_IS_NUM(args[1])) { 1209 | uint32_t index = validateIndex(vm, args[1], objList->elements.count); 1210 | if (index == UINT32_MAX) { 1211 | return false; 1212 | } 1213 | RET_VALUE(objList->elements.datas[index]); 1214 | } 1215 | 1216 | //索引要么为数字要么为ObjRange,若不是数字就应该为objRange 1217 | if (!VALUE_IS_OBJRANGE(args[1])) { 1218 | SET_ERROR_FALSE(vm, "subscript should be integer or range!"); 1219 | } 1220 | 1221 | int direction; 1222 | 1223 | uint32_t count = objList->elements.count; 1224 | 1225 | //返回的startIndex是objRange.from在objList.elements.data中的下标 1226 | uint32_t startIndex = calculateRange(vm, VALUE_TO_OBJRANGE(args[1]), &count, &direction); 1227 | 1228 | //新建一个list 存储该range在原来list中索引的元素 1229 | ObjList* result = newObjList(vm, count); 1230 | uint32_t idx = 0; 1231 | while (idx < count) { 1232 | //direction为-1表示从后往前倒序赋值 1233 | //如var l = [a,b,c,d,e,f,g]; l[5..3]表示[f,e,d] 1234 | result->elements.datas[idx] = objList->elements.datas[startIndex + idx * direction]; 1235 | idx++; 1236 | } 1237 | RET_OBJ(result); 1238 | } 1239 | 1240 | //objList[_]=(_):只支持数字做为subscript 1241 | static bool primListSubscriptSetter(VM* vm UNUSED, Value* args) { 1242 | //获取对象 1243 | ObjList* objList = VALUE_TO_OBJLIST(args[0]); 1244 | 1245 | //获取subscript 1246 | uint32_t index = validateIndex(vm, args[1], objList->elements.count); 1247 | if (index == UINT32_MAX) { 1248 | return false; 1249 | } 1250 | 1251 | //直接赋值 1252 | objList->elements.datas[index] = args[2]; 1253 | 1254 | RET_VALUE(args[2]); //把参数2做为返回值 1255 | } 1256 | 1257 | //objList.add(_):直接追加到list中 1258 | static bool primListAdd(VM* vm, Value* args) { 1259 | ObjList* objList = VALUE_TO_OBJLIST(args[0]); 1260 | ValueBufferAdd(vm, &objList->elements, args[1]); 1261 | RET_VALUE(args[1]); //把参数1做为返回值 1262 | } 1263 | 1264 | //objList.addCore_(_):编译内部使用的,用于编译列表直接量 1265 | static bool primListAddCore(VM* vm, Value* args) { 1266 | ObjList* objList = VALUE_TO_OBJLIST(args[0]); 1267 | ValueBufferAdd(vm, &objList->elements, args[1]); 1268 | RET_VALUE(args[0]); //返回列表自身 1269 | } 1270 | 1271 | //objList.clear():清空list 1272 | static bool primListClear(VM* vm, Value* args) { 1273 | ObjList* objList = VALUE_TO_OBJLIST(args[0]); 1274 | ValueBufferClear(vm, &objList->elements); 1275 | RET_NULL; 1276 | } 1277 | 1278 | //objList.count:返回list中元素个数 1279 | static bool primListCount(VM* vm UNUSED, Value* args) { 1280 | RET_NUM(VALUE_TO_OBJLIST(args[0])->elements.count); 1281 | } 1282 | 1283 | //objList.insert(_,_):插入元素 1284 | static bool primListInsert(VM* vm, Value* args) { 1285 | ObjList* objList = VALUE_TO_OBJLIST(args[0]); 1286 | //+1确保可以在最后插入 1287 | uint32_t index = validateIndex(vm, args[1], objList->elements.count + 1); 1288 | if (index == UINT32_MAX) { 1289 | return false; 1290 | } 1291 | insertElement(vm, objList, index, args[2]); 1292 | RET_VALUE(args[2]); //参数2做为返回值 1293 | } 1294 | 1295 | //objList.iterate(_):迭代list 1296 | static bool primListIterate(VM* vm, Value* args) { 1297 | ObjList* objList = VALUE_TO_OBJLIST(args[0]); 1298 | 1299 | //如果是第一次迭代 迭代索引肯定为空 直接返回索引0 1300 | if (VALUE_IS_NULL(args[1])) { 1301 | if (objList->elements.count == 0) { 1302 | RET_FALSE; 1303 | } 1304 | RET_NUM(0); 1305 | } 1306 | 1307 | //确保迭代器是整数 1308 | if (!validateInt(vm, args[1])) { 1309 | return false; 1310 | } 1311 | 1312 | double iter = VALUE_TO_NUM(args[1]); 1313 | //如果迭代完了就终止 1314 | if (iter < 0 || iter >= objList->elements.count - 1) { 1315 | RET_FALSE; 1316 | } 1317 | 1318 | RET_NUM(iter + 1); //返回下一个 1319 | } 1320 | 1321 | //objList.iteratorValue(_):返回迭代值 1322 | static bool primListIteratorValue(VM* vm, Value* args) { 1323 | //获取实例对象 1324 | ObjList* objList = VALUE_TO_OBJLIST(args[0]); 1325 | 1326 | uint32_t index = validateIndex(vm, args[1], objList->elements.count); 1327 | if (index == UINT32_MAX) { 1328 | return false; 1329 | } 1330 | 1331 | RET_VALUE(objList->elements.datas[index]); 1332 | } 1333 | 1334 | //objList.removeAt(_):删除指定位置的元素 1335 | static bool primListRemoveAt(VM* vm, Value* args) { 1336 | //获取实例对象 1337 | ObjList* objList = VALUE_TO_OBJLIST(args[0]); 1338 | 1339 | uint32_t index = validateIndex(vm, args[1], objList->elements.count); 1340 | if (index == UINT32_MAX) { 1341 | return false; 1342 | } 1343 | 1344 | RET_VALUE(removeElement(vm, objList, index)); 1345 | } 1346 | 1347 | //objMap.new():创建map对象 1348 | static bool primMapNew(VM* vm, Value* args UNUSED) { 1349 | RET_OBJ(newObjMap(vm)); 1350 | } 1351 | 1352 | //objMap[_]:返回map[key]对应的value 1353 | static bool primMapSubscript(VM* vm, Value* args) { 1354 | //校验key的合法性 1355 | if (!validateKey(vm, args[1])) { 1356 | return false; //出错了,切换线程 1357 | } 1358 | 1359 | //获得map对象实例 1360 | ObjMap* objMap = VALUE_TO_OBJMAP(args[0]); 1361 | 1362 | //从map中查找key(args[1])对应的value 1363 | Value value = mapGet(objMap, args[1]); 1364 | 1365 | //若没有相应的key则返回NULL 1366 | if (VALUE_IS_UNDEFINED(value)) { 1367 | RET_NULL; 1368 | } 1369 | 1370 | RET_VALUE(value); 1371 | } 1372 | 1373 | //objMap[_]=(_):map[key]=value 1374 | static bool primMapSubscriptSetter(VM* vm, Value* args) { 1375 | //校验key的合法性 1376 | if (!validateKey(vm, args[1])) { 1377 | return false; //出错了,切换线程 1378 | } 1379 | 1380 | //获得map对象实例 1381 | ObjMap* objMap = VALUE_TO_OBJMAP(args[0]); 1382 | 1383 | //在map中将key和value关联 1384 | //即map[key]=value 1385 | mapSet(vm, objMap, args[1], args[2]); 1386 | 1387 | RET_VALUE(args[2]); //返回value 1388 | } 1389 | 1390 | //objMap.addCore_(_,_):编译器编译map字面量时内部使用的, 1391 | //在map中添加(key-value)对儿并返回map自身 1392 | static bool primMapAddCore(VM* vm, Value* args) { 1393 | if (!validateKey(vm, args[1])) { 1394 | return false; //出错了,切换线程 1395 | } 1396 | 1397 | //获得map对象实例 1398 | ObjMap* objMap = VALUE_TO_OBJMAP(args[0]); 1399 | 1400 | //在map中将key和value关联 1401 | //即map[key]=value 1402 | mapSet(vm, objMap, args[1], args[2]); 1403 | 1404 | RET_VALUE(args[0]); //返回map对象自身 1405 | } 1406 | 1407 | //objMap.clear():清除map 1408 | static bool primMapClear(VM* vm, Value* args) { 1409 | clearMap(vm, VALUE_TO_OBJMAP(args[0])); 1410 | RET_NULL; 1411 | } 1412 | 1413 | //objMap.containsKey(_):判断map即args[0]是否包含key即args[1] 1414 | static bool primMapContainsKey(VM* vm, Value* args) { 1415 | if (!validateKey(vm, args[1])) { 1416 | return false; //出错了,切换线程 1417 | } 1418 | 1419 | //直接去get该key,判断是否get成功 1420 | RET_BOOL(!VALUE_IS_UNDEFINED(mapGet(VALUE_TO_OBJMAP(args[0]), args[1]))); 1421 | } 1422 | 1423 | //objMap.count:返回map中entry个数 1424 | static bool primMapCount(VM* vm UNUSED, Value* args) { 1425 | RET_NUM(VALUE_TO_OBJMAP(args[0])->count); 1426 | } 1427 | 1428 | //objMap.remove(_):删除map[key] map是args[0] key是args[1] 1429 | static bool primMapRemove(VM* vm, Value* args) { 1430 | if (!validateKey(vm, args[1])) { 1431 | return false; //出错了,切换线程 1432 | } 1433 | 1434 | RET_VALUE(removeKey(vm, VALUE_TO_OBJMAP(args[0]), args[1])); 1435 | } 1436 | 1437 | //objMap.iterate_(_):迭代map中的entry, 1438 | //返回entry的索引供keyIteratorValue_和valueIteratorValue_做迭代器 1439 | static bool primMapIterate(VM* vm, Value* args) { 1440 | //获得map对象实例 1441 | ObjMap* objMap = VALUE_TO_OBJMAP(args[0]); 1442 | 1443 | //map中若空则返回false不可迭代 1444 | if (objMap->count == 0) { 1445 | RET_FALSE; 1446 | } 1447 | 1448 | //若没有传入迭代器,迭代默认是从第0个entry开始 1449 | uint32_t index = 0; 1450 | 1451 | //若不是第一次迭代,传进了迭代器 1452 | if (!VALUE_IS_NULL(args[1])) { 1453 | //iter必须为整数 1454 | if (!validateInt(vm, args[1])) { 1455 | //本线程出错了,返回false是为了切换到下一线 1456 | return false; 1457 | } 1458 | 1459 | //迭代器不能小0 1460 | if (VALUE_TO_NUM(args[1]) < 0) { 1461 | RET_FALSE; 1462 | } 1463 | 1464 | index = (uint32_t)VALUE_TO_NUM(args[1]); 1465 | //迭代器不能越界 1466 | if (index >= objMap->capacity) { 1467 | RET_FALSE; 1468 | } 1469 | 1470 | index++; //更新迭代器 1471 | } 1472 | 1473 | //返回下一个正在使用(有效)的entry 1474 | while (index < objMap->capacity) { 1475 | //entries是个数组, 元素是哈希槽, 1476 | //哈希值散布在这些槽中并不连续,因此逐个判断槽位是否在用 1477 | if (!VALUE_IS_UNDEFINED(objMap->entries[index].key)) { 1478 | RET_NUM(index); //返回entry索引 1479 | } 1480 | index++; 1481 | } 1482 | 1483 | //若没有有效的entry了就返回false,迭代结束 1484 | RET_FALSE; 1485 | } 1486 | 1487 | //objMap.keyIteratorValue_(_): key=map.keyIteratorValue(iter) 1488 | static bool primMapKeyIteratorValue(VM* vm, Value* args) { 1489 | ObjMap* objMap = VALUE_TO_OBJMAP(args[0]); 1490 | 1491 | uint32_t index = validateIndex(vm, args[1], objMap->capacity); 1492 | if (index == UINT32_MAX) { 1493 | return false; 1494 | } 1495 | 1496 | Entry* entry = &objMap->entries[index]; 1497 | if (VALUE_IS_UNDEFINED(entry->key)) { 1498 | SET_ERROR_FALSE(vm, "invalid iterator!"); 1499 | } 1500 | 1501 | //返回该key 1502 | RET_VALUE(entry->key); 1503 | } 1504 | 1505 | //objMap.valueIteratorValue_(_): 1506 | //value = map.valueIteratorValue_(iter) 1507 | static bool primMapValueIteratorValue(VM* vm, Value* args) { 1508 | ObjMap* objMap = VALUE_TO_OBJMAP(args[0]); 1509 | 1510 | uint32_t index = validateIndex(vm, args[1], objMap->capacity); 1511 | if (index == UINT32_MAX) { 1512 | return false; 1513 | } 1514 | 1515 | Entry* entry = &objMap->entries[index]; 1516 | if (VALUE_IS_UNDEFINED(entry->key)) { 1517 | SET_ERROR_FALSE(vm, "invalid iterator!"); 1518 | } 1519 | 1520 | //返回该key 1521 | RET_VALUE(entry->value); 1522 | } 1523 | 1524 | //objRange.from: 返回range的from 1525 | static bool primRangeFrom(VM* vm UNUSED, Value* args) { 1526 | RET_NUM(VALUE_TO_OBJRANGE(args[0])->from); 1527 | } 1528 | 1529 | //objRange.to: 返回range的to 1530 | static bool primRangeTo(VM* vm UNUSED, Value* args) { 1531 | RET_NUM(VALUE_TO_OBJRANGE(args[0])->to); 1532 | } 1533 | 1534 | //objRange.min: 返回range中from和to较小的值 1535 | static bool primRangeMin(VM* vm UNUSED, Value* args) { 1536 | ObjRange* objRange = VALUE_TO_OBJRANGE(args[0]); 1537 | RET_NUM(fmin(objRange->from, objRange->to)); 1538 | } 1539 | 1540 | //objRange.max: 返回range中from和to较大的值 1541 | static bool primRangeMax(VM* vm UNUSED, Value* args) { 1542 | ObjRange* objRange = VALUE_TO_OBJRANGE(args[0]); 1543 | RET_NUM(fmax(objRange->from, objRange->to)); 1544 | } 1545 | 1546 | //objRange.iterate(_): 迭代range中的值,并不索引 1547 | static bool primRangeIterate(VM* vm, Value* args) { 1548 | ObjRange* objRange = VALUE_TO_OBJRANGE(args[0]); 1549 | 1550 | //若未提供iter说明是第一次迭代,因此返回range->from 1551 | if (VALUE_IS_NULL(args[1])) { 1552 | RET_NUM(objRange->from); 1553 | } 1554 | 1555 | //迭代器必须是数字 1556 | if (!validateNum(vm, args[1])) { 1557 | return false; 1558 | } 1559 | 1560 | //获得迭代器 1561 | double iter = VALUE_TO_NUM(args[1]); 1562 | 1563 | //若是正方向 1564 | if (objRange->from < objRange->to) { 1565 | iter++; 1566 | if (iter > objRange->to) { 1567 | RET_FALSE; 1568 | } 1569 | } else { //若是反向迭代 1570 | iter--; 1571 | if (iter < objRange->to) { 1572 | RET_FALSE; 1573 | } 1574 | } 1575 | 1576 | RET_NUM(iter); 1577 | } 1578 | 1579 | //objRange.iteratorValue(_): range的迭代就是range中从from到to之间的值 1580 | //因此直接返回迭代器就是range的值 1581 | static bool primRangeIteratorValue(VM* vm UNUSED, Value* args) { 1582 | ObjRange* objRange = VALUE_TO_OBJRANGE(args[0]); 1583 | double value = VALUE_TO_NUM(args[1]); 1584 | 1585 | //确保args[1]在from和to的范围中 1586 | //若是正方向 1587 | if (objRange->from < objRange->to) { 1588 | if (value >= objRange->from && value <= objRange->to) { 1589 | RET_VALUE(args[1]); 1590 | } 1591 | } else { //若是反向迭代 1592 | if (value <= objRange->from && value >= objRange->to) { 1593 | RET_VALUE(args[1]); 1594 | } 1595 | } 1596 | RET_FALSE; 1597 | } 1598 | 1599 | //System.clock: 返回以秒为单位的系统时钟 1600 | static bool primSystemClock(VM* vm UNUSED, Value* args UNUSED) { 1601 | RET_NUM((double)time(NULL)); 1602 | } 1603 | 1604 | //System.gc(): 启动gc 1605 | static bool primSystemGC(VM* vm, Value* args) { 1606 | startGC(vm); 1607 | RET_NULL; 1608 | } 1609 | 1610 | //System.importModule(_): 导入并编译模块args[1],把模块挂载到vm->allModules 1611 | static bool primSystemImportModule(VM* vm, Value* args) { 1612 | if (!validateString(vm, args[1])) { //模块名为字符串 1613 | return false; 1614 | } 1615 | 1616 | //导入模块name并编译 把模块挂载到vm->allModules 1617 | Value result = importModule(vm, args[1]); 1618 | 1619 | //若已经导入过则返回NULL_VAL 1620 | if (VALUE_IS_NULL(result)) { 1621 | RET_NULL; 1622 | } 1623 | 1624 | //若编译过程中出了问题,切换到下一线程 1625 | if (!VALUE_IS_NULL(vm->curThread->errorObj)) { 1626 | return false; 1627 | } 1628 | 1629 | //回收1个slot空间 1630 | vm->curThread->esp--; 1631 | 1632 | ObjThread* nextThread = VALUE_TO_OBJTHREAD(result); 1633 | nextThread->caller = vm->curThread; 1634 | vm->curThread = nextThread; 1635 | //返回false,vm会切换到此新加载模块的线程 1636 | return false; 1637 | } 1638 | 1639 | //System.getModuleVariable(_,_): 获取模块args[1]中的模块变量args[2] 1640 | static bool primSystemGetModuleVariable(VM* vm, Value* args) { 1641 | if (!validateString(vm, args[1])) { 1642 | return false; 1643 | } 1644 | 1645 | if (!validateString(vm, args[2])) { 1646 | return false; 1647 | } 1648 | 1649 | Value result = getModuleVariable(vm, args[1], args[2]); 1650 | if (VALUE_IS_NULL(result)) { 1651 | //出错了,给vm返回false以切换线程 1652 | return false; 1653 | } 1654 | 1655 | RET_VALUE(result); 1656 | } 1657 | 1658 | //System.writeString_(_): 输出字符串args[1] 1659 | static bool primSystemWriteString(VM* vm UNUSED, Value* args) { 1660 | ObjString* objString = VALUE_TO_OBJSTR(args[1]); 1661 | ASSERT(objString->value.start[objString->value.length] == '\0', "string isn`t terminated!"); 1662 | printString(objString->value.start); 1663 | RET_VALUE(args[1]); 1664 | } 1665 | 1666 | //执行模块 1667 | VMResult executeModule(VM* vm, Value moduleName, const char* moduleCode) { 1668 | ObjThread* objThread = loadModule(vm, moduleName, moduleCode); 1669 | return executeInstruction(vm, objThread); 1670 | } 1671 | 1672 | //table中查找符号symbol 找到后返回索引,否则返回-1 1673 | int getIndexFromSymbolTable(SymbolTable* table, const char* symbol, uint32_t length) { 1674 | ASSERT(length != 0, "length of symbol is 0!"); 1675 | uint32_t index = 0; 1676 | while (index < table->count) { 1677 | if (length == table->datas[index].length && 1678 | memcmp(table->datas[index].str, symbol, length) == 0) { 1679 | return index; 1680 | } 1681 | index++; 1682 | } 1683 | return -1; 1684 | } 1685 | 1686 | //往table中添加符号symbol,返回其索引 1687 | int addSymbol(VM* vm, SymbolTable* table, const char* symbol, uint32_t length) { 1688 | ASSERT(length != 0, "length of symbol is 0!"); 1689 | String string; 1690 | string.str = ALLOCATE_ARRAY(vm, char, length + 1); 1691 | memcpy(string.str, symbol, length); 1692 | string.str[length] = '\0'; 1693 | string.length = length; 1694 | StringBufferAdd(vm, table, string); 1695 | return table->count - 1; 1696 | } 1697 | 1698 | //确保符号已添加到符号表 1699 | int ensureSymbolExist(VM* vm, SymbolTable* table, const char* symbol, uint32_t length) { 1700 | int symbolIndex = getIndexFromSymbolTable(table, symbol, length); 1701 | if (symbolIndex == -1) { 1702 | return addSymbol(vm, table, symbol, length); 1703 | } 1704 | return symbolIndex; 1705 | } 1706 | 1707 | //定义类 1708 | static Class* defineClass(VM* vm, ObjModule* objModule, const char* name) { 1709 | //1先创建类 1710 | Class* class = newRawClass(vm, name, 0); 1711 | 1712 | //2把类做为普通变量在模块中定义 1713 | defineModuleVar(vm, objModule, name, strlen(name), OBJ_TO_VALUE(class)); 1714 | return class; 1715 | } 1716 | 1717 | //使class->methods[index]=method 1718 | void bindMethod(VM* vm, Class* class, uint32_t index, Method method) { 1719 | if (index >= class->methods.count) { 1720 | Method emptyPad = {MT_NONE, {0}}; 1721 | MethodBufferFillWrite(vm, &class->methods, emptyPad, index - class->methods.count + 1); 1722 | } 1723 | class->methods.datas[index] = method; 1724 | } 1725 | 1726 | //绑定基类 1727 | void bindSuperClass(VM* vm, Class* subClass, Class* superClass) { 1728 | subClass->superClass = superClass; 1729 | 1730 | //继承基类属性数 1731 | subClass->fieldNum += superClass->fieldNum; 1732 | 1733 | //继承基类方法 1734 | uint32_t idx = 0; 1735 | while (idx < superClass->methods.count) { 1736 | bindMethod(vm, subClass, idx, superClass->methods.datas[idx]); 1737 | idx++; 1738 | } 1739 | } 1740 | 1741 | //绑定fn.call的重载 1742 | static void bindFnOverloadCall(VM* vm, const char* sign) { 1743 | uint32_t index = ensureSymbolExist(vm, &vm->allMethodNames, sign, strlen(sign)); 1744 | //构造method 1745 | Method method = {MT_FN_CALL, {0}}; 1746 | bindMethod(vm, vm->fnClass, index, method); 1747 | } 1748 | 1749 | //编译核心模块 1750 | void buildCore(VM* vm) { 1751 | 1752 | //核心模块不需要名字,模块也允许名字为空 1753 | ObjModule* coreModule = newObjModule(vm, NULL); 1754 | 1755 | pushTmpRoot(vm, (ObjHeader*)coreModule); 1756 | //创建核心模块,录入到vm->allModules 1757 | mapSet(vm, vm->allModules, CORE_MODULE, OBJ_TO_VALUE(coreModule)); 1758 | popTmpRoot(vm); 1759 | 1760 | //创建object类并绑定方法 1761 | vm->objectClass = defineClass(vm, coreModule, "object"); 1762 | PRIM_METHOD_BIND(vm->objectClass, "!", primObjectNot); 1763 | PRIM_METHOD_BIND(vm->objectClass, "==(_)", primObjectEqual); 1764 | PRIM_METHOD_BIND(vm->objectClass, "!=(_)", primObjectNotEqual); 1765 | PRIM_METHOD_BIND(vm->objectClass, "is(_)", primObjectIs); 1766 | PRIM_METHOD_BIND(vm->objectClass, "toString", primObjectToString); 1767 | PRIM_METHOD_BIND(vm->objectClass, "type", primObjectType); 1768 | 1769 | //定义classOfClass类,它是所有meta类的meta类和基类 1770 | vm->classOfClass = defineClass(vm, coreModule, "class"); 1771 | 1772 | //objectClass是任何类的基类 1773 | bindSuperClass(vm, vm->classOfClass, vm->objectClass); 1774 | 1775 | PRIM_METHOD_BIND(vm->classOfClass, "name", primClassName); 1776 | PRIM_METHOD_BIND(vm->classOfClass, "supertype", primClassSupertype); 1777 | PRIM_METHOD_BIND(vm->classOfClass, "toString", primClassToString); 1778 | 1779 | //定义object类的元信息类objectMetaclass,它无须挂载到vm 1780 | Class* objectMetaclass = defineClass(vm, coreModule, "objectMeta"); 1781 | 1782 | //classOfClass类是所有meta类的meta类和基类 1783 | bindSuperClass(vm, objectMetaclass, vm->classOfClass); 1784 | 1785 | //类型比较 1786 | PRIM_METHOD_BIND(objectMetaclass, "same(_,_)", primObjectmetaSame); 1787 | 1788 | //绑定各自的meta类 1789 | vm->objectClass->objHeader.class = objectMetaclass; 1790 | objectMetaclass->objHeader.class = vm->classOfClass; 1791 | vm->classOfClass->objHeader.class = vm->classOfClass; //元信息类回路,meta类终点 1792 | 1793 | //执行核心模块 1794 | executeModule(vm, CORE_MODULE, coreModuleCode); 1795 | 1796 | //Bool类定义在core.script.inc中,将其挂载Bool类到vm->boolClass 1797 | vm->boolClass = VALUE_TO_CLASS(getCoreClassValue(coreModule, "Bool")); 1798 | PRIM_METHOD_BIND(vm->boolClass, "toString", primBoolToString); 1799 | PRIM_METHOD_BIND(vm->boolClass, "!", primBoolNot); 1800 | 1801 | //Thread类也是在core.script.inc中定义的, 1802 | //将其挂载到vm->threadClass并补充原生方法 1803 | vm->threadClass = VALUE_TO_CLASS(getCoreClassValue(coreModule, "Thread")); 1804 | //以下是类方法 1805 | PRIM_METHOD_BIND(vm->threadClass->objHeader.class, "new(_)", primThreadNew); 1806 | PRIM_METHOD_BIND(vm->threadClass->objHeader.class, "abort(_)", primThreadAbort); 1807 | PRIM_METHOD_BIND(vm->threadClass->objHeader.class, "current", primThreadCurrent); 1808 | PRIM_METHOD_BIND(vm->threadClass->objHeader.class, "suspend()", primThreadSuspend); 1809 | PRIM_METHOD_BIND(vm->threadClass->objHeader.class, "yield(_)", primThreadYieldWithArg); 1810 | PRIM_METHOD_BIND(vm->threadClass->objHeader.class, "yield()", primThreadYieldWithoutArg); 1811 | //以下是实例方法 1812 | PRIM_METHOD_BIND(vm->threadClass, "call()", primThreadCallWithoutArg); 1813 | PRIM_METHOD_BIND(vm->threadClass, "call(_)", primThreadCallWithArg); 1814 | PRIM_METHOD_BIND(vm->threadClass, "isDone", primThreadIsDone); 1815 | 1816 | //绑定函数类 1817 | vm->fnClass = VALUE_TO_CLASS(getCoreClassValue(coreModule, "Fn")); 1818 | PRIM_METHOD_BIND(vm->fnClass->objHeader.class, "new(_)", primFnNew); 1819 | 1820 | //绑定call的重载方法 1821 | bindFnOverloadCall(vm, "call()"); 1822 | bindFnOverloadCall(vm, "call(_)"); 1823 | bindFnOverloadCall(vm, "call(_,_)"); 1824 | bindFnOverloadCall(vm, "call(_,_,_)"); 1825 | bindFnOverloadCall(vm, "call(_,_,_,_)"); 1826 | bindFnOverloadCall(vm, "call(_,_,_,_,_)"); 1827 | bindFnOverloadCall(vm, "call(_,_,_,_,_,_)"); 1828 | bindFnOverloadCall(vm, "call(_,_,_,_,_,_,_)"); 1829 | bindFnOverloadCall(vm, "call(_,_,_,_,_,_,_,_)"); 1830 | bindFnOverloadCall(vm, "call(_,_,_,_,_,_,_,_,_)"); 1831 | bindFnOverloadCall(vm, "call(_,_,_,_,_,_,_,_,_,_)"); 1832 | bindFnOverloadCall(vm, "call(_,_,_,_,_,_,_,_,_,_,_)"); 1833 | bindFnOverloadCall(vm, "call(_,_,_,_,_,_,_,_,_,_,_,_)"); 1834 | bindFnOverloadCall(vm, "call(_,_,_,_,_,_,_,_,_,_,_,_,_)"); 1835 | bindFnOverloadCall(vm, "call(_,_,_,_,_,_,_,_,_,_,_,_,_,_)"); 1836 | bindFnOverloadCall(vm, "call(_,_,_,_,_,_,_,_,_,_,_,_,_,_,_)"); 1837 | bindFnOverloadCall(vm, "call(_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_)"); 1838 | 1839 | //绑定Null类的方法 1840 | vm->nullClass = VALUE_TO_CLASS(getCoreClassValue(coreModule, "Null")); 1841 | PRIM_METHOD_BIND(vm->nullClass, "!", primNullNot); 1842 | PRIM_METHOD_BIND(vm->nullClass, "toString", primNullToString); 1843 | 1844 | //绑定num类方法 1845 | vm->numClass = VALUE_TO_CLASS(getCoreClassValue(coreModule, "Num")); 1846 | //类方法 1847 | PRIM_METHOD_BIND(vm->numClass->objHeader.class, "fromString(_)", primNumFromString); 1848 | PRIM_METHOD_BIND(vm->numClass->objHeader.class, "pi", primNumPi); 1849 | //实例方法 1850 | PRIM_METHOD_BIND(vm->numClass, "+(_)", primNumPlus); 1851 | PRIM_METHOD_BIND(vm->numClass, "-(_)", primNumMinus); 1852 | PRIM_METHOD_BIND(vm->numClass, "*(_)", primNumMul); 1853 | PRIM_METHOD_BIND(vm->numClass, "/(_)", primNumDiv); 1854 | PRIM_METHOD_BIND(vm->numClass, ">(_)", primNumGt); 1855 | PRIM_METHOD_BIND(vm->numClass, ">=(_)", primNumGe); 1856 | PRIM_METHOD_BIND(vm->numClass, "<(_)", primNumLt); 1857 | PRIM_METHOD_BIND(vm->numClass, "<=(_)", primNumLe); 1858 | 1859 | //位运算 1860 | PRIM_METHOD_BIND(vm->numClass, "&(_)", primNumBitAnd); 1861 | PRIM_METHOD_BIND(vm->numClass, "|(_)", primNumBitOr); 1862 | PRIM_METHOD_BIND(vm->numClass, ">>(_)", primNumBitShiftRight); 1863 | PRIM_METHOD_BIND(vm->numClass, "<<(_)", primNumBitShiftLeft); 1864 | //以上都是通过rules中INFIX_OPERATOR来解析的 1865 | 1866 | //下面大多数方法是通过rules中'.'对应的led(callEntry)来解析, 1867 | //少数符号依然是INFIX_OPERATOR解析 1868 | PRIM_METHOD_BIND(vm->numClass, "abs", primNumAbs); 1869 | PRIM_METHOD_BIND(vm->numClass, "acos", primNumAcos); 1870 | PRIM_METHOD_BIND(vm->numClass, "asin", primNumAsin); 1871 | PRIM_METHOD_BIND(vm->numClass, "atan", primNumAtan); 1872 | PRIM_METHOD_BIND(vm->numClass, "ceil", primNumCeil); 1873 | PRIM_METHOD_BIND(vm->numClass, "cos", primNumCos); 1874 | PRIM_METHOD_BIND(vm->numClass, "floor", primNumFloor); 1875 | PRIM_METHOD_BIND(vm->numClass, "-", primNumNegate); 1876 | PRIM_METHOD_BIND(vm->numClass, "sin", primNumSin); 1877 | PRIM_METHOD_BIND(vm->numClass, "sqrt", primNumSqrt); 1878 | PRIM_METHOD_BIND(vm->numClass, "tan", primNumTan); 1879 | PRIM_METHOD_BIND(vm->numClass, "%(_)", primNumMod); 1880 | PRIM_METHOD_BIND(vm->numClass, "~", primNumBitNot); 1881 | PRIM_METHOD_BIND(vm->numClass, "..(_)", primNumRange); 1882 | PRIM_METHOD_BIND(vm->numClass, "atan(_)", primNumAtan2); 1883 | PRIM_METHOD_BIND(vm->numClass, "fraction", primNumFraction); 1884 | PRIM_METHOD_BIND(vm->numClass, "isInfinity", primNumIsInfinity); 1885 | PRIM_METHOD_BIND(vm->numClass, "isInteger", primNumIsInteger); 1886 | PRIM_METHOD_BIND(vm->numClass, "isNan", primNumIsNan); 1887 | PRIM_METHOD_BIND(vm->numClass, "toString", primNumToString); 1888 | PRIM_METHOD_BIND(vm->numClass, "truncate", primNumTruncate); 1889 | PRIM_METHOD_BIND(vm->numClass, "==(_)", primNumEqual); 1890 | PRIM_METHOD_BIND(vm->numClass, "!=(_)", primNumNotEqual); 1891 | 1892 | //字符串类 1893 | vm->stringClass = VALUE_TO_CLASS(getCoreClassValue(coreModule, "String")); 1894 | PRIM_METHOD_BIND(vm->stringClass->objHeader.class, "fromCodePoint(_)", primStringFromCodePoint); 1895 | PRIM_METHOD_BIND(vm->stringClass, "+(_)", primStringPlus); 1896 | PRIM_METHOD_BIND(vm->stringClass, "[_]", primStringSubscript); 1897 | PRIM_METHOD_BIND(vm->stringClass, "byteAt_(_)", primStringByteAt); 1898 | PRIM_METHOD_BIND(vm->stringClass, "byteCount_", primStringByteCount); 1899 | PRIM_METHOD_BIND(vm->stringClass, "codePointAt_(_)", primStringCodePointAt); 1900 | PRIM_METHOD_BIND(vm->stringClass, "contains(_)", primStringContains); 1901 | PRIM_METHOD_BIND(vm->stringClass, "endsWith(_)", primStringEndsWith); 1902 | PRIM_METHOD_BIND(vm->stringClass, "indexOf(_)", primStringIndexOf); 1903 | PRIM_METHOD_BIND(vm->stringClass, "iterate(_)", primStringIterate); 1904 | PRIM_METHOD_BIND(vm->stringClass, "iterateByte_(_)", primStringIterateByte); 1905 | PRIM_METHOD_BIND(vm->stringClass, "iteratorValue(_)", primStringIteratorValue); 1906 | PRIM_METHOD_BIND(vm->stringClass, "startsWith(_)", primStringStartsWith); 1907 | PRIM_METHOD_BIND(vm->stringClass, "toString", primStringToString); 1908 | PRIM_METHOD_BIND(vm->stringClass, "count", primStringByteCount); 1909 | 1910 | //List类 1911 | vm->listClass = VALUE_TO_CLASS(getCoreClassValue(coreModule, "List")); 1912 | PRIM_METHOD_BIND(vm->listClass->objHeader.class, "new()", primListNew); 1913 | PRIM_METHOD_BIND(vm->listClass, "[_]", primListSubscript); 1914 | PRIM_METHOD_BIND(vm->listClass, "[_]=(_)", primListSubscriptSetter); 1915 | PRIM_METHOD_BIND(vm->listClass, "add(_)", primListAdd); 1916 | PRIM_METHOD_BIND(vm->listClass, "addCore_(_)", primListAddCore); 1917 | PRIM_METHOD_BIND(vm->listClass, "clear()", primListClear); 1918 | PRIM_METHOD_BIND(vm->listClass, "count", primListCount); 1919 | PRIM_METHOD_BIND(vm->listClass, "insert(_,_)", primListInsert); 1920 | PRIM_METHOD_BIND(vm->listClass, "iterate(_)", primListIterate); 1921 | PRIM_METHOD_BIND(vm->listClass, "iteratorValue(_)", primListIteratorValue); 1922 | PRIM_METHOD_BIND(vm->listClass, "removeAt(_)", primListRemoveAt); 1923 | 1924 | //map类 1925 | vm->mapClass = VALUE_TO_CLASS(getCoreClassValue(coreModule, "Map")); 1926 | PRIM_METHOD_BIND(vm->mapClass->objHeader.class, "new()", primMapNew); 1927 | PRIM_METHOD_BIND(vm->mapClass, "[_]", primMapSubscript); 1928 | PRIM_METHOD_BIND(vm->mapClass, "[_]=(_)", primMapSubscriptSetter); 1929 | PRIM_METHOD_BIND(vm->mapClass, "addCore_(_,_)", primMapAddCore); 1930 | PRIM_METHOD_BIND(vm->mapClass, "clear()", primMapClear); 1931 | PRIM_METHOD_BIND(vm->mapClass, "containsKey(_)", primMapContainsKey); 1932 | PRIM_METHOD_BIND(vm->mapClass, "count", primMapCount); 1933 | PRIM_METHOD_BIND(vm->mapClass, "remove(_)", primMapRemove); 1934 | PRIM_METHOD_BIND(vm->mapClass, "iterate_(_)", primMapIterate); 1935 | PRIM_METHOD_BIND(vm->mapClass, "keyIteratorValue_(_)", primMapKeyIteratorValue); 1936 | PRIM_METHOD_BIND(vm->mapClass, "valueIteratorValue_(_)", primMapValueIteratorValue); 1937 | 1938 | //range类 1939 | vm->rangeClass = VALUE_TO_CLASS(getCoreClassValue(coreModule, "Range")); 1940 | PRIM_METHOD_BIND(vm->rangeClass, "from", primRangeFrom); 1941 | PRIM_METHOD_BIND(vm->rangeClass, "to", primRangeTo); 1942 | PRIM_METHOD_BIND(vm->rangeClass, "min", primRangeMin); 1943 | PRIM_METHOD_BIND(vm->rangeClass, "max", primRangeMax); 1944 | PRIM_METHOD_BIND(vm->rangeClass, "iterate(_)", primRangeIterate); 1945 | PRIM_METHOD_BIND(vm->rangeClass, "iteratorValue(_)", primRangeIteratorValue); 1946 | 1947 | //system类 1948 | Class* systemClass = VALUE_TO_CLASS(getCoreClassValue(coreModule, "System")); 1949 | PRIM_METHOD_BIND(systemClass->objHeader.class, "clock", primSystemClock); 1950 | PRIM_METHOD_BIND(systemClass->objHeader.class, "gc()", primSystemGC); 1951 | PRIM_METHOD_BIND(systemClass->objHeader.class, "importModule(_)", primSystemImportModule); 1952 | PRIM_METHOD_BIND(systemClass->objHeader.class, "getModuleVariable(_,_)", primSystemGetModuleVariable); 1953 | PRIM_METHOD_BIND(systemClass->objHeader.class, "writeString_(_)", primSystemWriteString); 1954 | 1955 | //在核心自举过程中创建了很多ObjString对象,创建过程中需要调用initObjHeader初始化对象头, 1956 | //使其class指向vm->stringClass.但那时的vm->stringClass尚未初始化,因此现在更正. 1957 | ObjHeader* objHeader = vm->allObjects; 1958 | while (objHeader != NULL) { 1959 | if (objHeader->type == OT_STRING) { 1960 | objHeader->class = vm->stringClass; 1961 | } 1962 | objHeader = objHeader->next; 1963 | } 1964 | } 1965 | -------------------------------------------------------------------------------- /vm/core.h: -------------------------------------------------------------------------------- 1 | #ifndef _VM_CORE_H 2 | #define _VM_CORE_H 3 | #include "vm.h" 4 | extern char* rootDir; 5 | char* readFile(const char* sourceFile); 6 | VMResult executeModule(VM* vm, Value moduleName, const char* moduleCode); 7 | int getIndexFromSymbolTable(SymbolTable* table, const char* symbol, uint32_t length); 8 | int addSymbol(VM* vm, SymbolTable* table, const char* symbol, uint32_t length); 9 | void buildCore(VM* vm); 10 | void bindMethod(VM* vm, Class* class, uint32_t index, Method method); 11 | void bindSuperClass(VM* vm, Class* subClass, Class* superClass); 12 | int ensureSymbolExist(VM* vm, SymbolTable* table, const char* symbol, uint32_t length); 13 | #endif 14 | -------------------------------------------------------------------------------- /vm/core.script.inc: -------------------------------------------------------------------------------- 1 | static const char* coreModuleCode = 2 | "class Null {}\n" 3 | "class Bool {}\n" 4 | "class Num {}\n" 5 | "class Fn {}\n" 6 | "class Thread {}\n" 7 | "\n" 8 | "class Sequence {\n" 9 | " all(f) {\n" 10 | " var result = true\n" 11 | " for element (this) {\n" 12 | " result = f.call(element)\n" 13 | " if (!result) return result\n" 14 | " }\n" 15 | " return result\n" 16 | " }\n" 17 | "\n" 18 | " any(f) {\n" 19 | " var result = false\n" 20 | " for element (this) {\n" 21 | " result = f.call(element)\n" 22 | " if (result) return result\n" 23 | " }\n" 24 | " return result\n" 25 | " }\n" 26 | "\n" 27 | " contains(element) {\n" 28 | " for item (this) if (element == item) return true\n" 29 | " return false\n" 30 | " }\n" 31 | "\n" 32 | " count {\n" 33 | " var result = 0\n" 34 | " for element (this) result = result + 1\n" 35 | " return result\n" 36 | " }\n" 37 | "\n" 38 | " count(f) {\n" 39 | " var result = 0\n" 40 | " for element (this) if (f.call(element)) result = result + 1\n" 41 | " return result\n" 42 | " }\n" 43 | "\n" 44 | " each(f) {\n" 45 | " for element (this) f.call(element)\n" 46 | " }\n" 47 | "\n" 48 | " isEmpty {\n" 49 | " return iterate(null) ? false : true\n" 50 | " }\n" 51 | "\n" 52 | " map(transformation) {\n" 53 | " return MapSequence.new(this, transformation)\n" 54 | " }\n" 55 | "\n" 56 | " where(predicate) {\n" 57 | " return WhereSequence.new(this, predicate)\n" 58 | " }\n" 59 | "\n" 60 | " reduce(acc, f) {\n" 61 | " for element (this) acc = f.call(acc, element)\n" 62 | " return acc\n" 63 | " }\n" 64 | "\n" 65 | " reduce(f) {\n" 66 | " var iter = iterate(null)\n" 67 | " if (!iter) Thread.abort(\"Can't reduce an empty sequence.\")\n" 68 | " var result = iteratorValue(iter)\n" 69 | " while (iter = iterate(iter)) result = f.call(result, iteratorValue(iter))\n" 70 | " return result\n" 71 | " }\n" 72 | "\n" 73 | " join(sep) {\n" 74 | " var first = true\n" 75 | " var result = \"\"\n" 76 | " for element (this) {\n" 77 | " if (!first) result = result + sep\n" 78 | " first = false\n" 79 | " result = result + element.toString\n" 80 | " }\n" 81 | " return result\n" 82 | " }\n" 83 | "\n" 84 | " join() {\n" 85 | " return join(\"\")\n" 86 | " }\n" 87 | "\n" 88 | " toList {\n" 89 | " var result = List.new()\n" 90 | " for element (this) result.add(element)\n" 91 | " return result\n" 92 | " }\n" 93 | "}\n" 94 | "\n" 95 | "class MapSequence < Sequence {\n" 96 | " var sequence\n" 97 | " var fn\n" 98 | " new(seq, f) {\n" 99 | " sequence = seq\n" 100 | " fn = f\n" 101 | " }\n" 102 | "\n" 103 | " iterate(iterator) { \n" 104 | " return sequence.iterate(iterator)\n" 105 | " }\n" 106 | " iteratorValue(iterator) {\n" 107 | " return fn.call(sequence.iteratorValue(iterator))\n" 108 | " }\n" 109 | "}\n" 110 | "\n" 111 | "class WhereSequence < Sequence {\n" 112 | " var sequence\n" 113 | " var fn\n" 114 | " new(seq, f) {\n" 115 | " sequence = seq\n" 116 | " fn = f\n" 117 | " }\n" 118 | "\n" 119 | " iterate(iterator) {\n" 120 | " while (iterator = sequence.iterate(iterator)) \n" 121 | " if (fn.call(sequence.iteratorValue(iterator))) break\n" 122 | " return iterator\n" 123 | " }\n" 124 | "\n" 125 | " iteratorValue(iterator) {\n" 126 | " return sequence.iteratorValue(iterator)\n" 127 | " }\n" 128 | "}\n" 129 | "\n" 130 | "class String < Sequence {\n" 131 | " bytes { \n" 132 | " return StringByteSequence.new(this)\n" 133 | " }\n" 134 | " codePoints {\n" 135 | " return StringCodePointSequence.new(this)\n" 136 | " }\n" 137 | "\n" 138 | " *(count) {\n" 139 | " if (!(count is num) || !count.isInteger || count < 0) \n" 140 | " Thread.abort(\"Count must be a non-negative integer.\")\n" 141 | " var result = \"\"\n" 142 | " for i (0..(count - 1)) result = result + this\n" 143 | " return result\n" 144 | " }\n" 145 | "}\n" 146 | "\n" 147 | "class StringByteSequence < Sequence {\n" 148 | " var string\n" 149 | " new(str) {\n" 150 | " string = str\n" 151 | " }\n" 152 | "\n" 153 | " [index] { \n" 154 | " return string.byteAt_(index)\n" 155 | " }\n" 156 | " iterate(iterator) {\n" 157 | " return string.iterateByte_(iterator) \n" 158 | " }\n" 159 | " iteratorValue(iterator) {\n" 160 | " return string.byteAt_(iterator) \n" 161 | " }\n" 162 | "\n" 163 | " count { \n" 164 | " return string.byteCount_ \n" 165 | " }\n" 166 | "}\n" 167 | "\n" 168 | "class StringCodePointSequence < Sequence {\n" 169 | " var string\n" 170 | " new(str) {\n" 171 | " string = str\n" 172 | " }\n" 173 | "\n" 174 | " [index] { \n" 175 | " return string.codePointAt_(index)\n" 176 | " }\n" 177 | " iterate(iterator) {\n" 178 | " return string.iterate(iterator) \n" 179 | " }\n" 180 | " iteratorValue(iterator) {\n" 181 | " return string.codePointAt_(iterator)\n" 182 | " }\n" 183 | "\n" 184 | " count {\n" 185 | " return string.count \n" 186 | " }\n" 187 | "}\n" 188 | "\n" 189 | "class List < Sequence {\n" 190 | " addAll(other) {\n" 191 | " for element (other) add(element)\n" 192 | " return other\n" 193 | " }\n" 194 | "\n" 195 | " toString {\n" 196 | " return \"[%(join(\",\"))]\" \n" 197 | " }\n" 198 | "\n" 199 | " +(other) {\n" 200 | " var result = this[0..-1]\n" 201 | " for element (other) result.add(element)\n" 202 | " return result\n" 203 | " }\n" 204 | "\n" 205 | " *(count) {\n" 206 | " if (!(count is num) || !count.isInteger || count < 0) \n" 207 | " Thread.abort(\"Count must be a non-negative integer.\")\n" 208 | " var result = []\n" 209 | " for i (0..(count - 1)) result.addAll(this)\n" 210 | " return result\n" 211 | " }\n" 212 | "}\n" 213 | "\n" 214 | "class Map {\n" 215 | " keys { \n" 216 | " return MapKeySequence.new(this) \n" 217 | " }\n" 218 | " values {\n" 219 | " return MapValueSequence.new(this)\n" 220 | " }\n" 221 | "\n" 222 | " toString {\n" 223 | " var first = true\n" 224 | " var result = \"{\"\n" 225 | "\n" 226 | " for key (keys) {\n" 227 | " if (!first) result = result + \", \"\n" 228 | " first = false\n" 229 | " result = result + \"%(key): %(this[key])\"\n" 230 | " }\n" 231 | "\n" 232 | " return result + \"}\"\n" 233 | " }\n" 234 | "}\n" 235 | "\n" 236 | "class MapKeySequence < Sequence {\n" 237 | " var map\n" 238 | " new(mp) {\n" 239 | " map = mp\n" 240 | " }\n" 241 | "\n" 242 | " iterate(n) {\n" 243 | " return map.iterate_(n) \n" 244 | " }\n" 245 | " iteratorValue(iterator) {\n" 246 | " return map.keyIteratorValue_(iterator)\n" 247 | " }\n" 248 | "}\n" 249 | "\n" 250 | "class MapValueSequence < Sequence {\n" 251 | " var map\n" 252 | " new(mp) {\n" 253 | " map = mp\n" 254 | " }\n" 255 | "\n" 256 | " iterate(n) {\n" 257 | " return map.iterate_(n) \n" 258 | " }\n" 259 | " iteratorValue(iterator) {\n" 260 | " return map.valueIteratorValue_(iterator) \n" 261 | " }\n" 262 | "}\n" 263 | "\n" 264 | "class Range < Sequence {}\n" 265 | "\n" 266 | "class System {\n" 267 | " static print() {\n" 268 | " writeString_(\"\n\")\n" 269 | " }\n" 270 | "\n" 271 | " static print(obj) {\n" 272 | " writeObject_(obj)\n" 273 | " writeString_(\"\n\")\n" 274 | " return obj\n" 275 | " }\n" 276 | "\n" 277 | " static printAll(sequence) {\n" 278 | " for object (sequence) writeObject_(object)\n" 279 | " writeString_(\"\n\")\n" 280 | " }\n" 281 | "\n" 282 | " static write(obj) {\n" 283 | " writeObject_(obj)\n" 284 | " return obj\n" 285 | " }\n" 286 | "\n" 287 | " static writeAll(sequence) {\n" 288 | " for object (sequence) writeObject_(object)\n" 289 | " }\n" 290 | "\n" 291 | " static writeObject_(obj) {\n" 292 | " var str = obj.toString\n" 293 | " if (str is String) {\n" 294 | " writeString_(str)\n" 295 | " } else {\n" 296 | " writeString_(\"[invalid toString]\")\n" 297 | " }\n" 298 | " }\n" 299 | "}\n"; 300 | -------------------------------------------------------------------------------- /vm/opcode.inc: -------------------------------------------------------------------------------- 1 | /***************** 有关栈slot说明 ***************** 2 | 1 基于栈的虚拟机, 操作数和运算结果都会保存在栈中. 3 | 2 运行时栈是由Value数组模拟的,栈中元素称为slot. 4 | 3 有的指令使栈空间增大一些slot,有的则减小一些slot. 5 | 4 函数中的局部变量也要存储在栈中. 6 | 综上,函数所需要的栈空间需要连同函数内所有操作码对栈空间的需求一并统计. 7 | 操作码的行为是一定的,对栈的影响也是一定的, 8 | 因此在定义操作码时,以slot为单位,一并描述操作码对栈空间大小的影响. 9 | 下面以此格式定义操作码及相应影响: 10 | 操作码 栈空间大小的影响(!!!注意,不是操作数) 11 | *************************************************/ 12 | OPCODE_SLOTS(LOAD_CONSTANT, 1) 13 | OPCODE_SLOTS(PUSH_NULL, 1) 14 | OPCODE_SLOTS(PUSH_FALSE, 1) 15 | OPCODE_SLOTS(PUSH_TRUE, 1) 16 | OPCODE_SLOTS(LOAD_LOCAL_VAR, 1) 17 | OPCODE_SLOTS(STORE_LOCAL_VAR, 0) 18 | OPCODE_SLOTS(LOAD_UPVALUE, 1) 19 | OPCODE_SLOTS(STORE_UPVALUE, 0) 20 | OPCODE_SLOTS(LOAD_MODULE_VAR, 1) 21 | OPCODE_SLOTS(STORE_MODULE_VAR, 0) 22 | OPCODE_SLOTS(LOAD_THIS_FIELD, 1) 23 | OPCODE_SLOTS(STORE_THIS_FIELD, 0) 24 | OPCODE_SLOTS(LOAD_FIELD, 0) 25 | OPCODE_SLOTS(STORE_FIELD, -1) 26 | OPCODE_SLOTS(POP, -1) 27 | OPCODE_SLOTS(CALL0, 0) 28 | OPCODE_SLOTS(CALL1, -1) 29 | OPCODE_SLOTS(CALL2, -2) 30 | OPCODE_SLOTS(CALL3, -3) 31 | OPCODE_SLOTS(CALL4, -4) 32 | OPCODE_SLOTS(CALL5, -5) 33 | OPCODE_SLOTS(CALL6, -6) 34 | OPCODE_SLOTS(CALL7, -7) 35 | OPCODE_SLOTS(CALL8, -8) 36 | OPCODE_SLOTS(CALL9, -9) 37 | OPCODE_SLOTS(CALL10, -10) 38 | OPCODE_SLOTS(CALL11, -11) 39 | OPCODE_SLOTS(CALL12, -12) 40 | OPCODE_SLOTS(CALL13, -13) 41 | OPCODE_SLOTS(CALL14, -14) 42 | OPCODE_SLOTS(CALL15, -15) 43 | OPCODE_SLOTS(CALL16, -16) 44 | OPCODE_SLOTS(SUPER0, 0) 45 | OPCODE_SLOTS(SUPER1, -1) 46 | OPCODE_SLOTS(SUPER2, -2) 47 | OPCODE_SLOTS(SUPER3, -3) 48 | OPCODE_SLOTS(SUPER4, -4) 49 | OPCODE_SLOTS(SUPER5, -5) 50 | OPCODE_SLOTS(SUPER6, -6) 51 | OPCODE_SLOTS(SUPER7, -7) 52 | OPCODE_SLOTS(SUPER8, -8) 53 | OPCODE_SLOTS(SUPER9, -9) 54 | OPCODE_SLOTS(SUPER10, -10) 55 | OPCODE_SLOTS(SUPER11, -11) 56 | OPCODE_SLOTS(SUPER12, -12) 57 | OPCODE_SLOTS(SUPER13, -13) 58 | OPCODE_SLOTS(SUPER14, -14) 59 | OPCODE_SLOTS(SUPER15, -15) 60 | OPCODE_SLOTS(SUPER16, -16) 61 | OPCODE_SLOTS(JUMP, 0) 62 | OPCODE_SLOTS(LOOP, 0) 63 | OPCODE_SLOTS(JUMP_IF_FALSE, -1) 64 | OPCODE_SLOTS(AND, -1) 65 | OPCODE_SLOTS(OR, -1) 66 | OPCODE_SLOTS(CLOSE_UPVALUE, -1) 67 | OPCODE_SLOTS(RETURN, 0) 68 | OPCODE_SLOTS(CREATE_CLOSURE, 1) 69 | OPCODE_SLOTS(CONSTRUCT, 0) 70 | OPCODE_SLOTS(CREATE_CLASS, -1) 71 | OPCODE_SLOTS(INSTANCE_METHOD, -2) 72 | OPCODE_SLOTS(STATIC_METHOD, -2) 73 | OPCODE_SLOTS(END, 0) 74 | -------------------------------------------------------------------------------- /vm/vm.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | #include 3 | #include "core.h" 4 | #include "compiler.h" 5 | #ifdef DEBUG 6 | #include "debug.h" 7 | #endif 8 | #include "gc.h" 9 | #include "class.h" 10 | 11 | //把obj做为临时的根对象,就是把obj添加为gc的白名单,避免被gc回收 12 | void pushTmpRoot(VM* vm, ObjHeader* obj) { 13 | ASSERT(obj != NULL, "root obj is null!"); 14 | ASSERT(vm->tmpRootNum < MAX_TEMP_ROOTS_NUM, "temporary roots too much!"); 15 | vm->tmpRoots[vm->tmpRootNum++] = obj; 16 | } 17 | 18 | //去掉临时的根对象 19 | void popTmpRoot(VM* vm) { 20 | ASSERT(vm->tmpRootNum < MAX_TEMP_ROOTS_NUM, "temporary roots too much!"); 21 | vm->tmpRootNum--; 22 | } 23 | 24 | //初始化虚拟机 25 | void initVM(VM* vm) { 26 | vm->allocatedBytes = 0; 27 | vm->allObjects = NULL; 28 | vm->curParser = NULL; 29 | StringBufferInit(&vm->allMethodNames); 30 | vm->allModules = newObjMap(vm); 31 | vm->curParser = NULL; 32 | vm->config.heapGrowthFactor = 1.5; 33 | 34 | //最小堆大小为1MB 35 | vm->config.minHeapSize = 1024 * 1024; 36 | //初始堆大小为10MB 37 | vm->config.initialHeapSize = 1024 * 1024 * 10; 38 | 39 | vm->config.nextGC = vm->config.initialHeapSize; 40 | vm->grays.count = 0; 41 | vm->grays.capacity = 32; 42 | 43 | //初始化指针数组grayObjects 44 | vm->grays.grayObjects = 45 | (ObjHeader**)malloc(vm->grays.capacity * sizeof(ObjHeader*)); 46 | } 47 | 48 | //新建虚拟机 49 | VM* newVM() { 50 | VM* vm = (VM*)malloc(sizeof(VM)); 51 | if (vm == NULL) { 52 | MEM_ERROR("allocate VM failed!"); 53 | } 54 | initVM(vm); 55 | buildCore(vm); 56 | return vm; 57 | } 58 | 59 | //释放虚拟机vm 60 | void freeVM(VM* vm) { 61 | ASSERT(vm->allMethodNames.count > 0, "VM have already been freed!"); 62 | 63 | //释放所有的对象 64 | ObjHeader* objHeader = vm->allObjects; 65 | while (objHeader != NULL) { 66 | //释放之前先备份下一个结点地址 67 | ObjHeader* next = objHeader->next; 68 | freeObject(vm, objHeader); 69 | objHeader = next; 70 | } 71 | 72 | vm->grays.grayObjects = DEALLOCATE(vm, vm->grays.grayObjects); 73 | StringBufferClear(vm, &vm->allMethodNames); 74 | DEALLOCATE(vm, vm); 75 | } 76 | 77 | //确保stack有效 78 | void ensureStack(VM* vm, ObjThread* objThread, uint32_t neededSlots) { 79 | if (objThread->stackCapacity >= neededSlots) { 80 | return; 81 | } 82 | 83 | uint32_t newStackCapacity = ceilToPowerOf2(neededSlots); 84 | ASSERT(newStackCapacity > objThread->stackCapacity, "newStackCapacity error!"); 85 | 86 | //记录原栈底以用于下面判断扩容后的栈是否是原地扩容 87 | Value* oldStackBottom = objThread->stack; 88 | 89 | uint32_t slotSize = sizeof(Value); 90 | objThread->stack = (Value*)memManager(vm, objThread->stack, 91 | objThread->stackCapacity * slotSize, newStackCapacity * slotSize); 92 | objThread->stackCapacity = newStackCapacity; 93 | 94 | //为判断是否原地扩容 95 | long offset = objThread->stack - oldStackBottom; 96 | 97 | //说明os无法在原地满足内存需求, 重新分配了起始地址,下面要调整 98 | if (offset != 0) { 99 | //调整各堆栈框架的地址 100 | uint32_t idx = 0; 101 | while (idx < objThread->usedFrameNum) { 102 | objThread->frames[idx++].stackStart += offset; 103 | } 104 | 105 | //调整"open upValue" 106 | ObjUpvalue* upvalue = objThread->openUpvalues; 107 | while (upvalue != NULL) { 108 | upvalue->localVarPtr += offset; 109 | upvalue = upvalue->next; 110 | } 111 | 112 | //更新栈顶 113 | objThread->esp += offset; 114 | } 115 | } 116 | 117 | //为objClosure在objThread中创建运行时栈 118 | inline static void createFrame(VM* vm, ObjThread* objThread, 119 | ObjClosure* objClosure, int argNum) { 120 | 121 | if (objThread->usedFrameNum + 1 > objThread->frameCapacity) { //扩容 122 | uint32_t newCapacity = objThread->frameCapacity * 2; 123 | uint32_t frameSize = sizeof(Frame); 124 | objThread->frames = (Frame*)memManager(vm, objThread->frames, 125 | frameSize * objThread->frameCapacity, frameSize * newCapacity); 126 | objThread->frameCapacity = newCapacity; 127 | } 128 | 129 | //栈大小等于栈顶-栈底 130 | uint32_t stackSlots = (uint32_t)(objThread->esp - objThread->stack); 131 | //总共需要的栈大小 132 | uint32_t neededSlots = stackSlots + objClosure->fn->maxStackSlotUsedNum; 133 | 134 | ensureStack(vm, objThread, neededSlots); 135 | 136 | //准备上cpu 137 | prepareFrame(objThread, objClosure, objThread->esp - argNum); 138 | } 139 | 140 | //关闭在栈中slot为lastSlot及之上的upvalue 141 | static void closeUpvalue(ObjThread* objThread, Value* lastSlot) { 142 | ObjUpvalue* upvalue = objThread->openUpvalues; 143 | while (upvalue != NULL && upvalue->localVarPtr >= lastSlot) { 144 | //localVarPtr改指向本结构中的closedUpvalue 145 | upvalue->closedUpvalue = *(upvalue->localVarPtr); 146 | upvalue->localVarPtr = &(upvalue->closedUpvalue); 147 | 148 | upvalue = upvalue->next; 149 | } 150 | objThread->openUpvalues = upvalue; 151 | } 152 | 153 | //创建线程已打开的upvalue链表,并将localVarPtr所属的upvalue以降序插入到该链表 154 | static ObjUpvalue* createOpenUpvalue(VM* vm, ObjThread* objThread, Value* localVarPtr) { 155 | //如果openUpvalues链表为空就创建 156 | if (objThread->openUpvalues == NULL) { 157 | objThread->openUpvalues = newObjUpvalue(vm, localVarPtr); 158 | return objThread->openUpvalues; 159 | } 160 | 161 | //下面以upvalue.localVarPtr降序组织openUpvalues 162 | ObjUpvalue* preUpvalue = NULL; 163 | ObjUpvalue* upvalue = objThread->openUpvalues; 164 | 165 | //后面的代码保证了openUpvalues按照降顺组织, 166 | //下面向堆栈的底部遍历,直到找到合适的插入位置 167 | while (upvalue != NULL && upvalue->localVarPtr > localVarPtr) { 168 | preUpvalue = upvalue; 169 | upvalue = upvalue->next; 170 | } 171 | 172 | //如果之前已经插入了该upvalue则返回 173 | if (upvalue != NULL && upvalue->localVarPtr == localVarPtr) { 174 | return upvalue; 175 | } 176 | 177 | //openUpvalues中未找到该upvalue, 178 | //现在就创建新upvalue,按照降序插入到链表 179 | ObjUpvalue* newUpvalue = newObjUpvalue(vm, localVarPtr); 180 | 181 | //保证了openUpvalues首结点upvalue->localVarPtr的值是最高的 182 | if (preUpvalue == NULL) { 183 | //说明上面while的循环体未执行,新结点(形参localVarPtr)的值大于等于链表首结点 184 | //因此使链表结点指向它所在的新upvalue结点 185 | objThread->openUpvalues = newUpvalue; 186 | } else { 187 | //preUpvalue已处于正确的位置 188 | preUpvalue->next = newUpvalue; 189 | } 190 | newUpvalue->next = upvalue; 191 | 192 | return newUpvalue;//返回该结点 193 | } 194 | 195 | //校验基类合法性 196 | static void validateSuperClass(VM* vm, Value classNameValue, 197 | uint32_t fieldNum, Value superClassValue) { 198 | 199 | //首先确保superClass的类型得是class 200 | if (!VALUE_IS_CLASS(superClassValue)) { 201 | ObjString* classNameString = VALUE_TO_OBJSTR(classNameValue); 202 | RUN_ERROR("class \"%s\" `s superClass is not a valid class!", 203 | classNameString->value.start); 204 | } 205 | 206 | Class* superClass = VALUE_TO_CLASS(superClassValue); 207 | 208 | //基类不允许为内建类 209 | if (superClass == vm->stringClass || 210 | superClass == vm->mapClass || 211 | superClass == vm->rangeClass || 212 | superClass == vm->listClass || 213 | superClass == vm->nullClass || 214 | superClass == vm->boolClass || 215 | superClass == vm->numClass || 216 | superClass == vm->fnClass || 217 | superClass == vm->threadClass 218 | ) { 219 | RUN_ERROR("superClass mustn`t be a buildin class!"); 220 | } 221 | 222 | //子类也要继承基类的域, 223 | //故子类自己的域+基类域的数量不可超过MAX_FIELD_NUM 224 | if (superClass->fieldNum + fieldNum > MAX_FIELD_NUM) { 225 | RUN_ERROR("number of field including super exceed %d!", MAX_FIELD_NUM); 226 | } 227 | } 228 | 229 | //修正部分指令操作数 230 | static void patchOperand(Class* class, ObjFn* fn) { 231 | int ip = 0; 232 | OpCode opCode; 233 | while (true) { 234 | opCode = (OpCode)fn->instrStream.datas[ip++]; 235 | switch (opCode) { 236 | 237 | case OPCODE_LOAD_FIELD: 238 | case OPCODE_STORE_FIELD: 239 | case OPCODE_LOAD_THIS_FIELD: 240 | case OPCODE_STORE_THIS_FIELD: 241 | //修正子类的field数目 参数是1字节 242 | fn->instrStream.datas[ip++] += class->superClass->fieldNum; 243 | break; 244 | 245 | case OPCODE_SUPER0: 246 | case OPCODE_SUPER1: 247 | case OPCODE_SUPER2: 248 | case OPCODE_SUPER3: 249 | case OPCODE_SUPER4: 250 | case OPCODE_SUPER5: 251 | case OPCODE_SUPER6: 252 | case OPCODE_SUPER7: 253 | case OPCODE_SUPER8: 254 | case OPCODE_SUPER9: 255 | case OPCODE_SUPER10: 256 | case OPCODE_SUPER11: 257 | case OPCODE_SUPER12: 258 | case OPCODE_SUPER13: 259 | case OPCODE_SUPER14: 260 | case OPCODE_SUPER15: 261 | case OPCODE_SUPER16: { 262 | //指令流1: 2字节的method索引 263 | //指令流2: 2字节的基类常量索引 264 | 265 | ip += 2; //跳过2字节的method索引 266 | uint32_t superClassIdx = 267 | (fn->instrStream.datas[ip] << 8) | fn->instrStream.datas[ip + 1]; 268 | 269 | //回填在函数emitCallBySignature中的占位VT_TO_VALUE(VT_NULL) 270 | fn->constants.datas[superClassIdx] = OBJ_TO_VALUE(class->superClass); 271 | 272 | ip += 2; //跳过2字节的基类索引 273 | 274 | break; 275 | } 276 | 277 | case OPCODE_CREATE_CLOSURE: { 278 | //指令流: 2字节待创建闭包的函数在常量表中的索引+函数所用的upvalue数 * 2 279 | 280 | //函数是存储到常量表中,获取待创建闭包的函数在常量表中的索引 281 | uint32_t fnIdx = (fn->instrStream.datas[ip] << 8) | fn->instrStream.datas[ip + 1]; 282 | 283 | //递归进入该函数的指令流,继续为其中的super和field修正操作数 284 | patchOperand(class, VALUE_TO_OBJFN(fn->constants.datas[fnIdx])); 285 | 286 | //ip-1是操作码OPCODE_CREATE_CLOSURE, 287 | //闭包中的参数涉及到upvalue,调用getBytesOfOperands获得参数字节数 288 | ip += getBytesOfOperands(fn->instrStream.datas, fn->constants.datas, ip - 1); 289 | 290 | break; 291 | } 292 | 293 | case OPCODE_END: 294 | //用于从当前及递归嵌套闭包时返回 295 | return; 296 | 297 | default: 298 | //其它指令不需要回填因此就跳过 299 | ip += getBytesOfOperands(fn->instrStream.datas, fn->constants.datas, ip - 1); 300 | break; 301 | } 302 | } 303 | } 304 | 305 | //绑定方法和修正操作数 306 | static void bindMethodAndPatch(VM* vm, OpCode opCode, 307 | uint32_t methodIndex, Class* class, Value methodValue) { 308 | 309 | //如果是静态方法,就将类指向meta类(使接收者为meta类) 310 | if (opCode == OPCODE_STATIC_METHOD) { 311 | class = class->objHeader.class; 312 | } 313 | 314 | Method method; 315 | method.type = MT_SCRIPT; 316 | method.obj = VALUE_TO_OBJCLOSURE(methodValue); 317 | 318 | //修正操作数 319 | patchOperand(class, method.obj->fn); 320 | 321 | //修正过后,绑定method到class 322 | bindMethod(vm, class, methodIndex, method); 323 | } 324 | 325 | //执行指令 326 | VMResult executeInstruction(VM* vm, register ObjThread* curThread) { 327 | vm->curThread = curThread; 328 | register Frame* curFrame; 329 | register Value* stackStart; 330 | register uint8_t* ip; 331 | register ObjFn* fn; 332 | OpCode opCode; 333 | 334 | //定义操作运行时栈的宏 335 | //esp是栈中下一个可写入数据的slot 336 | #define PUSH(value) (*curThread->esp++ = value) //压栈 337 | #define POP() (*(--curThread->esp)) //出栈 338 | #define DROP() (curThread->esp--) 339 | #define PEEK() (*(curThread->esp - 1)) // 获得栈顶的数据 340 | #define PEEK2() (*(curThread->esp - 2)) // 获得次栈顶的数据 341 | 342 | //下面是读取指令流:objfn.instrStream.datas 343 | #define READ_BYTE() (*ip++) //从指令流中读取一字节 344 | //读取指令流中的2字节 345 | #define READ_SHORT() (ip += 2, (uint16_t)((ip[-2] << 8) | ip[-1])) 346 | 347 | //当前指令单元执行的进度就是在指令流中的指针,即ip,将其保存起来 348 | #define STORE_CUR_FRAME() curFrame->ip = ip // 备份ip以能回到当前 349 | 350 | //加载最新的frame 351 | #define LOAD_CUR_FRAME() \ 352 | /* frames是数组,索引从0起,故usedFrameNum-1 */ \ 353 | curFrame = &curThread->frames[curThread->usedFrameNum - 1]; \ 354 | stackStart = curFrame->stackStart; \ 355 | ip = curFrame->ip; \ 356 | fn = curFrame->closure->fn; 357 | 358 | #define DECODE loopStart: \ 359 | opCode = READ_BYTE();\ 360 | switch (opCode) 361 | 362 | #define CASE(shortOpCode) case OPCODE_##shortOpCode 363 | #define LOOP() goto loopStart 364 | 365 | LOAD_CUR_FRAME(); 366 | DECODE { 367 | //若OPCODE依赖于指令环境(栈和指令流),会在各OPCODE下说明 368 | 369 | CASE(LOAD_LOCAL_VAR): 370 | //指令流: 1字节的局部变量索引 371 | 372 | PUSH(stackStart[READ_BYTE()]); 373 | LOOP(); 374 | 375 | CASE(LOAD_THIS_FIELD): { 376 | //指令流: 1字节的field索引 377 | 378 | uint8_t fieldIdx = READ_BYTE(); 379 | 380 | //stackStart[0]是实例对象this 381 | ASSERT(VALUE_IS_OBJINSTANCE(stackStart[0]), "method receiver should be objInstance."); 382 | ObjInstance* objInstance = VALUE_TO_OBJINSTANCE(stackStart[0]); 383 | 384 | ASSERT(fieldIdx < objInstance->objHeader.class->fieldNum, "out of bounds field!"); 385 | PUSH(objInstance->fields[fieldIdx]); 386 | LOOP(); 387 | } 388 | 389 | CASE(POP): 390 | DROP(); 391 | LOOP(); 392 | 393 | CASE(PUSH_NULL): 394 | PUSH(VT_TO_VALUE(VT_NULL)); 395 | LOOP(); 396 | 397 | CASE(PUSH_FALSE): 398 | PUSH(VT_TO_VALUE(VT_FALSE)); 399 | LOOP(); 400 | 401 | CASE(PUSH_TRUE): 402 | PUSH(VT_TO_VALUE(VT_TRUE)); 403 | LOOP(); 404 | 405 | CASE(STORE_LOCAL_VAR): 406 | //栈顶: 局部变量值 407 | //指令流: 1字节的局部变量索引 408 | 409 | //将PEEK()得到的栈顶数据写入指令参数(即READ_BYTE()得到的值)为索引的栈的slot中 410 | stackStart[READ_BYTE()] = PEEK(); 411 | LOOP(); 412 | 413 | CASE(LOAD_CONSTANT): 414 | //指令流: 2字节的常量索引 415 | 416 | //加载常量就是把常量表中的数据入栈 417 | PUSH(fn->constants.datas[READ_SHORT()]); 418 | LOOP(); 419 | 420 | { 421 | int argNum, index; 422 | Value* args; 423 | Class* class; 424 | Method* method; 425 | 426 | CASE(CALL0): 427 | CASE(CALL1): 428 | CASE(CALL2): 429 | CASE(CALL3): 430 | CASE(CALL4): 431 | CASE(CALL5): 432 | CASE(CALL6): 433 | CASE(CALL7): 434 | CASE(CALL8): 435 | CASE(CALL9): 436 | CASE(CALL10): 437 | CASE(CALL11): 438 | CASE(CALL12): 439 | CASE(CALL13): 440 | CASE(CALL14): 441 | CASE(CALL15): 442 | CASE(CALL16): 443 | //指令流1: 2字节的method索引 444 | //因为还有个隐式的receiver(就是下面的args[0]), 所以参数个数+1. 445 | argNum = opCode - OPCODE_CALL0 + 1; 446 | 447 | //读取2字节的数据(CALL指令的操作数),index是方法名的索引 448 | index = READ_SHORT(); 449 | 450 | //为参数指针数组args赋值 451 | args = curThread->esp - argNum; 452 | 453 | //获得方法所在的类 454 | class = getClassOfObj(vm, args[0]); 455 | goto invokeMethod; 456 | 457 | CASE(SUPER0): 458 | CASE(SUPER1): 459 | CASE(SUPER2): 460 | CASE(SUPER3): 461 | CASE(SUPER4): 462 | CASE(SUPER5): 463 | CASE(SUPER6): 464 | CASE(SUPER7): 465 | CASE(SUPER8): 466 | CASE(SUPER9): 467 | CASE(SUPER10): 468 | CASE(SUPER11): 469 | CASE(SUPER12): 470 | CASE(SUPER13): 471 | CASE(SUPER14): 472 | CASE(SUPER15): 473 | CASE(SUPER16): 474 | //指令流1: 2字节的method索引 475 | //指令流2: 2字节的基类常量索引 476 | 477 | //因为还有个隐式的receiver(就是下面的args[0]), 所以参数个数+1. 478 | argNum = opCode - OPCODE_SUPER0 + 1; 479 | index = READ_SHORT(); 480 | args = curThread->esp - argNum; 481 | 482 | //在函数bindMethodAndPatch中实现的基类的绑定 483 | class = VALUE_TO_CLASS(fn->constants.datas[READ_SHORT()]); 484 | 485 | invokeMethod: 486 | if ((uint32_t)index > class->methods.count || 487 | (method = &class->methods.datas[index])->type == MT_NONE) { 488 | RUN_ERROR("method \"%s\" not found!", vm->allMethodNames.datas[index].str); 489 | } 490 | 491 | switch (method->type) { 492 | case MT_PRIMITIVE: 493 | 494 | //如果返回值为true,则vm进行空间回收的工作 495 | if (method->primFn(vm, args)) { 496 | //args[0]是返回值, argNum-1是保留args[0], 497 | //args[0]的空间最终由返回值的接收者即函数的主调方回收 498 | curThread->esp -= argNum - 1; 499 | } else { 500 | //如果返回false则说明有两种情况: 501 | // 1 出错(比如原生函数primThreadAbort使线程报错或无错退出), 502 | // 2 或者切换了线程,此时vm->curThread已经被切换为新的线程 503 | //保存线程的上下文环境,运行新线程之后还能回到当前老线程指令流的正确位置 504 | STORE_CUR_FRAME(); 505 | 506 | if (!VALUE_IS_NULL(curThread->errorObj)) { 507 | if (VALUE_IS_OBJSTR(curThread->errorObj)) { 508 | ObjString* err = VALUE_TO_OBJSTR(curThread->errorObj); 509 | printf("%s", err->value.start); 510 | } 511 | //出错后将返回值置为null,避免主调方获取到错误的结果 512 | PEEK() = VT_TO_VALUE(VT_NULL); 513 | } 514 | 515 | //如果没有待执行的线程,说明执行完毕 516 | if (vm->curThread == NULL) { 517 | return VM_RESULT_SUCCESS; 518 | } 519 | 520 | //vm->curThread已经由返回false的函数置为下一个线程 521 | //切换到下一个线程的上下文 522 | curThread = vm->curThread; 523 | LOAD_CUR_FRAME(); 524 | } 525 | break; 526 | 527 | case MT_SCRIPT: 528 | STORE_CUR_FRAME(); 529 | createFrame(vm, curThread, (ObjClosure*)method->obj, argNum); 530 | LOAD_CUR_FRAME(); //加载最新的frame 531 | break; 532 | 533 | case MT_FN_CALL: 534 | ASSERT(VALUE_IS_OBJCLOSURE(args[0]), "instance must be a closure!"); 535 | ObjFn* objFn = VALUE_TO_OBJCLOSURE(args[0])->fn; 536 | //-1是去掉实例this 537 | if (argNum - 1 < objFn->argNum) { 538 | RUN_ERROR("arguments less"); 539 | } 540 | 541 | STORE_CUR_FRAME(); 542 | createFrame(vm, curThread, VALUE_TO_OBJCLOSURE(args[0]), argNum); 543 | LOAD_CUR_FRAME(); //加载最新的frame 544 | break; 545 | 546 | default: 547 | NOT_REACHED(); 548 | } 549 | 550 | LOOP(); 551 | } 552 | 553 | CASE(LOAD_UPVALUE): 554 | //指令流: 1字节的upvalue索引 555 | PUSH(*((curFrame->closure->upvalues[READ_BYTE()])->localVarPtr)); 556 | LOOP(); 557 | 558 | CASE(STORE_UPVALUE): 559 | //栈顶: upvalue值 560 | //指令流: 1字节的upvalue索引 561 | 562 | *((curFrame->closure->upvalues[READ_BYTE()])->localVarPtr) = PEEK(); 563 | LOOP(); 564 | 565 | CASE(LOAD_MODULE_VAR): 566 | //指令流: 2字节的模块变量索引 567 | 568 | PUSH(fn->module->moduleVarValue.datas[READ_SHORT()]); 569 | LOOP(); 570 | 571 | CASE(STORE_MODULE_VAR): 572 | //栈顶: 模块变量值 573 | 574 | fn->module->moduleVarValue.datas[READ_SHORT()] = PEEK(); 575 | LOOP(); 576 | 577 | CASE(STORE_THIS_FIELD): { 578 | //栈顶: field值 579 | //指令流: 1字节的field索引 580 | 581 | uint8_t fieldIdx = READ_BYTE(); 582 | ASSERT(VALUE_IS_OBJINSTANCE(stackStart[0]), "receiver should be instance!"); 583 | ObjInstance* objInstance = VALUE_TO_OBJINSTANCE(stackStart[0]); 584 | ASSERT(fieldIdx < objInstance->objHeader.class->fieldNum, "out of bounds field!"); 585 | objInstance->fields[fieldIdx] = PEEK(); 586 | LOOP(); 587 | } 588 | 589 | CASE(LOAD_FIELD): { 590 | //栈顶:实例对象 591 | //指令流: 1字节的field索引 592 | 593 | uint8_t fieldIdx = READ_BYTE(); //获取待加载的字段索引 594 | Value receiver = POP(); //获取消息接收者 595 | ASSERT(VALUE_IS_OBJINSTANCE(receiver), "receiver should be instance!"); 596 | ObjInstance* objInstance = VALUE_TO_OBJINSTANCE(receiver); 597 | ASSERT(fieldIdx < objInstance->objHeader.class->fieldNum, "out of bounds field!"); 598 | PUSH(objInstance->fields[fieldIdx]); 599 | LOOP(); 600 | } 601 | 602 | CASE(STORE_FIELD): { 603 | //栈顶:实例对象 次栈顶:filed值 604 | //指令流: 1字节的field索引 605 | 606 | uint8_t fieldIdx = READ_BYTE(); //获取待加载的字段索引 607 | Value receiver = POP(); //获取消息接收者 608 | ASSERT(VALUE_IS_OBJINSTANCE(receiver), "receiver should be instance!"); 609 | ObjInstance* objInstance = VALUE_TO_OBJINSTANCE(receiver); 610 | ASSERT(fieldIdx < objInstance->objHeader.class->fieldNum, "out of bounds field!"); 611 | objInstance->fields[fieldIdx] = PEEK(); 612 | LOOP(); 613 | } 614 | 615 | CASE(JUMP): { 616 | //指令流: 2字节的跳转正偏移量 617 | 618 | int16_t offset = READ_SHORT(); 619 | ASSERT(offset > 0, "OPCODE_JUMP`s operand must be positive!"); 620 | ip += offset; 621 | LOOP(); 622 | } 623 | 624 | CASE(LOOP): { 625 | //指令流: 2字节的跳转正偏移量 626 | 627 | int16_t offset = READ_SHORT(); 628 | ASSERT(offset > 0, "OPCODE_LOOP`s operand must be positive!"); 629 | ip -= offset; 630 | LOOP(); 631 | } 632 | 633 | CASE(JUMP_IF_FALSE): { 634 | //栈顶: 跳转条件bool值 635 | //指令流: 2字节的跳转偏移量 636 | 637 | int16_t offset = READ_SHORT(); 638 | ASSERT(offset > 0, "OPCODE_JUMP_IF_FALSE`s operand must be positive!"); 639 | Value condition = POP(); 640 | if (VALUE_IS_FALSE(condition) || VALUE_IS_NULL(condition)) { 641 | ip += offset; 642 | } 643 | LOOP(); 644 | } 645 | 646 | CASE(AND): { 647 | //栈顶: 跳转条件bool值 648 | //指令流: 2字节的跳转偏移量 649 | 650 | int16_t offset = READ_SHORT(); 651 | ASSERT(offset > 0, "OPCODE_AND`s operand must be positive!"); 652 | Value condition = PEEK(); 653 | 654 | if (VALUE_IS_FALSE(condition) || VALUE_IS_NULL(condition)) { 655 | //若条件为假则不再计算and的右操作数,跳过右操作数的计算指令 656 | ip += offset; 657 | } else { 658 | //若条件为真则继续执行and右边的表达式计算步骤,丢掉栈顶的条件 659 | DROP(); 660 | } 661 | LOOP(); 662 | } 663 | 664 | CASE(OR): { 665 | //栈顶: 跳转条件bool值 666 | //指令流: 2字节的跳转偏移量 667 | 668 | int16_t offset = READ_SHORT(); 669 | ASSERT(offset > 0, "OPCODE_OR`s operand must be positive!"); 670 | Value condition = PEEK(); 671 | 672 | if (VALUE_IS_FALSE(condition) || VALUE_IS_NULL(condition)) { 673 | //若条件为假或空则执行or右操作数的计算步骤,丢掉跳转条件 674 | DROP(); 675 | } else { 676 | //若条件为真则跳过or右边的表达式,无须计算 677 | ip += offset; 678 | } 679 | LOOP(); 680 | } 681 | 682 | CASE(CLOSE_UPVALUE): 683 | //栈顶: 相当于局部变量 684 | //把地址大于栈顶局部变量的upvalue关闭 685 | closeUpvalue(curThread, curThread->esp - 1); 686 | DROP(); //弹出栈顶局部变量 687 | LOOP(); 688 | 689 | CASE(RETURN): { 690 | //栈顶: 返回值 691 | 692 | //获取返回值 693 | Value retVal = POP(); 694 | 695 | //return是从函数返回 故该堆栈框架使用完毕,增加可用堆栈框架数量 696 | curThread->usedFrameNum--; 697 | 698 | //关闭堆栈框架即此作用域内所有upvalue 699 | closeUpvalue(curThread, stackStart); 700 | 701 | //如果一个堆栈框架都没用, 702 | //说明它没有调用函数或者所有的函数调用都返回了,可以结束它 703 | if (curThread->usedFrameNum == 0) { 704 | //如果并不是被另一线程调用的,就直接结束 705 | if (curThread->caller == NULL) { 706 | curThread->stack[0] = retVal; 707 | 708 | //保留stack[0]中的结果,其它都丢弃 709 | curThread->esp = curThread->stack + 1; 710 | return VM_RESULT_SUCCESS; 711 | } 712 | 713 | //恢复主调方线程的调度 714 | ObjThread* callerThread = curThread->caller; 715 | curThread->caller = NULL; 716 | curThread = callerThread; 717 | vm->curThread = callerThread; 718 | 719 | //在主调线程的栈顶存储被调线程的执行结果 720 | curThread->esp[-1] = retVal; 721 | } else { 722 | //将返回值置于运行时栈栈顶 723 | stackStart[0] = retVal; 724 | //回收堆栈:保留除结果所在的slot即stackStart[0] 其它全丢弃 725 | curThread->esp = stackStart + 1; 726 | } 727 | 728 | LOAD_CUR_FRAME(); 729 | LOOP(); 730 | } 731 | 732 | CASE(CONSTRUCT): { 733 | //栈底: startStart[0]是class 734 | 735 | ASSERT(VALUE_IS_CLASS(stackStart[0]), 736 | "stackStart[0] should be a class for OPCODE_CONSTRUCT!"); 737 | 738 | //将创建的类实例存储到stackStart[0],即this 739 | ObjInstance* objInstance = newObjInstance(vm, VALUE_TO_CLASS(stackStart[0])); 740 | //此时stackStart[0]是类,其类名便是方法所定义的类 741 | //把对象写入stackStart[0] 742 | stackStart[0] = OBJ_TO_VALUE(objInstance); 743 | 744 | LOOP(); 745 | } 746 | 747 | CASE(CREATE_CLOSURE): { 748 | //指令流: 2字节待创建闭包的函数在常量表中的索引+函数所用的upvalue数 * 2 749 | 750 | //endCompileUnit已经将闭包函数添加进了常量表 751 | ObjFn* objFn = VALUE_TO_OBJFN(fn->constants.datas[READ_SHORT()]); 752 | ObjClosure* objClosure = newObjClosure(vm, objFn); 753 | //将创建好的闭包的value结构压到栈顶, 754 | //后续会有函数如defineMethod从栈底取出 755 | //先将其压到栈中,后面再创建upvalue,这样可避免在创建upvalue过程中被GC 756 | PUSH(OBJ_TO_VALUE(objClosure)); 757 | 758 | uint32_t idx = 0; 759 | while (idx < objFn->upvalueNum) { 760 | //读入endCompilerUnit函数最后为每个upvale写入的数据对儿 761 | uint8_t isEnclosingLocalVar = READ_BYTE(); 762 | uint8_t index = READ_BYTE(); 763 | 764 | if (isEnclosingLocalVar) { //是直接外层的局部变量 765 | //创建upvalue 766 | objClosure->upvalues[idx] = 767 | createOpenUpvalue(vm, curThread, curFrame->stackStart + index); 768 | } else { 769 | //直接从父编译单元中继承 770 | objClosure->upvalues[idx] = curFrame->closure->upvalues[index]; 771 | } 772 | idx++; 773 | } 774 | 775 | LOOP(); 776 | } 777 | 778 | CASE(CREATE_CLASS): { 779 | //指令流: 1字节的field数量 780 | //栈顶: 基类 次栈顶: 子类名 781 | 782 | uint32_t fieldNum = READ_BYTE(); 783 | Value superClass = curThread->esp[-1]; //基类名 784 | Value className = curThread->esp[-2]; //子类名 785 | 786 | //回收基类所占的栈空间, 787 | //次栈顶的空间暂时保留,创建的类会直接用该空间. 788 | DROP(); 789 | 790 | //校验基类合法性,若不合法则停止运行 791 | validateSuperClass(vm, className, fieldNum, superClass); 792 | Class* class = newClass(vm, VALUE_TO_OBJSTR(className), 793 | fieldNum, VALUE_TO_CLASS(superClass)); 794 | 795 | //类存储于栈底 796 | stackStart[0] = OBJ_TO_VALUE(class); 797 | 798 | LOOP(); 799 | } 800 | 801 | CASE(INSTANCE_METHOD): 802 | CASE(STATIC_METHOD): { 803 | //指令流: 待绑定的方法"名字"在vm->allMethodNames中的2字节的索引 804 | //栈顶: 待绑定的类 次栈顶: 待绑定的方法 805 | 806 | //获得方法名的索引 807 | uint32_t methodNameIndex = READ_SHORT(); 808 | 809 | //从栈顶中获得待绑定的类 810 | Class* class = VALUE_TO_CLASS(PEEK()); 811 | 812 | //从次栈顶中获得待绑定的方法, 813 | //这是由OPCODE_CREATE_CLOSURE操作码生成后压到栈中的 814 | Value method = PEEK2(); 815 | 816 | bindMethodAndPatch(vm, opCode, methodNameIndex, class, method); 817 | 818 | DROP(); 819 | DROP(); 820 | LOOP(); 821 | } 822 | 823 | CASE(END): 824 | NOT_REACHED(); 825 | } 826 | NOT_REACHED(); 827 | 828 | #undef PUSH 829 | #undef POP 830 | #undef DROP 831 | #undef PEEK 832 | #undef PEEK2 833 | #undef LOAD_CUR_FRAME 834 | #undef STORE_CUR_FRAME 835 | #undef READ_BYTE 836 | #undef READ_SHORT 837 | } 838 | -------------------------------------------------------------------------------- /vm/vm.h: -------------------------------------------------------------------------------- 1 | #ifndef _VM_VM_H 2 | #define _VM_VM_H 3 | #include "common.h" 4 | #include "class.h" 5 | #include "obj_map.h" 6 | #include "obj_thread.h" 7 | #include "parser.h" 8 | 9 | //为定义在opcode.inc中的操作码加上前缀"OPCODE_" 10 | #define OPCODE_SLOTS(opcode, effect) OPCODE_##opcode, 11 | 12 | //最多临时根对象数量 13 | #define MAX_TEMP_ROOTS_NUM 8 14 | 15 | typedef enum { 16 | #include "opcode.inc" 17 | } OpCode; 18 | #undef OPCODE_SLOTS 19 | 20 | typedef enum vmResult { 21 | VM_RESULT_SUCCESS, 22 | VM_RESULT_ERROR 23 | } VMResult; //虚拟机执行结果 24 | //如果执行无误,可以将字符码输出到文件缓存,避免下次重新编译 25 | 26 | //灰色对象信息结构 27 | typedef struct { 28 | //gc中的灰对象(也是保留对象)指针数组 29 | ObjHeader** grayObjects; 30 | uint32_t capacity; 31 | uint32_t count; 32 | } Gray; 33 | 34 | typedef struct { 35 | //堆生长因子 36 | int heapGrowthFactor; 37 | 38 | //初始堆大小,默认为10MB 39 | uint32_t initialHeapSize; 40 | 41 | //最小堆大小,默认为1MB 42 | uint32_t minHeapSize; 43 | 44 | //第一次触发gc的堆大小,默认为initialHeapSize 45 | uint32_t nextGC; 46 | } Configuration; 47 | 48 | struct vm { 49 | Class* classOfClass; 50 | Class* objectClass; 51 | Class* stringClass; 52 | Class* mapClass; 53 | Class* rangeClass; 54 | Class* listClass; 55 | Class* nullClass; 56 | Class* boolClass; 57 | Class* numClass; 58 | Class* fnClass; 59 | Class* threadClass; 60 | 61 | uint32_t allocatedBytes; //累计已分配的内存量 62 | ObjHeader* allObjects; //所有已分配对象链表 63 | SymbolTable allMethodNames; //(所有)类的方法名 64 | ObjMap* allModules; 65 | ObjThread* curThread; //当前正在执行的线程 66 | Parser* curParser; //当前词法分析器 67 | 68 | //临时的根对象集合(数组),存储临时需要被GC保留的对象,避免回收 69 | ObjHeader* tmpRoots[MAX_TEMP_ROOTS_NUM]; 70 | uint32_t tmpRootNum; 71 | 72 | //用于存储存活(保留)对象 73 | Gray grays; 74 | Configuration config; 75 | }; 76 | 77 | void initVM(VM* vm); 78 | VM* newVM(void); 79 | void ensureStack(VM* vm, ObjThread* objThread, uint32_t neededSlots); 80 | VMResult executeInstruction(VM* vm, register ObjThread* curThread); 81 | void pushTmpRoot(VM* vm, ObjHeader* obj); 82 | void popTmpRoot(VM* vm); 83 | void freeVM(VM* vm); 84 | #endif 85 | --------------------------------------------------------------------------------