From 437d3d9e053f63bc55b620d212800bd3d0b283c9 Mon Sep 17 00:00:00 2001 From: "K. Lange" Date: Sun, 31 Jul 2022 14:40:58 +0900 Subject: [PATCH] A reentrant Kuroko --- src/builtins.c | 48 ++-- src/chunk.c | 18 +- src/compiler.c | 33 +-- src/debug.c | 44 ++-- src/exceptions.c | 28 +-- src/fileio.c | 22 +- src/kuroko.c | 79 ++++--- src/kuroko/chunk.h | 22 +- src/kuroko/compiler.h | 2 +- src/kuroko/debug.h | 48 ++-- src/kuroko/memory.h | 21 +- src/kuroko/object.h | 57 +++-- src/kuroko/table.h | 39 ++-- src/kuroko/util.h | 50 ++-- src/kuroko/value.h | 29 ++- src/kuroko/vm.h | 207 +++++++++-------- src/memory.c | 64 +++--- src/modules/module_math.c | 14 +- src/modules/module_random.c | 4 +- src/modules/module_socket.c | 10 +- src/modules/module_timeit.c | 2 +- src/modules/module_wcwidth.c | 2 +- src/obj_base.c | 2 +- src/obj_bytes.c | 12 +- src/obj_dict.c | 26 +-- src/obj_function.c | 38 ++-- src/obj_gen.c | 24 +- src/obj_list.c | 54 +++-- src/obj_long.c | 96 +++++--- src/obj_numeric.c | 42 ++-- src/obj_range.c | 4 +- src/obj_set.c | 20 +- src/obj_slice.c | 8 +- src/obj_str.c | 30 +-- src/obj_tuple.c | 18 +- src/obj_typing.c | 6 +- src/object.c | 52 ++--- src/os.c | 9 +- src/private.h | 30 +-- src/sys.c | 2 +- src/table.c | 30 +-- src/threads.c | 21 +- src/time.c | 2 +- src/value.c | 38 ++-- src/vm.c | 426 ++++++++++++++++------------------- tools/compile.c | 97 ++++---- tools/demo.c | 6 +- tools/sandbox.c | 8 +- tools/simple-repl.h | 6 +- 49 files changed, 1034 insertions(+), 916 deletions(-) diff --git a/src/builtins.c b/src/builtins.c index 05384ca..dea1700 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -10,7 +10,7 @@ FUNC_SIG(list,__init__); FUNC_SIG(list,sort); -KrkValue krk_dirObject(int argc, const KrkValue argv[], int hasKw) { +KrkValue krk_dirObject_r(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { if (argc != 1) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", "dir", "exactly", 1, "", argc); @@ -71,8 +71,8 @@ KrkValue krk_dirObject(int argc, const KrkValue argv[], int hasKw) { myList = krk_list_of(0,NULL,0); krk_push(myList); krk_swap(1); - FUNC_NAME(list,__init__)(2,(KrkValue[]){krk_peek(1), krk_peek(0)},0); - FUNC_NAME(list,sort)(1,(KrkValue[]){krk_peek(1)},0); + FUNC_NAME(list,__init__)(_thread, 2,(KrkValue[]){krk_peek(1), krk_peek(0)},0); + FUNC_NAME(list,sort)(_thread, 1,(KrkValue[]){krk_peek(1)},0); krk_pop(); return krk_pop(); @@ -169,7 +169,7 @@ KRK_Method(object,__setattr__) { if (!IS_STRING(argv[1])) return krk_runtimeError(vm.exceptions->typeError, "expected str"); if (!IS_INSTANCE(argv[0])) { - return FUNC_NAME(krk,setattr)(argc,argv,hasKw); + return FUNC_NAME(krk,setattr)(_thread, argc,argv,hasKw); } /* It's an instance, that presumably does not have a `__setattr__`? */ @@ -271,7 +271,7 @@ KRK_Function(dir) { } /* Now sort it */ - FUNC_NAME(list,sort)(1,(KrkValue[]){krk_peek(0)},0); + FUNC_NAME(list,sort)(_thread, 1,(KrkValue[]){krk_peek(0)},0); return krk_pop(); /* Return the list */ } } @@ -332,24 +332,24 @@ KRK_Function(bin) { ((string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) == (KRK_OBJ_FLAGS_STRING_UCS2) ? ((uint16_t*)string->codes)[offset] : \ ((uint32_t*)string->codes)[offset])) -int krk_unpackIterable(KrkValue iterable, void * context, int callback(void *, const KrkValue *, size_t)) { +int krk_unpackIterable_r(KrkThreadState * _thread, KrkValue iterable, void * context, int callback(KrkThreadState *, void *, const KrkValue *, size_t)) { if (IS_TUPLE(iterable)) { - if (callback(context, AS_TUPLE(iterable)->values.values, AS_TUPLE(iterable)->values.count)) return 1; + if (callback(_thread, context, AS_TUPLE(iterable)->values.values, AS_TUPLE(iterable)->values.count)) return 1; } else if (IS_list(iterable)) { - if (callback(context, AS_LIST(iterable)->values, AS_LIST(iterable)->count)) return 1; + if (callback(_thread, context, AS_LIST(iterable)->values, AS_LIST(iterable)->count)) return 1; } else if (IS_dict(iterable)) { for (size_t i = 0; i < AS_DICT(iterable)->capacity; ++i) { if (!IS_KWARGS(AS_DICT(iterable)->entries[i].key)) { - if (callback(context, &AS_DICT(iterable)->entries[i].key, 1)) return 1; + if (callback(_thread, context, &AS_DICT(iterable)->entries[i].key, 1)) return 1; } } } else if (IS_STRING(iterable)) { krk_unicodeString(AS_STRING(iterable)); for (size_t i = 0; i < AS_STRING(iterable)->codesLength; ++i) { - KrkValue s = krk_string_get(2, (KrkValue[]){iterable,INTEGER_VAL(i)}, i); + KrkValue s = krk_string_get(_thread, 2, (KrkValue[]){iterable,INTEGER_VAL(i)}, i); if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return 1; krk_push(s); - if (callback(context, &s, 1)) { + if (callback(_thread, context, &s, 1)) { krk_pop(); return 1; } @@ -385,7 +385,7 @@ int krk_unpackIterable(KrkValue iterable, void * context, int callback(void *, c } krk_push(item); - if (callback(context, &item, 1)) { + if (callback(_thread, context, &item, 1)) { krk_pop(); /* item */ krk_pop(); /* __iter__ */ return 1; @@ -402,7 +402,7 @@ struct SimpleContext { KrkValue base; }; -static int _any_callback(void * context, const KrkValue * values, size_t count) { +static int _any_callback(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) { struct SimpleContext * _context = context; for (size_t i = 0; i < count; ++i) { if (!krk_isFalsey(values[i])) { @@ -420,7 +420,7 @@ KRK_Function(any) { return context.base; } -static int _all_callback(void * context, const KrkValue * values, size_t count) { +static int _all_callback(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) { struct SimpleContext * _context = context; for (size_t i = 0; i < count; ++i) { if (krk_isFalsey(values[i])) { @@ -655,7 +655,7 @@ KRK_Method(enumerate,__iter__) { return OBJECT_VAL(self); } -extern KrkValue krk_operator_add (KrkValue a, KrkValue b); +extern KrkValue krk_operator_add_r (KrkThreadState *, KrkValue a, KrkValue b); KRK_Method(enumerate,__call__) { METHOD_TAKES_NONE(); size_t stackOffset = krk_currentThread.stackTop - krk_currentThread.stack; @@ -686,7 +686,7 @@ KRK_Method(enumerate,__call__) { tupleOut->values.values[tupleOut->values.count++] = counter; tupleOut->values.values[tupleOut->values.count++] = krk_pop(); - krk_push(krk_operator_add(counter, INTEGER_VAL(1))); + krk_push(krk_operator_add_r(_thread, counter, INTEGER_VAL(1))); krk_attachNamedValue(&self->fields, "_counter", krk_pop()); KrkValue out = krk_pop(); @@ -694,10 +694,10 @@ KRK_Method(enumerate,__call__) { return out; } -static int _sum_callback(void * context, const KrkValue * values, size_t count) { +static int _sum_callback(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) { struct SimpleContext * _context = context; for (size_t i = 0; i < count; ++i) { - _context->base = krk_operator_add(_context->base, values[i]); + _context->base = krk_operator_add_r(_thread,_context->base, values[i]); if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return 1; } return 0; @@ -714,7 +714,7 @@ KRK_Function(sum) { return context.base; } -static int _min_callback(void * context, const KrkValue * values, size_t count) { +static int _min_callback(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) { struct SimpleContext * _context = context; for (size_t i = 0; i < count; ++i) { if (IS_KWARGS(_context->base)) _context->base = values[i]; @@ -731,7 +731,7 @@ KRK_Function(min) { FUNCTION_TAKES_AT_LEAST(1); struct SimpleContext context = { KWARGS_VAL(0) }; if (argc > 1) { - if (_min_callback(&context, argv, argc)) return NONE_VAL(); + if (_min_callback(_thread, &context, argv, argc)) return NONE_VAL(); } else { if (krk_unpackIterable(argv[0], &context, _min_callback)) return NONE_VAL(); } @@ -739,7 +739,7 @@ KRK_Function(min) { return context.base; } -static int _max_callback(void * context, const KrkValue * values, size_t count) { +static int _max_callback(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) { struct SimpleContext * _context = context; for (size_t i = 0; i < count; ++i) { if (IS_KWARGS(_context->base)) _context->base = values[i]; @@ -756,7 +756,7 @@ KRK_Function(max) { FUNCTION_TAKES_AT_LEAST(1); struct SimpleContext context = { KWARGS_VAL(0) }; if (argc > 1) { - if (_max_callback(&context, argv, argc)) return NONE_VAL(); + if (_max_callback(_thread, &context, argv, argc)) return NONE_VAL(); } else { if (krk_unpackIterable(argv[0], &context, _max_callback)) return NONE_VAL(); } @@ -1131,7 +1131,7 @@ KRK_Function(format) { return result; } -static void module_sweep(KrkInstance * inst) { +static void module_sweep(KrkThreadState * _thread, KrkInstance * inst) { #ifndef STATIC_ONLY struct KrkModule * module = (struct KrkModule*)inst; if (module->libHandle) { @@ -1141,7 +1141,7 @@ static void module_sweep(KrkInstance * inst) { } _noexport -void _createAndBind_builtins(void) { +void _createAndBind_builtins(KrkThreadState *_thread) { vm.baseClasses->objectClass = krk_newClass(S("object"), NULL); krk_push(OBJECT_VAL(vm.baseClasses->objectClass)); diff --git a/src/chunk.c b/src/chunk.c index 80bfa37..221c0d8 100644 --- a/src/chunk.c +++ b/src/chunk.c @@ -4,7 +4,7 @@ #include "opcode_enum.h" -void krk_initChunk(KrkChunk * chunk) { +void krk_initChunk_r(struct KrkThreadState * _thread, KrkChunk * chunk) { chunk->count = 0; chunk->capacity = 0; chunk->code = NULL; @@ -16,7 +16,7 @@ void krk_initChunk(KrkChunk * chunk) { krk_initValueArray(&chunk->constants); } -static void addLine(KrkChunk * chunk, size_t line) { +static void addLine(struct KrkThreadState * _thread, KrkChunk * chunk, size_t line) { if (chunk->linesCount && chunk->lines[chunk->linesCount-1].line == line) return; if (chunk->linesCapacity < chunk->linesCount + 1) { int old = chunk->linesCapacity; @@ -27,7 +27,7 @@ static void addLine(KrkChunk * chunk, size_t line) { chunk->linesCount++; } -void krk_writeChunk(KrkChunk * chunk, uint8_t byte, size_t line) { +void krk_writeChunk_r(struct KrkThreadState * _thread, KrkChunk * chunk, uint8_t byte, size_t line) { if (chunk->capacity < chunk->count + 1) { int old = chunk->capacity; chunk->capacity = GROW_CAPACITY(old); @@ -35,25 +35,25 @@ void krk_writeChunk(KrkChunk * chunk, uint8_t byte, size_t line) { } chunk->code[chunk->count] = byte; - addLine(chunk, line); + addLine(_thread, chunk, line); chunk->count++; } -void krk_freeChunk(KrkChunk * chunk) { +void krk_freeChunk_r(struct KrkThreadState * _thread, KrkChunk * chunk) { FREE_ARRAY(uint8_t, chunk->code, chunk->capacity); FREE_ARRAY(KrkLineMap, chunk->lines, chunk->linesCapacity); krk_freeValueArray(&chunk->constants); krk_initChunk(chunk); } -size_t krk_addConstant(KrkChunk * chunk, KrkValue value) { +size_t krk_addConstant_r(struct KrkThreadState * _thread, KrkChunk * chunk, KrkValue value) { krk_push(value); krk_writeValueArray(&chunk->constants, value); krk_pop(); return chunk->constants.count - 1; } -void krk_emitConstant(KrkChunk * chunk, size_t ind, size_t line) { +void krk_emitConstant_r(struct KrkThreadState * _thread, KrkChunk * chunk, size_t ind, size_t line) { if (ind >= 256) { krk_writeChunk(chunk, OP_CONSTANT_LONG, line); krk_writeChunk(chunk, 0xFF & (ind >> 16), line); @@ -65,13 +65,13 @@ void krk_emitConstant(KrkChunk * chunk, size_t ind, size_t line) { } } -size_t krk_writeConstant(KrkChunk * chunk, KrkValue value, size_t line) { +size_t krk_writeConstant_r(struct KrkThreadState * _thread, KrkChunk * chunk, KrkValue value, size_t line) { size_t ind = krk_addConstant(chunk, value); krk_emitConstant(chunk, ind, line); return ind; } -size_t krk_lineNumber(KrkChunk * chunk, size_t offset) { +size_t krk_lineNumber_r(struct KrkThreadState * _thread, KrkChunk * chunk, size_t offset) { size_t line = 0; for (size_t i = 0; i < chunk->linesCount; ++i) { if (chunk->lines[i].startOffset > offset) break; diff --git a/src/compiler.c b/src/compiler.c index 80eb0ef..b70ea1f 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -278,9 +278,10 @@ typedef struct GlobalState { KrkScanner scanner; Compiler * current; ClassCompiler * currentClass; + KrkThreadState * thread; } GlobalState; -static void _GlobalState_gcscan(KrkInstance * _self) { +static void _GlobalState_gcscan(KrkThreadState * _thread, KrkInstance * _self) { struct GlobalState * self = (void*)_self; Compiler * compiler = self->current; while (compiler != NULL) { @@ -290,10 +291,13 @@ static void _GlobalState_gcscan(KrkInstance * _self) { } } -static void _GlobalState_gcsweep(KrkInstance * _self) { +static void _GlobalState_gcsweep(KrkThreadState * _thread, KrkInstance * _self) { /* nothing to do? */ } +#undef _thread +#define _thread (state->thread) + #define currentChunk() (&state->current->codeobject->chunk) #define EMIT_OPERAND_OP(opc, arg) do { if (arg < 256) { emitBytes(opc, arg); } \ @@ -619,7 +623,7 @@ static KrkCodeObject * endCompiler(struct GlobalState * state) { return function; } -static void freeCompiler(Compiler * compiler) { +static void freeCompiler(struct GlobalState * state, Compiler * compiler) { FREE_ARRAY(Local,compiler->locals, compiler->localsSpace); FREE_ARRAY(Upvalue,compiler->upvalues, compiler->upvaluesSpace); FREE_ARRAY(struct LoopExit,compiler->breaks, compiler->breakSpace); @@ -1414,7 +1418,7 @@ static void functionPrologue(struct GlobalState * state, Compiler * compiler) { if (compiler->annotationCount) { emitByte(OP_ANNOTATE); } - freeCompiler(compiler); + freeCompiler(state, compiler); } static int argumentList(struct GlobalState * state, FunctionType type) { @@ -1704,7 +1708,7 @@ _pop_class: size_t indFunc = krk_addConstant(currentChunk(), OBJECT_VAL(makeclass)); EMIT_OPERAND_OP(OP_CLOSURE, indFunc); doUpvalues(state, &subcompiler, makeclass); - freeCompiler(&subcompiler); + freeCompiler(state, &subcompiler); emitBytes(OP_CALL, 0); return classCompiler.name; @@ -3115,7 +3119,7 @@ static void generatorExpression(struct GlobalState * state, KrkScanner scannerBe size_t indFunc = krk_addConstant(currentChunk(), OBJECT_VAL(subfunction)); EMIT_OPERAND_OP(OP_CLOSURE, indFunc); doUpvalues(state, &subcompiler, subfunction); - freeCompiler(&subcompiler); + freeCompiler(state, &subcompiler); emitBytes(OP_CALL, 0); } @@ -3150,7 +3154,7 @@ static void comprehensionExpression(struct GlobalState * state, KrkScanner scann size_t indFunc = krk_addConstant(currentChunk(), OBJECT_VAL(subfunction)); EMIT_OPERAND_OP(OP_CLOSURE, indFunc); doUpvalues(state, &subcompiler, subfunction); - freeCompiler(&subcompiler); + freeCompiler(state, &subcompiler); emitBytes(OP_CALL, 0); } @@ -3732,22 +3736,23 @@ static int maybeSingleExpression(struct GlobalState * state) { * @return A compiled code object, or NULL on error. * @exception SyntaxError if @p src could not be compiled. */ -KrkCodeObject * krk_compile(const char * src, char * fileName) { +KrkCodeObject * krk_compile(KrkThreadState * base_thread, const char * src, char * fileName) { - KrkClass * GlobalState = krk_newClass(S("GlobalState"), KRK_BASE_CLASS(object)); - krk_push(OBJECT_VAL(GlobalState)); + KrkClass * GlobalState = krk_newClass_r(base_thread, krk_copyString_r(base_thread, "GlobalState", 11), base_thread->owner->baseClasses->objectClass); + krk_push_r(base_thread, OBJECT_VAL(GlobalState)); GlobalState->allocSize = sizeof(struct GlobalState); GlobalState->_ongcscan = _GlobalState_gcscan; GlobalState->_ongcsweep = _GlobalState_gcsweep; GlobalState->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT; - krk_finalizeClass(GlobalState); + krk_finalizeClass_r(base_thread, GlobalState); - struct GlobalState * state = (void*)krk_newInstance(GlobalState); - krk_push(OBJECT_VAL(state)); + struct GlobalState * state = (void*)krk_newInstance_r(base_thread, GlobalState); + krk_push_r(base_thread, OBJECT_VAL(state)); /* Point a new scanner at the source. */ state->scanner = krk_initScanner(src); + state->thread = base_thread; /* Reset parser state. */ memset(&state->parser, 0, sizeof(state->parser)); @@ -3777,7 +3782,7 @@ KrkCodeObject * krk_compile(const char * src, char * fileName) { } KrkCodeObject * function = endCompiler(state); - freeCompiler(&compiler); + freeCompiler(state, &compiler); /* * We'll always get something out of endCompiler even if it diff --git a/src/debug.c b/src/debug.c index 35f7a13..594d897 100644 --- a/src/debug.c +++ b/src/debug.c @@ -18,7 +18,7 @@ * the VM will never be called to produce a string, which would result in * a nasty infinite recursion if we did it while trying to trace the VM! */ -void krk_debug_dumpStack(FILE * file, KrkCallFrame * frame) { +void krk_debug_dumpStack_r(struct KrkThreadState * _thread, FILE * file, KrkCallFrame * frame) { size_t i = 0; if (!frame) frame = &krk_currentThread.frames[krk_currentThread.frameCount-1]; for (KrkValue * slot = krk_currentThread.stack; slot < krk_currentThread.stackTop; slot++) { @@ -64,7 +64,7 @@ void krk_debug_dumpStack(FILE * file, KrkCallFrame * frame) { } -void krk_disassembleCodeObject(FILE * f, KrkCodeObject * func, const char * name) { +void krk_disassembleCodeObject_r(struct KrkThreadState * _thread, FILE * f, KrkCodeObject * func, const char * name) { KrkChunk * chunk = &func->chunk; /* Function header */ fprintf(f, "<%s(", name); @@ -93,7 +93,7 @@ static inline const char * opcodeClean(const char * opc) { return &opc[3]; } -static int isJumpTarget(KrkCodeObject * func, size_t startPoint) { +static int isJumpTarget(KrkThreadState * _thread, KrkCodeObject * func, size_t startPoint) { KrkChunk * chunk = &func->chunk; size_t offset = 0; @@ -211,7 +211,7 @@ static int isJumpTarget(KrkCodeObject * func, size_t startPoint) { } \ } -size_t krk_disassembleInstruction(FILE * f, KrkCodeObject * func, size_t offset) { +size_t krk_disassembleInstruction_r(struct KrkThreadState * _thread, FILE * f, KrkCodeObject * func, size_t offset) { KrkChunk * chunk = &func->chunk; if (offset > 0 && krk_lineNumber(chunk, offset) == krk_lineNumber(chunk, offset - 1)) { fprintf(f, " "); @@ -219,7 +219,7 @@ size_t krk_disassembleInstruction(FILE * f, KrkCodeObject * func, size_t offset) if (offset > 0) fprintf(f,"\n"); fprintf(f, "%4d ", (int)krk_lineNumber(chunk, offset)); } - if (isJumpTarget(func,offset)) { + if (isJumpTarget(_thread, func,offset)) { fprintf(f, " >> "); } else { fprintf(f, " "); @@ -284,7 +284,7 @@ struct DebuggerState { struct BreakpointEntry breakpoints[MAX_BREAKPOINTS]; }; -int krk_debug_addBreakpointCodeOffset(KrkCodeObject * target, size_t offset, int flags) { +int krk_debug_addBreakpointCodeOffset_r(struct KrkThreadState * _thread, KrkCodeObject * target, size_t offset, int flags) { int index = vm.dbgState->breakpointsCount; if (vm.dbgState->breakpointsCount == MAX_BREAKPOINTS) { /* See if any are available */ @@ -310,7 +310,7 @@ int krk_debug_addBreakpointCodeOffset(KrkCodeObject * target, size_t offset, int return index; } -int krk_debug_addBreakpointFileLine(KrkString * filename, size_t line, int flags) { +int krk_debug_addBreakpointFileLine_r(struct KrkThreadState * _thread, KrkString * filename, size_t line, int flags) { KrkCodeObject * target = NULL; @@ -350,7 +350,7 @@ int krk_debug_addBreakpointFileLine(KrkString * filename, size_t line, int flags return krk_debug_addBreakpointCodeOffset(target, offset, flags); } -int krk_debug_enableBreakpoint(int breakIndex) { +int krk_debug_enableBreakpoint_r(struct KrkThreadState * _thread, int breakIndex) { if (breakIndex < 0 || breakIndex >= vm.dbgState->breakpointsCount || vm.dbgState->breakpoints[breakIndex].inFunction == NULL) return 1; vm.dbgState->breakpoints[breakIndex].inFunction->chunk.code[vm.dbgState->breakpoints[breakIndex].offset] = OP_BREAKPOINT; @@ -363,7 +363,7 @@ KRK_Function(enablebreakpoint) { return NONE_VAL(); } -int krk_debug_disableBreakpoint(int breakIndex) { +int krk_debug_disableBreakpoint_r(struct KrkThreadState * _thread, int breakIndex) { if (breakIndex < 0 || breakIndex >= vm.dbgState->breakpointsCount || vm.dbgState->breakpoints[breakIndex].inFunction == NULL) return 1; vm.dbgState->breakpoints[breakIndex].inFunction->chunk.code[vm.dbgState->breakpoints[breakIndex].offset] = @@ -380,7 +380,7 @@ KRK_Function(disablebreakpoint) { return NONE_VAL(); } -int krk_debug_removeBreakpoint(int breakIndex) { +int krk_debug_removeBreakpoint_r(struct KrkThreadState * _thread, int breakIndex) { if (breakIndex < 0 || breakIndex >= vm.dbgState->breakpointsCount || vm.dbgState->breakpoints[breakIndex].inFunction == NULL) return 1; krk_debug_disableBreakpoint(breakIndex); @@ -459,7 +459,7 @@ KRK_Function(addbreakpoint) { * we clear the debugging bits. Then we make a new exception * to attach a traceback to. */ -void krk_debug_dumpTraceback(void) { +void krk_debug_dumpTraceback_r(struct KrkThreadState * _thread) { int flagsBefore = krk_currentThread.flags; krk_debug_disableSingleStep(); krk_push(krk_currentThread.currentException); @@ -471,15 +471,15 @@ void krk_debug_dumpTraceback(void) { krk_currentThread.flags = flagsBefore; } -void krk_debug_enableSingleStep(void) { +void krk_debug_enableSingleStep_r(struct KrkThreadState * _thread) { krk_currentThread.flags |= KRK_THREAD_SINGLE_STEP; } -void krk_debug_disableSingleStep(void) { +void krk_debug_disableSingleStep_r(struct KrkThreadState * _thread) { krk_currentThread.flags &= ~(KRK_THREAD_SINGLE_STEP); } -int krk_debuggerHook(KrkCallFrame * frame) { +int krk_debuggerHook_r(struct KrkThreadState * _thread, KrkCallFrame * frame) { if (!vm.dbgState->debuggerHook) abort(); @@ -492,7 +492,7 @@ int krk_debuggerHook(KrkCallFrame * frame) { vm.dbgState->repeatStack_bottom = -1; if (!vm.dbgState->thisWasForced) { - int result = vm.dbgState->debuggerHook(frame); + int result = vm.dbgState->debuggerHook(_thread,frame); switch (result) { case KRK_DEBUGGER_CONTINUE: krk_debug_disableSingleStep(); @@ -525,13 +525,13 @@ int krk_debuggerHook(KrkCallFrame * frame) { return 0; } -int krk_debug_registerCallback(KrkDebugCallback hook) { +int krk_debug_registerCallback_r(struct KrkThreadState * _thread, KrkDebugCallback hook) { if (vm.dbgState->debuggerHook) return 1; vm.dbgState->debuggerHook = hook; return 0; } -int krk_debug_examineBreakpoint(int breakIndex, KrkCodeObject ** funcOut, size_t * offsetOut, int * flagsOut, int * enabled) { +int krk_debug_examineBreakpoint_r(struct KrkThreadState * _thread, int breakIndex, KrkCodeObject ** funcOut, size_t * offsetOut, int * flagsOut, int * enabled) { if (breakIndex < 0 || breakIndex >= vm.dbgState->breakpointsCount) return -1; if (vm.dbgState->breakpoints[breakIndex].inFunction == NULL) @@ -545,7 +545,7 @@ int krk_debug_examineBreakpoint(int breakIndex, KrkCodeObject ** funcOut, size_t return 0; } -int krk_debugBreakpointHandler(void) { +int krk_debugBreakpointHandler_r(struct KrkThreadState * _thread) { int index = -1; KrkCallFrame * frame = &krk_currentThread.frames[krk_currentThread.frameCount-1]; @@ -633,7 +633,7 @@ KRK_Function(build) { krk_push(OBJECT_VAL(krk_currentThread.module)); KrkInstance * module = krk_currentThread.module; krk_currentThread.module = NULL; - KrkCodeObject * c = krk_compile(code->chars,fileName); + KrkCodeObject * c = krk_compile(_thread, code->chars,fileName); krk_currentThread.module = module; krk_pop(); if (c) return OBJECT_VAL(c); @@ -663,7 +663,7 @@ KRK_Function(build) { #define EXPAND_ARGS_MORE #define FORMAT_VALUE_MORE #define LOCAL_MORE local = operand; -static KrkValue _examineInternal(KrkCodeObject* func) { +static KrkValue _examineInternal(KrkThreadState * _thread, KrkCodeObject* func) { KrkValue output = krk_list_of(0,NULL,0); krk_push(output); @@ -722,7 +722,7 @@ static KrkValue _examineInternal(KrkCodeObject* func) { KRK_Function(examine) { FUNCTION_TAKES_EXACTLY(1); CHECK_ARG(0,codeobject,KrkCodeObject*,func); - return _examineInternal(func); + return _examineInternal(_thread, func); } #undef SIMPLE @@ -735,7 +735,7 @@ KRK_Function(examine) { #undef EXPAND_ARGS_MORE #undef FORMAT_VALUE_MORE -void krk_module_init_dis(void) { +void krk_module_init_dis(struct KrkThreadState * _thread) { KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass); krk_attachNamedObject(&vm.modules, "dis", (KrkObj*)module); krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("dis")); diff --git a/src/exceptions.c b/src/exceptions.c index accc355..8409a4e 100644 --- a/src/exceptions.c +++ b/src/exceptions.c @@ -108,7 +108,7 @@ KRK_Method(KeyError,__str__) { return krk_callDirect(krk_getType(arg)->_reprer, 1); } } - return FUNC_NAME(Exception,__str__)(argc,argv,hasKw); + return FUNC_NAME(Exception,__str__)(_thread, argc,argv,hasKw); } /** @@ -159,7 +159,7 @@ KRK_Method(SyntaxError,__str__) { } else { krk_push(OBJECT_VAL(S(""))); } - KrkValue formattedString = krk_string_format(9, + KrkValue formattedString = krk_string_format(_thread, 9, (KrkValue[]){krk_peek(3), file, lineno, krk_peek(0), line, krk_peek(2), krk_peek(4), krk_peek(1), arg}, 0); krk_pop(); /* instr */ krk_pop(); /* class */ @@ -181,7 +181,7 @@ _badSyntaxError: * and bind the native methods for exception objects. */ _noexport -void _createAndBind_exceptions(void) { +void _createAndBind_exceptions(KrkThreadState * _thread) { /* Add exception classes */ ADD_EXCEPTION_CLASS(vm.exceptions->baseException, Exception, vm.baseClasses->objectClass); BIND_METHOD(Exception,__init__); @@ -211,7 +211,7 @@ void _createAndBind_exceptions(void) { krk_finalizeClass(SyntaxError); } -static void dumpInnerException(KrkValue exception, int depth) { +static void dumpInnerException(KrkThreadState * _thread, KrkValue exception, int depth) { if (depth > 10) { fprintf(stderr, "Too many inner exceptions encountered.\n"); return; @@ -224,10 +224,10 @@ static void dumpInnerException(KrkValue exception, int depth) { /* Print cause or context */ if (krk_tableGet(&AS_INSTANCE(exception)->fields, OBJECT_VAL(S("__cause__")), &inner) && !IS_NONE(inner)) { - dumpInnerException(inner, depth + 1); + dumpInnerException(_thread, inner, depth + 1); fprintf(stderr, "\nThe above exception was the direct cause of the following exception:\n\n"); } else if (krk_tableGet(&AS_INSTANCE(exception)->fields, OBJECT_VAL(S("__context__")), &inner) && !IS_NONE(inner)) { - dumpInnerException(inner, depth + 1); + dumpInnerException(_thread, inner, depth + 1); fprintf(stderr, "\nDuring handling of the above exception, another exception occurred:\n\n"); } @@ -335,16 +335,16 @@ static void dumpInnerException(KrkValue exception, int depth) { * and then move inwards; on each call frame we try to open * the source file and print the corresponding line. */ -void krk_dumpTraceback(void) { +void krk_dumpTraceback_r(KrkThreadState * _thread) { if (!krk_valuesEqual(krk_currentThread.currentException,NONE_VAL())) { - dumpInnerException(krk_currentThread.currentException, 0); + dumpInnerException(_thread, krk_currentThread.currentException, 0); } } /** * Attach a traceback to the current exception object, if it doesn't already have one. */ -static void attachTraceback(void) { +static void attachTraceback(KrkThreadState * _thread) { if (IS_INSTANCE(krk_currentThread.currentException)) { KrkInstance * theException = AS_INSTANCE(krk_currentThread.currentException); KrkValue tracebackList; @@ -392,7 +392,7 @@ static void attachTraceback(void) { } /* else: probably a legacy 'raise str', just don't bother. */ } -void krk_attachInnerException(KrkValue innerException) { +void krk_attachInnerException_r(KrkThreadState * _thread, KrkValue innerException) { if (IS_INSTANCE(krk_currentThread.currentException)) { KrkInstance * theException = AS_INSTANCE(krk_currentThread.currentException); if (krk_valuesSame(krk_currentThread.currentException,innerException)) { @@ -404,7 +404,7 @@ void krk_attachInnerException(KrkValue innerException) { } } -void krk_raiseException(KrkValue base, KrkValue cause) { +void krk_raiseException_r(KrkThreadState * _thread, KrkValue base, KrkValue cause) { if (IS_CLASS(base)) { krk_push(base); base = krk_callStack(0); @@ -418,7 +418,7 @@ void krk_raiseException(KrkValue base, KrkValue cause) { krk_attachNamedValue(&AS_INSTANCE(krk_currentThread.currentException)->fields, "__cause__", cause); } - attachTraceback(); + attachTraceback(_thread); krk_currentThread.flags |= KRK_THREAD_HAS_EXCEPTION; } @@ -427,7 +427,7 @@ void krk_raiseException(KrkValue base, KrkValue cause) { * and formats a message string to attach to it. Exception classes are * found in vm.exceptions and are initialized on startup. */ -KrkValue krk_runtimeError(KrkClass * type, const char * fmt, ...) { +KrkValue krk_runtimeError_r(KrkThreadState * _thread, KrkClass * type, const char * fmt, ...) { KrkValue msg = KWARGS_VAL(0); struct StringBuilder sb = {0}; @@ -568,6 +568,6 @@ _finish: /* Set the current exception to be picked up by handleException */ krk_currentThread.currentException = OBJECT_VAL(exceptionObject); - attachTraceback(); + attachTraceback(_thread); return NONE_VAL(); } diff --git a/src/fileio.c b/src/fileio.c index 0271a28..cb67f05 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -156,7 +156,7 @@ KRK_Method(File,readlines) { krk_push(myList); for (;;) { - KrkValue line = FUNC_NAME(File,readline)(1, argv, 0); + KrkValue line = FUNC_NAME(File,readline)(_thread, 1, argv, 0); if (IS_NONE(line)) break; if (krk_currentThread.flags & KRK_THREAD_SIGNALLED) break; @@ -259,10 +259,10 @@ KRK_Method(File,__enter__) { return NONE_VAL(); } KRK_Method(File,__exit__) { - return FUNC_NAME(File,close)(1,argv,0); + return FUNC_NAME(File,close)(_thread, 1,argv,0); } -static void makeFileInstance(KrkInstance * module, const char name[], FILE * file) { +static void makeFileInstance(KrkThreadState * _thread, KrkInstance * module, const char name[], FILE * file) { KrkInstance * fileObject = krk_newInstance(KRK_BASE_CLASS(File)); krk_push(OBJECT_VAL(fileObject)); KrkValue filename = OBJECT_VAL(krk_copyString(name,strlen(name))); @@ -327,7 +327,7 @@ KRK_Method(BinaryFile,readlines) { krk_push(myList); for (;;) { - KrkValue line = FUNC_NAME(BinaryFile,readline)(1, argv, 0); + KrkValue line = FUNC_NAME(BinaryFile,readline)(_thread, 1, argv, 0); if (IS_NONE(line)) break; if (krk_currentThread.flags & KRK_THREAD_SIGNALLED) break; @@ -410,7 +410,7 @@ KRK_Method(BinaryFile,write) { #undef CURRENT_CTYPE -static void _file_sweep(KrkInstance * self) { +static void _file_sweep(KrkThreadState * _thread, KrkInstance * self) { struct File * me = (void *)self; if (me->filePtr && !me->unowned) { fclose(me->filePtr); @@ -418,7 +418,7 @@ static void _file_sweep(KrkInstance * self) { } } -static void _dir_sweep(KrkInstance * self) { +static void _dir_sweep(KrkThreadState * _thread, KrkInstance * self) { struct Directory * me = (void *)self; if (me->dirPtr) { closedir(me->dirPtr); @@ -491,10 +491,10 @@ KRK_Method(Directory,__enter__) { return NONE_VAL(); } KRK_Method(Directory,__exit__) { - return FUNC_NAME(Directory,close)(1,argv,0); + return FUNC_NAME(Directory,close)(_thread, 1,argv,0); } -void krk_module_init_fileio(void) { +void krk_module_init_fileio(KrkThreadState * _thread) { KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass); krk_attachNamedObject(&vm.modules, "fileio", (KrkObj*)module); krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("fileio")); @@ -558,9 +558,9 @@ void krk_module_init_fileio(void) { krk_finalizeClass(Directory); /* Make an instance for stdout, stderr, and stdin */ - makeFileInstance(module, "stdin", stdin); - makeFileInstance(module, "stdout", stdout); - makeFileInstance(module, "stderr", stderr); + makeFileInstance(_thread, module, "stdin", stdin); + makeFileInstance(_thread, module, "stdout", stdout); + makeFileInstance(_thread, module, "stderr", stderr); /* Our base will be the open method */ KRK_DOC(BIND_FUNC(module,open), "@brief Open a file.\n" diff --git a/src/kuroko.c b/src/kuroko.c index a75ad75..73e3aa6 100644 --- a/src/kuroko.c +++ b/src/kuroko.c @@ -35,6 +35,7 @@ #define CALLGRIND_TMP_FILE "/tmp/kuroko.callgrind.tmp" +static KrkThreadState * _global_thread = NULL; static int enableRline = 1; static int exitRepl = 0; static int pasteEnabled = 0; @@ -66,7 +67,7 @@ static int doRead(char * buf, size_t bufSize) { return read(STDIN_FILENO, buf, bufSize); } -static KrkValue readLine(char * prompt, int promptWidth, char * syntaxHighlighter) { +static KrkValue readLine(KrkThreadState * _thread, char * prompt, int promptWidth, char * syntaxHighlighter) { struct StringBuilder sb = {0}; #ifndef NO_RLINE @@ -144,7 +145,7 @@ KRK_Function(input) { } } - return readLine(prompt, promptLength, syntaxHighlighter); + return readLine(_thread, prompt, promptLength, syntaxHighlighter); } #ifndef NO_RLINE @@ -156,7 +157,7 @@ KRK_Function(input) { * We can probably also use valueGetProperty which does correct binding * for native dynamic fields... */ -static KrkValue findFromProperty(KrkValue current, KrkToken next) { +static KrkValue findFromProperty(KrkThreadState * _thread, KrkValue current, KrkToken next) { KrkValue member = OBJECT_VAL(krk_copyString(next.start, next.literalWidth)); krk_push(member); KrkValue value = krk_valueGetAttribute_default(current, AS_CSTRING(member), NONE_VAL()); @@ -174,6 +175,7 @@ static char * syn_krk_keywords[] = { }; static void tab_complete_func(rline_context_t * c) { + KrkThreadState * _thread = _global_thread; /* Figure out where the cursor is and if we should be completing anything. */ if (c->offset) { size_t stackIn = krk_currentThread.stackTop - krk_currentThread.stack; @@ -224,7 +226,7 @@ static void tab_complete_func(rline_context_t * c) { int isGlobal = 1; while (n > base) { /* And look at the potential fields for instances/classes */ - KrkValue next = findFromProperty(root, space[count-n]); + KrkValue next = findFromProperty(_thread, root, space[count-n]); if (IS_NONE(next)) { /* If we hit None, we found something invalid (or literally hit a None * object, but really the difference is minimal in this case: Nothing @@ -274,7 +276,7 @@ static void tab_complete_func(rline_context_t * c) { KrkString * s = AS_STRING(AS_LIST(dirList)->values[i]); krk_push(OBJECT_VAL(s)); KrkToken asToken = {.start = s->chars, .literalWidth = s->length}; - KrkValue thisValue = findFromProperty(root, asToken); + KrkValue thisValue = findFromProperty(_thread, root, asToken); krk_push(thisValue); if (IS_CLOSURE(thisValue) || IS_BOUND_METHOD(thisValue) || (IS_NATIVE(thisValue) && !((AS_OBJECT(thisValue)->flags & KRK_OBJ_FLAGS_FUNCTION_IS_DYNAMIC_PROPERTY)))) { @@ -390,7 +392,7 @@ _cleanup: #ifndef KRK_DISABLE_DEBUG static char * lastDebugCommand = NULL; -static int debuggerHook(KrkCallFrame * frame) { +static int debuggerHook(KrkThreadState *_thread,KrkCallFrame * frame) { /* File information */ fprintf(stderr, "At offset 0x%04lx of function '%s' from '%s' on line %lu:\n", @@ -474,7 +476,7 @@ static int debuggerHook(KrkCallFrame * frame) { } else { size_t frameCount = krk_currentThread.frameCount; /* Compile statement */ - KrkCodeObject * expression = krk_compile(arg,""); + KrkCodeObject * expression = krk_compile(_thread, arg,""); if (expression) { /* Make sure stepping is disabled first. */ krk_debug_disableSingleStep(); @@ -640,6 +642,7 @@ _dbgQuit: #endif static void handleSigint(int sigNum) { + KrkThreadState * _thread = _global_thread; /* Don't set the signal flag if the VM is not running */ if (!krk_currentThread.frameCount) return; krk_currentThread.flags |= KRK_THREAD_SIGNALLED; @@ -647,6 +650,7 @@ static void handleSigint(int sigNum) { #ifndef _WIN32 static void handleSigtrap(int sigNum) { + KrkThreadState * _thread = _global_thread; if (!krk_currentThread.frameCount) return; krk_currentThread.flags |= KRK_THREAD_SINGLE_STEP; } @@ -680,9 +684,9 @@ static void bindSignalHandlers(void) { #endif } -static void findInterpreter(char * argv[]) { +static char * findInterpreter(char * argv[]) { #ifdef _WIN32 - vm.binpath = strdup(_pgmptr); + return strdup(_pgmptr); #else /* Try asking /proc */ char tmp[4096]; @@ -697,7 +701,7 @@ static void findInterpreter(char * argv[]) { } else { /* Search PATH for argv[0] */ char * p = getenv("PATH"); - if (!p) return; + if (!p) return NULL; char * _path = strdup(p); char * path = _path; while (path) { @@ -714,25 +718,25 @@ static void findInterpreter(char * argv[]) { free(_path); } } - if (binpath) { - vm.binpath = binpath; - } /* Else, give up at this point and just don't attach it at all. */ + return binpath; #endif } +extern KrkThreadState * krk_initVM_withBinpath(int flags, char * binpath); + static int runString(char * argv[], int flags, char * string) { - findInterpreter(argv); - krk_initVM(flags); + char * path = findInterpreter(argv); + KrkThreadState * _thread = krk_initVM_withBinpath(flags,path); krk_startModule("__main__"); krk_attachNamedValue(&krk_currentThread.module->fields,"__doc__", NONE_VAL()); - krk_interpret(string, ""); - krk_freeVM(); + krk_interpret(_thread, string, ""); + krk_freeVM(_thread); return 0; } static int compileFile(char * argv[], int flags, char * fileName) { - findInterpreter(argv); - krk_initVM(flags); + char * path = findInterpreter(argv); + KrkThreadState * _thread = krk_initVM_withBinpath(flags,path); /* Open the file. */ FILE * f = fopen(fileName,"r"); @@ -754,7 +758,7 @@ static int compileFile(char * argv[], int flags, char * fileName) { krk_startModule("__main__"); /* Call the compiler directly. */ - KrkCodeObject * func = krk_compile(buf, fileName); + KrkCodeObject * func = krk_compile(_thread, buf, fileName); /* See if there was an exception. */ if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) { @@ -765,7 +769,7 @@ static int compileFile(char * argv[], int flags, char * fileName) { free(buf); /* Close out the compiler */ - krk_freeVM(); + krk_freeVM(_thread); return func == NULL; } @@ -791,6 +795,7 @@ int main(int argc, char * argv[]) { int inspectAfter = 0; int opt; int maxDepth = -1; + FILE * callgrindFile = NULL; while ((opt = getopt(argc, argv, "+:c:C:dgGim:rR:stTMSV-:")) != -1) { switch (opt) { case 'c': @@ -820,7 +825,7 @@ int main(int argc, char * argv[]) { break; case 'T': { flags |= KRK_GLOBAL_CALLGRIND; - vm.callgrindFile = fopen(CALLGRIND_TMP_FILE,"w"); + callgrindFile = fopen(CALLGRIND_TMP_FILE,"w"); break; } case 'i': @@ -890,9 +895,10 @@ int main(int argc, char * argv[]) { } } -_finishArgs: - findInterpreter(argv); - krk_initVM(flags); +_finishArgs: (void)0; + char * path = findInterpreter(argv); + KrkThreadState * _thread = krk_initVM_withBinpath(flags,path); + if (callgrindFile) _thread->owner->callgrindFile = callgrindFile; if (maxDepth != -1) { krk_setMaximumRecursionDepth(maxDepth); @@ -907,7 +913,7 @@ _finishArgs: for (int arg = optind; arg < argc; ++arg) { krk_push(OBJECT_VAL(krk_copyString(argv[arg],strlen(argv[arg])))); } - KrkValue argList = krk_callNativeOnStack(argc - optind + (optind == argc), &krk_currentThread.stackTop[-(argc - optind + (optind == argc))], 0, krk_list_of); + KrkValue argList = krk_callNativeOnStack(argc - optind + (optind == argc), &krk_currentThread.stackTop[-(argc - optind + (optind == argc))], 0, krk_list_of_r); krk_push(argList); krk_attachNamedValue(&vm.system->fields, "argv", argList); krk_pop(); @@ -933,7 +939,7 @@ _finishArgs: krk_push(OBJECT_VAL(S(":"))); /* Split into list */ - KrkValue list = krk_string_split(2,(KrkValue[]){krk_peek(1),krk_peek(0)},0); + KrkValue list = krk_string_split(_thread, 2,(KrkValue[]){krk_peek(1),krk_peek(0)},0); krk_push(list); krk_swap(2); krk_pop(); /* colon */ @@ -943,7 +949,7 @@ _finishArgs: krk_push(krk_valueGetAttribute(OBJECT_VAL(vm.system), "module_paths")); extern FUNC_SIG(list,extend); - FUNC_NAME(list,extend)(2,(KrkValue[]){krk_peek(1),krk_peek(0)},0); + FUNC_NAME(list,extend)(_thread,2,(KrkValue[]){krk_peek(1),krk_peek(0)},0); /* Store */ krk_attachNamedValue(&vm.system->fields, "module_paths", list); @@ -978,7 +984,7 @@ _finishArgs: AS_STRING(krk_peek(0))); if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) { krk_dumpTraceback(); - krk_resetStack(); + krk_resetStack(_thread); } if (!inspectAfter) return out; if (IS_INSTANCE(krk_peek(0))) { @@ -986,7 +992,7 @@ _finishArgs: } } else if (optind != argc) { krk_startModule("__main__"); - result = krk_runfile(argv[optind],argv[optind]); + result = krk_runfile(_thread, argv[optind],argv[optind]); if (IS_NONE(result) && krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) result = INTEGER_VAL(1); } @@ -998,7 +1004,7 @@ _finishArgs: } if (runCmd) { - result = krk_interpret(runCmd, ""); + result = krk_interpret(_thread, runCmd, ""); } if ((!moduleAsMain && !runCmd && optind == argc) || inspectAfter) { @@ -1052,6 +1058,7 @@ _finishArgs: /* Enable syntax highlight for Kuroko */ rline_exp_set_syntax("krk"); /* Bind a callback for \t */ + _global_thread = _thread; rline_exp_set_tab_complete_func(tab_complete_func); #endif @@ -1187,7 +1194,7 @@ _finishArgs: FREE_ARRAY(char *, lines, lineCapacity); if (valid) { - KrkValue result = krk_interpret(allData, ""); + KrkValue result = krk_interpret(_thread, allData, ""); if (!IS_NONE(result)) { krk_attachNamedValue(&vm.builtins->fields, "_", result); KrkClass * type = krk_getType(result); @@ -1205,7 +1212,7 @@ _finishArgs: fprintf(stdout, formatStr, AS_CSTRING(result)); } } - krk_resetStack(); + krk_resetStack(_thread); free(allData); } @@ -1217,17 +1224,17 @@ _finishArgs: fclose(vm.callgrindFile); vm.globalFlags &= ~(KRK_GLOBAL_CALLGRIND); - krk_resetStack(); + krk_resetStack(_thread); krk_startModule(""); krk_attachNamedObject(&krk_currentThread.module->fields, "filename", (KrkObj*)S(CALLGRIND_TMP_FILE)); - krk_interpret( + krk_interpret(_thread, "from callgrind import processFile\n" "import kuroko\n" "import os\n" "processFile(filename, os.getpid(), ' '.join(kuroko.argv))",""); } - krk_freeVM(); + krk_freeVM(_thread); if (IS_INTEGER(result)) return AS_INTEGER(result); diff --git a/src/kuroko/chunk.h b/src/kuroko/chunk.h index 11f1e2d..a3c45ff 100644 --- a/src/kuroko/chunk.h +++ b/src/kuroko/chunk.h @@ -50,37 +50,43 @@ typedef struct { * @brief Initialize an opcode chunk. * @memberof KrkChunk */ -extern void krk_initChunk(KrkChunk * chunk); +extern void krk_initChunk_r(struct KrkThreadState * _thread, KrkChunk * chunk); +#define krk_initChunk(c) krk_initChunk_r(_thread, c) /** * @memberof KrkChunk * @brief Append a byte to an opcode chunk. */ -extern void krk_writeChunk(KrkChunk * chunk, uint8_t byte, size_t line); +extern void krk_writeChunk_r(struct KrkThreadState * _thread, KrkChunk * chunk, uint8_t byte, size_t line); +#define krk_writeChunk(c,b,l) krk_writeChunk_r(_thread,c,b,l) /** * @brief Release the resources allocated to an opcode chunk. * @memberof KrkChunk */ -extern void krk_freeChunk(KrkChunk * chunk); +extern void krk_freeChunk_r(struct KrkThreadState * _thread, KrkChunk * chunk); +#define krk_freeChunk(c) krk_freeChunk_r(_thread,c) /** * @brief Add a new constant value to an opcode chunk. * @memberof KrkChunk */ -extern size_t krk_addConstant(KrkChunk * chunk, KrkValue value); +extern size_t krk_addConstant_r(struct KrkThreadState * _thread, KrkChunk * chunk, KrkValue value); +#define krk_addConstant(c,v) krk_addConstant_r(_thread,c,v) /** * @brief Write an OP_CONSTANT(_LONG) instruction. * @memberof KrkChunk */ -extern void krk_emitConstant(KrkChunk * chunk, size_t ind, size_t line); +extern void krk_emitConstant_r(struct KrkThreadState * _thread, KrkChunk * chunk, size_t ind, size_t line); +#define krk_emitConstant(c,i,l) krk_emitConstant_r(_thread,c,i,l) /** * @brief Add a new constant and write an instruction for it. * @memberof KrkChunk */ -extern size_t krk_writeConstant(KrkChunk * chunk, KrkValue value, size_t line); +extern size_t krk_writeConstant_r(struct KrkThreadState * _thread, KrkChunk * chunk, KrkValue value, size_t line); +#define krk_writeConstant(c,v,l) krk_writeConstant_r(_thread,c,v,l) /** * @brief Obtain the line number for a byte offset into a bytecode chunk. @@ -94,4 +100,6 @@ extern size_t krk_writeConstant(KrkChunk * chunk, KrkValue value, size_t line); * @param offset Byte offset of the instruction to locate. * @return Line number, 1-indexed. */ -extern size_t krk_lineNumber(KrkChunk * chunk, size_t offset); +extern size_t krk_lineNumber_r(struct KrkThreadState * _thread, KrkChunk * chunk, size_t offset); +#define krk_lineNumber(c,o) krk_lineNumber_r(_thread,c,o) + diff --git a/src/kuroko/compiler.h b/src/kuroko/compiler.h index 969040f..bd954d3 100644 --- a/src/kuroko/compiler.h +++ b/src/kuroko/compiler.h @@ -14,5 +14,5 @@ * @param fileName Path name of the source file or a representative string like "" * @return The code object resulting from the compilation, or NULL if compilation failed. */ -extern KrkCodeObject * krk_compile(const char * src, char * fileName); +extern KrkCodeObject * krk_compile(struct KrkThreadState * _thread, const char * src, char * fileName); diff --git a/src/kuroko/debug.h b/src/kuroko/debug.h index 739795e..58b495e 100644 --- a/src/kuroko/debug.h +++ b/src/kuroko/debug.h @@ -32,7 +32,8 @@ * @param func Code object to disassemble. * @param name Function name to display in disassembly output. */ -extern void krk_disassembleCodeObject(FILE * f, KrkCodeObject * func, const char * name); +extern void krk_disassembleCodeObject_r(struct KrkThreadState * _thread, FILE * f, KrkCodeObject * func, const char * name); +#define krk_disassembleCodeObject(f,fn,n) krk_disassembleCodeObject_r(_thread,f,fn,n) /** * @brief Print a disassembly of a single opcode instruction. @@ -46,14 +47,16 @@ extern void krk_disassembleCodeObject(FILE * f, KrkCodeObject * func, const char * @param offset Byte offset of the instruction to disassemble. * @return The size of the instruction in bytes. */ -extern size_t krk_disassembleInstruction(FILE * f, KrkCodeObject * func, size_t offset); +extern size_t krk_disassembleInstruction_r(struct KrkThreadState * _thread, FILE * f, KrkCodeObject * func, size_t offset); +#define krk_disassembleInstruction(f,fn,o) krk_disassembleInstruction_r(_thread,f,fn,o) /** * @brief Called by the VM when a breakpoint is encountered. * * Internal method, should not generally be called. */ -extern int krk_debugBreakpointHandler(void); +extern int krk_debugBreakpointHandler_r(struct KrkThreadState * _thread); +#define krk_debugBreakpointHandler() krk_debugBreakpointHandler_r(_thread) /** * @brief Called by the VM on single step. @@ -64,13 +67,14 @@ extern int krk_debugBreakpointHandler(void); * * Internal method, should not generally be called. */ -extern int krk_debuggerHook(KrkCallFrame * frame); +extern int krk_debuggerHook_r(struct KrkThreadState * _thread, KrkCallFrame * frame); +#define krk_debuggerHook(f) krk_debuggerHook_r(_thread,f) /** * @brief Function pointer for a debugger hook. * @ref krk_debug_registerCallback() */ -typedef int (*KrkDebugCallback)(KrkCallFrame *frame); +typedef int (*KrkDebugCallback)(struct KrkThreadState * _thread, KrkCallFrame *frame); /** * @brief Register a debugger callback. @@ -91,7 +95,8 @@ typedef int (*KrkDebugCallback)(KrkCallFrame *frame); * already registered, in which case the new hook * has not been registered. */ -extern int krk_debug_registerCallback(KrkDebugCallback hook); +extern int krk_debug_registerCallback_r(struct KrkThreadState * _thread, KrkDebugCallback hook); +#define krk_debug_registerCallback(h) krk_debug_registerCallback_r(_thread,h) /** * @brief Add a breakpoint to the given line of a file. @@ -108,7 +113,8 @@ extern int krk_debug_registerCallback(KrkDebugCallback hook); * @param flags Allows configuring the disposition of the breakpoint. * @return A breakpoint identifier handle on success, or -1 on failure. */ -extern int krk_debug_addBreakpointFileLine(KrkString * filename, size_t line, int flags); +extern int krk_debug_addBreakpointFileLine_r(struct KrkThreadState * _thread, KrkString * filename, size_t line, int flags); +#define krk_debug_addBreakpointFileLine(f,l,fl) krk_debug_addBreakpointFileLine_r(_thread,f,l,fl) /** * @brief Add a breakpoint to the given code object. @@ -126,7 +132,8 @@ extern int krk_debug_addBreakpointFileLine(KrkString * filename, size_t line, in * @param flags Allows configuring the disposition of the breakpoint. * @return A breakpoint identifier handle on success, or -1 on failure. */ -extern int krk_debug_addBreakpointCodeOffset(KrkCodeObject * codeObject, size_t offset, int flags); +extern int krk_debug_addBreakpointCodeOffset_r(struct KrkThreadState * _thread, KrkCodeObject * codeObject, size_t offset, int flags); +#define krk_debug_addBreakpointCodeOffset(c,o,f) krk_debug_addBreakpointCodeOffset_r(_thread,c,o,f) /** * @brief Remove a breakpoint from the breakpoint table. @@ -138,7 +145,8 @@ extern int krk_debug_addBreakpointCodeOffset(KrkCodeObject * codeObject, size_t * @param breakpointId The breakpoint to remove. * @return 0 on success, 1 if the breakpoint identifier is invalid. */ -extern int krk_debug_removeBreakpoint(int breakpointId); +extern int krk_debug_removeBreakpoint_r(struct KrkThreadState * _thread, int breakpointId); +#define krk_debug_removeBreakpoint(b) krk_debug_removeBreakpoint_r(_thread,b) /** * @brief Enable a breakpoint. @@ -149,7 +157,8 @@ extern int krk_debug_removeBreakpoint(int breakpointId); * @param breakpointId The breakpoint to enable. * @return 0 on success, 1 if the breakpoint identifier is invalid. */ -extern int krk_debug_enableBreakpoint(int breakpointId); +extern int krk_debug_enableBreakpoint_r(struct KrkThreadState * _thread, int breakpointId); +#define krk_debug_enableBreakpoint(b) krk_debug_enableBreakpoint_r(_thread,b) /** * @brief Disable a breakpoint. @@ -162,17 +171,21 @@ extern int krk_debug_enableBreakpoint(int breakpointId); * @param breakpointId The breakpoint to disable. * @return 0 on success, 1 if the breakpoint identifier is invalid. */ -extern int krk_debug_disableBreakpoint(int breakpointId); +extern int krk_debug_disableBreakpoint_r(struct KrkThreadState * _thread, int breakpointId); +#define krk_debug_disableBreakpoint(b) krk_debug_disableBreakpoint_r(_thread,b) + /** * @brief Enable single stepping in the current thread. */ -extern void krk_debug_enableSingleStep(void); +extern void krk_debug_enableSingleStep_r(struct KrkThreadState * _thread); +#define krk_debug_enableSingleStep() krk_debug_enableSingleStep_r(_thread); /** * @brief Disable single stepping in the current thread. */ -extern void krk_debug_disableSingleStep(void); +extern void krk_debug_disableSingleStep_r(struct KrkThreadState * _thread); +#define krk_debug_disableSingleStep() krk_debug_disableSingleStep_r(_thread) /** * @brief Safely dump a traceback to stderr. @@ -180,7 +193,8 @@ extern void krk_debug_disableSingleStep(void); * Wraps @ref krk_dumpTraceback() so it can be safely * called from a debugger. */ -extern void krk_debug_dumpTraceback(void); +extern void krk_debug_dumpTraceback_r(struct KrkThreadState * _thread); +#define krk_debug_dumpTraceback() krk_debug_dumpTraceback_r(_thread); /** * @brief Retreive information on a breakpoint. @@ -195,7 +209,8 @@ extern void krk_debug_dumpTraceback(void); * @param enabledOut (Out) Whether the breakpoint is enabled or not. * @return 0 on success, -1 on out of range, -2 if the selected slot was removed. */ -extern int krk_debug_examineBreakpoint(int breakIndex, KrkCodeObject ** funcOut, size_t * offsetOut, int * flagsOut, int *enabledOut); +extern int krk_debug_examineBreakpoint_r(struct KrkThreadState * _thread, int breakIndex, KrkCodeObject ** funcOut, size_t * offsetOut, int * flagsOut, int *enabledOut); +#define krk_debug_examineBreakpoint(b,f,o,fl,e) krk_debug_examineBreakpoint_r(_thread,b,f,o,fl,e) /** * @brief Print the elements on the stack. @@ -204,7 +219,8 @@ extern int krk_debug_examineBreakpoint(int breakIndex, KrkCodeObject ** funcOut, * highlighting @p frame as the activate call point and indicating * where its arguments start. */ -extern void krk_debug_dumpStack(FILE * f, KrkCallFrame * frame); +extern void krk_debug_dumpStack_r(struct KrkThreadState * _thread, FILE * f, KrkCallFrame * frame); +#define krk_debug_dumpStack(f,fr) krk_debug_dumpStack_r(_thread,f,fr) /** * @def KRK_BREAKPOINT_NORMAL diff --git a/src/kuroko/memory.h b/src/kuroko/memory.h index 48a6f4f..528ee74 100644 --- a/src/kuroko/memory.h +++ b/src/kuroko/memory.h @@ -27,7 +27,8 @@ * @param new New size of the object. * @return New pointer for heap object. */ -extern void * krk_reallocate(void * ptr, size_t old, size_t new); +extern void * krk_reallocate_r(struct KrkThreadState * _thread, void * ptr, size_t old, size_t new); +#define krk_reallocate(p,o,n) krk_reallocate_r(_thread,p,o,n) /** * @brief Release all objects. @@ -35,7 +36,8 @@ extern void * krk_reallocate(void * ptr, size_t old, size_t new); * Generally called automatically by krk_freeVM(); releases all of * the GC-tracked heap objects. */ -extern void krk_freeObjects(void); +extern void krk_freeObjects_r(struct KrkThreadState * _thread); +#define krk_freeObjects() krk_freeObjects_r(_thread) /** * @brief Run a cycle of the garbage collector. @@ -46,7 +48,8 @@ extern void krk_freeObjects(void); * * @return The number of bytes released by this collection cycle. */ -extern size_t krk_collectGarbage(void); +extern size_t krk_collectGarbage_r(struct KrkThreadState * _thread); +#define krk_collectGarbage() krk_collectGarbage_r(_thread) /** * @brief During a GC scan cycle, mark a value as used. @@ -57,7 +60,8 @@ extern size_t krk_collectGarbage(void); * * @param value The value to mark. */ -extern void krk_markValue(KrkValue value); +extern void krk_markValue_r(struct KrkThreadState * _thread, KrkValue value); +#define krk_markValue(v) krk_markValue_r(_thread,v) /** * @brief During a GC scan cycle, mark an object as used. @@ -66,7 +70,8 @@ extern void krk_markValue(KrkValue value); * * @param object The object to mark. */ -extern void krk_markObject(KrkObj * object); +extern void krk_markObject_r(struct KrkThreadState * _thread, KrkObj * object); +#define krk_markObject(o) krk_markObject_r(_thread,o) /** * @brief During a GC scan cycle, mark the contents of a table as used. @@ -76,7 +81,8 @@ extern void krk_markObject(KrkObj * object); * * @param table The table to mark. */ -extern void krk_markTable(KrkTable * table); +extern void krk_markTable_r(struct KrkThreadState * _thread, KrkTable * table); +#define krk_markTable(t) krk_markTable_r(_thread,t) /** * @brief Assume ownership of @p size bytes at @p ptr @@ -89,4 +95,5 @@ extern void krk_markTable(KrkTable * table); * @param ptr Pointer to take ownership of * @param size Size of data at @p ptr */ -extern void krk_gcTakeBytes(const void * ptr, size_t size); +extern void krk_gcTakeBytes_r(struct KrkThreadState * _thread, const void * ptr, size_t size); +#define krk_gcTakeBytes(p,s) krk_gcTakeBytes_r(_thread,p,s) diff --git a/src/kuroko/object.h b/src/kuroko/object.h index a0ebb1b..e4f3365 100644 --- a/src/kuroko/object.h +++ b/src/kuroko/object.h @@ -31,6 +31,8 @@ typedef enum { KRK_OBJ_BYTES, } KrkObjType; +struct KrkThreadState; + #undef KrkObj /** * @brief The most basic object type. @@ -178,7 +180,7 @@ typedef struct { KrkTable * globalsTable; /**< @brief Pointer to globals table with owner object */ } KrkClosure; -typedef void (*KrkCleanupCallback)(struct KrkInstance *); +typedef void (*KrkCleanupCallback)(struct KrkThreadState *, struct KrkInstance *); /** * @brief Type object. @@ -269,7 +271,7 @@ typedef struct { KrkObj * method; /**< @brief Function to call */ } KrkBoundMethod; -typedef KrkValue (*NativeFn)(int argCount, const KrkValue* args, int hasKwargs); +typedef KrkValue (*NativeFn)(struct KrkThreadState *, int argCount, const KrkValue* args, int hasKwargs); /** * @brief Managed binding to a C function. @@ -387,7 +389,8 @@ struct KrkSlice { * @param length Length of the C string. * @return A string object. */ -extern KrkString * krk_takeString(char * chars, size_t length); +extern KrkString * krk_takeString_r(struct KrkThreadState * _thread, char * chars, size_t length); +#define krk_takeString(c,l) krk_takeString_r(_thread,c,l) /** * @brief Like @ref krk_takeString but for when the caller has already calculated @@ -405,7 +408,8 @@ extern KrkString * krk_takeString(char * chars, size_t length); * @param type Compact type of the string, eg. UCS1, UCS2, UCS4... @see KrkStringType * @param hash Precalculated string hash. */ -extern KrkString * krk_takeStringVetted(char * chars, size_t length, size_t codesLength, KrkStringType type, uint32_t hash); +extern KrkString * krk_takeStringVetted_r(struct KrkThreadState * _thread, char * chars, size_t length, size_t codesLength, KrkStringType type, uint32_t hash); +#define krk_takeStringVetted(c,l,cl,t,h) krk_takeStringVetted_r(_thread,c,l,cl,t,h) /** * @brief Obtain a string object representation of the given C string. @@ -422,7 +426,8 @@ extern KrkString * krk_takeStringVetted(char * chars, size_t length, size_t code * @param length Length of the C string. * @return A string object. */ -extern KrkString * krk_copyString(const char * chars, size_t length); +extern KrkString * krk_copyString_r(struct KrkThreadState * _thread, const char * chars, size_t length); +#define krk_copyString(c,l) krk_copyString_r(_thread,c,l) /** * @brief Ensure that a codepoint representation of a string is available. @@ -436,7 +441,8 @@ extern KrkString * krk_copyString(const char * chars, size_t length); * @param string String to obtain the codepoint representation of. * @return A pointer to the bytes of the codepoint representation. */ -extern void * krk_unicodeString(KrkString * string); +extern void * krk_unicodeString_r(struct KrkThreadState * _thread, KrkString * string); +#define krk_unicodeString(s) krk_unicodeString_r(_thread,s) /** * @brief Obtain the codepoint at a given index in a string. @@ -454,7 +460,8 @@ extern void * krk_unicodeString(KrkString * string); * @param index Offset of the codepoint to obtain. * @return Integer representation of the codepoint at the requested index. */ -extern uint32_t krk_unicodeCodepoint(KrkString * string, size_t index); +extern uint32_t krk_unicodeCodepoint_r(struct KrkThreadState * _thread, KrkString * string, size_t index); +#define krk_unicodeCodepoint(s,i) krk_unicodeCodepoint_r(_thread,s,i) /** * @brief Convert an integer codepoint to a UTF-8 byte representation. @@ -467,7 +474,8 @@ extern uint32_t krk_unicodeCodepoint(KrkString * string, size_t index); * @param out Array to write UTF-8 sequence into. * @return The length of the UTF-8 sequence, in bytes. */ -extern size_t krk_codepointToBytes(krk_integer_type value, unsigned char * out); +extern size_t krk_codepointToBytes_r(struct KrkThreadState * _thread, krk_integer_type value, unsigned char * out); +#define krk_codepointToBytes(v,o) krk_codepointToBytes_r(_thread,v,o) /** * @brief Convert a function into a generator with the given arguments. @@ -481,12 +489,14 @@ extern size_t krk_codepointToBytes(krk_integer_type value, unsigned char * out); * @param argCount Number of arguments in @p arguments * @return A new generator object. */ -extern KrkInstance * krk_buildGenerator(KrkClosure * function, KrkValue * arguments, size_t argCount); +extern KrkInstance * krk_buildGenerator_r(struct KrkThreadState * _thread, KrkClosure * function, KrkValue * arguments, size_t argCount); +#define krk_buildGenerator(f,a,c) krk_buildGenerator_r(_thread,f,a,c) /** * @brief Calls __await__ */ -extern int krk_getAwaitable(void); +extern int krk_getAwaitable_r(struct KrkThreadState * _thread); +#define krk_getAwaitable() krk_getAwaitable_r(_thread) /** * @brief Special value for type hint expressions. @@ -504,7 +514,8 @@ extern NativeFn krk_GenericAlias; * no assigned names or docstrings. This is intended only * to be used by a compiler directly. */ -extern KrkCodeObject * krk_newCodeObject(void); +extern KrkCodeObject * krk_newCodeObject_r(struct KrkThreadState * _thread); +#define krk_newCodeObject() krk_newCodeObject_r(_thread) /** * @brief Create a native function binding object. @@ -514,7 +525,8 @@ extern KrkCodeObject * krk_newCodeObject(void); * which can then be used in the same place a function object * (KrkClosure) would be used. */ -extern KrkNative * krk_newNative(NativeFn function, const char * name, int type); +extern KrkNative * krk_newNative_r(struct KrkThreadState * _thread, NativeFn function, const char * name, int type); +#define krk_newNative(f,n,t) krk_newNative_r(_thread,f,n,t) /** * @brief Create a new function object. @@ -527,7 +539,8 @@ extern KrkNative * krk_newNative(NativeFn function, const char * name, int * * @param function Code object to assign to the new function object. */ -extern KrkClosure * krk_newClosure(KrkCodeObject * function, KrkValue globals); +extern KrkClosure * krk_newClosure_r(struct KrkThreadState * _thread, KrkCodeObject * function, KrkValue globals); +#define krk_newClosure(f,g) krk_newClosure_r(_thread,f,g) /** * @brief Create an upvalue slot. @@ -538,7 +551,8 @@ extern KrkClosure * krk_newClosure(KrkCodeObject * function, KrkValue global * process of running compiled bytecode and creating function * objects from code objects. */ -extern KrkUpvalue * krk_newUpvalue(int slot); +extern KrkUpvalue * krk_newUpvalue_r(struct KrkThreadState * _thread, int slot); +#define krk_newUpvalue(s) krk_newUpvalue_r(_thread, s) /** * @brief Create a new class object. @@ -548,7 +562,8 @@ extern KrkUpvalue * krk_newUpvalue(int slot); * Generally, you will want to use @ref krk_makeClass instead, * which handles binding the class to a module. */ -extern KrkClass * krk_newClass(KrkString * name, KrkClass * base); +extern KrkClass * krk_newClass_r(struct KrkThreadState * _thread, KrkString * name, KrkClass * base); +#define krk_newClass(n,b) krk_newClass_r(_thread,n,b) /** * @brief Create a new instance of the given class. @@ -558,7 +573,8 @@ extern KrkClass * krk_newClass(KrkString * name, KrkClass * base); * Be sure to populate any fields expected by the class or call * its __init__ function (eg. with @ref krk_callStack) as needed. */ -extern KrkInstance * krk_newInstance(KrkClass * _class); +extern KrkInstance * krk_newInstance_r(struct KrkThreadState * _thread, KrkClass * _class); +#define krk_newInstance(c) krk_newInstance_r(_thread,c) /** * @brief Create a new bound method. @@ -568,7 +584,8 @@ extern KrkInstance * krk_newInstance(KrkClass * _class); * and returns a @c method object. When a @c method object is called, * @p receiver will automatically be provided as the first argument. */ -extern KrkBoundMethod * krk_newBoundMethod(KrkValue receiver, KrkObj * method); +extern KrkBoundMethod * krk_newBoundMethod_r(struct KrkThreadState * _thread, KrkValue receiver, KrkObj * method); +#define krk_newBoundMethod(r,m) krk_newBoundMethod_r(_thread,r,m) /** * @brief Create a new tuple. @@ -578,7 +595,8 @@ extern KrkBoundMethod * krk_newBoundMethod(KrkValue receiver, KrkObj * method); * The actual length of the tuple must be updated after places * values within it by setting @c value.count. */ -extern KrkTuple * krk_newTuple(size_t length); +extern KrkTuple * krk_newTuple_r(struct KrkThreadState * _thread, size_t length); +#define krk_newTuple(l) krk_newTuple_r(_thread,l) /** * @brief Create a new byte array. @@ -587,7 +605,8 @@ extern KrkTuple * krk_newTuple(size_t length); * Allocates a bytes object of the given size, optionally copying * data from @p source. */ -extern KrkBytes * krk_newBytes(size_t length, uint8_t * source); +extern KrkBytes * krk_newBytes_r(struct KrkThreadState * _thread, size_t length, uint8_t * source); +#define krk_newBytes(l,s) krk_newBytes_r(_thread,l,s) #define krk_isObjType(v,t) (IS_OBJECT(v) && (AS_OBJECT(v)->type == (t))) #define OBJECT_TYPE(value) (AS_OBJECT(value)->type) diff --git a/src/kuroko/table.h b/src/kuroko/table.h index 1b84ac2..e95b11c 100644 --- a/src/kuroko/table.h +++ b/src/kuroko/table.h @@ -41,7 +41,8 @@ typedef struct { * * @param table Hash table to initialize. */ -extern void krk_initTable(KrkTable * table); +extern void krk_initTable_r(struct KrkThreadState * _thread, KrkTable * table); +#define krk_initTable(t) krk_initTable_r(_thread,t) /** * @brief Release resources associated with a hash table. @@ -51,7 +52,8 @@ extern void krk_initTable(KrkTable * table); * * @param table Hash table to release. */ -extern void krk_freeTable(KrkTable * table); +extern void krk_freeTable_r(struct KrkThreadState * _thread, KrkTable * table); +#define krk_freeTable(t) krk_freeTable_r(_thread,t) /** * @brief Add all key-value pairs from 'from' into 'to'. @@ -64,7 +66,8 @@ extern void krk_freeTable(KrkTable * table); * @param from Source table. * @param to Destination table. */ -extern void krk_tableAddAll(KrkTable * from, KrkTable * to); +extern void krk_tableAddAll_r(struct KrkThreadState * _thread, KrkTable * from, KrkTable * to); +#define krk_tableAddAll(f,t) krk_tableAddAll_r(_thread,f,t) /** * @brief Find a character sequence in the string interning table. @@ -80,7 +83,8 @@ extern void krk_tableAddAll(KrkTable * from, KrkTable * to); * @param hash Precalculated hash value for the string. * @return If the string was found, the string object representation, else NULL. */ -extern struct KrkString * krk_tableFindString(KrkTable * table, const char * chars, size_t length, uint32_t hash); +extern struct KrkString * krk_tableFindString_r(struct KrkThreadState * _thread, KrkTable * table, const char * chars, size_t length, uint32_t hash); +#define krk_tableFindString(t,c,l,h) krk_tableFindString_r(_thread,t,c,l,h) /** * @brief Assign a value to a key in a table. @@ -95,7 +99,8 @@ extern struct KrkString * krk_tableFindString(KrkTable * table, const char * cha * @param value Value to assign to the key. * @return 0 if the key was already present and has been overwritten, 1 if the key is new to the table. */ -extern int krk_tableSet(KrkTable * table, KrkValue key, KrkValue value); +extern int krk_tableSet_r(struct KrkThreadState * _thread, KrkTable * table, KrkValue key, KrkValue value); +#define krk_tableSet(t,k,v) krk_tableSet_r(_thread,t,k,v) /** * @brief Obtain the value associated with a key in a table. @@ -110,7 +115,8 @@ extern int krk_tableSet(KrkTable * table, KrkValue key, KrkValue value); * @param value Output pointer to place resulting value in. * @return 0 if the key was not found, 1 if it was. */ -extern int krk_tableGet(KrkTable * table, KrkValue key, KrkValue * value); +extern int krk_tableGet_r(struct KrkThreadState * _thread, KrkTable * table, KrkValue key, KrkValue * value); +#define krk_tableGet(t,k,v) krk_tableGet_r(_thread,t,k,v) /** * @brief Obtain the value associated with a string key in a table. @@ -125,7 +131,8 @@ extern int krk_tableGet(KrkTable * table, KrkValue key, KrkValue * value); * @param value Output pointer to place resulting value in. * @return 0 if the key was not found, 1 if it was. */ -extern int krk_tableGet_fast(KrkTable * table, struct KrkString * str, KrkValue * value); +extern int krk_tableGet_fast_r(struct KrkThreadState * _thread, KrkTable * table, struct KrkString * str, KrkValue * value); +#define krk_tableGet_fast(t,s,v) krk_tableGet_fast_r(_thread,t,s,v) /** * @brief Remove a key from a hash table. @@ -138,7 +145,8 @@ extern int krk_tableGet_fast(KrkTable * table, struct KrkString * str, KrkValue * @param key Key to delete. * @return 1 if the value was found and deleted, 0 if it was not present. */ -extern int krk_tableDelete(KrkTable * table, KrkValue key); +extern int krk_tableDelete_r(struct KrkThreadState * _thread, KrkTable * table, KrkValue key); +#define krk_tableDelete(t,k) krk_tableDelete_r(_thread,t,k) /** * @brief Remove a key from a hash table, with identity lookup. @@ -151,7 +159,8 @@ extern int krk_tableDelete(KrkTable * table, KrkValue key); * @param key Key to delete. * @return 1 if the value was found and deleted, 0 if it was not present. */ -extern int krk_tableDeleteExact(KrkTable * table, KrkValue key); +extern int krk_tableDeleteExact_r(struct KrkThreadState * _thread, KrkTable * table, KrkValue key); +#define krk_tableDeleteExact(t,k) krk_tableDeleteExact_r(_thread,t,k) /** * @brief Internal table scan function. @@ -166,7 +175,8 @@ extern int krk_tableDeleteExact(KrkTable * table, KrkValue key); * @param key Key to locate. * @return A pointer to the entry for 'key'. */ -extern KrkTableEntry * krk_findEntry(KrkTableEntry * entries, size_t capacity, KrkValue key); +extern KrkTableEntry * krk_findEntry_r(struct KrkThreadState * _thread, KrkTableEntry * entries, size_t capacity, KrkValue key); +#define krk_findEntry(e,c,k) krk_findEntry_r(_thread,e,c,k) /** * @brief Calculate the hash for a value. @@ -178,7 +188,8 @@ extern KrkTableEntry * krk_findEntry(KrkTableEntry * entries, size_t capacity, K * @param *hashOut An unsigned 32-bit hash value. * @return Status code 0 for success, 1 for unhashable type. */ -extern int krk_hashValue(KrkValue value, uint32_t *hashOut); +extern int krk_hashValue_r(struct KrkThreadState * _thread, KrkValue value, uint32_t *hashOut); +#define krk_hashValue(v,h) krk_hashValue_r(_thread,v,h) /** * @brief Preset the size of a table. @@ -189,7 +200,8 @@ extern int krk_hashValue(KrkValue value, uint32_t *hashOut); * @param table Table to resize. * @param capacity Target capacity. */ -extern void krk_tableAdjustCapacity(KrkTable * table, size_t capacity); +extern void krk_tableAdjustCapacity_r(struct KrkThreadState * _thread, KrkTable * table, size_t capacity); +#define krk_tableAdjustCapacity(t,c) krk_tableAdjustCapacity_r(_thread,t,c) /** * @brief Update the value of a table entry only if it is found. @@ -205,4 +217,5 @@ extern void krk_tableAdjustCapacity(KrkTable * table, size_t capacity); * @param value Value to assign to the key. * @return 0 if the key was not present, 1 if it was found and updated. */ -extern int krk_tableSetIfExists(KrkTable * table, KrkValue key, KrkValue value); +extern int krk_tableSetIfExists_r(struct KrkThreadState * _thread, KrkTable * table, KrkValue key, KrkValue value); +#define krk_tableSetIfExists(t,k,v) krk_tableSetIfExists_r(_thread,t,k,v) diff --git a/src/kuroko/util.h b/src/kuroko/util.h index b76d638..943ab86 100644 --- a/src/kuroko/util.h +++ b/src/kuroko/util.h @@ -63,7 +63,7 @@ ctype name __attribute__((unused)) = AS_ ## type (argv[i]) #define FUNC_NAME(klass, name) _ ## klass ## _ ## name -#define FUNC_SIG(klass, name) _noexport KrkValue FUNC_NAME(klass,name) (int argc, const KrkValue argv[], int hasKw) +#define FUNC_SIG(klass, name) _noexport KrkValue FUNC_NAME(klass,name) (KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) /* These forms are deprecated. */ #define KRK_METHOD(klass, name, ...) FUNC_SIG(klass, name) { \ @@ -86,27 +86,27 @@ #define KRK_Method_internal_name(klass, name) \ _krk_method_ ## klass ## _ ## name #define KRK_Method_internal_sig(klass, name) \ - static inline KrkValue KRK_Method_internal_name(klass,name) (const char * _method_name, CURRENT_CTYPE CURRENT_NAME, int argc, const KrkValue argv[], int hasKw) + static inline KrkValue KRK_Method_internal_name(klass,name) (const char * _method_name, CURRENT_CTYPE CURRENT_NAME, KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) #define KRK_Method(klass, name) \ KRK_Method_internal_sig(klass, name); \ FUNC_SIG(klass, name) { \ static const char * _method_name = # name; \ CHECK_ARG(0,klass,CURRENT_CTYPE,CURRENT_NAME); \ - return KRK_Method_internal_name(klass,name)(_method_name, CURRENT_NAME, argc, argv, hasKw); \ + return KRK_Method_internal_name(klass,name)(_method_name, CURRENT_NAME, _thread, argc, argv, hasKw); \ } \ KRK_Method_internal_sig(klass,name) #define KRK_Function_internal_name(name) \ _krk_function_ ## name #define KRK_Function_internal_sig(name) \ - static inline KrkValue KRK_Function_internal_name(name) (const char * _method_name, int argc, const KrkValue argv[], int hasKw) + static inline KrkValue KRK_Function_internal_name(name) (const char * _method_name, KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) #define KRK_Function(name) \ KRK_Function_internal_sig(name); \ - static KrkValue _krk_ ## name (int argc, const KrkValue argv[], int hasKw) { \ + static KrkValue _krk_ ## name (KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { \ static const char* _method_name = # name; \ - return KRK_Function_internal_name(name)(_method_name,argc,argv,hasKw); \ + return KRK_Function_internal_name(name)(_method_name,_thread, argc,argv,hasKw); \ } \ KRK_Function_internal_sig(name) @@ -125,7 +125,7 @@ struct StringBuilder { * @param sb String builder to append to. * @param c Character to append. */ -static inline void pushStringBuilder(struct StringBuilder * sb, char c) { +static inline void pushStringBuilder_r(struct KrkThreadState * _thread, struct StringBuilder * sb, char c) { if (sb->capacity < sb->length + 1) { size_t old = sb->capacity; sb->capacity = GROW_CAPACITY(old); @@ -133,6 +133,7 @@ static inline void pushStringBuilder(struct StringBuilder * sb, char c) { } sb->bytes[sb->length++] = c; } +#define pushStringBuilder(sb,c) pushStringBuilder_r(_thread,sb,c) /** * @brief Append a string to the end of a string builder. @@ -141,7 +142,7 @@ static inline void pushStringBuilder(struct StringBuilder * sb, char c) { * @param str C string to add. * @param len Length of the C string. */ -static inline void pushStringBuilderStr(struct StringBuilder * sb, const char *str, size_t len) { +static inline void pushStringBuilderStr_r(struct KrkThreadState * _thread, struct StringBuilder * sb, const char *str, size_t len) { if (sb->capacity < sb->length + len) { size_t prevcap = sb->capacity; while (sb->capacity < sb->length + len) { @@ -154,6 +155,7 @@ static inline void pushStringBuilderStr(struct StringBuilder * sb, const char *s sb->bytes[sb->length++] = *(str++); } } +#define pushStringBuilderStr(sb,st,l) pushStringBuilderStr_r(_thread,sb,st,l) /** * @brief Finalize a string builder into a string object. @@ -165,11 +167,12 @@ static inline void pushStringBuilderStr(struct StringBuilder * sb, const char *s * @param sb String builder to finalize. * @return A value representing a string object. */ -static inline KrkValue finishStringBuilder(struct StringBuilder * sb) { +static inline KrkValue finishStringBuilder_r(struct KrkThreadState * _thread, struct StringBuilder * sb) { KrkValue out = OBJECT_VAL(krk_copyString(sb->bytes, sb->length)); FREE_ARRAY(char,sb->bytes, sb->capacity); return out; } +#define finishStringBuilder(sb) finishStringBuilder_r(_thread,sb) /** * @brief Finalize a string builder in a bytes object. @@ -180,11 +183,12 @@ static inline KrkValue finishStringBuilder(struct StringBuilder * sb) { * @param sb String builder to finalize. * @return A value representing a bytes object. */ -static inline KrkValue finishStringBuilderBytes(struct StringBuilder * sb) { +static inline KrkValue finishStringBuilderBytes_r(struct KrkThreadState * _thread, struct StringBuilder * sb) { KrkValue out = OBJECT_VAL(krk_newBytes(sb->length, (uint8_t*)sb->bytes)); FREE_ARRAY(char,sb->bytes, sb->capacity); return out; } +#define finishStringBuilderBytes(sb) finishStringBuilderBytes_r(_thread,sb) /** * @brief Discard the contents of a string builder. @@ -196,10 +200,11 @@ static inline KrkValue finishStringBuilderBytes(struct StringBuilder * sb) { * @param sb String builder to discard. * @return None, as a convenience. */ -static inline KrkValue discardStringBuilder(struct StringBuilder * sb) { +static inline KrkValue discardStringBuilder_r(struct KrkThreadState * _thread, struct StringBuilder * sb) { FREE_ARRAY(char,sb->bytes, sb->capacity); return NONE_VAL(); } +#define discardStringBuilder(sb) discardStringBuilder_r(_thread,sb) #define IS_int(o) (IS_INTEGER(o)) #define AS_int(o) (AS_INTEGER(o)) @@ -246,21 +251,21 @@ static inline KrkValue discardStringBuilder(struct StringBuilder * sb) { #define IS_slice(o) krk_isInstanceOf(o,vm.baseClasses->sliceClass) #define AS_slice(o) ((struct KrkSlice*)AS_INSTANCE(o)) -extern KrkValue krk_dict_nth_key_fast(size_t capacity, KrkTableEntry * entries, size_t index); -extern KrkValue FUNC_NAME(str,__getitem__)(int,const KrkValue*,int); -extern KrkValue FUNC_NAME(str,split)(int,const KrkValue*,int); -extern KrkValue FUNC_NAME(str,format)(int,const KrkValue*,int); +extern KrkValue krk_dict_nth_key_fast(KrkThreadState *,size_t capacity, KrkTableEntry * entries, size_t index); +extern KrkValue FUNC_NAME(str,__getitem__)(KrkThreadState *,int,const KrkValue*,int); +extern KrkValue FUNC_NAME(str,split)(KrkThreadState *,int,const KrkValue*,int); +extern KrkValue FUNC_NAME(str,format)(KrkThreadState *,int,const KrkValue*,int); #define krk_string_get FUNC_NAME(str,__getitem__) #define krk_string_split FUNC_NAME(str,split) #define krk_string_format FUNC_NAME(str,format) -static inline void _setDoc_class(KrkClass * thing, const char * text, size_t size) { +static inline void _setDoc_class(struct KrkThreadState * _thread, KrkClass * thing, const char * text, size_t size) { thing->docstring = krk_copyString(text, size); } -static inline void _setDoc_instance(KrkInstance * thing, const char * text, size_t size) { +static inline void _setDoc_instance(struct KrkThreadState * _thread, KrkInstance * thing, const char * text, size_t size) { krk_attachNamedObject(&thing->fields, "__doc__", (KrkObj*)krk_copyString(text, size)); } -static inline void _setDoc_native(KrkNative * thing, const char * text, size_t size) { +static inline void _setDoc_native(struct KrkThreadState * _thread, KrkNative * thing, const char * text, size_t size) { (void)size; thing->doc = text; } @@ -285,17 +290,17 @@ static inline void _setDoc_native(KrkNative * thing, const char * text, size_t s KrkClass*: _setDoc_class, \ KrkInstance*: _setDoc_instance, \ KrkNative*: _setDoc_native \ - )(thing,text,sizeof(text)-1) + )(_thread,thing,text,sizeof(text)-1) #endif #define BUILTIN_FUNCTION(name, func, docStr) KRK_DOC(krk_defineNative(&vm.builtins->fields, name, func), docStr) -extern int krk_extractSlicer(const char * _method_name, KrkValue slicerVal, krk_integer_type count, krk_integer_type *start, krk_integer_type *end, krk_integer_type *step); +extern int krk_extractSlicer(KrkThreadState * _thread, const char * _method_name, KrkValue slicerVal, krk_integer_type count, krk_integer_type *start, krk_integer_type *end, krk_integer_type *step); #define KRK_SLICER(arg,count) \ krk_integer_type start; \ krk_integer_type end; \ krk_integer_type step; \ - if (krk_extractSlicer(_method_name, arg, count, &start, &end, &step)) + if (krk_extractSlicer(_thread, _method_name, arg, count, &start, &end, &step)) /** * @brief Unpack an iterable. @@ -308,7 +313,8 @@ extern int krk_extractSlicer(const char * _method_name, KrkValue slicerVal, krk_ * If @p iterable is not iterable, an exception is set and 1 is returned. * If @p callback returns non-zero, unpacking stops and 1 is returned, with no additional exception. */ -extern int krk_unpackIterable(KrkValue iterable, void * context, int callback(void *, const KrkValue *, size_t)); +extern int krk_unpackIterable_r(KrkThreadState * _thread, KrkValue iterable, void * context, int callback(KrkThreadState *, void *, const KrkValue *, size_t)); +#define krk_unpackIterable(i,c,cb) krk_unpackIterable_r(_thread,i,c,cb) #define KRK_BASE_CLASS(cls) (vm.baseClasses->cls ## Class) diff --git a/src/kuroko/value.h b/src/kuroko/value.h index 057aac1..1a30391 100644 --- a/src/kuroko/value.h +++ b/src/kuroko/value.h @@ -23,6 +23,8 @@ typedef enum { KRK_VAL_NOTIMPL = 0x7FFE, } KrkValueType; +struct KrkThreadState; + /* * The following poorly-named macros define bit patterns for identifying * various boxed types. @@ -83,7 +85,8 @@ typedef struct { * * @param array Value array to initialize. */ -extern void krk_initValueArray(KrkValueArray * array); +extern void krk_initValueArray_r(struct KrkThreadState * _thread, KrkValueArray * array); +#define krk_initValueArray(a) krk_initValueArray_r(_thread,a) /** * @brief Add a value to a value array. @@ -95,7 +98,8 @@ extern void krk_initValueArray(KrkValueArray * array); * @param array Array to append to. * @param value Value to append to array. */ -extern void krk_writeValueArray(KrkValueArray * array, KrkValue value); +extern void krk_writeValueArray_r(struct KrkThreadState * _thread, KrkValueArray * array, KrkValue value); +#define krk_writeValueArray(a,v) krk_writeValueArray_r(_thread,a,v) /** * @brief Release relesources used by a value array. @@ -108,7 +112,8 @@ extern void krk_writeValueArray(KrkValueArray * array, KrkValue value); * * @param array Array to release. */ -extern void krk_freeValueArray(KrkValueArray * array); +extern void krk_freeValueArray_r(struct KrkThreadState * _thread, KrkValueArray * array); +#define krk_freeValueArray(a) krk_freeValueArray_r(_thread,a) /** * @brief Print a string representation of a value. @@ -126,7 +131,8 @@ extern void krk_freeValueArray(KrkValueArray * array); * @param f Stream to write to. * @param value Value to display. */ -extern void krk_printValue(FILE * f, KrkValue value); +extern void krk_printValue_r(struct KrkThreadState * _thread, FILE * f, KrkValue value); +#define krk_printValue(f,v) krk_printValue_r(_thread,f,v) /** * @brief Print a value without calling the VM. @@ -144,7 +150,8 @@ extern void krk_printValue(FILE * f, KrkValue value); * @param f Stream to write to. * @param value Value to display. */ -extern void krk_printValueSafe(FILE * f, KrkValue value); +extern void krk_printValueSafe_r(struct KrkThreadState * _thread, FILE * f, KrkValue value); +#define krk_printValueSafe(f,v) krk_printValueSafe_r(_thread,f,v) /** * @brief Compare two values for equality. @@ -156,7 +163,8 @@ extern void krk_printValueSafe(FILE * f, KrkValue value); * * @return 1 if values are equivalent, 0 otherwise. */ -extern int krk_valuesEqual(KrkValue a, KrkValue b); +extern int krk_valuesEqual_r(struct KrkThreadState * _thread, KrkValue a, KrkValue b); +#define krk_valuesEqual(a,b) krk_valuesEqual_r(_thread,a,b) /** * @brief Compare two values by identity. @@ -169,7 +177,8 @@ extern int krk_valuesEqual(KrkValue a, KrkValue b); * * @return 1 if values represent the same object or value, 0 otherwise. */ -extern int krk_valuesSame(KrkValue a, KrkValue b); +extern int krk_valuesSame_r(struct KrkThreadState * _thread, KrkValue a, KrkValue b); +#define krk_valuesSame(a,b) krk_valuesSame_r(_thread,a,b) /** * @brief Compare two values by identity, then by equality. @@ -179,9 +188,11 @@ extern int krk_valuesSame(KrkValue a, KrkValue b); * * @return 1 if values represent the same object or value, 0 otherwise. */ -extern int krk_valuesSameOrEqual(KrkValue a, KrkValue b); +extern int krk_valuesSameOrEqual_r(struct KrkThreadState * _thread, KrkValue a, KrkValue b); +#define krk_valuesSameOrEqual(a,b) krk_valuesSameOrEqual_r(_thread,a,b) -extern KrkValue krk_parse_int(const char * start, size_t width, unsigned int base); +extern KrkValue krk_parse_int_r(struct KrkThreadState * _thread, const char * start, size_t width, unsigned int base); +#define krk_parse_int(s,w,b) krk_parse_int_r(_thread,s,w,b) typedef union { KrkValue val; diff --git a/src/kuroko/vm.h b/src/kuroko/vm.h index dbaaa25..c80c06a 100644 --- a/src/kuroko/vm.h +++ b/src/kuroko/vm.h @@ -171,6 +171,7 @@ typedef struct KrkThreadState { KrkValue * stackMax; /**< End of allocated stack space. */ KrkValue scratchSpace[KRK_THREAD_SCRATCH_SIZE]; /**< A place to store a few values to keep them from being prematurely GC'd. */ + struct KrkVM * owner; } KrkThreadState; /** @@ -224,42 +225,13 @@ typedef struct KrkVM { #define KRK_GLOBAL_THREADS (1 << 13) #define KRK_GLOBAL_NO_DEFAULT_MODULES (1 << 14) -#ifndef KRK_DISABLE_THREADS -# define threadLocal __thread -#else -# define threadLocal -#endif - /** * @brief Thread-local VM state. * * See @c KrkThreadState for more information. */ -#if !defined(KRK_DISABLE_THREADS) && ((defined(__APPLE__)) && defined(__aarch64__)) -extern void krk_forceThreadData(void); -#define krk_currentThread (*_macos_currentThread()) -#pragma clang diagnostic ignored "-Wlanguage-extension-token" -inline KrkThreadState * _macos_currentThread(void) { - extern const uint64_t tls_desc[] asm("_krk_currentThread"); - const uintptr_t * threadptr; asm ("mrs %0, TPIDRRO_EL0" : "=r"(threadptr)); - return (KrkThreadState*)(threadptr[tls_desc[1]] + tls_desc[2]); -} -#elif !defined(KRK_DISABLE_THREADS) && ((defined(_WIN32) && !defined(KRKINLIB)) || defined(KRK_MEDIOCRE_TLS)) -#define krk_currentThread (*krk_getCurrentThread()) -#else -extern threadLocal KrkThreadState krk_currentThread; -#endif - -/** - * @brief Singleton instance of the shared VM state. - */ -extern KrkVM krk_vm; - -/** - * @def vm - * @brief Convenience macro for namespacing. - */ -#define vm krk_vm +#define krk_currentThread (*_thread) +#define vm (*_thread->owner) /** * @brief Initialize the VM at program startup. @@ -273,7 +245,7 @@ extern KrkVM krk_vm; * * @param flags Combination of global VM flags and initial thread flags. */ -extern void krk_initVM(int flags); +extern KrkThreadState * krk_initVM(int flags); /** * @brief Release resources from the VM. @@ -285,7 +257,7 @@ extern void krk_initVM(int flags); * heap memory, FILE pointers or descriptors, or various other things which were * initialized by C extension modules. */ -extern void krk_freeVM(void); +extern void krk_freeVM(KrkThreadState*); /** * @brief Reset the current thread's stack state to the top level. @@ -295,7 +267,7 @@ extern void krk_freeVM(void); * during normal execution by C extensions. Values on the stack may be lost * to garbage collection after a call to @c krk_resetStack . */ -extern void krk_resetStack(void); +extern void krk_resetStack(KrkThreadState *); /** * @brief Compile and execute a source code input. @@ -316,7 +288,7 @@ extern void krk_resetStack(void); * indicate @c KRK_THREAD_HAS_EXCEPTION and @c krk_currentThread.currentException * should contain the raised exception value. */ -extern KrkValue krk_interpret(const char * src, char * fromFile); +extern KrkValue krk_interpret(KrkThreadState *, const char * src, char * fromFile); /** * @brief Load and run a source file and return when execution completes. @@ -330,7 +302,7 @@ extern KrkValue krk_interpret(const char * src, char * fromFile); * @return As with @c krk_interpret, an object representing the newly created module, * or the final return value of the VM execution. */ -extern KrkValue krk_runfile(const char * fileName, char * fromFile); +extern KrkValue krk_runfile(KrkThreadState *, const char * fileName, char * fromFile); /** * @brief Push a stack value. @@ -340,7 +312,8 @@ extern KrkValue krk_runfile(const char * fileName, char * fromFile); * * @param value Value to push. */ -extern void krk_push(KrkValue value); +extern void krk_push_r(KrkThreadState *, KrkValue value); +#define krk_push(v) krk_push_r(_thread, v) /** * @brief Pop the top of the stack. @@ -352,7 +325,8 @@ extern void krk_push(KrkValue value); * * @return The value previously at the top of the stack. */ -extern KrkValue krk_pop(void); +extern KrkValue krk_pop_r(KrkThreadState *); +#define krk_pop() krk_pop_r(_thread) /** * @brief Peek down from the top of the stack. @@ -362,7 +336,8 @@ extern KrkValue krk_pop(void); * @param distance How far down from the top of the stack to peek (0 = the top) * @return The value from the stack. */ -extern KrkValue krk_peek(int distance); +extern KrkValue krk_peek_r(KrkThreadState *, int distance); +#define krk_peek(d) krk_peek_r(_thread, d) /** * @brief Swap the top of the stack of the value @p distance slots down. @@ -372,7 +347,8 @@ extern KrkValue krk_peek(int distance); * * @param distance How from down from the top of the stack to swap (0 = the top) */ -extern void krk_swap(int distance); +extern void krk_swap_r(KrkThreadState *, int distance); +#define krk_swap(d) krk_swap_r(_thread, d) /** * @brief Get the name of the type of a value. @@ -385,7 +361,8 @@ extern void krk_swap(int distance); * @param value Value to examine * @return Nul-terminated C string of the type of @p value */ -extern const char * krk_typeName(KrkValue value); +extern const char * krk_typeName_r(KrkThreadState *, KrkValue value); +#define krk_typeName(v) krk_typeName_r(_thread, v) /** * @brief Attach a native C function to an attribute table. @@ -402,7 +379,8 @@ extern const char * krk_typeName(KrkValue value); * @param function Native function pointer to attach * @return A pointer to the object representing the attached function. */ -extern KrkNative * krk_defineNative(KrkTable * table, const char * name, NativeFn function); +extern KrkNative * krk_defineNative_r(KrkThreadState *, KrkTable * table, const char * name, NativeFn function); +#define krk_defineNative(t,n,f) krk_defineNative_r(_thread,t,n,f) /** * @brief Attach a native dynamic property to an attribute table. @@ -417,7 +395,8 @@ extern KrkNative * krk_defineNative(KrkTable * table, const char * name, NativeF * @param func Native function pointer to attach * @return A pointer to the property object created. */ -extern KrkNative * krk_defineNativeProperty(KrkTable * table, const char * name, NativeFn func); +extern KrkNative * krk_defineNativeProperty_r(KrkThreadState *, KrkTable * table, const char * name, NativeFn func); +#define krk_defineNativeProperty(t,n,f) krk_defineNativeProperty_r(_thread,t,n,f) /** * @brief Attach a value to an attribute table. @@ -441,7 +420,8 @@ extern KrkNative * krk_defineNativeProperty(KrkTable * table, const char * name, * @param name Nil-terminated C string with the name to assign * @param obj Value to attach. */ -extern void krk_attachNamedValue(KrkTable * table, const char name[], KrkValue obj); +extern void krk_attachNamedValue_r(KrkThreadState *, KrkTable * table, const char name[], KrkValue obj); +#define krk_attachNamedValue(t,n,o) krk_attachNamedValue_r(_thread,t,n,o) /** * @brief Attach an object to an attribute table. @@ -467,7 +447,8 @@ extern void krk_attachNamedValue(KrkTable * table, const char name[], KrkValue o * @param name Nil-terminated C string with the name to assign * @param obj Object to attach. */ -extern void krk_attachNamedObject(KrkTable * table, const char name[], KrkObj * obj); +extern void krk_attachNamedObject_r(KrkThreadState *, KrkTable * table, const char name[], KrkObj * obj); +#define krk_attachNamedObject(t,n,o) krk_attachNamedObject_r(_thread,t,n,o) /** * @brief Produce and raise an exception with a formatted message. @@ -498,7 +479,8 @@ extern void krk_attachNamedObject(KrkTable * table, const char name[], KrkObj * * @param fmt Format string. * @return As a convenience to C extension authors, returns @c None */ -extern KrkValue krk_runtimeError(KrkClass * type, const char * fmt, ...); +extern KrkValue krk_runtimeError_r(KrkThreadState *, KrkClass * type, const char * fmt, ...); +#define krk_runtimeError(t,...) krk_runtimeError_r(_thread, t, __VA_ARGS__) /** * @brief Raise an exception value. @@ -516,7 +498,8 @@ extern KrkValue krk_runtimeError(KrkClass * type, const char * fmt, ...); * @param base Exception object or class to raise. * @param cause Exception cause object or class to attach. */ -extern void krk_raiseException(KrkValue base, KrkValue cause); +extern void krk_raiseException_r(KrkThreadState *, KrkValue base, KrkValue cause); +#define krk_raiseException(b,c) krk_raiseException_r(_thread,b,c) /** * @brief Attach an inner exception to the current exception object. @@ -527,7 +510,8 @@ extern void krk_raiseException(KrkValue base, KrkValue cause); * * @param innerException \__context__ to set. */ -extern void krk_attachInnerException(KrkValue innerException); +extern void krk_attachInnerException_r(KrkThreadState *, KrkValue innerException); +#define krk_attachInnerException(i) krk_attachInnerException_r(_thread,i) /** * @brief Get a pointer to the current thread state. @@ -538,7 +522,8 @@ extern void krk_attachInnerException(KrkValue innerException); * * @return Pointer to current thread's thread state. */ -extern KrkThreadState * krk_getCurrentThread(void); +//extern KrkThreadState * krk_getCurrentThread(void); +#define krk_getCurrentThread() (_thread) /** * @brief Continue VM execution until the next exit trigger. @@ -553,7 +538,8 @@ extern KrkThreadState * krk_getCurrentThread(void); * returned by the inner function before the VM returned * to the exit frame. */ -extern KrkValue krk_runNext(void); +extern KrkValue krk_runNext_r(KrkThreadState *); +#define krk_runNext() krk_runNext_r(_thread); /** * @brief Get the class representing a value. @@ -566,7 +552,9 @@ extern KrkValue krk_runNext(void); * @param value Reference value to examine. * @return A pointer to the value's type's class object. */ -extern KrkClass * krk_getType(KrkValue value); +extern KrkClass * krk_getType_r(KrkThreadState *, KrkValue value); +#define krk_getType(v) krk_getType_r(_thread,v) + /** * @brief Determine if a class is an instance or subclass of a given type. @@ -585,7 +573,8 @@ extern KrkClass * krk_getType(KrkValue value); * @param type Class object to test for membership of. * @return 1 if @p obj is an instance of @p type or of a subclass of @p type */ -extern int krk_isInstanceOf(KrkValue obj, const KrkClass * type); +extern int krk_isInstanceOf_r(KrkThreadState *, KrkValue obj, const KrkClass * type); +#define krk_isInstanceOf(o,t) krk_isInstanceOf_r(_thread,o,t) /** * @brief Perform method binding on the stack. @@ -601,7 +590,8 @@ extern int krk_isInstanceOf(KrkValue obj, const KrkClass * type); * @param name String object with the name of the method to resolve. * @return 1 if the method has been bound, 0 if binding failed. */ -extern int krk_bindMethod(KrkClass * _class, KrkString * name); +extern int krk_bindMethod_r(KrkThreadState *, KrkClass * _class, KrkString * name); +#define krk_bindMethod(c,n) krk_bindMethod_r(_thread,c,n) /** * @brief Call a callable value in the current stack context. @@ -621,37 +611,43 @@ extern int krk_bindMethod(KrkClass * _class, KrkString * name); * 2: The callable was a native function and result should be popped now. * Else: The call failed. An exception may have already been set. */ -extern int krk_callValue(KrkValue callee, int argCount, int callableOnStack); +extern int krk_callValue_r(KrkThreadState *, KrkValue callee, int argCount, int callableOnStack); +#define krk_callValue(c,a,s) krk_callValue_r(_thread,c,a,s) /** * @brief Create a list object. * @memberof KrkList */ -extern KrkValue krk_list_of(int argc, const KrkValue argv[], int hasKw); +extern KrkValue krk_list_of_r(KrkThreadState *, int argc, const KrkValue argv[], int hasKw); +#define krk_list_of(c,v,k) krk_list_of_r(_thread,c,v,k) /** * @brief Create a dict object. * @memberof KrkDict */ -extern KrkValue krk_dict_of(int argc, const KrkValue argv[], int hasKw); +extern KrkValue krk_dict_of_r(KrkThreadState *, int argc, const KrkValue argv[], int hasKw); +#define krk_dict_of(c,v,k) krk_dict_of_r(_thread,c,v,k) /** * @brief Create a tuple object. * @memberof KrkTuple */ -extern KrkValue krk_tuple_of(int argc, const KrkValue argv[], int hasKw); +extern KrkValue krk_tuple_of_r(KrkThreadState *, int argc, const KrkValue argv[], int hasKw); +#define krk_tuple_of(c,v,k) krk_tuple_of_r(_thread,c,v,k) /** * @brief Create a set object. * @memberof Set */ -extern KrkValue krk_set_of(int argc, const KrkValue argv[], int hasKw); +extern KrkValue krk_set_of_r(KrkThreadState *, int argc, const KrkValue argv[], int hasKw); +#define krk_set_of(c,v,k) krk_set_of_r(_thread,c,v,k) /** * @brief Create a slice object. * @memberof KrkSlice */ -extern KrkValue krk_slice_of(int argc, const KrkValue argv[], int hasKw); +extern KrkValue krk_slice_of_r(KrkThreadState *, int argc, const KrkValue argv[], int hasKw); +#define krk_slice_of(c,v,k) krk_slice_of_r(_thread,c,v,k) /** * @brief Call a callable on the stack with @p argCount arguments. @@ -665,7 +661,8 @@ extern KrkValue krk_slice_of(int argc, const KrkValue argv[], int hasKw); * @param argCount Arguments to collect from the stack. * @return The return value of the function. */ -extern KrkValue krk_callStack(int argCount); +extern KrkValue krk_callStack_r(KrkThreadState *, int argCount); +#define krk_callStack(a) krk_callStack_r(_thread,a) /** * @brief Call a closure or native function with @p argCount arguments. @@ -678,7 +675,8 @@ extern KrkValue krk_callStack(int argCount); * @param argCount Arguments to collect from the stack. * @return The return value of the function. */ -extern KrkValue krk_callDirect(KrkObj * callable, int argCount); +extern KrkValue krk_callDirect_r(KrkThreadState *, KrkObj * callable, int argCount); +#define krk_callDirect(c,a) krk_callDirect_r(_thread,c,a) /** * @brief Convenience function for creating new types. @@ -693,7 +691,8 @@ extern KrkValue krk_callDirect(KrkObj * callable, int argCount); * @param base Pointer to class object to inherit from. * @return A pointer to the class object, equivalent to the value assigned to @p _class. */ -extern KrkClass * krk_makeClass(KrkInstance * module, KrkClass ** _class, const char * name, KrkClass * base); +extern KrkClass * krk_makeClass_r(KrkThreadState *, KrkInstance * module, KrkClass ** _class, const char * name, KrkClass * base); +#define krk_makeClass(m,c,n,b) krk_makeClass_r(_thread,m,c,n,b) /** * @brief Finalize a class by collecting pointers to core methods. @@ -705,7 +704,8 @@ extern KrkClass * krk_makeClass(KrkInstance * module, KrkClass ** _class, const * * @param _class Class object to finalize. */ -extern void krk_finalizeClass(KrkClass * _class); +extern void krk_finalizeClass_r(KrkThreadState *, KrkClass * _class); +#define krk_finalizeClass(c) krk_finalizeClass_r(_thread,c) /** * @brief If there is an active exception, print a traceback to @c stderr @@ -718,7 +718,8 @@ extern void krk_finalizeClass(KrkClass * _class); * open source files to print faulting lines and may call into the VM if the * exception object has a managed implementation of @c \__str__. */ -extern void krk_dumpTraceback(void); +extern void krk_dumpTraceback_r(KrkThreadState *); +#define krk_dumpTraceback() krk_dumpTraceback_r(_thread) /** * @brief Set up a new module object in the current thread. @@ -730,14 +731,16 @@ extern void krk_dumpTraceback(void); * @param name Name of the module, which is assigned to @c \__name__ * @return The instance object representing the module. */ -extern KrkInstance * krk_startModule(const char * name); +extern KrkInstance * krk_startModule_r(KrkThreadState *, const char * name); +#define krk_startModule(n) krk_startModule_r(_thread,n) /** * @brief Obtain a list of properties for an object. * * This is the native function bound to @c object.__dir__ */ -extern KrkValue krk_dirObject(int argc, const KrkValue argv[], int hasKw); +extern KrkValue krk_dirObject_r(KrkThreadState *, int argc, const KrkValue argv[], int hasKw); +#define krk_dirObject(c,v,k) krk_dirObject_r(_thread,c,v,k) /** * @brief Load a module from a file with a specified name. @@ -752,7 +755,8 @@ extern KrkValue krk_dirObject(int argc, const KrkValue argv[], int hasKw); * @param parent Parent module object, if loaded from a package. * @return 1 if the module was loaded, 0 if an @ref ImportError occurred. */ -extern int krk_loadModule(KrkString * path, KrkValue * moduleOut, KrkString * runAs, KrkValue parent); +extern int krk_loadModule_r(KrkThreadState *, KrkString * path, KrkValue * moduleOut, KrkString * runAs, KrkValue parent); +#define krk_loadModule(f,m,r,p) krk_loadModule_r(_thread,f,m,r,p) /** * @brief Load a module by a dotted name. @@ -763,7 +767,8 @@ extern int krk_loadModule(KrkString * path, KrkValue * moduleOut, KrkString * ru * @param name String object of the dot-separated package path to import. * @return 1 if the module was loaded, 0 if an @ref ImportError occurred. */ -extern int krk_doRecursiveModuleLoad(KrkString * name); +extern int krk_doRecursiveModuleLoad_r(KrkThreadState *, KrkString * name); +#define krk_doRecursiveModuleLoad(n) krk_doRecursiveModuleLoad_r(_thread,n) /** * @brief Load the dotted name @p name with the final element as @p runAs @@ -777,7 +782,8 @@ extern int krk_doRecursiveModuleLoad(KrkString * name); * @param runAs Alternative name to attach to @c \__name__ for the module. * @return 1 on success, 0 on failure. */ -extern int krk_importModule(KrkString * name, KrkString * runAs); +extern int krk_importModule_r(KrkThreadState *, KrkString * name, KrkString * runAs); +#define krk_importModule(n,r) krk_importModule_r(_thread,n,r) /** * @brief Determine the truth of a value. @@ -790,7 +796,8 @@ extern int krk_importModule(KrkString * name, KrkString * runAs); * @param value Value to examine. * @return 1 if falsey, 0 if truthy */ -extern int krk_isFalsey(KrkValue value); +extern int krk_isFalsey_r(KrkThreadState *, KrkValue value); +#define krk_isFalsey(v) krk_isFalsey_r(_thread,v) /** * @brief Obtain a property of an object by name. @@ -808,12 +815,14 @@ extern int krk_isFalsey(KrkValue value); * exception set in the current thread if the attribute was * not found. */ -extern KrkValue krk_valueGetAttribute(KrkValue value, char * name); +extern KrkValue krk_valueGetAttribute_r(KrkThreadState *, KrkValue value, char * name); +#define krk_valueGetAttribute(v,n) krk_valueGetAttribute_r(_thread,v,n) /** * @brief See @ref krk_valueGetAttribute */ -extern KrkValue krk_valueGetAttribute_default(KrkValue value, char * name, KrkValue defaultVal); +extern KrkValue krk_valueGetAttribute_default_r(KrkThreadState *, KrkValue value, char * name, KrkValue defaultVal); +#define krk_valueGetAttribute_default(v,n,d) krk_valueGetAttribute_default_r(_thread,v,n,d) /** * @brief Set a property of an object by name. @@ -832,7 +841,8 @@ extern KrkValue krk_valueGetAttribute_default(KrkValue value, char * name, KrkVa * exception set in the current thread if the object can * not have a property set. */ -extern KrkValue krk_valueSetAttribute(KrkValue owner, char * name, KrkValue to); +extern KrkValue krk_valueSetAttribute_r(KrkThreadState *, KrkValue owner, char * name, KrkValue to); +#define krk_valueSetAttribute(o,n,t) krk_valueSetAttribute_r(_thread,o,n,t) /** * @brief Delete a property of an object by name. @@ -847,7 +857,8 @@ extern KrkValue krk_valueSetAttribute(KrkValue owner, char * name, KrkValue to); * @param owner The owner of the property to delete. * @param name C-string of the property name to delete. */ -extern KrkValue krk_valueDelAttribute(KrkValue owner, char * name); +extern KrkValue krk_valueDelAttribute_r(KrkThreadState *, KrkValue owner, char * name); +#define krk_valueDelAttribute(o,n) krk_valueDelAttribute_r(_thread,o,n) /** * @brief Concatenate two strings. @@ -855,42 +866,48 @@ extern KrkValue krk_valueDelAttribute(KrkValue owner, char * name); * This is a convenience function which calls @c str.__add__ on the top stack * values. Generally, this should be avoided - use @c StringBuilder instead. */ -extern void krk_addObjects(void); +extern void krk_addObjects_r(KrkThreadState *); +#define krk_addObjects() krk_addObjects_r(_thread) /** * @brief Compare two values, returning @ref True if the left is less than the right. * * This is equivalent to the opcode instruction OP_LESS. */ -extern KrkValue krk_operator_lt(KrkValue,KrkValue); +extern KrkValue krk_operator_lt_r(KrkThreadState *, KrkValue,KrkValue); +#define krk_operator_lt(a,b) krk_operator_lt_r(_thread,a,b) /** * @brief Compare to values, returning @ref True if the left is greater than the right. * * This is equivalent to the opcode instruction OP_GREATER. */ -extern KrkValue krk_operator_gt(KrkValue,KrkValue); +extern KrkValue krk_operator_gt_r(KrkThreadState *, KrkValue,KrkValue); +#define krk_operator_gt(a,b) krk_operator_gt_r(_thread,a,b) /** * @brief Compare two values, returning @ref True if the left is less than or equal to the right. * * This is equivalent to the opcode instruction OP_LESS_EQUAL. */ -extern KrkValue krk_operator_le(KrkValue,KrkValue); +extern KrkValue krk_operator_le_r(KrkThreadState *, KrkValue,KrkValue); +#define krk_operator_le(a,b) krk_operator_le_r(_thread,a,b) /** * @brief Compare to values, returning @ref True if the left is greater than or equal to the right. * * This is equivalent to the opcode instruction OP_GREATER_EQUAL. */ -extern KrkValue krk_operator_ge(KrkValue,KrkValue); +extern KrkValue krk_operator_ge_r(KrkThreadState *, KrkValue,KrkValue); +#define krk_operator_ge(a,b) krk_operator_ge_r(_thread,a,b) /** * @brief Set the maximum recursion call depth. * * Must not be called while execution is in progress. */ -extern void krk_setMaximumRecursionDepth(size_t maxDepth); +extern void krk_setMaximumRecursionDepth_r(KrkThreadState *, size_t maxDepth); +#define krk_setMaximumRecursionDepth(m) krk_setMaximumRecursionDepth_r(_thread,m) /** * @brief Call a native function using a reference to stack arguments safely. @@ -902,7 +919,8 @@ extern void krk_setMaximumRecursionDepth(size_t maxDepth); * held stack is reallocated, it will be freed when execution returns to the call * to @c krk_callNativeOnStack that holds it. */ -extern KrkValue krk_callNativeOnStack(size_t argCount, const KrkValue *stackArgs, int hasKw, NativeFn native); +extern KrkValue krk_callNativeOnStack_r(KrkThreadState *, size_t argCount, const KrkValue *stackArgs, int hasKw, NativeFn native); +#define krk_callNativeOnStack(c,v,k,n) krk_callNativeOnStack_r(_thread,c,v,k,n) /** * @brief Set an attribute of an instance object, bypassing \__setattr__. @@ -918,7 +936,8 @@ extern KrkValue krk_callNativeOnStack(size_t argCount, const KrkValue *stackArgs * @param to New value for the attribute * @return The value set, which is likely @p to but may be the returned value of a descriptor \__set__ method. */ -extern KrkValue krk_instanceSetAttribute_wrapper(KrkValue owner, KrkString * name, KrkValue to); +extern KrkValue krk_instanceSetAttribute_wrapper_r(KrkThreadState *, KrkValue owner, KrkString * name, KrkValue to); +#define krk_instanceSetAttribute_wrapper(o,n,t) krk_instanceSetAttribute_wrapper_r(_thread,o,n,t) /** * @brief Implementation of the GET_PROPERTY instruction. @@ -933,7 +952,9 @@ extern KrkValue krk_instanceSetAttribute_wrapper(KrkValue owner, KrkString * nam * @param name Name of the attribute to look up. * @return 1 if the attribute was found, 0 otherwise. */ -extern int krk_getAttribute(KrkString * name); +extern int krk_getAttribute_r(KrkThreadState *, KrkString * name); +#define krk_getAttribute(n) krk_getAttribute_r(_thread,n) + /** * @brief Implementation of the SET_PROPERTY instruction. @@ -950,7 +971,8 @@ extern int krk_getAttribute(KrkString * name); * @param name Name of the attribute to set. * @return 1 if the attribute could be set, 0 otherwise. */ -extern int krk_setAttribute(KrkString * name); +extern int krk_setAttribute_r(KrkThreadState *, KrkString * name); +#define krk_setAttribute(n) krk_setAttribute_r(_thread,n) /** * @brief Implementation of the DEL_PROPERTY instruction. @@ -965,45 +987,46 @@ extern int krk_setAttribute(KrkString * name); * @param name Name of the attribute to delete. * @return 1 if the attribute was found and can be deleted, 0 otherwise. */ -extern int krk_delAttribute(KrkString * name); +extern int krk_delAttribute_r(KrkThreadState *, KrkString * name); +#define krk_delAttribute(n) krk_delAttribute_r(_thread,n) /** * @brief Initialize the built-in 'kuroko' module. */ -extern void krk_module_init_kuroko(void); +extern void krk_module_init_kuroko(KrkThreadState *); /** * @brief Initialize the built-in 'gc' module. */ -extern void krk_module_init_gc(void); +extern void krk_module_init_gc(KrkThreadState *); /** * @brief Initialize the built-in 'time' module. */ -extern void krk_module_init_time(void); +extern void krk_module_init_time(KrkThreadState *); /** * @brief Initialize the built-in 'os' module. */ -extern void krk_module_init_os(void); +extern void krk_module_init_os(KrkThreadState *); /** * @brief Initialize the built-in 'fileio' module. */ -extern void krk_module_init_fileio(void); +extern void krk_module_init_fileio(KrkThreadState *); /** * @brief Initialize the built-in 'dis' module. * * Not available if KRK_DISABLE_DEBUG is set. */ -extern void krk_module_init_dis(void); +extern void krk_module_init_dis(KrkThreadState *); /** * @brief Initialize the built-in 'threading' module. * * Not available if KRK_DISABLE_THREADS is set. */ -extern void krk_module_init_threading(void); +extern void krk_module_init_threading(KrkThreadState *); diff --git a/src/memory.c b/src/memory.c index bdc3af6..f77a69c 100644 --- a/src/memory.c +++ b/src/memory.c @@ -143,7 +143,7 @@ static int _debug_mem_has(const void *ptr) { } #endif -void krk_gcTakeBytes(const void * ptr, size_t size) { +void krk_gcTakeBytes_r(KrkThreadState * _thread, const void * ptr, size_t size) { #if defined(KRK_EXTENSIVE_MEMORY_DEBUGGING) _debug_mem_set(ptr, size); #endif @@ -151,7 +151,7 @@ void krk_gcTakeBytes(const void * ptr, size_t size) { vm.bytesAllocated += size; } -void * krk_reallocate(void * ptr, size_t old, size_t new) { +void * krk_reallocate_r(KrkThreadState * _thread, void * ptr, size_t old, size_t new) { vm.bytesAllocated -= old; vm.bytesAllocated += new; @@ -198,7 +198,7 @@ void * krk_reallocate(void * ptr, size_t old, size_t new) { return out; } -static void freeObject(KrkObj * object) { +static void freeObject(KrkThreadState * _thread, KrkObj * object) { switch (object->type) { case KRK_OBJ_STRING: { KrkString * string = (KrkString*)object; @@ -245,7 +245,7 @@ static void freeObject(KrkObj * object) { case KRK_OBJ_INSTANCE: { KrkInstance * inst = (KrkInstance*)object; if (inst->_class->_ongcsweep) { - inst->_class->_ongcsweep(inst); + inst->_class->_ongcsweep(_thread, inst); } krk_freeTable(&inst->fields); krk_reallocate(object,inst->_class->allocSize,0); @@ -269,14 +269,14 @@ static void freeObject(KrkObj * object) { } } -void krk_freeObjects() { +void krk_freeObjects_r(KrkThreadState * _thread) { KrkObj * object = vm.objects; KrkObj * other = NULL; while (object) { KrkObj * next = object->next; if (object->type == KRK_OBJ_INSTANCE) { - freeObject(object); + freeObject(_thread, object); } else { object->next = other; other = object; @@ -289,14 +289,14 @@ void krk_freeObjects() { if (other->type == KRK_OBJ_CLASS) { ((KrkClass*)other)->base = NULL; } - freeObject(other); + freeObject(_thread, other); other = next; } free(vm.grayStack); } -void krk_freeMemoryDebugger(void) { +void krk_freeMemoryDebugger_r(KrkThreadState * _thread) { #if defined(KRK_EXTENSIVE_MEMORY_DEBUGGING) for (unsigned int i = 0; i < DHE_SIZE; ++i) { _dhe * x = _debug_mem[i]; @@ -313,7 +313,7 @@ void krk_freeMemoryDebugger(void) { #endif } -void krk_markObject(KrkObj * object) { +void krk_markObject_r(KrkThreadState * _thread, KrkObj * object) { if (!object) return; if (object->flags & KRK_OBJ_FLAGS_IS_MARKED) return; object->flags |= KRK_OBJ_FLAGS_IS_MARKED; @@ -326,18 +326,18 @@ void krk_markObject(KrkObj * object) { vm.grayStack[vm.grayCount++] = object; } -void krk_markValue(KrkValue value) { +void krk_markValue_r(KrkThreadState * _thread, KrkValue value) { if (!IS_OBJECT(value)) return; krk_markObject(AS_OBJECT(value)); } -static void markArray(KrkValueArray * array) { +static void markArray(KrkThreadState * _thread, KrkValueArray * array) { for (size_t i = 0; i < array->count; ++i) { krk_markValue(array->values[i]); } } -static void blackenObject(KrkObj * object) { +static void blackenObject(KrkThreadState * _thread, KrkObj * object) { switch (object->type) { case KRK_OBJ_CLOSURE: { KrkClosure * closure = (KrkClosure *)object; @@ -356,9 +356,9 @@ static void blackenObject(KrkObj * object) { krk_markObject((KrkObj*)function->qualname); krk_markObject((KrkObj*)function->docstring); krk_markObject((KrkObj*)function->chunk.filename); - markArray(&function->requiredArgNames); - markArray(&function->keywordArgNames); - markArray(&function->chunk.constants); + markArray(_thread, &function->requiredArgNames); + markArray(_thread, &function->keywordArgNames); + markArray(_thread, &function->chunk.constants); for (size_t i = 0; i < function->localNameCount; ++i) { krk_markObject((KrkObj*)function->localNames[i].name); } @@ -378,7 +378,7 @@ static void blackenObject(KrkObj * object) { } case KRK_OBJ_INSTANCE: { krk_markObject((KrkObj*)((KrkInstance*)object)->_class); - if (((KrkInstance*)object)->_class->_ongcscan) ((KrkInstance*)object)->_class->_ongcscan((KrkInstance*)object); + if (((KrkInstance*)object)->_class->_ongcscan) ((KrkInstance*)object)->_class->_ongcscan(_thread, (KrkInstance*)object); krk_markTable(&((KrkInstance*)object)->fields); break; } @@ -390,7 +390,7 @@ static void blackenObject(KrkObj * object) { } case KRK_OBJ_TUPLE: { KrkTuple * tuple = (KrkTuple *)object; - markArray(&tuple->values); + markArray(_thread, &tuple->values); break; } case KRK_OBJ_NATIVE: @@ -400,14 +400,14 @@ static void blackenObject(KrkObj * object) { } } -static void traceReferences() { +static void traceReferences(KrkThreadState * _thread) { while (vm.grayCount > 0) { KrkObj * object = vm.grayStack[--vm.grayCount]; - blackenObject(object); + blackenObject(_thread, object); } } -static size_t sweep() { +static size_t sweep(KrkThreadState * _thread) { KrkObj * previous = NULL; KrkObj * object = vm.objects; size_t count = 0; @@ -424,7 +424,7 @@ static size_t sweep() { } else { vm.objects = object; } - freeObject(unreached); + freeObject(_thread, unreached); count++; } else { object->flags |= KRK_OBJ_FLAGS_SECOND_CHANCE; @@ -435,7 +435,7 @@ static size_t sweep() { return count; } -void krk_markTable(KrkTable * table) { +void krk_markTable_r(KrkThreadState * _thread, KrkTable * table) { for (size_t i = 0; i < table->capacity; ++i) { KrkTableEntry * entry = &table->entries[i]; krk_markValue(entry->key); @@ -443,7 +443,7 @@ void krk_markTable(KrkTable * table) { } } -static void tableRemoveWhite(KrkTable * table) { +static void tableRemoveWhite(KrkThreadState * _thread, KrkTable * table) { for (size_t i = 0; i < table->capacity; ++i) { KrkTableEntry * entry = &table->entries[i]; if (IS_OBJECT(entry->key) && !((AS_OBJECT(entry->key))->flags & KRK_OBJ_FLAGS_IS_MARKED)) { @@ -452,7 +452,7 @@ static void tableRemoveWhite(KrkTable * table) { } } -static void markThreadRoots(KrkThreadState * thread) { +static void markThreadRoots(KrkThreadState * _thread, KrkThreadState * thread) { for (KrkValue * slot = thread->stack; slot && slot < thread->stackTop; ++slot) { krk_markValue(*slot); } @@ -468,10 +468,10 @@ static void markThreadRoots(KrkThreadState * thread) { } } -static void markRoots() { +static void markRoots(KrkThreadState * _thread) { KrkThreadState * thread = vm.threads; while (thread) { - markThreadRoots(thread); + markThreadRoots(_thread, thread); thread = thread->next; } @@ -505,7 +505,7 @@ static int smartSize(char _out[100], size_t s) { } #endif -size_t krk_collectGarbage(void) { +size_t krk_collectGarbage_r(KrkThreadState * _thread) { #ifndef KRK_NO_GC_TRACING struct timespec outTime, inTime; @@ -516,10 +516,10 @@ size_t krk_collectGarbage(void) { size_t bytesBefore = vm.bytesAllocated; #endif - markRoots(); - traceReferences(); - tableRemoveWhite(&vm.strings); - size_t out = sweep(); + markRoots(_thread); + traceReferences(_thread); + tableRemoveWhite(_thread, &vm.strings); + size_t out = sweep(_thread); /** * The GC scheduling is in need of some improvement. The strategy at the moment @@ -581,7 +581,7 @@ KRK_Function(resume) { return NONE_VAL(); } -void krk_module_init_gc(void) { +void krk_module_init_gc(KrkThreadState * _thread) { /** * gc = module() * diff --git a/src/modules/module_math.c b/src/modules/module_math.c index ebf6044..2e47ae9 100644 --- a/src/modules/module_math.c +++ b/src/modules/module_math.c @@ -39,7 +39,7 @@ } #define MATH_DELEGATE(func) \ -static KrkValue _math_ ## func(int argc, const KrkValue argv[], int hasKw) { \ +static KrkValue _math_ ## func(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { \ ONE_ARGUMENT(func) \ if (IS_FLOATING(argv[0])) { \ return INTEGER_VAL(func(AS_FLOATING(argv[0]))); \ @@ -58,7 +58,7 @@ MATH_DELEGATE(floor) MATH_DELEGATE(trunc) #define MATH_ONE_NAME(func,name) \ -static KrkValue _math_ ## name(int argc, const KrkValue argv[], int hasKw) { \ +static KrkValue _math_ ## name(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { \ ONE_ARGUMENT(name) \ FORCE_FLOAT(argv[0],arg_0) \ if (IS_FLOATING(arg_0)) { \ @@ -94,7 +94,7 @@ MATH_ONE(lgamma) #endif #define MATH_TWO(func) \ -static KrkValue _math_ ## func(int argc, const KrkValue argv[], int hasKw) { \ +static KrkValue _math_ ## func(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { \ TWO_ARGUMENTS(func) \ FORCE_FLOAT(argv[0],arg_0) \ FORCE_FLOAT(argv[1],arg_1) \ @@ -109,7 +109,7 @@ MATH_TWO(remainder) MATH_TWO(pow) MATH_TWO(atan2) -static KrkValue _float_pow(int argc, const KrkValue argv[], int hasKw) { +static KrkValue _float_pow(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { TWO_ARGUMENTS(__pow__); if (unlikely(!IS_FLOATING(argv[0]))) return krk_runtimeError(vm.exceptions->typeError, "expected float"); if (likely(IS_FLOATING(argv[1]))) { @@ -121,7 +121,7 @@ static KrkValue _float_pow(int argc, const KrkValue argv[], int hasKw) { } -static KrkValue _math_frexp(int argc, const KrkValue argv[], int hasKw) { +static KrkValue _math_frexp(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { ONE_ARGUMENT(frexp) FORCE_FLOAT(argv[0],arg_0) if (!IS_FLOATING(arg_0)) { @@ -137,7 +137,7 @@ static KrkValue _math_frexp(int argc, const KrkValue argv[], int hasKw) { } #define MATH_IS(func) \ -static KrkValue _math_ ## func(int argc, const KrkValue argv[], int hasKw) { \ +static KrkValue _math_ ## func(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { \ ONE_ARGUMENT(func) \ if (!IS_FLOATING(argv[0])) REAL_NUMBER_NOT(func,argv[0]) \ return BOOLEAN_VAL(func(AS_FLOATING(argv[0]))); \ @@ -149,7 +149,7 @@ MATH_IS(isnan) #define bind(name) krk_defineNative(&module->fields, #name, _math_ ## name) -KrkValue krk_module_onload_math(void) { +KrkValue krk_module_onload_math(KrkThreadState * _thread) { KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass); krk_push(OBJECT_VAL(module)); diff --git a/src/modules/module_random.c b/src/modules/module_random.c index b799165..8acab98 100644 --- a/src/modules/module_random.c +++ b/src/modules/module_random.c @@ -58,7 +58,7 @@ KRK_Function(seed) { return NONE_VAL(); } -KrkValue krk_module_onload_random(void) { +KrkValue krk_module_onload_random(KrkThreadState * _thread) { KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass); krk_push(OBJECT_VAL(module)); @@ -67,7 +67,7 @@ KrkValue krk_module_onload_random(void) { BIND_FUNC(module, random); BIND_FUNC(module, seed); - FUNC_NAME(krk,seed)(0,NULL,0); + FUNC_NAME(krk,seed)(_thread, 0,NULL,0); return krk_pop(); } diff --git a/src/modules/module_socket.c b/src/modules/module_socket.c index eeecf2f..e21b007 100644 --- a/src/modules/module_socket.c +++ b/src/modules/module_socket.c @@ -109,7 +109,7 @@ KRK_Method(socket,__repr__) { return OBJECT_VAL(krk_copyString(tmp,len)); } -static int socket_parse_address(struct socket * self, KrkValue address, struct sockaddr_storage *sock_addr, socklen_t *sock_size) { +static int socket_parse_address(KrkThreadState * _thread, struct socket * self, KrkValue address, struct sockaddr_storage *sock_addr, socklen_t *sock_size) { if (self->family == AF_INET) { /* Should be 2-tuple */ if (!IS_tuple(address)) { @@ -186,7 +186,7 @@ KRK_Method(socket,connect) { socklen_t sock_size = 0; /* What do we take? I guess a tuple for AF_INET */ - int parseResult = socket_parse_address(self, argv[1], &sock_addr, &sock_size); + int parseResult = socket_parse_address(_thread, self, argv[1], &sock_addr, &sock_size); if (parseResult) { if (!(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return krk_runtimeError(SocketError, "Unspecified error."); @@ -209,7 +209,7 @@ KRK_Method(socket,bind) { socklen_t sock_size = 0; /* What do we take? I guess a tuple for AF_INET */ - int parseResult = socket_parse_address(self, argv[1], &sock_addr, &sock_size); + int parseResult = socket_parse_address(_thread, self, argv[1], &sock_addr, &sock_size); if (parseResult) { if (!(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return krk_runtimeError(SocketError, "Unspecified error."); @@ -355,7 +355,7 @@ KRK_Method(socket,sendto) { socklen_t sock_size = 0; /* What do we take? I guess a tuple for AF_INET */ - int parseResult = socket_parse_address(self, argv[argc-1], &sock_addr, &sock_size); + int parseResult = socket_parse_address(_thread, self, argv[argc-1], &sock_addr, &sock_size); if (parseResult) { if (!(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return krk_runtimeError(SocketError, "Unspecified error."); @@ -404,7 +404,7 @@ KRK_Function(htons) { return INTEGER_VAL(htons(value)); } -KrkValue krk_module_onload_socket(void) { +KrkValue krk_module_onload_socket(KrkThreadState * _thread) { KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass); krk_push(OBJECT_VAL(module)); diff --git a/src/modules/module_timeit.c b/src/modules/module_timeit.c index 47da84b..6d02868 100644 --- a/src/modules/module_timeit.c +++ b/src/modules/module_timeit.c @@ -34,7 +34,7 @@ KRK_Function(timeit) { return FLOATING_VAL(after-before); } -KrkValue krk_module_onload_timeit(void) { +KrkValue krk_module_onload_timeit(KrkThreadState * _thread) { KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass); krk_push(OBJECT_VAL(module)); diff --git a/src/modules/module_wcwidth.c b/src/modules/module_wcwidth.c index c61ed3e..03c2e53 100644 --- a/src/modules/module_wcwidth.c +++ b/src/modules/module_wcwidth.c @@ -17,7 +17,7 @@ KRK_Function(wcwidth) { return INTEGER_VAL(wcwidth(codepoint)); } -KrkValue krk_module_onload_wcwidth(void) { +KrkValue krk_module_onload_wcwidth(KrkThreadState * _thread) { KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass); krk_push(OBJECT_VAL(module)); KRK_DOC(module, "Character widths."); diff --git a/src/obj_base.c b/src/obj_base.c index c6f0820..62e1d6b 100644 --- a/src/obj_base.c +++ b/src/obj_base.c @@ -84,7 +84,7 @@ KRK_Method(type,__getitem__) { } _noexport -void _createAndBind_type(void) { +void _createAndBind_type(KrkThreadState * _thread) { KrkClass * type = ADD_BASE_CLASS(vm.baseClasses->typeClass, "type", vm.baseClasses->objectClass); type->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT; diff --git a/src/obj_bytes.c b/src/obj_bytes.c index 4b9a85b..964da81 100644 --- a/src/obj_bytes.c +++ b/src/obj_bytes.c @@ -193,7 +193,7 @@ struct _bytes_join_context { int isFirst; }; -static int _bytes_join_callback(void * context, const KrkValue * values, size_t count) { +static int _bytes_join_callback(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) { struct _bytes_join_context * _context = context; for (size_t i = 0; i < count; ++i) { @@ -247,7 +247,7 @@ KRK_Method(bytes,__iter__) { KrkInstance * output = krk_newInstance(vm.baseClasses->bytesiteratorClass); krk_push(OBJECT_VAL(output)); - FUNC_NAME(bytesiterator,__init__)(2, (KrkValue[]){krk_peek(0), argv[0]},0); + FUNC_NAME(bytesiterator,__init__)(_thread, 2, (KrkValue[]){krk_peek(0), argv[0]},0); krk_pop(); return OBJECT_VAL(output); @@ -265,7 +265,7 @@ struct BytesIterator { #define IS_bytesiterator(o) krk_isInstanceOf(o,vm.baseClasses->bytesiteratorClass) #define AS_bytesiterator(o) (struct BytesIterator*)AS_OBJECT(o) -static void _bytesiterator_gcscan(KrkInstance * self) { +static void _bytesiterator_gcscan(KrkThreadState * _thread, KrkInstance * self) { krk_markValue(((struct BytesIterator*)self)->l); } @@ -291,7 +291,7 @@ KRK_Method(bytesiterator,__call__) { #undef CURRENT_CTYPE #define CURRENT_CTYPE struct ByteArray * -static void _bytearray_gcscan(KrkInstance * self) { +static void _bytearray_gcscan(KrkThreadState * _thread, KrkInstance * self) { krk_markValue(((struct ByteArray*)self)->actual); } @@ -408,7 +408,7 @@ KRK_Method(bytearray,__iter__) { KrkInstance * output = krk_newInstance(vm.baseClasses->bytesiteratorClass); krk_push(OBJECT_VAL(output)); - FUNC_NAME(bytesiterator,__init__)(2, (KrkValue[]){krk_peek(0), self->actual},0); + FUNC_NAME(bytesiterator,__init__)(_thread, 2, (KrkValue[]){krk_peek(0), self->actual},0); krk_pop(); return OBJECT_VAL(output); @@ -416,7 +416,7 @@ KRK_Method(bytearray,__iter__) { _noexport -void _createAndBind_bytesClass(void) { +void _createAndBind_bytesClass(KrkThreadState * _thread) { KrkClass * bytes = ADD_BASE_CLASS(vm.baseClasses->bytesClass, "bytes", vm.baseClasses->objectClass); bytes->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT; KRK_DOC(BIND_METHOD(bytes,__init__), diff --git a/src/obj_dict.c b/src/obj_dict.c index 89c34f5..520eb3f 100644 --- a/src/obj_dict.c +++ b/src/obj_dict.c @@ -8,7 +8,7 @@ * Exposed method called to produce dictionaries from `{expr: expr, ...}` sequences in managed code. * Expects arguments as `key,value,key,value`... */ -KrkValue krk_dict_of(int argc, const KrkValue argv[], int hasKw) { +KrkValue krk_dict_of_r(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { if (argc % 2 != 0) return krk_runtimeError(vm.exceptions->argumentError, "Expected even number of arguments to krk_dict_of"); KrkInstance * outDict = krk_newInstance(vm.baseClasses->dictClass); krk_push(OBJECT_VAL(outDict)); @@ -20,11 +20,11 @@ KrkValue krk_dict_of(int argc, const KrkValue argv[], int hasKw) { return krk_pop(); } -static void _dict_gcscan(KrkInstance * self) { +static void _dict_gcscan(KrkThreadState * _thread, KrkInstance * self) { krk_markTable(&((KrkDict*)self)->entries); } -static void _dict_gcsweep(KrkInstance * self) { +static void _dict_gcsweep(KrkThreadState * _thread, KrkInstance * self) { krk_freeTable(&((KrkDict*)self)->entries); } @@ -37,7 +37,7 @@ struct _keyvalue_pair_context { int counter; }; -static int _keyvalue_pair_callback(void * context, const KrkValue * entries, size_t count) { +static int _keyvalue_pair_callback(KrkThreadState * _thread, void * context, const KrkValue * entries, size_t count) { struct _keyvalue_pair_context * _context = context; if (count > 2) { @@ -62,7 +62,7 @@ static int _keyvalue_pair_callback(void * context, const KrkValue * entries, siz return 0; } -static int unpackKeyValuePair(void * self, const KrkValue * pairs, size_t count) { +static int unpackKeyValuePair(KrkThreadState * _thread, void * self, const KrkValue * pairs, size_t count) { struct _keyvalue_pair_context context = { (KrkDict*)self, NONE_VAL(), 0 }; for (size_t i = 0; i < count; ++i) { @@ -267,7 +267,7 @@ KRK_Method(dict,keys) { METHOD_TAKES_NONE(); KrkInstance * output = krk_newInstance(vm.baseClasses->dictkeysClass); krk_push(OBJECT_VAL(output)); - FUNC_NAME(dictkeys,__init__)(2, (KrkValue[]){krk_peek(0), argv[0]},0); + FUNC_NAME(dictkeys,__init__)(_thread, 2, (KrkValue[]){krk_peek(0), argv[0]},0); krk_pop(); return OBJECT_VAL(output); } @@ -278,7 +278,7 @@ KRK_Method(dict,items) { METHOD_TAKES_NONE(); KrkInstance * output = krk_newInstance(vm.baseClasses->dictitemsClass); krk_push(OBJECT_VAL(output)); - FUNC_NAME(dictitems,__init__)(2, (KrkValue[]){krk_peek(0), argv[0]},0); + FUNC_NAME(dictitems,__init__)(_thread, 2, (KrkValue[]){krk_peek(0), argv[0]},0); krk_pop(); return OBJECT_VAL(output); } @@ -289,12 +289,12 @@ KRK_Method(dict,values) { METHOD_TAKES_NONE(); KrkInstance * output = krk_newInstance(vm.baseClasses->dictvaluesClass); krk_push(OBJECT_VAL(output)); - FUNC_NAME(dictvalues,__init__)(2, (KrkValue[]){krk_peek(0), argv[0]},0); + FUNC_NAME(dictvalues,__init__)(_thread, 2, (KrkValue[]){krk_peek(0), argv[0]},0); krk_pop(); return OBJECT_VAL(output); } -KrkValue krk_dict_nth_key_fast(size_t capacity, KrkTableEntry * entries, size_t index) { +KrkValue krk_dict_nth_key_fast(KrkThreadState * _thread, size_t capacity, KrkTableEntry * entries, size_t index) { size_t found = 0; for (size_t i = 0; i < capacity; ++i) { if (IS_KWARGS(entries[i].key)) continue; @@ -307,7 +307,7 @@ KrkValue krk_dict_nth_key_fast(size_t capacity, KrkTableEntry * entries, size_t #undef CURRENT_CTYPE #define CURRENT_CTYPE struct DictItems * -static void _dictitems_gcscan(KrkInstance * self) { +static void _dictitems_gcscan(KrkThreadState * _thread, KrkInstance * self) { krk_markValue(((struct DictItems*)self)->dict); } @@ -391,7 +391,7 @@ KRK_Method(dictitems,__repr__) { #undef CURRENT_CTYPE #define CURRENT_CTYPE struct DictKeys * -static void _dictkeys_gcscan(KrkInstance * self) { +static void _dictkeys_gcscan(KrkThreadState * _thread, KrkInstance * self) { krk_markValue(((struct DictKeys*)self)->dict); } @@ -457,7 +457,7 @@ KRK_Method(dictkeys,__repr__) { #undef CURRENT_CTYPE #define CURRENT_CTYPE struct DictValues * -static void _dictvalues_gcscan(KrkInstance * self) { +static void _dictvalues_gcscan(KrkThreadState * _thread, KrkInstance * self) { krk_markValue(((struct DictValues*)self)->dict); } @@ -521,7 +521,7 @@ KRK_Method(dictvalues,__repr__) { } _noexport -void _createAndBind_dictClass(void) { +void _createAndBind_dictClass(KrkThreadState * _thread) { KrkClass * dict = ADD_BASE_CLASS(vm.baseClasses->dictClass, "dict", vm.baseClasses->objectClass); dict->allocSize = sizeof(KrkDict); dict->_ongcscan = _dict_gcscan; diff --git a/src/obj_function.c b/src/obj_function.c index 6b0a267..f8971c8 100644 --- a/src/obj_function.c +++ b/src/obj_function.c @@ -6,14 +6,14 @@ #include /* Check for and return the name of a native function as a string object */ -static KrkValue nativeFunctionName(KrkValue func) { +static KrkValue nativeFunctionName(KrkThreadState * _thread, KrkValue func) { const char * string = ((KrkNative*)AS_OBJECT(func))->name; if (!string) return OBJECT_VAL(S("")); size_t len = strlen(string); return OBJECT_VAL(krk_copyString(string,len)); } -static KrkTuple * functionArgs(KrkCodeObject * _self) { +static KrkTuple * functionArgs(KrkThreadState * _thread, KrkCodeObject * _self) { KrkTuple * tuple = krk_newTuple(_self->requiredArgs + _self->keywordArgs + !!(_self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) + !!(_self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS)); krk_push(OBJECT_VAL(tuple)); @@ -109,7 +109,7 @@ KRK_Method(function,__name__) { ATTRIBUTE_NOT_ASSIGNABLE(); if (IS_NATIVE(self)) { - return nativeFunctionName(self); + return nativeFunctionName(_thread, self); } else if (IS_CLOSURE(self) && AS_CLOSURE(self)->function->name) { return OBJECT_VAL(AS_CLOSURE(self)->function->name); } @@ -155,9 +155,9 @@ KRK_Method(function,__str__) { pushStringBuilderStr(&sb, "")); @@ -188,7 +188,7 @@ KRK_Method(function,__file__) { KRK_Method(function,__args__) { ATTRIBUTE_NOT_ASSIGNABLE(); if (!IS_CLOSURE(self)) return OBJECT_VAL(krk_newTuple(0)); - KrkTuple * tuple = functionArgs(AS_CLOSURE(self)->function); + KrkTuple * tuple = functionArgs(_thread, AS_CLOSURE(self)->function); return OBJECT_VAL(tuple); } @@ -218,7 +218,7 @@ KRK_Method(codeobject,__name__) { KRK_Method(codeobject,__str__) { METHOD_TAKES_NONE(); - KrkValue s = FUNC_NAME(codeobject,__name__)(1,argv,0); + KrkValue s = FUNC_NAME(codeobject,__name__)(_thread, 1,argv,0); if (!IS_STRING(s)) return NONE_VAL(); krk_push(s); @@ -290,7 +290,7 @@ KRK_Method(codeobject,co_flags) { KRK_Method(codeobject,__args__) { ATTRIBUTE_NOT_ASSIGNABLE(); - KrkTuple * tuple = functionArgs(self); + KrkTuple * tuple = functionArgs(_thread, self); return OBJECT_VAL(tuple); } @@ -309,23 +309,23 @@ FUNC_SIG(method,__init__) { KRK_Method(method,__name__) { ATTRIBUTE_NOT_ASSIGNABLE(); - return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__name__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?")); + return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__name__)(_thread, 1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?")); } KRK_Method(method,__qualname__) { ATTRIBUTE_NOT_ASSIGNABLE(); - return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__qualname__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?")); + return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__qualname__)(_thread, 1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?")); } KRK_Method(method,_ip_to_line) { METHOD_TAKES_EXACTLY(1); - return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,_ip_to_line)(2,(KrkValue[]){OBJECT_VAL(self->method),argv[1]},0) : OBJECT_VAL(S("?")); + return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,_ip_to_line)(_thread, 2,(KrkValue[]){OBJECT_VAL(self->method),argv[1]},0) : OBJECT_VAL(S("?")); } KRK_Method(method,__str__) { METHOD_TAKES_NONE(); - KrkValue s = FUNC_NAME(method,__qualname__)(1,argv,0); - if (!IS_STRING(s)) s = FUNC_NAME(method,__name__)(1,argv,0); + KrkValue s = FUNC_NAME(method,__qualname__)(_thread, 1,argv,0); + if (!IS_STRING(s)) s = FUNC_NAME(method,__name__)(_thread, 1,argv,0); if (!IS_STRING(s)) return NONE_VAL(); krk_push(s); @@ -344,27 +344,27 @@ KRK_Method(method,__str__) { KRK_Method(method,__file__) { ATTRIBUTE_NOT_ASSIGNABLE(); - return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__file__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?")); + return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__file__)(_thread, 1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?")); } KRK_Method(method,__args__) { ATTRIBUTE_NOT_ASSIGNABLE(); - return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__args__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?")); + return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__args__)(_thread, 1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?")); } KRK_Method(method,__doc__) { ATTRIBUTE_NOT_ASSIGNABLE(); - return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__doc__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?")); + return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__doc__)(_thread, 1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?")); } KRK_Method(method,__annotations__) { ATTRIBUTE_NOT_ASSIGNABLE(); - return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__annotations__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?")); + return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__annotations__)(_thread, 1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?")); } KRK_Method(method,__code__) { ATTRIBUTE_NOT_ASSIGNABLE(); - return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__code__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?")); + return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__code__)(_thread, 1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?")); } KRK_Method(method,__func__) { @@ -394,7 +394,7 @@ KRK_Function(classmethod) { } _noexport -void _createAndBind_functionClass(void) { +void _createAndBind_functionClass(KrkThreadState * _thread) { KrkClass * codeobject = ADD_BASE_CLASS(vm.baseClasses->codeobjectClass, "codeobject", vm.baseClasses->objectClass); codeobject->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT; BIND_METHOD(codeobject,__init__); diff --git a/src/obj_gen.c b/src/obj_gen.c index ef6ed96..06be334 100644 --- a/src/obj_gen.c +++ b/src/obj_gen.c @@ -37,7 +37,7 @@ struct generator { #define CURRENT_CTYPE struct generator * #define CURRENT_NAME self -static void _generator_close_upvalues(struct generator * self) { +static void _generator_close_upvalues(KrkThreadState * _thread, struct generator * self) { while (self->capturedUpvalues) { KrkUpvalue * upvalue = self->capturedUpvalues; upvalue->closed = self->args[upvalue->location]; @@ -46,7 +46,7 @@ static void _generator_close_upvalues(struct generator * self) { } } -static void _generator_gcscan(KrkInstance * _self) { +static void _generator_gcscan(KrkThreadState * _thread, KrkInstance * _self) { struct generator * self = (struct generator*)_self; krk_markObject((KrkObj*)self->closure); for (size_t i = 0; i < self->argCount; ++i) { @@ -58,14 +58,14 @@ static void _generator_gcscan(KrkInstance * _self) { krk_markValue(self->result); } -static void _generator_gcsweep(KrkInstance * self) { - _generator_close_upvalues((struct generator*)self); +static void _generator_gcsweep(KrkThreadState * _thread, KrkInstance * self) { + _generator_close_upvalues(_thread, (struct generator*)self); free(((struct generator*)self)->args); } -static void _set_generator_done(struct generator * self) { +static void _set_generator_done(KrkThreadState * _thread, struct generator * self) { self->ip = NULL; - _generator_close_upvalues(self); + _generator_close_upvalues(_thread, self); } /** @@ -79,7 +79,7 @@ static void _set_generator_done(struct generator * self) { * @param argCount Number of arguments in @p argsIn * @return A @ref generator object. */ -KrkInstance * krk_buildGenerator(KrkClosure * closure, KrkValue * argsIn, size_t argCount) { +KrkInstance * krk_buildGenerator_r(KrkThreadState * _thread, KrkClosure * closure, KrkValue * argsIn, size_t argCount) { /* Copy the args */ KrkValue * args = malloc(sizeof(KrkValue) * (argCount)); memcpy(args, argsIn, sizeof(KrkValue) * argCount); @@ -175,13 +175,13 @@ KRK_Method(generator,__call__) { if (IS_KWARGS(result) && AS_INTEGER(result) == 0) { self->result = krk_pop(); - _set_generator_done(self); + _set_generator_done(_thread, self); return OBJECT_VAL(self); } /* Was there an exception? */ if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) { - _set_generator_done(self); + _set_generator_done(_thread, self); krk_currentThread.stackTop = krk_currentThread.stack + frame->slots; return NONE_VAL(); } @@ -222,7 +222,7 @@ KRK_Method(generator,send) { if (!self->started && !IS_NONE(argv[1])) { return krk_runtimeError(vm.exceptions->typeError, "Can not send non-None value to just-started generator"); } - return FUNC_NAME(generator,__call__)(argc,argv,0); + return FUNC_NAME(generator,__call__)(_thread, argc,argv,0); } KRK_Method(generator,__finish__) { @@ -238,7 +238,7 @@ KRK_Method(generator,gi_running) { return BOOLEAN_VAL(self->running); } -int krk_getAwaitable(void) { +int krk_getAwaitable_r(KrkThreadState * _thread) { if (IS_generator(krk_peek(0)) && AS_generator(krk_peek(0))->type == KRK_OBJ_FLAGS_CODEOBJECT_IS_COROUTINE) { /* Good to go */ return 1; @@ -265,7 +265,7 @@ int krk_getAwaitable(void) { } _noexport -void _createAndBind_generatorClass(void) { +void _createAndBind_generatorClass(KrkThreadState * _thread) { KrkClass * generator = ADD_BASE_CLASS(vm.baseClasses->generatorClass, "generator", vm.baseClasses->objectClass); generator->allocSize = sizeof(struct generator); generator->_ongcscan = _generator_gcscan; diff --git a/src/obj_list.c b/src/obj_list.c index 1c23897..88a7b32 100644 --- a/src/obj_list.c +++ b/src/obj_list.c @@ -14,20 +14,20 @@ if (val < 0) val = 0; \ if (val > (krk_integer_type)self->values.count) val = self->values.count -static void _list_gcscan(KrkInstance * self) { +static void _list_gcscan(KrkThreadState * _thread, KrkInstance * self) { for (size_t i = 0; i < ((KrkList*)self)->values.count; ++i) { krk_markValue(((KrkList*)self)->values.values[i]); } } -static void _list_gcsweep(KrkInstance * self) { +static void _list_gcsweep(KrkThreadState * _thread, KrkInstance * self) { krk_freeValueArray(&((KrkList*)self)->values); } /** * Convenience constructor for the C API. */ -KrkValue krk_list_of(int argc, const KrkValue argv[], int hasKw) { +KrkValue krk_list_of_r(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { KrkValue outList = OBJECT_VAL(krk_newInstance(vm.baseClasses->listClass)); krk_push(outList); krk_initValueArray(AS_LIST(outList)); @@ -80,7 +80,7 @@ KRK_Method(list,__getitem__) { } /* make into a list */ - KrkValue result = krk_callNativeOnStack(len, &krk_currentThread.stackTop[-len], 0, krk_list_of); + KrkValue result = krk_callNativeOnStack(len, &krk_currentThread.stackTop[-len], 0, krk_list_of_r); krk_currentThread.stackTop[-len-1] = result; while (len) { krk_pop(); @@ -158,7 +158,7 @@ KRK_Method(list,__repr__) { return finishStringBuilder(&sb); } -static int _list_extend_callback(void * context, const KrkValue * values, size_t count) { +static int _list_extend_callback(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) { KrkValueArray * positionals = context; if (positionals->count + count > positionals->capacity) { size_t old = positionals->capacity; @@ -193,7 +193,7 @@ KRK_Method(list,__init__) { krk_initValueArray(AS_LIST(argv[0])); pthread_rwlock_init(&self->rwlock, NULL); if (argc == 2) { - _list_extend(2,(KrkValue[]){argv[0],argv[1]},0); + FUNC_NAME(list,extend)(_thread, 2,(KrkValue[]){argv[0],argv[1]},0); } return argv[0]; } @@ -207,7 +207,7 @@ KRK_Method(list,__mul__) { krk_push(out); for (krk_integer_type i = 0; i < howMany; i++) { - _list_extend(2, (KrkValue[]){out,argv[0]},0); + FUNC_NAME(list,extend)(_thread, 2, (KrkValue[]){out,argv[0]},0); } return krk_pop(); @@ -287,12 +287,12 @@ KRK_Method(list,__setitem__) { } while (len < newLen) { - FUNC_NAME(list,insert)(3, (KrkValue[]){argv[0], INTEGER_VAL(start + len), AS_LIST(argv[2])->values[len]}, 0); + FUNC_NAME(list,insert)(_thread, 3, (KrkValue[]){argv[0], INTEGER_VAL(start + len), AS_LIST(argv[2])->values[len]}, 0); len++; } while (newLen < len) { - FUNC_NAME(list,pop)(2, (KrkValue[]){argv[0], INTEGER_VAL(start + len - 1)}, 0); + FUNC_NAME(list,pop)(_thread, 2, (KrkValue[]){argv[0], INTEGER_VAL(start + len - 1)}, 0); len--; } @@ -306,7 +306,7 @@ KRK_Method(list,__delitem__) { METHOD_TAKES_EXACTLY(1); if (IS_INTEGER(argv[1])) { - FUNC_NAME(list,pop)(2,(KrkValue[]){argv[0],INTEGER_VAL(argv[1])},0); + FUNC_NAME(list,pop)(_thread, 2,(KrkValue[]){argv[0],INTEGER_VAL(argv[1])},0); } else if (IS_slice(argv[1])) { KRK_SLICER(argv[1],self->values.count) { return NONE_VAL(); @@ -319,7 +319,7 @@ KRK_Method(list,__delitem__) { krk_integer_type len = end - start; while (len > 0) { - FUNC_NAME(list,pop)(2,(KrkValue[]){argv[0],INTEGER_VAL(start)},0); + FUNC_NAME(list,pop)(_thread, 2,(KrkValue[]){argv[0],INTEGER_VAL(start)},0); len--; } } else { @@ -335,7 +335,7 @@ KRK_Method(list,remove) { for (size_t i = 0; i < self->values.count; ++i) { if (krk_valuesSameOrEqual(self->values.values[i], argv[1])) { pthread_rwlock_unlock(&self->rwlock); - return FUNC_NAME(list,pop)(2,(KrkValue[]){argv[0], INTEGER_VAL(i)},0); + return FUNC_NAME(list,pop)(_thread, 2,(KrkValue[]){argv[0], INTEGER_VAL(i)},0); } if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) { pthread_rwlock_unlock(&self->rwlock); @@ -428,9 +428,15 @@ KRK_Method(list,reverse) { return NONE_VAL(); } -static int _list_sorter(const void * _a, const void * _b) { + extern void qsort_r(void *base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *, void *), + void *arg); + + +static int _list_sorter(const void * _a, const void * _b, void * t) { KrkValue a = *(KrkValue*)_a; KrkValue b = *(KrkValue*)_b; + KrkThreadState * _thread = t; /* Avoid actually calling the sort function if there's an active exception */ if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return -1; @@ -445,7 +451,7 @@ KRK_Method(list,sort) { METHOD_TAKES_NONE(); pthread_rwlock_wrlock(&self->rwlock); - qsort(self->values.values, self->values.count, sizeof(KrkValue), _list_sorter); + qsort_r(self->values.values, self->values.count, sizeof(KrkValue), _list_sorter, _thread); pthread_rwlock_unlock(&self->rwlock); return NONE_VAL(); @@ -458,7 +464,7 @@ KRK_Method(list,__add__) { pthread_rwlock_rdlock(&self->rwlock); KrkValue outList = krk_list_of(self->values.count, self->values.values, 0); /* copy */ pthread_rwlock_unlock(&self->rwlock); - FUNC_NAME(list,extend)(2,(KrkValue[]){outList,argv[1]},0); /* extend */ + FUNC_NAME(list,extend)(_thread, 2,(KrkValue[]){outList,argv[1]},0); /* extend */ return outList; } @@ -469,7 +475,7 @@ KRK_Method(list,__iter__) { KrkInstance * output = krk_newInstance(vm.baseClasses->listiteratorClass); krk_push(OBJECT_VAL(output)); - FUNC_NAME(listiterator,__init__)(2, (KrkValue[]){krk_peek(0), argv[0]},0); + FUNC_NAME(listiterator,__init__)(_thread, 2, (KrkValue[]){krk_peek(0), argv[0]},0); krk_pop(); return OBJECT_VAL(output); @@ -508,7 +514,7 @@ struct ListIterator { #define IS_listiterator(o) (likely(IS_INSTANCE(o) && AS_INSTANCE(o)->_class == vm.baseClasses->listiteratorClass) || krk_isInstanceOf(o,vm.baseClasses->listiteratorClass)) #define AS_listiterator(o) (struct ListIterator*)AS_OBJECT(o) -static void _listiterator_gcscan(KrkInstance * self) { +static void _listiterator_gcscan(KrkThreadState * _thread, KrkInstance * self) { krk_markValue(((struct ListIterator*)self)->l); } @@ -544,32 +550,32 @@ _bad: goto _maybeGood; } -static KrkValue _sorted(int argc, const KrkValue argv[], int hasKw) { +static KrkValue _sorted(KrkThreadState *_thread, int argc, const KrkValue argv[], int hasKw) { if (argc != 1) return krk_runtimeError(vm.exceptions->argumentError,"%s() takes %s %d argument%s (%d given)","sorted","exactly",1,"",argc); KrkValue listOut = krk_list_of(0,NULL,0); krk_push(listOut); - FUNC_NAME(list,extend)(2,(KrkValue[]){listOut,argv[0]},0); + FUNC_NAME(list,extend)(_thread, 2,(KrkValue[]){listOut,argv[0]},0); if (!IS_NONE(krk_currentThread.currentException)) return NONE_VAL(); - FUNC_NAME(list,sort)(1,&listOut,0); + FUNC_NAME(list,sort)(_thread, 1,&listOut,0); if (!IS_NONE(krk_currentThread.currentException)) return NONE_VAL(); return krk_pop(); } -static KrkValue _reversed(int argc, const KrkValue argv[], int hasKw) { +static KrkValue _reversed(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { /* FIXME The Python reversed() function produces an iterator and only works for things with indexing or a __reversed__ method; * Building a list and reversing it like we do here is not correct! */ if (argc != 1) return krk_runtimeError(vm.exceptions->argumentError,"%s() takes %s %d argument%s (%d given)","reversed","exactly",1,"",argc); KrkValue listOut = krk_list_of(0,NULL,0); krk_push(listOut); - FUNC_NAME(list,extend)(2,(KrkValue[]){listOut,argv[0]},0); + FUNC_NAME(list,extend)(_thread, 2,(KrkValue[]){listOut,argv[0]},0); if (!IS_NONE(krk_currentThread.currentException)) return NONE_VAL(); - FUNC_NAME(list,reverse)(1,&listOut,0); + FUNC_NAME(list,reverse)(_thread, 1,&listOut,0); if (!IS_NONE(krk_currentThread.currentException)) return NONE_VAL(); return krk_pop(); } _noexport -void _createAndBind_listClass(void) { +void _createAndBind_listClass(KrkThreadState * _thread) { KrkClass * list = ADD_BASE_CLASS(vm.baseClasses->listClass, "list", vm.baseClasses->objectClass); list->allocSize = sizeof(KrkList); list->_ongcscan = _list_gcscan; diff --git a/src/obj_long.c b/src/obj_long.c index 471ff0b..9327681 100644 --- a/src/obj_long.c +++ b/src/obj_long.c @@ -1175,7 +1175,7 @@ static void make_long(krk_integer_type t, struct BigInt * self) { krk_long_init_si(self->value, t); } -static void _long_gcsweep(KrkInstance * self) { +static void _long_gcsweep(KrkThreadState * _thread, KrkInstance * self) { krk_long_clear(((struct BigInt*)self)->value); } @@ -1224,7 +1224,7 @@ KRK_Method(long,__float__) { return FLOATING_VAL(krk_long_get_double(self->value)); } -static KrkValue _krk_long_truediv(KrkLong * top, KrkLong * bottom) { +static KrkValue _krk_long_truediv(KrkThreadState * _thread, KrkLong * top, KrkLong * bottom) { if (bottom->width == 0) return krk_runtimeError(vm.exceptions->valueError, "float division by zero"); KrkLong quot, rem; @@ -1241,7 +1241,7 @@ static KrkValue _krk_long_truediv(KrkLong * top, KrkLong * bottom) { return FLOATING_VAL(quot_float + (rem_float / div_float)); } -static KrkValue checked_float_div(double top, double bottom) { +static KrkValue checked_float_div(KrkThreadState * _thread, double top, double bottom) { if (unlikely(bottom == 0.0)) return krk_runtimeError(vm.exceptions->valueError, "float division by zero"); return FLOATING_VAL(top/bottom); } @@ -1250,18 +1250,18 @@ KRK_Method(long,__truediv__) { krk_long tmp; if (IS_long(argv[1])) krk_long_init_copy(tmp, AS_long(argv[1])->value); else if (IS_INTEGER(argv[1])) krk_long_init_si(tmp, AS_INTEGER(argv[1])); - else if (IS_FLOATING(argv[1])) return checked_float_div(krk_long_get_double(self->value), AS_FLOATING(argv[1])); + else if (IS_FLOATING(argv[1])) return checked_float_div(_thread, krk_long_get_double(self->value), AS_FLOATING(argv[1])); else return NOTIMPL_VAL(); - return _krk_long_truediv(self->value,tmp); + return _krk_long_truediv(_thread, self->value,tmp); } KRK_Method(long,__rtruediv__) { krk_long tmp; if (IS_long(argv[1])) krk_long_init_copy(tmp, AS_long(argv[1])->value); else if (IS_INTEGER(argv[1])) krk_long_init_si(tmp, AS_INTEGER(argv[1])); - else if (IS_FLOATING(argv[1])) return checked_float_div(AS_FLOATING(argv[1]), krk_long_get_double(self->value)); + else if (IS_FLOATING(argv[1])) return checked_float_div(_thread, AS_FLOATING(argv[1]), krk_long_get_double(self->value)); else return NOTIMPL_VAL(); - return _krk_long_truediv(tmp,self->value); + return _krk_long_truediv(_thread, tmp,self->value); } #define PRINTER(name,base,prefix) \ @@ -1280,7 +1280,7 @@ KRK_Method(long,__hash__) { return INTEGER_VAL((uint32_t)(krk_long_medium(self->value))); } -static KrkValue make_long_obj(KrkLong * val) { +static KrkValue make_long_obj_r(KrkThreadState * _thread, KrkLong * val) { krk_integer_type maybe = 0; if (val->width == 0) { maybe = 0; @@ -1301,8 +1301,9 @@ static KrkValue make_long_obj(KrkLong * val) { krk_long_clear(val); return INTEGER_VAL(maybe); } +#define make_long_obj(v) make_long_obj_r(_thread, v) -KrkValue krk_parse_int(const char * start, size_t width, unsigned int base) { +KrkValue krk_parse_int_r(KrkThreadState * _thread, const char * start, size_t width, unsigned int base) { KrkLong _value; if (krk_long_parse_string(start, &_value, base, width)) { return NONE_VAL(); @@ -1335,7 +1336,7 @@ KRK_Method(long,__int__) { return make_long_obj(tmp); \ } \ _noexport \ - KrkValue krk_long_coerced_ ## name (krk_integer_type a, krk_integer_type b) { \ + KrkValue krk_long_coerced_ ## name (KrkThreadState * _thread, krk_integer_type a, krk_integer_type b) { \ krk_long tmp_res, tmp_a, tmp_b; \ krk_long_init_si(tmp_res, 0); \ krk_long_init_si(tmp_a, a); \ @@ -1357,7 +1358,7 @@ BASIC_BIN_OP(or, krk_long_or) BASIC_BIN_OP(xor,krk_long_xor) BASIC_BIN_OP(and,krk_long_and) -static void _krk_long_lshift(krk_long out, krk_long val, krk_long shift) { +static void _krk_long_lshift(KrkThreadState * _thread, krk_long out, krk_long val, krk_long shift) { if (krk_long_sign(shift) < 0) { krk_runtimeError(vm.exceptions->valueError, "negative shift count"); return; } krk_long multiplier; krk_long_init_si(multiplier,0); @@ -1366,7 +1367,7 @@ static void _krk_long_lshift(krk_long out, krk_long val, krk_long shift) { krk_long_clear(multiplier); } -static void _krk_long_rshift(krk_long out, krk_long val, krk_long shift) { +static void _krk_long_rshift(KrkThreadState * _thread, krk_long out, krk_long val, krk_long shift) { if (krk_long_sign(shift) < 0) { krk_runtimeError(vm.exceptions->valueError, "negative shift count"); return; } krk_long multiplier, garbage; krk_long_init_many(multiplier,garbage,NULL); @@ -1375,7 +1376,7 @@ static void _krk_long_rshift(krk_long out, krk_long val, krk_long shift) { krk_long_clear_many(multiplier,garbage,NULL); } -static void _krk_long_mod(krk_long out, krk_long a, krk_long b) { +static void _krk_long_mod(KrkThreadState * _thread, krk_long out, krk_long a, krk_long b) { if (krk_long_sign(b) == 0) { krk_runtimeError(vm.exceptions->valueError, "integer division or modulo by zero"); return; } krk_long garbage; krk_long_init_si(garbage,0); @@ -1383,7 +1384,7 @@ static void _krk_long_mod(krk_long out, krk_long a, krk_long b) { krk_long_clear(garbage); } -static void _krk_long_div(krk_long out, krk_long a, krk_long b) { +static void _krk_long_div(KrkThreadState * _thread, krk_long out, krk_long a, krk_long b) { if (krk_long_sign(b) == 0) { krk_runtimeError(vm.exceptions->valueError, "integer division or modulo by zero"); return; } krk_long garbage; krk_long_init_si(garbage,0); @@ -1391,7 +1392,7 @@ static void _krk_long_div(krk_long out, krk_long a, krk_long b) { krk_long_clear(garbage); } -static void _krk_long_pow(krk_long out, krk_long a, krk_long b) { +static void _krk_long_pow(KrkThreadState * _thread, krk_long out, krk_long a, krk_long b) { if (krk_long_sign(b) == 0) { krk_long_clear(out); krk_long_init_si(out, 1); @@ -1450,11 +1451,40 @@ static void _krk_long_pow(krk_long out, krk_long a, krk_long b) { FINISH_OUTPUT(out); } -BASIC_BIN_OP(lshift,_krk_long_lshift) -BASIC_BIN_OP(rshift,_krk_long_rshift) -BASIC_BIN_OP(mod,_krk_long_mod) -BASIC_BIN_OP(floordiv,_krk_long_div) -BASIC_BIN_OP(pow,_krk_long_pow) + +#define UNBASIC_BIN_OP(name, long_func) \ + KRK_Method(long,__ ## name ## __) { \ + krk_long tmp; \ + if (IS_long(argv[1])) krk_long_init_copy(tmp, AS_long(argv[1])->value); \ + else if (IS_INTEGER(argv[1])) krk_long_init_si(tmp, AS_INTEGER(argv[1])); \ + else return NOTIMPL_VAL(); \ + long_func(_thread,tmp,self->value,tmp); \ + return make_long_obj(tmp); \ + } \ + KRK_Method(long,__r ## name ## __) { \ + krk_long tmp; \ + if (IS_long(argv[1])) krk_long_init_copy(tmp, AS_long(argv[1])->value); \ + else if (IS_INTEGER(argv[1])) krk_long_init_si(tmp, AS_INTEGER(argv[1])); \ + else return NOTIMPL_VAL(); \ + long_func(_thread,tmp,tmp,self->value); \ + return make_long_obj(tmp); \ + } \ + _noexport \ + KrkValue krk_long_coerced_ ## name (KrkThreadState * _thread, krk_integer_type a, krk_integer_type b) { \ + krk_long tmp_res, tmp_a, tmp_b; \ + krk_long_init_si(tmp_res, 0); \ + krk_long_init_si(tmp_a, a); \ + krk_long_init_si(tmp_b, b); \ + long_func(_thread,tmp_res, tmp_a, tmp_b); \ + krk_long_clear_many(tmp_a, tmp_b, NULL); \ + return make_long_obj(tmp_res); \ + } + +UNBASIC_BIN_OP(lshift,_krk_long_lshift) +UNBASIC_BIN_OP(rshift,_krk_long_rshift) +UNBASIC_BIN_OP(mod,_krk_long_mod) +UNBASIC_BIN_OP(floordiv,_krk_long_div) +UNBASIC_BIN_OP(pow,_krk_long_pow) #define COMPARE_OP(name, comp) \ KRK_Method(long,__ ## name ## __) { \ @@ -1509,9 +1539,9 @@ KRK_Method(long,__pos__) { return argv[0]; } -extern KrkValue krk_doFormatString(const char * typeName, KrkString * format_spec, int positive, void* abs, int (*callback)(void *,int,int*)); +extern KrkValue krk_doFormatString(KrkThreadState *, const char * typeName, KrkString * format_spec, int positive, void* abs, int (*callback)(KrkThreadState *,void *,int,int*)); -static int formatLongCallback(void * a, int base, int *more) { +static int formatLongCallback(KrkThreadState * _thread, void * a, int base, int *more) { uint32_t result = _div_inplace((KrkLong*)a, base); *more = krk_long_sign(a); return result; @@ -1525,7 +1555,7 @@ KRK_Method(long,__format__) { krk_long_init_copy(&tmp, self->value); krk_long_set_sign(&tmp, 1); - KrkValue result = krk_doFormatString("long",format_spec, + KrkValue result = krk_doFormatString(_thread, "long",format_spec, krk_long_sign(self->value) >= 0, &tmp, formatLongCallback); @@ -1534,7 +1564,7 @@ KRK_Method(long,__format__) { return result; } -static KrkValue long_bit_count(KrkLong * val) { +static KrkValue long_bit_count(KrkThreadState * _thread, KrkLong * val) { size_t count = 0; size_t bits = _bits_in(val); @@ -1548,10 +1578,10 @@ static KrkValue long_bit_count(KrkLong * val) { } KRK_Method(long,bit_count) { - return long_bit_count(self->value); + return long_bit_count(_thread,self->value); } -static KrkValue long_bit_length(KrkLong * val) { +static KrkValue long_bit_length(KrkThreadState * _thread, KrkLong * val) { size_t bits = _bits_in(val); KrkLong tmp; krk_long_init_ui(&tmp, bits); @@ -1559,10 +1589,10 @@ static KrkValue long_bit_length(KrkLong * val) { } KRK_Method(long,bit_length) { - return long_bit_length(self->value); + return long_bit_length(_thread, self->value); } -static KrkValue long_to_bytes(KrkLong * val, size_t argc, const KrkValue argv[], int hasKw) { +static KrkValue long_to_bytes(KrkThreadState * _thread, KrkLong * val, size_t argc, const KrkValue argv[], int hasKw) { static const char _method_name[] = "to_bytes"; /** * @fn to_bytes(length: int, byteorder: str, *, signed: bool = False) -> bytes @@ -1681,7 +1711,7 @@ static KrkValue long_to_bytes(KrkLong * val, size_t argc, const KrkValue argv[], KRK_Method(long,to_bytes) { METHOD_TAKES_AT_LEAST(2); - return long_to_bytes(self->value, argc, argv, hasKw); + return long_to_bytes(_thread, self->value, argc, argv, hasKw); } /** @@ -1747,7 +1777,7 @@ KRK_Method(long,_get_digit) { KRK_Method(int,bit_count) { krk_long value; krk_long_init_si(value, self); - KrkValue out = long_bit_count(value); + KrkValue out = long_bit_count(_thread,value); krk_long_clear(value); return out; } @@ -1755,7 +1785,7 @@ KRK_Method(int,bit_count) { KRK_Method(int,bit_length) { krk_long value; krk_long_init_si(value, self); - KrkValue out = long_bit_length(value); + KrkValue out = long_bit_length(_thread, value); krk_long_clear(value); return out; } @@ -1763,7 +1793,7 @@ KRK_Method(int,bit_length) { KRK_Method(int,to_bytes) { krk_long value; krk_long_init_si(value, self); - KrkValue out = long_to_bytes(value, argc, argv, hasKw); + KrkValue out = long_to_bytes(_thread, value, argc, argv, hasKw); krk_long_clear(value); return out; } @@ -1776,7 +1806,7 @@ KRK_Method(int,to_bytes) { BIND_METHOD(klass,__r ## name ## __); \ krk_defineNative(&_ ## klass->methods,"__i" #name "__",_ ## klass ## ___ ## name ## __); _noexport -void _createAndBind_longClass(void) { +void _createAndBind_longClass(KrkThreadState * _thread) { KrkClass * _long = ADD_BASE_CLASS(vm.baseClasses->longClass, "long", vm.baseClasses->intClass); _long->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT; _long->allocSize = sizeof(struct BigInt); diff --git a/src/obj_numeric.c b/src/obj_numeric.c index 66feb60..564411c 100644 --- a/src/obj_numeric.c +++ b/src/obj_numeric.c @@ -71,7 +71,7 @@ static inline int matches(char c, const char * options) { return 0; } -const char * krk_parseCommonFormatSpec(struct ParsedFormatSpec *result, const char * spec, size_t length) { +const char * krk_parseCommonFormatSpec(KrkThreadState * _thread, struct ParsedFormatSpec *result, const char * spec, size_t length) { result->fill = " "; result->fillSize = 1; @@ -147,10 +147,10 @@ const char * krk_parseCommonFormatSpec(struct ParsedFormatSpec *result, const ch return spec; } -KrkValue krk_doFormatString(const char * typeName, KrkString * format_spec, int positive, void * abs, int (*callback)(void *,int,int*)) { +KrkValue krk_doFormatString(KrkThreadState * _thread, const char * typeName, KrkString * format_spec, int positive, void * abs, int (*callback)(KrkThreadState*,void *,int,int*)) { struct ParsedFormatSpec opts = {0}; - const char * spec = krk_parseCommonFormatSpec(&opts, format_spec->chars, format_spec->length); + const char * spec = krk_parseCommonFormatSpec(_thread, &opts, format_spec->chars, format_spec->length); if (!spec) return NONE_VAL(); const char * altPrefix = NULL; @@ -211,7 +211,7 @@ KrkValue krk_doFormatString(const char * typeName, KrkString * format_spec, int int more = 0; do { - int digit = callback(abs, base, &more); + int digit = callback(_thread, abs, base, &more); if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) { discardStringBuilder(&sb); @@ -283,7 +283,7 @@ KrkValue krk_doFormatString(const char * typeName, KrkString * format_spec, int return finishStringBuilder(&sb); } -static int formatIntCallback(void * a, int base, int *more) { +static int formatIntCallback(KrkThreadState *_thread,void * a, int base, int *more) { krk_integer_type v = *(krk_integer_type*)a; int digit = v % base; v /= base; @@ -299,7 +299,7 @@ KRK_Method(int,__format__) { krk_integer_type abs = self < 0 ? -self : self; - return krk_doFormatString(krk_typeName(argv[0]), format_spec, + return krk_doFormatString(_thread, krk_typeName(argv[0]), format_spec, self >= 0, &abs, formatIntCallback); @@ -316,15 +316,15 @@ KRK_Method(int,__format__) { * and then reduce if that still yields something that would fit in our 'int48'. */ #define OVERFLOW_CHECKED_INT_OPERATION(name,operator) \ - extern KrkValue krk_long_coerced_ ## name (krk_integer_type a, krk_integer_type b); \ + extern KrkValue krk_long_coerced_ ## name (KrkThreadState *, krk_integer_type a, krk_integer_type b); \ _noexport \ - KrkValue krk_int_op_ ## name (krk_integer_type a, krk_integer_type b) { \ + KrkValue krk_int_op_ ## name (KrkThreadState * _thread, krk_integer_type a, krk_integer_type b) { \ if (likely((int32_t)a == a && (int32_t)b == b)) { \ int32_t result_one = a operator b; \ int64_t result_two = a operator b; \ if (likely(result_one == result_two)) return INTEGER_VAL(result_two); \ } \ - return krk_long_coerced_ ## name (a, b); \ + return krk_long_coerced_ ## name (_thread, a, b); \ } OVERFLOW_CHECKED_INT_OPERATION(add,+) @@ -333,12 +333,12 @@ OVERFLOW_CHECKED_INT_OPERATION(mul,*) #define BASIC_BIN_OP(name,operator) \ KRK_Method(int,__ ## name ## __) { \ - if (likely(IS_INTEGER(argv[1]))) return krk_int_op_ ## name(self, AS_INTEGER(argv[1])); \ + if (likely(IS_INTEGER(argv[1]))) return krk_int_op_ ## name(_thread, self, AS_INTEGER(argv[1])); \ else if (likely(IS_FLOATING(argv[1]))) return FLOATING_VAL((double)self operator AS_FLOATING(argv[1])); \ return NOTIMPL_VAL(); \ } \ KRK_Method(int,__r ## name ## __) { \ - if (likely(IS_INTEGER(argv[1]))) return krk_int_op_ ## name(AS_INTEGER(argv[1]), self); \ + if (likely(IS_INTEGER(argv[1]))) return krk_int_op_ ## name(_thread, AS_INTEGER(argv[1]), self); \ else if (likely(IS_FLOATING(argv[1]))) return FLOATING_VAL(AS_FLOATING(argv[1]) operator (double)self); \ return NOTIMPL_VAL(); \ } @@ -368,13 +368,13 @@ INT_ONLY_BIN_OP(xor,^) INT_ONLY_BIN_OP(and,&) #define DEFER_TO_LONG(name) \ - extern KrkValue krk_long_coerced_ ## name (krk_integer_type a, krk_integer_type b); \ + extern KrkValue krk_long_coerced_ ## name (KrkThreadState *, krk_integer_type a, krk_integer_type b); \ KRK_Method(int,__ ## name ## __) { \ - if (likely(IS_INTEGER(argv[1]))) return krk_long_coerced_ ## name (self, AS_INTEGER(argv[1])); \ + if (likely(IS_INTEGER(argv[1]))) return krk_long_coerced_ ## name (_thread,self, AS_INTEGER(argv[1])); \ return NOTIMPL_VAL(); \ } \ KRK_Method(int,__r ## name ## __) { \ - if (likely(IS_INTEGER(argv[1]))) return krk_long_coerced_ ## name (AS_INTEGER(argv[1]), self); \ + if (likely(IS_INTEGER(argv[1]))) return krk_long_coerced_ ## name (_thread,AS_INTEGER(argv[1]), self); \ return NOTIMPL_VAL(); \ } @@ -423,7 +423,7 @@ KRK_Method(int,__rtruediv__) { * that Python produces, for compatibility, and also because that's * what our 'long' type does... */ -static KrkValue _krk_int_div(krk_integer_type a, krk_integer_type b) { +static KrkValue _krk_int_div(KrkThreadState * _thread, krk_integer_type a, krk_integer_type b) { if (unlikely(b == 0)) return krk_runtimeError(vm.exceptions->zeroDivisionError, "integer division or modulo by zero"); if (a == 0) return INTEGER_VAL(0); int64_t abs_a = a < 0 ? -a : a; @@ -436,7 +436,7 @@ static KrkValue _krk_int_div(krk_integer_type a, krk_integer_type b) { return INTEGER_VAL((abs_a / abs_b)); } -static KrkValue _krk_int_mod(krk_integer_type a, krk_integer_type b) { +static KrkValue _krk_int_mod(KrkThreadState * _thread, krk_integer_type a, krk_integer_type b) { if (unlikely(b == 0)) return krk_runtimeError(vm.exceptions->zeroDivisionError, "integer division or modulo by zero"); if (a == 0) return INTEGER_VAL(0); int64_t abs_a = a < 0 ? -a : a; @@ -455,13 +455,13 @@ static KrkValue _krk_int_mod(krk_integer_type a, krk_integer_type b) { KRK_Method(int,__mod__) { METHOD_TAKES_EXACTLY(1); - if (likely(IS_INTEGER(argv[1]))) return _krk_int_mod(self, AS_INTEGER(argv[1])); + if (likely(IS_INTEGER(argv[1]))) return _krk_int_mod(_thread, self, AS_INTEGER(argv[1])); return NOTIMPL_VAL(); } KRK_Method(int,__rmod__) { METHOD_TAKES_EXACTLY(1); - if (likely(IS_INTEGER(argv[1]))) return _krk_int_mod(AS_INTEGER(argv[1]), self); + if (likely(IS_INTEGER(argv[1]))) return _krk_int_mod(_thread, AS_INTEGER(argv[1]), self); return NOTIMPL_VAL(); } @@ -469,7 +469,7 @@ KRK_Method(int,__rmod__) { KRK_Method(int,__floordiv__) { METHOD_TAKES_EXACTLY(1); if (likely(IS_INTEGER(argv[1]))) { - return _krk_int_div(self,AS_INTEGER(argv[1])); + return _krk_int_div(_thread, self,AS_INTEGER(argv[1])); } else if (likely(IS_FLOATING(argv[1]))) { double b = AS_FLOATING(argv[1]); if (unlikely(b == 0.0)) return krk_runtimeError(vm.exceptions->zeroDivisionError, "float division by zero"); @@ -481,7 +481,7 @@ KRK_Method(int,__floordiv__) { KRK_Method(int,__rfloordiv__) { METHOD_TAKES_EXACTLY(1); if (unlikely(self == 0)) return krk_runtimeError(vm.exceptions->zeroDivisionError, "integer division by zero"); - else if (likely(IS_INTEGER(argv[1]))) return _krk_int_div(AS_INTEGER(argv[1]), self); + else if (likely(IS_INTEGER(argv[1]))) return _krk_int_div(_thread, AS_INTEGER(argv[1]), self); else if (likely(IS_FLOATING(argv[1]))) return FLOATING_VAL(__builtin_floor(AS_FLOATING(argv[1]) / (double)self)); return NOTIMPL_VAL(); } @@ -757,7 +757,7 @@ KRK_Method(NotImplementedType,__eq__) { BIND_METHOD(klass,__r ## name ## __); \ krk_defineNative(&_ ## klass->methods,"__i" #name "__",_ ## klass ## ___ ## name ## __); _noexport -void _createAndBind_numericClasses(void) { +void _createAndBind_numericClasses(KrkThreadState *_thread) { KrkClass * _int = ADD_BASE_CLASS(vm.baseClasses->intClass, "int", vm.baseClasses->objectClass); _int->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT; BIND_METHOD(int,__init__); diff --git a/src/obj_range.c b/src/obj_range.c index 05739a4..05c4c19 100644 --- a/src/obj_range.c +++ b/src/obj_range.c @@ -80,7 +80,7 @@ KRK_Method(range,__iter__) { krk_integer_type step = self->step; krk_push(OBJECT_VAL(output)); - FUNC_NAME(rangeiterator,__init__)(4, (KrkValue[]){krk_peek(0), INTEGER_VAL(min), INTEGER_VAL(max), INTEGER_VAL(step)},0); + FUNC_NAME(rangeiterator,__init__)(_thread, 4, (KrkValue[]){krk_peek(0), INTEGER_VAL(min), INTEGER_VAL(max), INTEGER_VAL(step)},0); krk_pop(); return OBJECT_VAL(output); @@ -112,7 +112,7 @@ KRK_Method(rangeiterator,__call__) { } _noexport -void _createAndBind_rangeClass(void) { +void _createAndBind_rangeClass(KrkThreadState * _thread) { KrkClass * range = ADD_BASE_CLASS(vm.baseClasses->rangeClass, "range", vm.baseClasses->objectClass); range->allocSize = sizeof(struct Range); range->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT; diff --git a/src/obj_set.c b/src/obj_set.c index 406b57f..8279af9 100644 --- a/src/obj_set.c +++ b/src/obj_set.c @@ -16,11 +16,11 @@ struct Set { #define IS_set(o) krk_isInstanceOf(o,KRK_BASE_CLASS(set)) #define AS_set(o) ((struct Set*)AS_OBJECT(o)) -static void _set_gcscan(KrkInstance * self) { +static void _set_gcscan(KrkThreadState * _thread, KrkInstance * self) { krk_markTable(&((struct Set*)self)->entries); } -static void _set_gcsweep(KrkInstance * self) { +static void _set_gcsweep(KrkThreadState * _thread, KrkInstance * self) { krk_freeTable(&((struct Set*)self)->entries); } @@ -36,14 +36,14 @@ struct SetIterator { #define IS_setiterator(o) krk_isInstanceOf(o,KRK_BASE_CLASS(setiterator)) #define AS_setiterator(o) ((struct SetIterator*)AS_OBJECT(o)) -static void _setiterator_gcscan(KrkInstance * self) { +static void _setiterator_gcscan(KrkThreadState * _thread, KrkInstance * self) { krk_markValue(((struct SetIterator*)self)->set); } #define CURRENT_CTYPE struct Set * #define CURRENT_NAME self -static int _set_init_callback(void * context, const KrkValue * values, size_t count) { +static int _set_init_callback(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) { struct Set * self = context; for (size_t i = 0; i < count; ++i) { krk_tableSet(&self->entries, values[i], BOOLEAN_VAL(1)); @@ -104,7 +104,7 @@ KRK_Method(set,__and__) { KrkValue outSet = OBJECT_VAL(krk_newInstance(KRK_BASE_CLASS(set))); krk_push(outSet); - FUNC_NAME(set,__init__)(1,&outSet,0); + FUNC_NAME(set,__init__)(_thread, 1,&outSet,0); KrkClass * type = krk_getType(argv[1]); if (!type->_contains) @@ -132,7 +132,7 @@ KRK_Method(set,__xor__) { KrkValue outSet = OBJECT_VAL(krk_newInstance(KRK_BASE_CLASS(set))); krk_push(outSet); - FUNC_NAME(set,__init__)(1,&outSet,0); + FUNC_NAME(set,__init__)(_thread, 1,&outSet,0); KrkClass * type = krk_getType(argv[1]); if (!type->_contains) @@ -177,7 +177,7 @@ KRK_Method(set,__or__) { KrkValue outSet = OBJECT_VAL(krk_newInstance(KRK_BASE_CLASS(set))); krk_push(outSet); - FUNC_NAME(set,__init__)(1,&outSet,0); + FUNC_NAME(set,__init__)(_thread, 1,&outSet,0); krk_tableAddAll(&self->entries, &AS_set(outSet)->entries); krk_tableAddAll(&them->entries, &AS_set(outSet)->entries); @@ -300,7 +300,7 @@ KRK_Method(set,__iter__) { METHOD_TAKES_NONE(); KrkInstance * output = krk_newInstance(KRK_BASE_CLASS(setiterator)); krk_push(OBJECT_VAL(output)); - FUNC_NAME(setiterator,__init__)(2,(KrkValue[]){krk_peek(0), argv[0]}, 0); + FUNC_NAME(setiterator,__init__)(_thread, 2,(KrkValue[]){krk_peek(0), argv[0]}, 0); return krk_pop(); } @@ -331,7 +331,7 @@ KRK_Method(setiterator,__call__) { } while (1); } -KrkValue krk_set_of(int argc, const KrkValue argv[], int hasKw) { +KrkValue krk_set_of_r(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { KrkValue outSet = OBJECT_VAL(krk_newInstance(KRK_BASE_CLASS(set))); krk_push(outSet); krk_initTable(&AS_set(outSet)->entries); @@ -345,7 +345,7 @@ KrkValue krk_set_of(int argc, const KrkValue argv[], int hasKw) { } _noexport -void _createAndBind_setClass(void) { +void _createAndBind_setClass(KrkThreadState * _thread) { KrkClass * set = krk_makeClass(vm.builtins, &KRK_BASE_CLASS(set), "set", vm.baseClasses->objectClass); set->allocSize = sizeof(struct Set); set->_ongcscan = _set_gcscan; diff --git a/src/obj_slice.c b/src/obj_slice.c index 700d7c3..950998c 100644 --- a/src/obj_slice.c +++ b/src/obj_slice.c @@ -5,13 +5,13 @@ #include #include -static void _slice_gcscan(KrkInstance * self) { +static void _slice_gcscan(KrkThreadState * _thread, KrkInstance * self) { krk_markValue(((struct KrkSlice*)self)->start); krk_markValue(((struct KrkSlice*)self)->end); krk_markValue(((struct KrkSlice*)self)->step); } -KrkValue krk_slice_of(int argc, const KrkValue argv[], int hasKw) { +KrkValue krk_slice_of_r(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { KrkValue outSlice = OBJECT_VAL(krk_newInstance(vm.baseClasses->sliceClass)); krk_push(outSlice); @@ -36,7 +36,7 @@ static inline krk_integer_type _wrapn(krk_integer_type count, krk_integer_type v return val; } -int krk_extractSlicer(const char * _method_name, KrkValue slicerVal, krk_integer_type count, krk_integer_type *start, krk_integer_type *end, krk_integer_type *step) { +int krk_extractSlicer(KrkThreadState * _thread, const char * _method_name, KrkValue slicerVal, krk_integer_type count, krk_integer_type *start, krk_integer_type *end, krk_integer_type *step) { if (!(IS_slice(slicerVal))) { TYPE_ERROR(slice, slicerVal); return 1; @@ -166,7 +166,7 @@ KRK_Method(slice,step) { } _noexport -void _createAndBind_sliceClass(void) { +void _createAndBind_sliceClass(KrkThreadState * _thread) { KrkClass * slice = ADD_BASE_CLASS(vm.baseClasses->sliceClass, "slice", vm.baseClasses->objectClass); slice->allocSize = sizeof(struct KrkSlice); slice->_ongcscan = _slice_gcscan; diff --git a/src/obj_str.c b/src/obj_str.c index e5223e3..275a857 100644 --- a/src/obj_str.c +++ b/src/obj_str.c @@ -6,7 +6,7 @@ #include "private.h" -static KrkValue FUNC_NAME(striterator,__init__)(int,const KrkValue[],int); +static KrkValue FUNC_NAME(striterator,__init__)(KrkThreadState*,int,const KrkValue[],int); #define CURRENT_CTYPE KrkString * #define CURRENT_NAME self @@ -169,14 +169,14 @@ KRK_Method(str,__getitem__) { } } -const char * krk_parseCommonFormatSpec(struct ParsedFormatSpec *result, const char * spec, size_t length); +const char * krk_parseCommonFormatSpec(KrkThreadState * _thread, struct ParsedFormatSpec *result, const char * spec, size_t length); KRK_Method(str,__format__) { METHOD_TAKES_EXACTLY(1); CHECK_ARG(1,str,KrkString*,format_spec); struct ParsedFormatSpec opts = {0}; - const char * spec = krk_parseCommonFormatSpec(&opts, format_spec->chars, format_spec->length); + const char * spec = krk_parseCommonFormatSpec(_thread, &opts, format_spec->chars, format_spec->length); if (!spec) return NONE_VAL(); switch (*spec) { @@ -408,7 +408,7 @@ KRK_Method(str,__mul__) { KRK_Method(str,__rmul__) { METHOD_TAKES_EXACTLY(1); - if (IS_INTEGER(argv[1])) return FUNC_NAME(str,__mul__)(argc,argv,hasKw); + if (IS_INTEGER(argv[1])) return FUNC_NAME(str,__mul__)(_thread, argc,argv,hasKw); return NOTIMPL_VAL(); } @@ -418,7 +418,7 @@ struct _str_join_context { int isFirst; }; -static int _str_join_callback(void * context, const KrkValue * values, size_t count) { +static int _str_join_callback(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) { struct _str_join_context * _context = context; for (size_t i = 0; i < count; ++i) { @@ -490,7 +490,7 @@ static int charIn(uint32_t c, KrkString * str) { * Implements all three of strip, lstrip, rstrip. * Set which = 0, 1, 2 respectively */ -static KrkValue _string_strip_shared(int argc, const KrkValue argv[], int which) { +static KrkValue _string_strip_shared(KrkThreadState *_thread, int argc, const KrkValue argv[], int which) { KrkString * subset = AS_STRING(vm.specialMethodNames[METHOD_STRSTRIP]); if (argc > 1) { if (IS_STRING(argv[1])) { @@ -519,15 +519,15 @@ static KrkValue _string_strip_shared(int argc, const KrkValue argv[], int which) KRK_Method(str,strip) { METHOD_TAKES_AT_MOST(1); /* TODO */ - return _string_strip_shared(argc,argv,0); + return _string_strip_shared(_thread, argc,argv,0); } KRK_Method(str,lstrip) { METHOD_TAKES_AT_MOST(1); /* TODO */ - return _string_strip_shared(argc,argv,1); + return _string_strip_shared(_thread, argc,argv,1); } KRK_Method(str,rstrip) { METHOD_TAKES_AT_MOST(1); /* TODO */ - return _string_strip_shared(argc,argv,2); + return _string_strip_shared(_thread, argc,argv,2); } #define strCompare(name,lop,iop,rop) \ @@ -831,7 +831,7 @@ KRK_Method(str,find) { } KRK_Method(str,index) { - KrkValue result = FUNC_NAME(str,find)(argc,argv,hasKw); + KrkValue result = FUNC_NAME(str,find)(_thread, argc,argv,hasKw); if (IS_INTEGER(result) && AS_INTEGER(result) == -1) { return krk_runtimeError(vm.exceptions->valueError, "substring not found"); } @@ -924,8 +924,8 @@ KRK_Method(str,__str__) { return argv[0]; } -void krk_addObjects(void) { - KrkValue tmp = FUNC_NAME(str,__add__)(2, (KrkValue[]){krk_peek(1), krk_peek(0)},0); +void krk_addObjects_r(KrkThreadState * _thread) { + KrkValue tmp = FUNC_NAME(str,__add__)(_thread, 2, (KrkValue[]){krk_peek(1), krk_peek(0)},0); krk_pop(); krk_pop(); krk_push(tmp); } @@ -935,7 +935,7 @@ KRK_Method(str,__iter__) { KrkInstance * output = krk_newInstance(vm.baseClasses->striteratorClass); krk_push(OBJECT_VAL(output)); - FUNC_NAME(striterator,__init__)(2, (KrkValue[]){krk_peek(0), argv[0]},0); + FUNC_NAME(striterator,__init__)(_thread, 2, (KrkValue[]){krk_peek(0), argv[0]},0); krk_pop(); return OBJECT_VAL(output); @@ -1057,14 +1057,14 @@ KRK_Method(striterator,__call__) { return argv[0]; } else { krk_attachNamedValue(&self->fields, "i", INTEGER_VAL(AS_INTEGER(_counter)+1)); - return FUNC_NAME(str,__getitem__)(2,(KrkValue[]){_str,_counter},3); + return FUNC_NAME(str,__getitem__)(_thread, 2,(KrkValue[]){_str,_counter},3); } _corrupt: return krk_runtimeError(vm.exceptions->typeError, "Corrupt str iterator: %s", errorStr); } _noexport -void _createAndBind_strClass(void) { +void _createAndBind_strClass(KrkThreadState * _thread) { KrkClass * str = ADD_BASE_CLASS(vm.baseClasses->strClass, "str", vm.baseClasses->objectClass); str->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT; BIND_METHOD(str,__init__); diff --git a/src/obj_tuple.c b/src/obj_tuple.c index a51dee4..6527f3f 100644 --- a/src/obj_tuple.c +++ b/src/obj_tuple.c @@ -9,7 +9,7 @@ if (index < 0) index += self->values.count; \ if (index < 0 || index >= (krk_integer_type)self->values.count) return krk_runtimeError(vm.exceptions->indexError, "tuple index out of range: " PRIkrk_int, index) -static int _tuple_init_callback(void * context, const KrkValue * values, size_t count) { +static int _tuple_init_callback(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) { KrkValueArray * positionals = context; if (positionals->count + count > positionals->capacity) { size_t old = positionals->capacity; @@ -24,7 +24,7 @@ static int _tuple_init_callback(void * context, const KrkValue * values, size_t return 0; } -static KrkValue _tuple_init(int argc, const KrkValue argv[], int hasKw) { +static KrkValue _tuple_init(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { if (argc == 1) { return OBJECT_VAL(krk_newTuple(0)); } else if (argc == 2) { @@ -42,7 +42,7 @@ static KrkValue _tuple_init(int argc, const KrkValue argv[], int hasKw) { } /* tuple creator */ -KrkValue krk_tuple_of(int argc, const KrkValue argv[], int hasKw) { +KrkValue krk_tuple_of_r(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { KrkTuple * self = krk_newTuple(argc); krk_push(OBJECT_VAL(self)); for (size_t i = 0; i < (size_t)argc; ++i) { @@ -99,7 +99,7 @@ KRK_Method(tuple,__getitem__) { } /* make into a list */ - KrkValue result = krk_callNativeOnStack(len, &krk_currentThread.stackTop[-len], 0, krk_tuple_of); + KrkValue result = krk_callNativeOnStack(len, &krk_currentThread.stackTop[-len], 0, krk_tuple_of_r); krk_currentThread.stackTop[-len-1] = result; while (len) { krk_pop(); @@ -201,18 +201,18 @@ struct TupleIter { int i; }; -static KrkValue _tuple_iter_init(int argc, const KrkValue argv[], int hasKw) { +static KrkValue _tuple_iter_init(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { struct TupleIter * self = (struct TupleIter *)AS_OBJECT(argv[0]); self->myTuple = argv[1]; self->i = 0; return argv[0]; } -static void _tuple_iter_gcscan(KrkInstance * self) { +static void _tuple_iter_gcscan(KrkThreadState * _thread, KrkInstance * self) { krk_markValue(((struct TupleIter*)self)->myTuple); } -static KrkValue _tuple_iter_call(int argc, const KrkValue argv[], int hasKw) { +static KrkValue _tuple_iter_call(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { struct TupleIter * self = (struct TupleIter *)AS_OBJECT(argv[0]); KrkValue t = self->myTuple; /* Tuple to iterate */ int i = self->i; @@ -227,7 +227,7 @@ static KrkValue _tuple_iter_call(int argc, const KrkValue argv[], int hasKw) { KRK_Method(tuple,__iter__) { KrkInstance * output = krk_newInstance(vm.baseClasses->tupleiteratorClass); krk_push(OBJECT_VAL(output)); - _tuple_iter_init(2, (KrkValue[]){krk_peek(0), argv[0]}, 0); + _tuple_iter_init(_thread, 2, (KrkValue[]){krk_peek(0), argv[0]}, 0); krk_pop(); return OBJECT_VAL(output); } @@ -270,7 +270,7 @@ KRK_Method(tuple,__mul__) { } _noexport -void _createAndBind_tupleClass(void) { +void _createAndBind_tupleClass(KrkThreadState *_thread) { KrkClass * tuple = ADD_BASE_CLASS(vm.baseClasses->tupleClass, "tuple", vm.baseClasses->objectClass); tuple->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT; BIND_METHOD(tuple,__repr__); diff --git a/src/obj_typing.c b/src/obj_typing.c index fbae6ef..7297c67 100644 --- a/src/obj_typing.c +++ b/src/obj_typing.c @@ -20,7 +20,7 @@ * So if you specify list[int], you'll get 'list[int]'. */ -static KrkValue typeToString(KrkValue val) { +static KrkValue typeToString(KrkThreadState * _thread, KrkValue val) { if (IS_CLASS(val)) { return OBJECT_VAL(AS_CLASS(val)->name); } else if (IS_STRING(val)) { @@ -30,7 +30,7 @@ static KrkValue typeToString(KrkValue val) { struct StringBuilder sb = {0}; for (size_t i = 0; i < AS_TUPLE(val)->values.count; ++i) { - krk_push(typeToString(AS_TUPLE(val)->values.values[i])); + krk_push(typeToString(_thread, AS_TUPLE(val)->values.values[i])); pushStringBuilderStr(&sb, AS_CSTRING(krk_peek(0)), AS_STRING(krk_peek(0))->length); krk_pop(); if (i < AS_TUPLE(val)->values.count - 1) { @@ -57,7 +57,7 @@ KRK_Function(__class_getitem__) { pushStringBuilderStr(&sb, AS_CLASS(argv[0])->name->chars, AS_CLASS(argv[0])->name->length); pushStringBuilder(&sb,'['); - krk_push(typeToString(argv[1])); + krk_push(typeToString(_thread, argv[1])); pushStringBuilderStr(&sb, AS_CSTRING(krk_peek(0)), AS_STRING(krk_peek(0))->length); krk_pop(); pushStringBuilder(&sb,']'); diff --git a/src/object.c b/src/object.c index 292fb1f..473cc2d 100644 --- a/src/object.c +++ b/src/object.c @@ -9,14 +9,14 @@ #include #define ALLOCATE_OBJECT(type, objectType) \ - (type*)allocateObject(sizeof(type), objectType) + (type*)allocateObject(_thread,sizeof(type), objectType) #ifndef KRK_DISABLE_THREADS static volatile int _stringLock = 0; static volatile int _objectLock = 0; #endif -static KrkObj * allocateObject(size_t size, KrkObjType type) { +static KrkObj * allocateObject(KrkThreadState *_thread, size_t size, KrkObjType type) { KrkObj * object = (KrkObj*)krk_reallocate(NULL, 0, size); memset(object,0,size); object->type = type; @@ -32,7 +32,7 @@ static KrkObj * allocateObject(size_t size, KrkObjType type) { return object; } -size_t krk_codepointToBytes(krk_integer_type value, unsigned char * out) { +size_t krk_codepointToBytes_r(KrkThreadState * _thread, krk_integer_type value, unsigned char * out) { if (value > 0xFFFF) { out[0] = (0xF0 | (value >> 18)); out[1] = (0x80 | ((value >> 12) & 0x3F)); @@ -100,7 +100,7 @@ _reject: return *state; } -static int checkString(const char * chars, size_t length, size_t *codepointCount) { +static int checkString(KrkThreadState * _thread, const char * chars, size_t length, size_t *codepointCount) { uint32_t state = 0; uint32_t codepoint = 0; unsigned char * end = (unsigned char *)chars + length; @@ -147,7 +147,7 @@ GENREADY(2,uint16_t) GENREADY(4,uint32_t) #undef GENREADY -void * krk_unicodeString(KrkString * string) { +void * krk_unicodeString_r(KrkThreadState * _thread, KrkString * string) { if (string->codes) return string->codes; else if ((string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) == KRK_OBJ_FLAGS_STRING_UCS1) _readyUCS1(string); else if ((string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) == KRK_OBJ_FLAGS_STRING_UCS2) _readyUCS2(string); @@ -156,7 +156,7 @@ void * krk_unicodeString(KrkString * string) { return string->codes; } -uint32_t krk_unicodeCodepoint(KrkString * string, size_t index) { +uint32_t krk_unicodeCodepoint_r(KrkThreadState * _thread, KrkString * string, size_t index) { krk_unicodeString(string); switch (string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) { case KRK_OBJ_FLAGS_STRING_ASCII: @@ -169,9 +169,9 @@ uint32_t krk_unicodeCodepoint(KrkString * string, size_t index) { } } -static KrkString * allocateString(char * chars, size_t length, uint32_t hash) { +static KrkString * allocateString(KrkThreadState * _thread, char * chars, size_t length, uint32_t hash) { size_t codesLength = 0; - int type = checkString(chars,length,&codesLength); + int type = checkString(_thread, chars,length,&codesLength); if (type == -1) { return krk_copyString("",0); } @@ -190,7 +190,7 @@ static KrkString * allocateString(char * chars, size_t length, uint32_t hash) { return string; } -static uint32_t hashString(const char * key, size_t length) { +static uint32_t hashString(KrkThreadState * _thread, const char * key, size_t length) { uint32_t hash = 0; /* This is the so-called "sdbm" hash. It comes from a piece of * public domain code from a clone of ndbm. */ @@ -200,8 +200,8 @@ static uint32_t hashString(const char * key, size_t length) { return hash; } -KrkString * krk_takeString(char * chars, size_t length) { - uint32_t hash = hashString(chars, length); +KrkString * krk_takeString_r(KrkThreadState * _thread, char * chars, size_t length) { + uint32_t hash = hashString(_thread, chars, length); _obtain_lock(_stringLock); KrkString * interned = krk_tableFindString(&vm.strings, chars, length, hash); if (interned != NULL) { @@ -212,12 +212,12 @@ KrkString * krk_takeString(char * chars, size_t length) { /* Part of taking ownership of this string is that we track its memory usage */ krk_gcTakeBytes(chars, length + 1); - KrkString * result = allocateString(chars, length, hash); + KrkString * result = allocateString(_thread, chars, length, hash); return result; } -KrkString * krk_copyString(const char * chars, size_t length) { - uint32_t hash = hashString(chars, length); +KrkString * krk_copyString_r(KrkThreadState * _thread, const char * chars, size_t length) { + uint32_t hash = hashString(_thread, chars, length); _obtain_lock(_stringLock); KrkString * interned = krk_tableFindString(&vm.strings, chars ? chars : "", length, hash); if (interned) { @@ -227,13 +227,13 @@ KrkString * krk_copyString(const char * chars, size_t length) { char * heapChars = ALLOCATE(char, length + 1); memcpy(heapChars, chars ? chars : "", length); heapChars[length] = '\0'; - KrkString * result = allocateString(heapChars, length, hash); + KrkString * result = allocateString(_thread, heapChars, length, hash); if (result->chars != heapChars) free(heapChars); _release_lock(_stringLock); return result; } -KrkString * krk_takeStringVetted(char * chars, size_t length, size_t codesLength, KrkStringType type, uint32_t hash) { +KrkString * krk_takeStringVetted_r(KrkThreadState * _thread, char * chars, size_t length, size_t codesLength, KrkStringType type, uint32_t hash) { _obtain_lock(_stringLock); KrkString * interned = krk_tableFindString(&vm.strings, chars, length, hash); if (interned != NULL) { @@ -256,7 +256,7 @@ KrkString * krk_takeStringVetted(char * chars, size_t length, size_t codesLength return string; } -KrkCodeObject * krk_newCodeObject(void) { +KrkCodeObject * krk_newCodeObject_r(KrkThreadState * _thread) { KrkCodeObject * codeobject = ALLOCATE_OBJECT(KrkCodeObject, KRK_OBJ_CODEOBJECT); codeobject->requiredArgs = 0; codeobject->keywordArgs = 0; @@ -271,7 +271,7 @@ KrkCodeObject * krk_newCodeObject(void) { return codeobject; } -KrkNative * krk_newNative(NativeFn function, const char * name, int type) { +KrkNative * krk_newNative_r(KrkThreadState * _thread, NativeFn function, const char * name, int type) { KrkNative * native = ALLOCATE_OBJECT(KrkNative, KRK_OBJ_NATIVE); native->function = function; native->obj.flags = type; @@ -280,7 +280,7 @@ KrkNative * krk_newNative(NativeFn function, const char * name, int type) { return native; } -KrkClosure * krk_newClosure(KrkCodeObject * function, KrkValue globals) { +KrkClosure * krk_newClosure_r(KrkThreadState * _thread, KrkCodeObject * function, KrkValue globals) { KrkUpvalue ** upvalues = ALLOCATE(KrkUpvalue*, function->upvalueCount); for (size_t i = 0; i < function->upvalueCount; ++i) { upvalues[i] = NULL; @@ -305,7 +305,7 @@ KrkClosure * krk_newClosure(KrkCodeObject * function, KrkValue globals) { return closure; } -KrkUpvalue * krk_newUpvalue(int slot) { +KrkUpvalue * krk_newUpvalue_r(KrkThreadState * _thread, int slot) { KrkUpvalue * upvalue = ALLOCATE_OBJECT(KrkUpvalue, KRK_OBJ_UPVALUE); upvalue->location = slot; upvalue->next = NULL; @@ -314,7 +314,7 @@ KrkUpvalue * krk_newUpvalue(int slot) { return upvalue; } -KrkClass * krk_newClass(KrkString * name, KrkClass * baseClass) { +KrkClass * krk_newClass_r(KrkThreadState * _thread, KrkString * name, KrkClass * baseClass) { KrkClass * _class = ALLOCATE_OBJECT(KrkClass, KRK_OBJ_CLASS); _class->name = name; _class->allocSize = sizeof(KrkInstance); @@ -333,21 +333,21 @@ KrkClass * krk_newClass(KrkString * name, KrkClass * baseClass) { return _class; } -KrkInstance * krk_newInstance(KrkClass * _class) { - KrkInstance * instance = (KrkInstance*)allocateObject(_class->allocSize, KRK_OBJ_INSTANCE); +KrkInstance * krk_newInstance_r(KrkThreadState * _thread, KrkClass * _class) { + KrkInstance * instance = (KrkInstance*)allocateObject(_thread, _class->allocSize, KRK_OBJ_INSTANCE); instance->_class = _class; krk_initTable(&instance->fields); return instance; } -KrkBoundMethod * krk_newBoundMethod(KrkValue receiver, KrkObj * method) { +KrkBoundMethod * krk_newBoundMethod_r(KrkThreadState * _thread, KrkValue receiver, KrkObj * method) { KrkBoundMethod * bound = ALLOCATE_OBJECT(KrkBoundMethod, KRK_OBJ_BOUND_METHOD); bound->receiver = receiver; bound->method = method; return bound; } -KrkTuple * krk_newTuple(size_t length) { +KrkTuple * krk_newTuple_r(KrkThreadState * _thread, size_t length) { KrkTuple * tuple = ALLOCATE_OBJECT(KrkTuple, KRK_OBJ_TUPLE); krk_initValueArray(&tuple->values); krk_push(OBJECT_VAL(tuple)); @@ -357,7 +357,7 @@ KrkTuple * krk_newTuple(size_t length) { return tuple; } -KrkBytes * krk_newBytes(size_t length, uint8_t * source) { +KrkBytes * krk_newBytes_r(KrkThreadState * _thread, size_t length, uint8_t * source) { KrkBytes * bytes = ALLOCATE_OBJECT(KrkBytes, KRK_OBJ_BYTES); bytes->length = length; bytes->bytes = NULL; diff --git a/src/os.c b/src/os.c index cb892b0..31934ec 100644 --- a/src/os.c +++ b/src/os.c @@ -139,7 +139,7 @@ KRK_Method(Environ,__delitem__) { return krk_callDirect(vm.baseClasses->dictClass->_delitem, 2); } -static void _loadEnviron(KrkInstance * module) { +static void _loadEnviron(KrkThreadState * _thread, KrkInstance * module) { /* Create a new class to subclass `dict` */ KrkClass * Environ = krk_makeClass(module, &KRK_BASE_CLASS(Environ), "_Environ", vm.baseClasses->dictClass); krk_attachNamedObject(&module->fields, "_Environ", (KrkObj*)Environ); @@ -463,7 +463,7 @@ KRK_Function(get_terminal_size) { } #endif -static int makeArgs(int count, const KrkValue * values, char *** argsOut, const char * _method_name) { +static int makeArgs_r(KrkThreadState * _thread, int count, const KrkValue * values, char *** argsOut, const char * _method_name) { char ** out = malloc(sizeof(char*)*(count+1)); for (int i = 0; i < count; ++i) { if (!IS_STRING(values[i])) { @@ -477,6 +477,7 @@ static int makeArgs(int count, const KrkValue * values, char *** argsOut, const *argsOut = out; return 0; } +#define makeArgs(c,v,a,m) makeArgs_r(_thread,c,v,a,m) KRK_Function(execl) { FUNCTION_TAKES_AT_LEAST(1); @@ -661,7 +662,7 @@ KRK_Function(S_ISSOCK) { } #endif -void krk_module_init_os(void) { +void krk_module_init_os(KrkThreadState * _thread) { KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass); krk_attachNamedObject(&vm.modules, "os", (KrkObj*)module); krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("os")); @@ -881,7 +882,7 @@ void krk_module_init_os(void) { "Obtain the size of the host terminal as a tuple of columns and lines."); #endif - _loadEnviron(module); + _loadEnviron(_thread, module); /* Nothing special */ KrkClass * stat_result = krk_makeClass(module, &KRK_BASE_CLASS(stat_result), "stat_result", vm.baseClasses->objectClass); diff --git a/src/private.h b/src/private.h index 8abee8f..949f7e8 100644 --- a/src/private.h +++ b/src/private.h @@ -7,21 +7,21 @@ */ #include "kuroko/kuroko.h" -extern void _createAndBind_numericClasses(void); -extern void _createAndBind_strClass(void); -extern void _createAndBind_listClass(void); -extern void _createAndBind_tupleClass(void); -extern void _createAndBind_bytesClass(void); -extern void _createAndBind_dictClass(void); -extern void _createAndBind_functionClass(void); -extern void _createAndBind_rangeClass(void); -extern void _createAndBind_setClass(void); -extern void _createAndBind_generatorClass(void); -extern void _createAndBind_sliceClass(void); -extern void _createAndBind_builtins(void); -extern void _createAndBind_type(void); -extern void _createAndBind_exceptions(void); -extern void _createAndBind_longClass(void); +extern void _createAndBind_numericClasses(KrkThreadState*); +extern void _createAndBind_strClass(KrkThreadState*); +extern void _createAndBind_listClass(KrkThreadState*); +extern void _createAndBind_tupleClass(KrkThreadState*); +extern void _createAndBind_bytesClass(KrkThreadState*); +extern void _createAndBind_dictClass(KrkThreadState*); +extern void _createAndBind_functionClass(KrkThreadState*); +extern void _createAndBind_rangeClass(KrkThreadState*); +extern void _createAndBind_setClass(KrkThreadState*); +extern void _createAndBind_generatorClass(KrkThreadState*); +extern void _createAndBind_sliceClass(KrkThreadState*); +extern void _createAndBind_builtins(KrkThreadState*); +extern void _createAndBind_type(KrkThreadState*); +extern void _createAndBind_exceptions(KrkThreadState*); +extern void _createAndBind_longClass(KrkThreadState*); /** * @brief Index numbers for always-available interned strings representing important method and member names. diff --git a/src/sys.c b/src/sys.c index cdfda69..855afcb 100644 --- a/src/sys.c +++ b/src/sys.c @@ -177,7 +177,7 @@ KRK_Function(inspect_value) { return OBJECT_VAL(krk_newBytes(sizeof(KrkValue),(uint8_t*)&argv[0])); } -void krk_module_init_kuroko(void) { +void krk_module_init_kuroko(KrkThreadState * _thread) { /** * kuroko = module() * diff --git a/src/table.c b/src/table.c index 5ae9646..3cdbc57 100644 --- a/src/table.c +++ b/src/table.c @@ -11,18 +11,18 @@ #define TABLE_MAX_LOAD 0.75 -void krk_initTable(KrkTable * table) { +void krk_initTable_r(struct KrkThreadState * _thread, KrkTable * table) { table->count = 0; table->capacity = 0; table->entries = NULL; } -void krk_freeTable(KrkTable * table) { +void krk_freeTable_r(struct KrkThreadState * _thread, KrkTable * table) { FREE_ARRAY(KrkTableEntry, table->entries, table->capacity); krk_initTable(table); } -inline int krk_hashValue(KrkValue value, uint32_t *hashOut) { +inline int krk_hashValue_r(struct KrkThreadState * _thread, KrkValue value, uint32_t *hashOut) { switch (KRK_VAL_TYPE(value)) { case KRK_VAL_BOOLEAN: case KRK_VAL_INTEGER: @@ -59,7 +59,7 @@ _unhashable: return 1; } -KrkTableEntry * krk_findEntry(KrkTableEntry * entries, size_t capacity, KrkValue key) { +KrkTableEntry * krk_findEntry_r(struct KrkThreadState * _thread, KrkTableEntry * entries, size_t capacity, KrkValue key) { uint32_t index; if (krk_hashValue(key, &index)) { return NULL; @@ -82,7 +82,7 @@ KrkTableEntry * krk_findEntry(KrkTableEntry * entries, size_t capacity, KrkValue } } -KrkTableEntry * krk_findEntryExact(KrkTableEntry * entries, size_t capacity, KrkValue key) { +KrkTableEntry * krk_findEntryExact_r(struct KrkThreadState * _thread, KrkTableEntry * entries, size_t capacity, KrkValue key) { uint32_t index; if (krk_hashValue(key, &index)) { return NULL; @@ -113,7 +113,7 @@ int __builtin_clz(unsigned int x) { } #endif -void krk_tableAdjustCapacity(KrkTable * table, size_t capacity) { +void krk_tableAdjustCapacity_r(struct KrkThreadState * _thread, KrkTable * table, size_t capacity) { if (capacity) { /* Fast power-of-two calculation */ size_t powerOfTwoCapacity = __builtin_clz(1) - __builtin_clz(capacity); @@ -142,7 +142,7 @@ void krk_tableAdjustCapacity(KrkTable * table, size_t capacity) { table->capacity = capacity; } -int krk_tableSet(KrkTable * table, KrkValue key, KrkValue value) { +int krk_tableSet_r(struct KrkThreadState * _thread, KrkTable * table, KrkValue key, KrkValue value) { if (table->count + 1 > table->capacity * TABLE_MAX_LOAD) { size_t capacity = GROW_CAPACITY(table->capacity); krk_tableAdjustCapacity(table, capacity); @@ -156,7 +156,7 @@ int krk_tableSet(KrkTable * table, KrkValue key, KrkValue value) { return isNewKey; } -int krk_tableSetIfExists(KrkTable * table, KrkValue key, KrkValue value) { +int krk_tableSetIfExists_r(struct KrkThreadState * _thread, KrkTable * table, KrkValue key, KrkValue value) { if (table->count == 0) return 0; KrkTableEntry * entry = krk_findEntry(table->entries, table->capacity, key); if (!entry) return 0; @@ -166,7 +166,7 @@ int krk_tableSetIfExists(KrkTable * table, KrkValue key, KrkValue value) { return 1; } -void krk_tableAddAll(KrkTable * from, KrkTable * to) { +void krk_tableAddAll_r(struct KrkThreadState * _thread, KrkTable * from, KrkTable * to) { for (size_t i = 0; i < from->capacity; ++i) { KrkTableEntry * entry = &from->entries[i]; if (!IS_KWARGS(entry->key)) { @@ -175,7 +175,7 @@ void krk_tableAddAll(KrkTable * from, KrkTable * to) { } } -int krk_tableGet(KrkTable * table, KrkValue key, KrkValue * value) { +int krk_tableGet_r(struct KrkThreadState * _thread, KrkTable * table, KrkValue key, KrkValue * value) { if (table->count == 0) return 0; KrkTableEntry * entry = krk_findEntry(table->entries, table->capacity, key); if (!entry || IS_KWARGS(entry->key)) { @@ -186,7 +186,7 @@ int krk_tableGet(KrkTable * table, KrkValue key, KrkValue * value) { } } -int krk_tableGet_fast(KrkTable * table, KrkString * str, KrkValue * value) { +int krk_tableGet_fast_r(struct KrkThreadState * _thread, KrkTable * table, KrkString * str, KrkValue * value) { if (unlikely(table->count == 0)) return 0; uint32_t index = str->obj.hash & (table->capacity-1); for (;;) { @@ -200,7 +200,7 @@ int krk_tableGet_fast(KrkTable * table, KrkString * str, KrkValue * value) { } } -int krk_tableDelete(KrkTable * table, KrkValue key) { +int krk_tableDelete_r(struct KrkThreadState * _thread, KrkTable * table, KrkValue key) { if (table->count == 0) return 0; KrkTableEntry * entry = krk_findEntry(table->entries, table->capacity, key); if (!entry || IS_KWARGS(entry->key)) { @@ -212,9 +212,9 @@ int krk_tableDelete(KrkTable * table, KrkValue key) { return 1; } -int krk_tableDeleteExact(KrkTable * table, KrkValue key) { +int krk_tableDeleteExact_r(struct KrkThreadState * _thread, KrkTable * table, KrkValue key) { if (table->count == 0) return 0; - KrkTableEntry * entry = krk_findEntryExact(table->entries, table->capacity, key); + KrkTableEntry * entry = krk_findEntryExact_r(_thread, table->entries, table->capacity, key); if (!entry || IS_KWARGS(entry->key)) { return 0; } @@ -224,7 +224,7 @@ int krk_tableDeleteExact(KrkTable * table, KrkValue key) { return 1; } -KrkString * krk_tableFindString(KrkTable * table, const char * chars, size_t length, uint32_t hash) { +KrkString * krk_tableFindString_r(struct KrkThreadState * _thread, KrkTable * table, const char * chars, size_t length, uint32_t hash) { if (table->count == 0) return NULL; uint32_t index = hash & (table->capacity-1); diff --git a/src/threads.c b/src/threads.c index fcfad13..a7af23b 100644 --- a/src/threads.c +++ b/src/threads.c @@ -32,6 +32,7 @@ struct Thread { KrkInstance inst; KrkThreadState * threadState; + KrkVM * owner; pthread_t nativeRef; pid_t tid; unsigned int started:1; @@ -61,10 +62,11 @@ KRK_Function(current_thread) { static volatile int _threadLock = 0; static void * _startthread(void * _threadObj) { -#if defined(__APPLE__) && defined(__aarch64__) - krk_forceThreadData(); -#endif - memset(&krk_currentThread, 0, sizeof(KrkThreadState)); + struct Thread * self = _threadObj; + self->threadState = calloc(1,sizeof(KrkThreadState)); + KrkThreadState * _thread = self->threadState; + _thread->owner = self->owner; + krk_currentThread.frames = calloc(vm.maximumCallDepth,sizeof(KrkCallFrame)); vm.globalFlags |= KRK_GLOBAL_THREADS; _obtain_lock(_threadLock); @@ -75,8 +77,6 @@ static void * _startthread(void * _threadObj) { _release_lock(_threadLock); /* Get our run function */ - struct Thread * self = _threadObj; - self->threadState = &krk_currentThread; self->tid = gettid(); KrkValue runMethod = NONE_VAL(); @@ -93,7 +93,7 @@ static void * _startthread(void * _threadObj) { /* Remove this thread from the thread pool, its stack is garbage anyway */ _obtain_lock(_threadLock); - krk_resetStack(); + krk_resetStack(_thread); KrkThreadState * previous = vm.threads; while (previous) { if (previous->next == &krk_currentThread) { @@ -133,6 +133,7 @@ KRK_Method(Thread,start) { self->started = 1; self->alive = 1; + self->owner = _thread->owner; pthread_create(&self->nativeRef, NULL, _startthread, (void*)self); return argv[0]; @@ -155,7 +156,7 @@ KRK_Method(Lock,__init__) { return argv[0]; } -static inline void _pushLockStatus(struct Lock * self, struct StringBuilder * sb) { +static inline void _pushLockStatus(KrkThreadState * _thread, struct Lock * self, struct StringBuilder * sb) { #ifdef __GLIBC__ { if (self->mutex.__data.__owner) { @@ -182,7 +183,7 @@ KRK_Method(Lock,__repr__) { pushStringBuilderStr(&sb, tmp, len); } - _pushLockStatus(self,&sb); + _pushLockStatus(_thread, self,&sb); pushStringBuilder(&sb,'>'); return finishStringBuilder(&sb); @@ -199,7 +200,7 @@ KRK_Method(Lock,__exit__) { return NONE_VAL(); } -void krk_module_init_threading(void) { +void krk_module_init_threading(KrkThreadState * _thread) { /** * threads = module() * diff --git a/src/time.c b/src/time.c index 24f9c52..56cf3d9 100644 --- a/src/time.c +++ b/src/time.c @@ -38,7 +38,7 @@ KRK_Function(time) { return FLOATING_VAL(out); } -void krk_module_init_time(void) { +void krk_module_init_time(KrkThreadState * _thread) { KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass); krk_attachNamedObject(&vm.modules, "time", (KrkObj*)module); krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("time")); diff --git a/src/value.c b/src/value.c index 35a2924..7808467 100644 --- a/src/value.c +++ b/src/value.c @@ -8,13 +8,13 @@ #include "opcode_enum.h" -void krk_initValueArray(KrkValueArray * array) { +void krk_initValueArray_r(KrkThreadState * _thread, KrkValueArray * array) { array->values = NULL; array->capacity = 0; array->count = 0; } -void krk_writeValueArray(KrkValueArray * array, KrkValue value) { +void krk_writeValueArray_r(KrkThreadState * _thread, KrkValueArray * array, KrkValue value) { if (array->capacity < array->count + 1) { int old = array->capacity; array->capacity = GROW_CAPACITY(old); @@ -25,12 +25,12 @@ void krk_writeValueArray(KrkValueArray * array, KrkValue value) { array->count++; } -void krk_freeValueArray(KrkValueArray * array) { +void krk_freeValueArray_r(KrkThreadState * _thread, KrkValueArray * array) { FREE_ARRAY(KrkValue, array->values, array->capacity); krk_initValueArray(array); } -void krk_printValue(FILE * f, KrkValue printable) { +void krk_printValue_r(KrkThreadState * _thread, FILE * f, KrkValue printable) { KrkClass * type = krk_getType(printable); if (type->_tostr) { krk_push(printable); @@ -49,7 +49,7 @@ void krk_printValue(FILE * f, KrkValue printable) { #define STRING_DEBUG_TRUNCATE 50 -void krk_printValueSafe(FILE * f, KrkValue printable) { +void krk_printValueSafe_r(KrkThreadState * _thread, FILE * f, KrkValue printable) { if (!IS_OBJECT(printable)) { switch (KRK_VAL_TYPE(printable)) { case KRK_VAL_INTEGER: fprintf(f, PRIkrk_int, AS_INTEGER(printable)); break; @@ -145,11 +145,11 @@ void krk_printValueSafe(FILE * f, KrkValue printable) { /** * Identity really should be the simple... */ -int krk_valuesSame(KrkValue a, KrkValue b) { +int krk_valuesSame_r(KrkThreadState * _thread, KrkValue a, KrkValue b) { return a == b; } -static inline int _krk_method_equivalence(KrkValue a, KrkValue b) { +static inline int _krk_method_equivalence(KrkThreadState * _thread, KrkValue a, KrkValue b) { KrkClass * type = krk_getType(a); if (likely(type && type->_eq)) { krk_push(a); @@ -173,7 +173,7 @@ static inline int _krk_method_equivalence(KrkValue a, KrkValue b) { return 0; } -static inline int _krk_same_type_equivalence(uint16_t valtype, KrkValue a, KrkValue b) { +static inline int _krk_same_type_equivalence(KrkThreadState * _thread, uint16_t valtype, KrkValue a, KrkValue b) { switch (valtype) { case KRK_VAL_BOOLEAN: case KRK_VAL_INTEGER: @@ -184,11 +184,11 @@ static inline int _krk_same_type_equivalence(uint16_t valtype, KrkValue a, KrkVa return a == b; case KRK_VAL_OBJECT: default: - return _krk_method_equivalence(a,b); + return _krk_method_equivalence(_thread,a,b); } } -static inline int _krk_same_type_equivalence_b(uint16_t valtype, KrkValue a, KrkValue b) { +static inline int _krk_same_type_equivalence_b(KrkThreadState * _thread, uint16_t valtype, KrkValue a, KrkValue b) { switch (valtype) { case KRK_VAL_BOOLEAN: case KRK_VAL_INTEGER: @@ -199,33 +199,33 @@ static inline int _krk_same_type_equivalence_b(uint16_t valtype, KrkValue a, Krk return 0; case KRK_VAL_OBJECT: default: - return _krk_method_equivalence(a,b); + return _krk_method_equivalence(_thread,a,b); } } -static inline int _krk_diff_type_equivalence(uint16_t val_a, uint16_t val_b, KrkValue a, KrkValue b) { +static inline int _krk_diff_type_equivalence(KrkThreadState * _thread, uint16_t val_a, uint16_t val_b, KrkValue a, KrkValue b) { /* We do not want to let KWARGS leak to anything needs to, eg., examine types. */ if (val_b == KRK_VAL_KWARGS || val_a == KRK_VAL_KWARGS) return 0; /* Fall back to methods */ - return _krk_method_equivalence(a,b); + return _krk_method_equivalence(_thread,a,b); } __attribute__((hot)) -int krk_valuesSameOrEqual(KrkValue a, KrkValue b) { +int krk_valuesSameOrEqual_r(KrkThreadState * _thread, KrkValue a, KrkValue b) { if (a == b) return 1; uint16_t val_a = KRK_VAL_TYPE(a); uint16_t val_b = KRK_VAL_TYPE(b); return (val_a == val_b) - ? _krk_same_type_equivalence_b(val_a, a, b) - : _krk_diff_type_equivalence(val_a, val_b, a, b); + ? _krk_same_type_equivalence_b(_thread, val_a, a, b) + : _krk_diff_type_equivalence(_thread, val_a, val_b, a, b); } __attribute__((hot)) -int krk_valuesEqual(KrkValue a, KrkValue b) { +int krk_valuesEqual_r(KrkThreadState * _thread, KrkValue a, KrkValue b) { uint16_t val_a = KRK_VAL_TYPE(a); uint16_t val_b = KRK_VAL_TYPE(b); return (val_a == val_b) - ? _krk_same_type_equivalence(val_a,a,b) - : _krk_diff_type_equivalence(val_a,val_b,a,b); + ? _krk_same_type_equivalence(_thread,val_a,a,b) + : _krk_diff_type_equivalence(_thread,val_a,val_b,a,b); } diff --git a/src/vm.c b/src/vm.c index 818c309..e34cc3c 100644 --- a/src/vm.c +++ b/src/vm.c @@ -17,61 +17,11 @@ #include "private.h" #include "opcode_enum.h" -/* Ensure we don't have a macro for this so we can reference a local version. */ -#undef krk_currentThread - -/* This is macro'd to krk_vm for namespacing reasons. */ -KrkVM vm = {0}; - -#ifndef KRK_DISABLE_THREADS -/* - * Marking our little VM thread state as 'initial-exec' is - * the fastest way to allocate TLS data and yields virtually - * identical performance in the single-thread case to not - * having a TLS pointer, but it has some drawbacks... - * - * Despite documentation saying otherwise, a small thread-local - * can generally be allocated even with dlopen, but this is - * not guaranteed. - */ -__attribute__((tls_model("initial-exec"))) -__thread KrkThreadState krk_currentThread; -#else -/* There is only one thread, so don't store it as TLS... */ -KrkThreadState krk_currentThread; -#endif - -#if !defined(KRK_DISABLE_THREADS) && defined(__APPLE__) && defined(__aarch64__) -/** - * I have not checked how this works on x86-64, so we only do this - * on M1 Macs at the moment, but TLS is disastrously poorly implemented - * with a function pointer thunk, provided by dyld. This is very slow. - * We can emulate the behavior inline, and achieve better performance - - * much closer to the direct access case, though not as good as a dedicated - * register - but in order for that to work we have to do at least one - * traditional access to trigger the "bootstrap" and ensure our thread - * state is actually allocated. We do that here, called by @c krk_initVM - * as well as by @c _startthread, and check that our approach yields - * the same address. - */ -void krk_forceThreadData(void) { - krk_currentThread.next = NULL; - assert(&krk_currentThread == _macos_currentThread()); -} -/** - * And then we macro away @c krk_currentThread behind the inlinable emulation - * which is defined in src/kuroko/vm.h so the rest of the interpreter can do - * the same - not strictly necessary, just doing it locally here is enough - * for major performance gains, but it's nice to be consistent. - */ -#define krk_currentThread (*_macos_currentThread()) -#endif - #if !defined(KRK_NO_TRACING) && !defined(__EMSCRIPTEN__) && !defined(KRK_NO_CALLGRIND) -static void _frame_in(KrkCallFrame * frame) { +static void _frame_in(KrkThreadState * _thread, KrkCallFrame * frame) { clock_gettime(CLOCK_MONOTONIC, &frame->in_time); } -static void _frame_out(KrkCallFrame * frame) { +static void _frame_out(KrkThreadState * _thread, KrkCallFrame * frame) { if (frame->closure->function->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_IS_GENERATOR) return; KrkCallFrame * caller = krk_currentThread.frameCount > 1 ? &krk_currentThread.frames[krk_currentThread.frameCount-2] : NULL; @@ -98,8 +48,8 @@ static void _frame_out(KrkCallFrame * frame) { (int)krk_lineNumber(&frame->closure->function->chunk, 0), (long long)diff.tv_sec, diff.tv_nsec); } -# define FRAME_IN(frame) if (unlikely(vm.globalFlags & KRK_GLOBAL_CALLGRIND)) { _frame_in(frame); } -# define FRAME_OUT(frame) if (unlikely(vm.globalFlags & KRK_GLOBAL_CALLGRIND)) { _frame_out(frame); } +# define FRAME_IN(frame) if (unlikely(vm.globalFlags & KRK_GLOBAL_CALLGRIND)) { _frame_in(_thread, frame); } +# define FRAME_OUT(frame) if (unlikely(vm.globalFlags & KRK_GLOBAL_CALLGRIND)) { _frame_out(_thread, frame); } #else # define FRAME_IN(frame) # define FRAME_OUT(frame) @@ -112,16 +62,16 @@ static void _frame_out(KrkCallFrame * frame) { * we make @ref krk_currentThread a macro outside of the core * sources that will call this function. */ -KrkThreadState * krk_getCurrentThread(void) { - return &krk_currentThread; -} +//KrkThreadState * krk_getCurrentThread(void) { +// return &krk_currentThread; +//} /** * Reset the stack pointers, frame, upvalue list, * clear the exception flag and current exception; * happens on startup (twice) and after an exception. */ -void krk_resetStack(void) { +void krk_resetStack(KrkThreadState * _thread) { krk_currentThread.stackTop = krk_currentThread.stack; krk_currentThread.stackMax = krk_currentThread.stack + krk_currentThread.stackSize; krk_currentThread.frameCount = 0; @@ -130,7 +80,7 @@ void krk_resetStack(void) { krk_currentThread.currentException = NONE_VAL(); } -void krk_growStack(void) { +void krk_growStack(KrkThreadState * _thread) { size_t old = krk_currentThread.stackSize; size_t old_offset = krk_currentThread.stackTop - krk_currentThread.stack; size_t newsize = GROW_CAPACITY(old); @@ -154,8 +104,8 @@ void krk_growStack(void) { * the stack to grow - eg. if you are calling into managed code * to do anything, or if you are pushing anything. */ -inline void krk_push(KrkValue value) { - if (unlikely(krk_currentThread.stackTop == krk_currentThread.stackMax)) krk_growStack(); +inline void krk_push_r(KrkThreadState * _thread, KrkValue value) { + if (unlikely(krk_currentThread.stackTop == krk_currentThread.stackMax)) krk_growStack(_thread); *krk_currentThread.stackTop++ = value; } @@ -167,7 +117,7 @@ inline void krk_push(KrkValue value) { * the repl relies on this it expects to be able to get the last * pushed value and display it (if it's not None). */ -inline KrkValue krk_pop() { +inline KrkValue krk_pop_r(KrkThreadState * _thread) { if (unlikely(krk_currentThread.stackTop == krk_currentThread.stack)) { abort(); } @@ -175,13 +125,13 @@ inline KrkValue krk_pop() { } /* Read a value `distance` units from the top of the stack without poping it. */ -inline KrkValue krk_peek(int distance) { +inline KrkValue krk_peek_r(KrkThreadState * _thread, int distance) { return krk_currentThread.stackTop[-1 - distance]; } /* Exchange the value `distance` units down from the top of the stack with * the value at the top of the stack. */ -inline void krk_swap(int distance) { +inline void krk_swap_r(KrkThreadState * _thread, int distance) { KrkValue top = krk_currentThread.stackTop[-1]; krk_currentThread.stackTop[-1] = krk_currentThread.stackTop[-1 - distance]; krk_currentThread.stackTop[-1 - distance] = top; @@ -191,7 +141,7 @@ inline void krk_swap(int distance) { * Bind a native function to the given table (eg. vm.builtins->fields, or _class->methods) * GC safe: pushes allocated values. */ -KrkNative * krk_defineNative(KrkTable * table, const char * name, NativeFn function) { +KrkNative * krk_defineNative_r(KrkThreadState * _thread, KrkTable * table, const char * name, NativeFn function) { KrkNative * func = krk_newNative(function, name, 0); krk_attachNamedObject(table, name, (KrkObj*)func); return func; @@ -203,7 +153,7 @@ KrkNative * krk_defineNative(KrkTable * table, const char * name, NativeFn funct * be used with the "fields" table rather than the methods table. This will eventually replace * the ":field" option for defineNative(). */ -KrkNative * krk_defineNativeProperty(KrkTable * table, const char * name, NativeFn function) { +KrkNative * krk_defineNativeProperty_r(KrkThreadState * _thread, KrkTable * table, const char * name, NativeFn function) { KrkNative * func = krk_newNative(function, name, 0); krk_push(OBJECT_VAL(func)); KrkInstance * property = krk_newInstance(vm.baseClasses->propertyClass); @@ -216,7 +166,7 @@ KrkNative * krk_defineNativeProperty(KrkTable * table, const char * name, Native /** * Shortcut for building classes. */ -KrkClass * krk_makeClass(KrkInstance * module, KrkClass ** _class, const char * name, KrkClass * base) { +KrkClass * krk_makeClass_r(KrkThreadState * _thread, KrkInstance * module, KrkClass ** _class, const char * name, KrkClass * base) { KrkString * str_Name = krk_copyString(name,strlen(name)); krk_push(OBJECT_VAL(str_Name)); *_class = krk_newClass(str_Name, base); @@ -241,7 +191,7 @@ KrkClass * krk_makeClass(KrkInstance * module, KrkClass ** _class, const char * * For a class built by managed code, called by OP_FINALIZE */ __attribute__((nonnull)) -void krk_finalizeClass(KrkClass * _class) { +void krk_finalizeClass_r(KrkThreadState * _thread, KrkClass * _class) { KrkValue tmp; struct TypeMap { @@ -285,7 +235,7 @@ void krk_finalizeClass(KrkClass * _class) { /** * This should really be the default behavior of type.__new__? */ -static void _callSetName(KrkClass * _class) { +static void _callSetName(KrkThreadState * _thread, KrkClass * _class) { KrkValue setnames = krk_list_of(0,NULL,0); krk_push(setnames); extern FUNC_SIG(list,append); @@ -296,8 +246,8 @@ static void _callSetName(KrkClass * _class) { if (!IS_KWARGS(entry->key)) { KrkClass * type = krk_getType(entry->value); if (type->_set_name) { - FUNC_NAME(list,append)(2,(KrkValue[]){setnames,entry->key},0); - FUNC_NAME(list,append)(2,(KrkValue[]){setnames,entry->value},0); + FUNC_NAME(list,append)(_thread, 2,(KrkValue[]){setnames,entry->key},0); + FUNC_NAME(list,append)(_thread, 2,(KrkValue[]){setnames,entry->value},0); } } } @@ -330,7 +280,7 @@ static void _callSetName(KrkClass * _class) { * Maps values to their base classes. * Internal version of type(). */ -inline KrkClass * krk_getType(KrkValue of) { +inline KrkClass * krk_getType_r(KrkThreadState * _thread, KrkValue of) { static size_t objClasses[] = { [KRK_OBJ_CODEOBJECT] = offsetof(struct BaseClasses, codeobjectClass), @@ -371,7 +321,7 @@ inline KrkClass * krk_getType(KrkValue of) { * type and didn't inherit from object(), everything is eventually * an object - even basic types like INTEGERs and FLOATINGs. */ -int krk_isInstanceOf(KrkValue obj, const KrkClass * type) { +int krk_isInstanceOf_r(KrkThreadState * _thread, KrkValue obj, const KrkClass * type) { KrkClass * mine = krk_getType(obj); while (mine) { if (mine == type) return 1; @@ -380,7 +330,7 @@ int krk_isInstanceOf(KrkValue obj, const KrkClass * type) { return 0; } -static inline int checkArgumentCount(const KrkClosure * closure, int argCount) { +static inline int checkArgumentCount(KrkThreadState * _thread, const KrkClosure * closure, int argCount) { int minArgs = closure->function->requiredArgs; int maxArgs = minArgs + closure->function->keywordArgs; if (unlikely(argCount < minArgs || argCount > maxArgs)) { @@ -395,7 +345,7 @@ static inline int checkArgumentCount(const KrkClosure * closure, int argCount) { return 1; } -static void multipleDefs(const KrkClosure * closure, int destination) { +static void multipleDefs(KrkThreadState * _thread, const KrkClosure * closure, int destination) { krk_runtimeError(vm.exceptions->typeError, "%s() got multiple values for argument '%S'", closure->function->name ? closure->function->name->chars : "", (destination < closure->function->requiredArgs ? AS_STRING(closure->function->requiredArgNames.values[destination]) : @@ -403,7 +353,7 @@ static void multipleDefs(const KrkClosure * closure, int destination) { S("")))); } -static int _unpack_op(void * context, const KrkValue * values, size_t count) { +static int _unpack_op(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) { KrkTuple * output = context; if (unlikely(output->values.count + count > output->values.capacity)) { krk_runtimeError(vm.exceptions->valueError, "too many values to unpack (expected %zu)", @@ -416,7 +366,7 @@ static int _unpack_op(void * context, const KrkValue * values, size_t count) { return 0; } -static int _unpack_args(void * context, const KrkValue * values, size_t count) { +static int _unpack_args(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) { KrkValueArray * positionals = context; if (positionals->count + count > positionals->capacity) { size_t old = positionals->capacity; @@ -431,7 +381,7 @@ static int _unpack_args(void * context, const KrkValue * values, size_t count) { return 0; } -int krk_processComplexArguments(int argCount, KrkValueArray * positionals, KrkTable * keywords, const char * name) { +int krk_processComplexArguments_r(KrkThreadState * _thread, int argCount, KrkValueArray * positionals, KrkTable * keywords, const char * name) { #define TOP_ARGS 3 size_t kwargsCount = AS_INTEGER(krk_currentThread.stackTop[-TOP_ARGS]); argCount--; @@ -481,6 +431,8 @@ int krk_processComplexArguments(int argCount, KrkValueArray * positionals, KrkTa return 1; } +#define krk_processComplexArguments(c,p,k,n) krk_processComplexArguments_r(_thread,c,p,k,n) + /** * Call a managed method. * Takes care of argument count checking, default argument filling, @@ -491,7 +443,7 @@ int krk_processComplexArguments(int argCount, KrkValueArray * positionals, KrkTa * `extra` is passed by `callValue` to tell us which case we have, and thus * where we need to restore the stack to when we return from this call. */ -static inline int _callManaged(KrkClosure * closure, int argCount, int returnDepth) { +static inline int _callManaged(KrkThreadState * _thread, KrkClosure * closure, int argCount, int returnDepth) { size_t potentialPositionalArgs = closure->function->potentialPositionals; size_t totalArguments = closure->function->totalArguments; size_t offsetOfExtraArgs = potentialPositionalArgs; @@ -527,7 +479,7 @@ static inline int _callManaged(KrkClosure * closure, int argCount, int returnDep /* Do we already know we have too many arguments? Let's bail before doing a bunch of work. */ if ((positionals->count > potentialPositionalArgs) && !(closure->function->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS)) { - checkArgumentCount(closure,positionals->count); + checkArgumentCount(_thread, closure,positionals->count); goto _errorDuringPositionals; } @@ -573,7 +525,7 @@ static inline int _callManaged(KrkClosure * closure, int argCount, int returnDep for (int j = 0; j < (int)closure->function->requiredArgs; ++j) { if (krk_valuesEqual(name, closure->function->requiredArgNames.values[j])) { if (!IS_KWARGS(krk_currentThread.stackTop[-argCount + j])) { - multipleDefs(closure,j); + multipleDefs(_thread, closure,j); goto _errorAfterPositionals; } krk_currentThread.stackTop[-argCount + j] = value; @@ -584,7 +536,7 @@ static inline int _callManaged(KrkClosure * closure, int argCount, int returnDep for (int j = 0; j < (int)closure->function->keywordArgs; ++j) { if (krk_valuesEqual(name, closure->function->keywordArgNames.values[j])) { if (!IS_KWARGS(krk_currentThread.stackTop[-argCount + j + closure->function->requiredArgs])) { - multipleDefs(closure, j + closure->function->requiredArgs); + multipleDefs(_thread, closure, j + closure->function->requiredArgs); goto _errorAfterPositionals; } krk_currentThread.stackTop[-argCount + j + closure->function->requiredArgs] = value; @@ -628,7 +580,7 @@ _finishKwarg: } else if ((size_t)argCount > potentialPositionalArgs && (closure->function->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS)) { KrkValue * startOfPositionals = &krk_currentThread.stackTop[-argCount]; KrkValue tmp = krk_callNativeOnStack(argCount - potentialPositionalArgs, - &startOfPositionals[potentialPositionalArgs], 0, krk_list_of); + &startOfPositionals[potentialPositionalArgs], 0, krk_list_of_r); startOfPositionals = &krk_currentThread.stackTop[-argCount]; startOfPositionals[offsetOfExtraArgs] = tmp; argCount = potentialPositionalArgs + 1; @@ -636,7 +588,7 @@ _finishKwarg: while (krk_currentThread.stackTop > startOfPositionals + argCount) krk_pop(); } - if (unlikely(!checkArgumentCount(closure, argCountX))) goto _errorAfterKeywords; + if (unlikely(!checkArgumentCount(_thread, closure, argCountX))) goto _errorAfterKeywords; while (argCount < (int)totalArguments) { krk_push(KWARGS_VAL(0)); @@ -678,20 +630,20 @@ _errorAfterKeywords: * If the stack is reallocated within this call, the old stack will not be freed until * all such nested calls through krk_callNativeOnStack have returned. */ -inline KrkValue krk_callNativeOnStack(size_t argCount, const KrkValue *stackArgs, int hasKw, NativeFn native) { +inline KrkValue krk_callNativeOnStack_r(KrkThreadState * _thread, size_t argCount, const KrkValue *stackArgs, int hasKw, NativeFn native) { /** * If someone is already preserving this stack, we can just call directly. */ if (unlikely(krk_currentThread.flags & KRK_THREAD_DEFER_STACK_FREE)) { - return native(argCount, stackArgs, hasKw); + return native(_thread, argCount, stackArgs, hasKw); } /* Mark the thread's stack as preserved. */ krk_currentThread.flags |= KRK_THREAD_DEFER_STACK_FREE; size_t sizeBefore = krk_currentThread.stackSize; void * stackBefore = krk_currentThread.stack; - KrkValue result = native(argCount, stackArgs, hasKw); + KrkValue result = native(_thread, argCount, stackArgs, hasKw); if (unlikely(krk_currentThread.stack != stackBefore)) { FREE_ARRAY(KrkValue, stackBefore, sizeBefore); @@ -707,12 +659,12 @@ inline KrkValue krk_callNativeOnStack(size_t argCount, const KrkValue *stackArgs * object on the stack - only its arguments. If that is the case, we unfortunately need * to rotate the stack so we can inject the implicit bound argument at the front. */ -static void _rotate(size_t argCount) { +static void _rotate(KrkThreadState * _thread, size_t argCount) { krk_push(NONE_VAL()); memmove(&krk_currentThread.stackTop[-argCount],&krk_currentThread.stackTop[-argCount-1],sizeof(KrkValue) * argCount); } -static inline int _callNative(KrkNative* callee, int argCount, int returnDepth) { +static inline int _callNative(KrkThreadState * _thread, KrkNative* callee, int argCount, int returnDepth) { NativeFn native = (NativeFn)callee->function; size_t stackOffsetAfterCall = (krk_currentThread.stackTop - krk_currentThread.stack) - argCount - returnDepth; KrkValue result; @@ -735,7 +687,7 @@ static inline int _callNative(KrkNative* callee, int argCount, int returnDepth) krk_currentThread.stackTop = &krk_currentThread.stack[stackOffsetAfterCall+1]; /* Call with list as arguments */ - result = native(AS_LIST(myList)->count-1, AS_LIST(myList)->values, 1); + result = native(_thread, AS_LIST(myList)->count-1, AS_LIST(myList)->values, 1); } else { result = krk_callNativeOnStack(argCount, krk_currentThread.stackTop - argCount, 0, native); } @@ -763,20 +715,20 @@ static inline int _callNative(KrkNative* callee, int argCount, int returnDepth) * If callValue returns 0, the VM should already be in the exception state * and it is not necessary to raise another exception. */ -int krk_callValue(KrkValue callee, int argCount, int returnDepth) { +int krk_callValue_r(KrkThreadState * _thread, KrkValue callee, int argCount, int returnDepth) { if (likely(IS_OBJECT(callee))) { _innerObject: switch (OBJECT_TYPE(callee)) { - case KRK_OBJ_CLOSURE: return _callManaged(AS_CLOSURE(callee), argCount, returnDepth); - case KRK_OBJ_NATIVE: return _callNative(AS_NATIVE(callee), argCount, returnDepth); + case KRK_OBJ_CLOSURE: return _callManaged(_thread, AS_CLOSURE(callee), argCount, returnDepth); + case KRK_OBJ_NATIVE: return _callNative(_thread, AS_NATIVE(callee), argCount, returnDepth); case KRK_OBJ_INSTANCE: { KrkClass * _class = AS_INSTANCE(callee)->_class; if (likely(_class->_call != NULL)) { - if (unlikely(returnDepth == 0)) _rotate(argCount); + if (unlikely(returnDepth == 0)) _rotate(_thread, argCount); krk_currentThread.stackTop[-argCount - 1] = callee; argCount++; returnDepth = returnDepth ? (returnDepth - 1) : 0; - return (_class->_call->type == KRK_OBJ_CLOSURE) ? _callManaged((KrkClosure*)_class->_call, argCount, returnDepth) : _callNative((KrkNative*)_class->_call, argCount, returnDepth); + return (_class->_call->type == KRK_OBJ_CLOSURE) ? _callManaged(_thread, (KrkClosure*)_class->_call, argCount, returnDepth) : _callNative(_thread, (KrkNative*)_class->_call, argCount, returnDepth); } else { krk_runtimeError(vm.exceptions->typeError, "'%T' object is not callable", callee); return 0; @@ -786,7 +738,7 @@ int krk_callValue(KrkValue callee, int argCount, int returnDepth) { KrkClass * _class = AS_CLASS(callee); KrkInstance * newInstance = krk_newInstance(_class); if (likely(_class->_init != NULL)) { - if (unlikely(returnDepth == 0)) _rotate(argCount); + if (unlikely(returnDepth == 0)) _rotate(_thread, argCount); krk_currentThread.stackTop[-argCount - 1] = OBJECT_VAL(newInstance); callee = OBJECT_VAL(_class->_init); argCount++; @@ -807,7 +759,7 @@ int krk_callValue(KrkValue callee, int argCount, int returnDepth) { krk_runtimeError(vm.exceptions->argumentError, "???"); return 0; } - if (unlikely(returnDepth == 0)) _rotate(argCount); + if (unlikely(returnDepth == 0)) _rotate(_thread, argCount); krk_currentThread.stackTop[-argCount - 1] = bound->receiver; callee = OBJECT_VAL(bound->method); argCount++; @@ -825,7 +777,7 @@ int krk_callValue(KrkValue callee, int argCount, int returnDepth) { /** * Takes care of runnext/pop */ -KrkValue krk_callStack(int argCount) { +KrkValue krk_callStack_r(KrkThreadState * _thread, int argCount) { switch (krk_callValue(krk_peek(argCount), argCount, 1)) { case 2: return krk_pop(); case 1: return krk_runNext(); @@ -833,11 +785,11 @@ KrkValue krk_callStack(int argCount) { } } -KrkValue krk_callDirect(KrkObj * callable, int argCount) { +KrkValue krk_callDirect_r(KrkThreadState * _thread, KrkObj * callable, int argCount) { int result = 0; switch (callable->type) { - case KRK_OBJ_CLOSURE: result = _callManaged((KrkClosure*)callable, argCount, 0); break; - case KRK_OBJ_NATIVE: result = _callNative((KrkNative*)callable, argCount, 0); break; + case KRK_OBJ_CLOSURE: result = _callManaged(_thread, (KrkClosure*)callable, argCount, 0); break; + case KRK_OBJ_NATIVE: result = _callNative(_thread, (KrkNative*)callable, argCount, 0); break; default: __builtin_unreachable(); } if (likely(result == 2)) return krk_pop(); @@ -849,7 +801,7 @@ KrkValue krk_callDirect(KrkObj * callable, int argCount) { * Attach a method call to its callee and return a BoundMethod. * Works for managed and native method calls. */ -int krk_bindMethod(KrkClass * _class, KrkString * name) { +int krk_bindMethod_r(KrkThreadState * _thread, KrkClass * _class, KrkString * name) { KrkClass * originalClass = _class; KrkValue method, out; while (_class) { @@ -863,7 +815,7 @@ int krk_bindMethod(KrkClass * _class, KrkString * name) { } else if (AS_OBJECT(method)->flags & KRK_OBJ_FLAGS_FUNCTION_IS_STATIC_METHOD) { out = method; } else if (AS_OBJECT(method)->flags & KRK_OBJ_FLAGS_FUNCTION_IS_DYNAMIC_PROPERTY) { - out = AS_NATIVE(method)->function(1, (KrkValue[]){krk_peek(0)}, 0); + out = AS_NATIVE(method)->function(_thread, 1, (KrkValue[]){krk_peek(0)}, 0); } else { out = OBJECT_VAL(krk_newBoundMethod(krk_peek(0), AS_OBJECT(method))); } @@ -887,7 +839,7 @@ int krk_bindMethod(KrkClass * _class, KrkString * name) { * Similar to @ref krk_bindMethod but does not create bound method objects. * @returns 1 if the result was an (unbound) method, 2 if it was something else, 0 if it was not found. */ -int krk_unbindMethod(KrkClass * _class, KrkString * name) { +int krk_unbindMethod(KrkThreadState * _thread, KrkClass * _class, KrkString * name) { KrkClass * originalClass = _class; KrkValue method, out; while (_class) { @@ -897,7 +849,7 @@ int krk_unbindMethod(KrkClass * _class, KrkString * name) { if (!_class) return 0; if (IS_NATIVE(method) || IS_CLOSURE(method)) { if (AS_OBJECT(method)->flags & KRK_OBJ_FLAGS_FUNCTION_IS_DYNAMIC_PROPERTY) { - out = AS_NATIVE(method)->function(1, (KrkValue[]){krk_peek(0)}, 0); + out = AS_NATIVE(method)->function(_thread, 1, (KrkValue[]){krk_peek(0)}, 0); } else if (AS_CLOSURE(method)->obj.flags & KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD) { krk_pop(); krk_push(OBJECT_VAL(originalClass)); @@ -930,7 +882,7 @@ int krk_unbindMethod(KrkClass * _class, KrkString * name) { * Capture upvalues and mark them as open. Called upon closure creation to * mark stack slots used by a function. */ -static KrkUpvalue * captureUpvalue(int index) { +static KrkUpvalue * captureUpvalue(KrkThreadState *_thread, int index) { KrkUpvalue * prevUpvalue = NULL; KrkUpvalue * upvalue = krk_currentThread.openUpvalues; while (upvalue != NULL && upvalue->location > index) { @@ -956,7 +908,7 @@ static KrkUpvalue * captureUpvalue(int index) { * Close upvalues by moving them out of the stack and into the heap. * Their location attribute is set to -1 to indicate they now live on the heap. */ -static void closeUpvalues(int last) { +static void closeUpvalues(KrkThreadState * _thread, int last) { while (krk_currentThread.openUpvalues != NULL && krk_currentThread.openUpvalues->location >= last) { KrkUpvalue * upvalue = krk_currentThread.openUpvalues; upvalue->closed = krk_currentThread.stack[upvalue->location]; @@ -968,7 +920,7 @@ static void closeUpvalues(int last) { /** * Same as above, but the object has already been wrapped in a value. */ -void krk_attachNamedValue(KrkTable * table, const char name[], KrkValue obj) { +void krk_attachNamedValue_r(KrkThreadState * _thread, KrkTable * table, const char name[], KrkValue obj) { krk_push(obj); krk_push(OBJECT_VAL(krk_copyString(name,strlen(name)))); krk_tableSet(table, krk_peek(0), krk_peek(1)); @@ -982,7 +934,7 @@ void krk_attachNamedValue(KrkTable * table, const char name[], KrkValue obj) { * Generally used to attach classes or objects to the globals table, or to * a native module's export object. */ -void krk_attachNamedObject(KrkTable * table, const char name[], KrkObj * obj) { +void krk_attachNamedObject_r(KrkThreadState * _thread, KrkTable * table, const char name[], KrkObj * obj) { krk_attachNamedValue(table,name,OBJECT_VAL(obj)); } @@ -995,7 +947,7 @@ void krk_attachNamedObject(KrkTable * table, const char name[], KrkObj * obj) { * Or in more managed code terms, `if None`, `if False`, and `if 0` are all * going to take the else branch. */ -int krk_isFalsey(KrkValue value) { +int krk_isFalsey_r(KrkThreadState * _thread, KrkValue value) { switch (KRK_VAL_TYPE(value)) { case KRK_VAL_NONE: return 1; case KRK_VAL_BOOLEAN: return !AS_BOOLEAN(value); @@ -1024,7 +976,7 @@ int krk_isFalsey(KrkValue value) { return 0; /* Assume anything else is truthy */ } -void krk_setMaximumRecursionDepth(size_t maxDepth) { +void krk_setMaximumRecursionDepth_r(KrkThreadState * _thread, size_t maxDepth) { vm.maximumCallDepth = maxDepth; KrkThreadState * thread = vm.threads; @@ -1034,16 +986,16 @@ void krk_setMaximumRecursionDepth(size_t maxDepth) { } } -void krk_initVM(int flags) { -#if !defined(KRK_DISABLE_THREADS) && defined(__APPLE__) && defined(__aarch64__) - krk_forceThreadData(); -#endif +KrkThreadState * krk_initVM_withBinpath(int flags, char * binpath) { + KrkThreadState * _thread = calloc(1,sizeof(KrkThreadState)); + _thread->owner = calloc(1,sizeof(KrkVM)); + vm.binpath = binpath; vm.globalFlags = flags & 0xFF00; vm.maximumCallDepth = KRK_CALL_FRAMES_MAX; /* Reset current thread */ - krk_resetStack(); + krk_resetStack(_thread); krk_currentThread.frames = calloc(vm.maximumCallDepth,sizeof(KrkCallFrame)); krk_currentThread.flags = flags & 0x00FF; krk_currentThread.module = NULL; @@ -1081,47 +1033,53 @@ void krk_initVM(int flags) { } /* Build classes for basic types */ - _createAndBind_builtins(); - _createAndBind_type(); - _createAndBind_numericClasses(); - _createAndBind_strClass(); - _createAndBind_listClass(); - _createAndBind_tupleClass(); - _createAndBind_bytesClass(); - _createAndBind_dictClass(); - _createAndBind_functionClass(); - _createAndBind_rangeClass(); - _createAndBind_setClass(); - _createAndBind_sliceClass(); - _createAndBind_exceptions(); - _createAndBind_generatorClass(); - _createAndBind_longClass(); + _createAndBind_builtins(_thread); + _createAndBind_type(_thread); + _createAndBind_numericClasses(_thread); + _createAndBind_strClass(_thread); + _createAndBind_listClass(_thread); + _createAndBind_tupleClass(_thread); + _createAndBind_bytesClass(_thread); + _createAndBind_dictClass(_thread); + _createAndBind_functionClass(_thread); + _createAndBind_rangeClass(_thread); + _createAndBind_setClass(_thread); + _createAndBind_sliceClass(_thread); + _createAndBind_exceptions(_thread); + _createAndBind_generatorClass(_thread); + _createAndBind_longClass(_thread); if (!(vm.globalFlags & KRK_GLOBAL_NO_DEFAULT_MODULES)) { #ifndef KRK_NO_SYSTEM_MODULES - krk_module_init_kuroko(); - krk_module_init_gc(); - krk_module_init_time(); - krk_module_init_os(); - krk_module_init_fileio(); + krk_module_init_kuroko(_thread); + krk_module_init_gc(_thread); + krk_module_init_time(_thread); + krk_module_init_os(_thread); + krk_module_init_fileio(_thread); #endif #ifndef KRK_DISABLE_DEBUG - krk_module_init_dis(); + krk_module_init_dis(_thread); #endif #ifndef KRK_DISABLE_THREADS - krk_module_init_threading(); + krk_module_init_threading(_thread); #endif } - /* The VM is now ready to start executing code. */ - krk_resetStack(); + krk_resetStack(_thread); + + return _thread; } +KrkThreadState * krk_initVM(int flags) { + return krk_initVM_withBinpath(flags,NULL); +} + + /** * Reclaim resources used by the VM. */ -void krk_freeVM() { +void krk_freeVM(KrkThreadState * _thread) { krk_freeTable(&vm.strings); krk_freeTable(&vm.modules); if (vm.specialMethodNames) free(vm.specialMethodNames); @@ -1137,22 +1095,24 @@ void krk_freeVM() { krk_currentThread.next = thread->next; FREE_ARRAY(size_t, thread->stack, thread->stackSize); free(thread->frames); + free(thread); } FREE_ARRAY(size_t, krk_currentThread.stack, krk_currentThread.stackSize); - memset(&krk_vm,0,sizeof(krk_vm)); free(krk_currentThread.frames); - memset(&krk_currentThread,0,sizeof(KrkThreadState)); - extern void krk_freeMemoryDebugger(void); - krk_freeMemoryDebugger(); + extern void krk_freeMemoryDebugger_r(KrkThreadState *_thread); + krk_freeMemoryDebugger_r(_thread); + + free(_thread->owner); + free(_thread); } /** * Internal type(value).__name__ call for use in debugging methods and * creating exception strings. */ -const char * krk_typeName(KrkValue value) { +const char * krk_typeName_r(KrkThreadState * _thread, KrkValue value) { return krk_getType(value)->name->chars; } @@ -1167,7 +1127,7 @@ const char * krk_typeName(KrkValue value) { #endif #define MAKE_COMPARE_OP(name,operator,inv) \ - _protected KrkValue krk_operator_ ## name (KrkValue a, KrkValue b) { \ + _protected KrkValue krk_operator_ ## name ## _r(KrkThreadState * _thread, KrkValue a, KrkValue b) { \ KrkClass * atype = krk_getType(a); \ if (likely(atype->_ ## name != NULL)) { \ krk_push(a); krk_push(b); \ @@ -1188,7 +1148,7 @@ const char * krk_typeName(KrkValue value) { } #define MAKE_BIN_OP(name,operator,inv) \ MAKE_COMPARE_OP(name,operator,inv) \ - _protected KrkValue krk_operator_i ## name (KrkValue a, KrkValue b) { \ + _protected KrkValue krk_operator_i ## name ## _r (KrkThreadState * _thread, KrkValue a, KrkValue b) { \ KrkClass * atype = krk_getType(a); \ if (likely(atype->_i ## name != NULL)) { \ krk_push(a); krk_push(b); \ @@ -1196,7 +1156,7 @@ const char * krk_typeName(KrkValue value) { if (!IS_NOTIMPL(result)) { return result; } \ } \ if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) return NONE_VAL(); \ - return krk_operator_ ## name(a,b); \ + return krk_operator_ ## name ## _r(_thread, a,b); \ } MAKE_BIN_OP(add,"+",radd) @@ -1219,17 +1179,17 @@ MAKE_COMPARE_OP(le, "<=", ge) MAKE_COMPARE_OP(ge, ">=", le) _protected -KrkValue krk_operator_eq(KrkValue a, KrkValue b) { +KrkValue krk_operator_eq_r(KrkThreadState * _thread, KrkValue a, KrkValue b) { return BOOLEAN_VAL(krk_valuesEqual(a,b)); } _protected -KrkValue krk_operator_is(KrkValue a, KrkValue b) { +KrkValue krk_operator_is_r(KrkThreadState * _thread, KrkValue a, KrkValue b) { return BOOLEAN_VAL(krk_valuesSame(a,b)); } #define MAKE_UNARY_OP(sname,operator,op) \ - _protected KrkValue krk_operator_ ## operator (KrkValue value) { \ + _protected KrkValue krk_operator_ ## operator ## _r (KrkThreadState * _thread, KrkValue value) { \ KrkClass * type = krk_getType(value); \ if (likely(type-> sname != NULL)) { \ krk_push(value); \ @@ -1254,7 +1214,7 @@ MAKE_UNARY_OP(_pos,pos,+) * stack manipulation could result in a handler being in the wrong place, * at which point there's no guarantees about what happens. */ -static int handleException() { +static int handleException(KrkThreadState * _thread) { int stackOffset, frameOffset; int exitSlot = (krk_currentThread.exitOnFrame >= 0) ? krk_currentThread.frames[krk_currentThread.exitOnFrame].outSlots : 0; for (stackOffset = (int)(krk_currentThread.stackTop - krk_currentThread.stack - 1); @@ -1276,7 +1236,7 @@ static int handleException() { krk_currentThread.frameCount = krk_currentThread.exitOnFrame; /* Ensure stack is in the expected place, as if we returned None. */ - closeUpvalues(exitSlot); + closeUpvalues(_thread, exitSlot); krk_currentThread.stackTop = &krk_currentThread.stack[exitSlot]; /* If exitSlot was not 0, there was an exception during a call to runNext(); @@ -1292,7 +1252,7 @@ static int handleException() { } /* We found an exception handler and can reset the VM to its call frame. */ - closeUpvalues(stackOffset); + closeUpvalues(_thread, stackOffset); krk_currentThread.stackTop = krk_currentThread.stack + stackOffset + 1; krk_currentThread.frameCount = frameOffset + 1; @@ -1310,7 +1270,7 @@ static int handleException() { * a later search path has a krk source and an earlier search path has a shared * object module, the later search path will still win. */ -int krk_loadModule(KrkString * path, KrkValue * moduleOut, KrkString * runAs, KrkValue parent) { +int krk_loadModule_r(KrkThreadState * _thread, KrkString * path, KrkValue * moduleOut, KrkString * runAs, KrkValue parent) { /* See if the module is already loaded */ if (krk_tableGet_fast(&vm.modules, runAs, moduleOut)) { krk_push(*moduleOut); @@ -1445,7 +1405,7 @@ int krk_loadModule(KrkString * path, KrkValue * moduleOut, KrkString * runAs, Kr krk_attachNamedValue(&krk_currentThread.module->fields, "__package__", NONE_VAL()); } } - krk_runfile(fileName,fileName); + krk_runfile(_thread,fileName,fileName); *moduleOut = OBJECT_VAL(krk_currentThread.module); krk_currentThread.module = enclosing; if (!IS_OBJECT(*moduleOut)) { @@ -1482,7 +1442,7 @@ int krk_loadModule(KrkString * path, KrkValue * moduleOut, KrkString * runAs, Kr char * handlerName = AS_CSTRING(krk_peek(0)); - KrkValue (*moduleOnLoad)(KrkString * name); + KrkValue (*moduleOnLoad)(KrkThreadState *, KrkString * name); dlSymType out = dlSym(dlRef, handlerName); memcpy(&moduleOnLoad,&out,sizeof(out)); @@ -1497,7 +1457,7 @@ int krk_loadModule(KrkString * path, KrkValue * moduleOut, KrkString * runAs, Kr krk_pop(); /* onload function */ - *moduleOut = moduleOnLoad(runAs); + *moduleOut = moduleOnLoad(_thread, runAs); if (!krk_isInstanceOf(*moduleOut, vm.baseClasses->moduleClass)) { dlClose(dlRef); krk_runtimeError(vm.exceptions->importError, @@ -1541,7 +1501,7 @@ int krk_loadModule(KrkString * path, KrkValue * moduleOut, KrkString * runAs, Kr return 0; } -int krk_importModule(KrkString * name, KrkString * runAs) { +int krk_importModule_r(KrkThreadState * _thread, KrkString * name, KrkString * runAs) { /* See if 'name' is clear to directly import */ int isClear = 1; for (size_t i = 0; i < name->length; ++i) { @@ -1603,7 +1563,7 @@ int krk_importModule(KrkString * name, KrkString * runAs) { /* We'll split the package name is str.split(__package__,'.') */ krk_push(packageName); krk_push(OBJECT_VAL(S("."))); - KrkValue components = krk_string_split(2,(KrkValue[]){krk_peek(1),krk_peek(0)}, 0); + KrkValue components = krk_string_split(_thread, 2,(KrkValue[]){krk_peek(1),krk_peek(0)}, 0); if (!IS_list(components)) { krk_runtimeError(vm.exceptions->importError, "internal error while calculating package path"); return 0; @@ -1670,7 +1630,7 @@ int krk_importModule(KrkString * name, KrkString * runAs) { krk_push(OBJECT_VAL(name)); // 3: remaining path to process krk_push(OBJECT_VAL(S("."))); // 4: string "." to search for do { - KrkValue listOut = krk_string_split(3,(KrkValue[]){krk_currentThread.stack[argBase+3], krk_currentThread.stack[argBase+4], INTEGER_VAL(1)}, 0); + KrkValue listOut = krk_string_split(_thread, 3,(KrkValue[]){krk_currentThread.stack[argBase+3], krk_currentThread.stack[argBase+4], INTEGER_VAL(1)}, 0); if (!IS_INSTANCE(listOut)) return 0; /* Set node */ @@ -1735,7 +1695,7 @@ int krk_importModule(KrkString * name, KrkString * runAs) { } while (1); } -int krk_doRecursiveModuleLoad(KrkString * name) { +int krk_doRecursiveModuleLoad_r(KrkThreadState * _thread, KrkString * name) { return krk_importModule(name,name); } @@ -1746,7 +1706,7 @@ int krk_doRecursiveModuleLoad(KrkString * name) { * Returns 0 if nothing was found, 1 if something was - and that * "something" will replace [stack top]. */ -static int valueGetProperty(KrkString * name) { +static int valueGetProperty(KrkThreadState * _thread, KrkString * name) { KrkValue this = krk_peek(0); KrkClass * objectClass; KrkValue value; @@ -1800,7 +1760,7 @@ static int valueGetProperty(KrkString * name) { * immediately called, eg. for GET_METHOD that is followed by argument pushing * and then CALL_METHOD. */ -static int valueGetMethod(KrkString * name) { +static int valueGetMethod(KrkThreadState * _thread, KrkString * name) { KrkValue this = krk_peek(0); KrkClass * objectClass; KrkValue value; @@ -1837,7 +1797,7 @@ static int valueGetMethod(KrkString * name) { } /* See if the base class for this non-instance type has a method available */ - int maybe = krk_unbindMethod(objectClass, name); + int maybe = krk_unbindMethod(_thread, objectClass, name); if (maybe) return maybe; if (objectClass->_getattr) { @@ -1850,14 +1810,14 @@ static int valueGetMethod(KrkString * name) { return 0; } -int krk_getAttribute(KrkString * name) { - return valueGetProperty(name); +int krk_getAttribute_r(KrkThreadState * _thread, KrkString * name) { + return valueGetProperty(_thread, name); } -KrkValue krk_valueGetAttribute(KrkValue value, char * name) { +KrkValue krk_valueGetAttribute_r(KrkThreadState *_thread, KrkValue value, char * name) { krk_push(OBJECT_VAL(krk_copyString(name,strlen(name)))); krk_push(value); - if (!valueGetProperty(AS_STRING(krk_peek(1)))) { + if (!valueGetProperty(_thread, AS_STRING(krk_peek(1)))) { return krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%s'", krk_peek(0), name); } krk_swap(1); @@ -1865,10 +1825,10 @@ KrkValue krk_valueGetAttribute(KrkValue value, char * name) { return krk_pop(); } -KrkValue krk_valueGetAttribute_default(KrkValue value, char * name, KrkValue defaultVal) { +KrkValue krk_valueGetAttribute_default_r(KrkThreadState * _thread, KrkValue value, char * name, KrkValue defaultVal) { krk_push(OBJECT_VAL(krk_copyString(name,strlen(name)))); krk_push(value); - if (!valueGetProperty(AS_STRING(krk_peek(1)))) { + if (!valueGetProperty(_thread, AS_STRING(krk_peek(1)))) { krk_pop(); krk_pop(); return defaultVal; @@ -1878,7 +1838,7 @@ KrkValue krk_valueGetAttribute_default(KrkValue value, char * name, KrkValue def return krk_pop(); } -static int valueDelProperty(KrkString * name) { +static int valueDelProperty(KrkThreadState * _thread, KrkString * name) { if (IS_INSTANCE(krk_peek(0))) { KrkInstance* instance = AS_INSTANCE(krk_peek(0)); if (!krk_tableDelete(&instance->fields, OBJECT_VAL(name))) { @@ -1908,21 +1868,21 @@ static int valueDelProperty(KrkString * name) { return 0; } -int krk_delAttribute(KrkString * name) { - return valueDelProperty(name); +int krk_delAttribute_r(KrkThreadState * _thread, KrkString * name) { + return valueDelProperty(_thread, name); } -KrkValue krk_valueDelAttribute(KrkValue owner, char * name) { +KrkValue krk_valueDelAttribute_r(KrkThreadState * _thread, KrkValue owner, char * name) { krk_push(OBJECT_VAL(krk_copyString(name,strlen(name)))); krk_push(owner); - if (!valueDelProperty(AS_STRING(krk_peek(1)))) { + if (!valueDelProperty(_thread, AS_STRING(krk_peek(1)))) { return krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%s'", krk_peek(0), name); } krk_pop(); /* String */ return NONE_VAL(); } -static int trySetDescriptor(KrkValue owner, KrkString * name, KrkValue value) { +static int trySetDescriptor(KrkThreadState * _thread, KrkValue owner, KrkString * name, KrkValue value) { KrkClass * _class = krk_getType(owner); KrkValue property; while (_class) { @@ -1944,7 +1904,7 @@ static int trySetDescriptor(KrkValue owner, KrkString * name, KrkValue value) { } _noexport -KrkValue krk_instanceSetAttribute_wrapper(KrkValue owner, KrkString * name, KrkValue to) { +KrkValue krk_instanceSetAttribute_wrapper_r(KrkThreadState * _thread, KrkValue owner, KrkString * name, KrkValue to) { if (!krk_tableSetIfExists(&AS_INSTANCE(owner)->fields, OBJECT_VAL(name), to)) { /* That might have raised an exception. */ if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return NONE_VAL(); @@ -1970,7 +1930,7 @@ KrkValue krk_instanceSetAttribute_wrapper(KrkValue owner, KrkString * name, KrkV return to; } -static int valueSetProperty(KrkString * name) { +static int valueSetProperty(KrkThreadState * _thread, KrkString * name) { KrkValue owner = krk_peek(1); KrkValue value = krk_peek(0); if (IS_INSTANCE(owner)) { @@ -1982,7 +1942,7 @@ static int valueSetProperty(KrkString * name) { return 1; } if (krk_tableSet(&AS_INSTANCE(owner)->fields, OBJECT_VAL(name), value)) { - if (trySetDescriptor(owner, name, value)) { + if (trySetDescriptor(_thread, owner, name, value)) { krk_tableDelete(&AS_INSTANCE(owner)->fields, OBJECT_VAL(name)); return 1; } @@ -1996,28 +1956,28 @@ static int valueSetProperty(KrkString * name) { } else if (IS_CLOSURE(owner)) { /* Closures shouldn't have descriptors, but let's let this happen anyway... */ if (krk_tableSet(&AS_CLOSURE(owner)->fields, OBJECT_VAL(name), value)) { - if (trySetDescriptor(owner, name, value)) { + if (trySetDescriptor(_thread, owner, name, value)) { krk_tableDelete(&AS_CLOSURE(owner)->fields, OBJECT_VAL(name)); return 1; } } } else { - return (trySetDescriptor(owner,name,value)); + return (trySetDescriptor(_thread, owner,name,value)); } krk_swap(1); krk_pop(); return 1; } -int krk_setAttribute(KrkString * name) { - return valueSetProperty(name); +int krk_setAttribute_r(KrkThreadState * _thread, KrkString * name) { + return valueSetProperty(_thread, name); } -KrkValue krk_valueSetAttribute(KrkValue owner, char * name, KrkValue to) { +KrkValue krk_valueSetAttribute_r(KrkThreadState * _thread, KrkValue owner, char * name, KrkValue to) { krk_push(OBJECT_VAL(krk_copyString(name,strlen(name)))); krk_push(owner); krk_push(to); - if (!valueSetProperty(AS_STRING(krk_peek(2)))) { + if (!valueSetProperty(_thread, AS_STRING(krk_peek(2)))) { return krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%s'", krk_peek(1), name); } krk_swap(1); @@ -2026,30 +1986,30 @@ KrkValue krk_valueSetAttribute(KrkValue owner, char * name, KrkValue to) { } #define BINARY_OP(op) { KrkValue b = krk_peek(0); KrkValue a = krk_peek(1); \ - a = krk_operator_ ## op (a,b); \ + a = krk_operator_ ## op ## _r(_thread, a,b); \ krk_currentThread.stackTop[-2] = a; krk_pop(); break; } #define INPLACE_BINARY_OP(op) { KrkValue b = krk_peek(0); KrkValue a = krk_peek(1); \ - a = krk_operator_i ## op (a,b); \ + a = krk_operator_i ## op ## _r(_thread, a,b); \ krk_currentThread.stackTop[-2] = a; krk_pop(); break; } -extern KrkValue krk_int_op_add(krk_integer_type a, krk_integer_type b); -extern KrkValue krk_int_op_sub(krk_integer_type a, krk_integer_type b); +extern KrkValue krk_int_op_add(KrkThreadState * _thread, krk_integer_type a, krk_integer_type b); +extern KrkValue krk_int_op_sub(KrkThreadState * _thread, krk_integer_type a, krk_integer_type b); /* These operations are most likely to occur on integers, so we special case them */ #define LIKELY_INT_BINARY_OP(op) { KrkValue b = krk_peek(0); KrkValue a = krk_peek(1); \ - if (likely(IS_INTEGER(a) && IS_INTEGER(b))) a = krk_int_op_ ## op (AS_INTEGER(a), AS_INTEGER(b)); \ - else a = krk_operator_ ## op (a,b); \ + if (likely(IS_INTEGER(a) && IS_INTEGER(b))) a = krk_int_op_ ## op (_thread, AS_INTEGER(a), AS_INTEGER(b)); \ + else a = krk_operator_ ## op ## _r (_thread, a,b); \ krk_currentThread.stackTop[-2] = a; krk_pop(); break; } /* Comparators like these are almost definitely going to happen on integers. */ #define LIKELY_INT_COMPARE_OP(op,operator) { KrkValue b = krk_peek(0); KrkValue a = krk_peek(1); \ if (likely(IS_INTEGER(a) && IS_INTEGER(b))) a = BOOLEAN_VAL(AS_INTEGER(a) operator AS_INTEGER(b)); \ - else a = krk_operator_ ## op (a,b); \ + else a = krk_operator_ ## op ## _r(_thread, a,b); \ krk_currentThread.stackTop[-2] = a; krk_pop(); break; } #define LIKELY_INT_UNARY_OP(op,operator) { KrkValue a = krk_peek(0); \ if (likely(IS_INTEGER(a))) a = INTEGER_VAL(operator AS_INTEGER(a)); \ - else a = krk_operator_ ## op (a); \ + else a = krk_operator_ ## op ## _r(_thread, a); \ krk_currentThread.stackTop[-1] = a; break; } #define READ_BYTE() (*frame->ip++) @@ -2060,7 +2020,7 @@ extern FUNC_SIG(list,append); extern FUNC_SIG(dict,__setitem__); extern FUNC_SIG(set,add); -static inline void makeCollection(NativeFn func, size_t count) { +static inline void makeCollection(KrkThreadState * _thread, NativeFn func, size_t count) { KrkValue collection = krk_callNativeOnStack(count, &krk_currentThread.stackTop[-count], 0, func); if (count) { krk_currentThread.stackTop[-count] = collection; @@ -2073,7 +2033,7 @@ static inline void makeCollection(NativeFn func, size_t count) { } } -static inline int doFormatString(int options) { +static inline int doFormatString(KrkThreadState * _thread, int options) { if (options & FORMAT_OP_FORMAT) { krk_swap(1); if (options & FORMAT_OP_EQ) { @@ -2133,7 +2093,7 @@ static inline int doFormatString(int options) { return 0; } -static inline void commonMethodInvoke(size_t methodOffset, int args, const char * msgFormat) { +static inline void commonMethodInvoke(KrkThreadState * _thread, size_t methodOffset, int args, const char * msgFormat) { KrkClass * type = krk_getType(krk_peek(args-1)); KrkObj * method = *(KrkObj**)((char*)type + methodOffset); if (likely(method != NULL)) { @@ -2147,7 +2107,7 @@ static inline void commonMethodInvoke(size_t methodOffset, int args, const char /** * VM main loop. */ -static KrkValue run() { +static KrkValue run(KrkThreadState * _thread) { KrkCallFrame* frame = &krk_currentThread.frames[krk_currentThread.frameCount - 1]; while (1) { @@ -2232,7 +2192,7 @@ _resumeHook: (void)0; case OP_RETURN: { _finishReturn: (void)0; KrkValue result = krk_pop(); - closeUpvalues(frame->slots); + closeUpvalues(_thread, frame->slots); /* See if this frame had a thing */ int stackOffset; for (stackOffset = (int)(krk_currentThread.stackTop - krk_currentThread.stack - 1); @@ -2318,29 +2278,29 @@ _finishReturn: (void)0; goto _finishException; } case OP_CLOSE_UPVALUE: - closeUpvalues((krk_currentThread.stackTop - krk_currentThread.stack)-1); + closeUpvalues(_thread, (krk_currentThread.stackTop - krk_currentThread.stack)-1); krk_pop(); break; case OP_INVOKE_GETTER: { - commonMethodInvoke(offsetof(KrkClass,_getter), 2, "'%T' object is not subscriptable"); + commonMethodInvoke(_thread, offsetof(KrkClass,_getter), 2, "'%T' object is not subscriptable"); break; } case OP_INVOKE_SETTER: { - commonMethodInvoke(offsetof(KrkClass,_setter), 3, "'%T' object doesn't support item assignment"); + commonMethodInvoke(_thread, offsetof(KrkClass,_setter), 3, "'%T' object doesn't support item assignment"); break; } case OP_INVOKE_DELETE: { - commonMethodInvoke(offsetof(KrkClass,_delitem), 2, "'%T' object doesn't support item deletion"); + commonMethodInvoke(_thread, offsetof(KrkClass,_delitem), 2, "'%T' object doesn't support item deletion"); krk_pop(); /* unused result */ break; } case OP_INVOKE_ITER: { - commonMethodInvoke(offsetof(KrkClass,_iter), 1, "'%T' object is not iterable"); + commonMethodInvoke(_thread, offsetof(KrkClass,_iter), 1, "'%T' object is not iterable"); break; } case OP_INVOKE_CONTAINS: { krk_swap(1); /* operands are backwards */ - commonMethodInvoke(offsetof(KrkClass,_contains), 2, "'%T' object can not be tested for membership"); + commonMethodInvoke(_thread, offsetof(KrkClass,_contains), 2, "'%T' object can not be tested for membership"); break; } case OP_INVOKE_AWAIT: { @@ -2352,7 +2312,7 @@ _finishReturn: (void)0; /* Store special methods for quick access */ krk_finalizeClass(_class); /* Call __set_name__? */ - _callSetName(_class); + _callSetName(_thread, _class); break; } case OP_INHERIT: { @@ -2724,7 +2684,7 @@ _finishReturn: (void)0; frame->ip += 2; } if (isLocal & 1) { - closure->upvalues[i] = captureUpvalue(frame->slots + index); + closure->upvalues[i] = captureUpvalue(_thread, frame->slots + index); } else { closure->upvalues[i] = frame->closure->upvalues[index]; } @@ -2761,7 +2721,7 @@ _finishReturn: (void)0; case OP_IMPORT_FROM: { ONE_BYTE_OPERAND; KrkString * name = READ_STRING(OPERAND); - if (unlikely(!valueGetProperty(name))) { + if (unlikely(!valueGetProperty(_thread, name))) { /* Try to import... */ KrkValue moduleName; if (!krk_tableGet(&AS_INSTANCE(krk_peek(0))->fields, vm.specialMethodNames[METHOD_NAME], &moduleName)) { @@ -2786,7 +2746,7 @@ _finishReturn: (void)0; case OP_GET_PROPERTY: { ONE_BYTE_OPERAND; KrkString * name = READ_STRING(OPERAND); - if (unlikely(!valueGetProperty(name))) { + if (unlikely(!valueGetProperty(_thread, name))) { krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%S'", krk_peek(0), name); goto _finishException; } @@ -2797,7 +2757,7 @@ _finishReturn: (void)0; case OP_DEL_PROPERTY: { ONE_BYTE_OPERAND; KrkString * name = READ_STRING(OPERAND); - if (unlikely(!valueDelProperty(name))) { + if (unlikely(!valueDelProperty(_thread, name))) { krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%S'", krk_peek(0), name); goto _finishException; } @@ -2808,7 +2768,7 @@ _finishReturn: (void)0; case OP_SET_PROPERTY: { ONE_BYTE_OPERAND; KrkString * name = READ_STRING(OPERAND); - if (unlikely(!valueSetProperty(name))) { + if (unlikely(!valueSetProperty(_thread, name))) { krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%S'", krk_peek(1), name); goto _finishException; } @@ -2867,7 +2827,7 @@ _finishReturn: (void)0; case OP_GET_METHOD: { ONE_BYTE_OPERAND; KrkString * name = READ_STRING(OPERAND); - int result = valueGetMethod(name); + int result = valueGetMethod(_thread, name); if (result == 2) { krk_push(NONE_VAL()); krk_swap(2); @@ -2897,7 +2857,7 @@ _finishReturn: (void)0; THREE_BYTE_OPERAND; case OP_CLOSE_MANY: { ONE_BYTE_OPERAND; - closeUpvalues((krk_currentThread.stackTop - krk_currentThread.stack) - OPERAND); + closeUpvalues(_thread, (krk_currentThread.stackTop - krk_currentThread.stack) - OPERAND); for (unsigned int i = 0; i < OPERAND; ++i) { krk_pop(); } @@ -2909,7 +2869,7 @@ _finishReturn: (void)0; case OP_EXIT_LOOP: { ONE_BYTE_OPERAND; _finishPopBlock: - closeUpvalues(frame->slots + OPERAND); + closeUpvalues(_thread, frame->slots + OPERAND); int stackOffset; for (stackOffset = (int)(krk_currentThread.stackTop - krk_currentThread.stack - 1); stackOffset >= (int)(frame->slots + OPERAND) && @@ -2944,35 +2904,35 @@ _finishPopBlock: THREE_BYTE_OPERAND; case OP_TUPLE: { ONE_BYTE_OPERAND; - makeCollection(krk_tuple_of, OPERAND); + makeCollection(_thread, krk_tuple_of_r, OPERAND); break; } case OP_MAKE_LIST_LONG: THREE_BYTE_OPERAND; case OP_MAKE_LIST: { ONE_BYTE_OPERAND; - makeCollection(krk_list_of, OPERAND); + makeCollection(_thread, krk_list_of_r, OPERAND); break; } case OP_MAKE_DICT_LONG: THREE_BYTE_OPERAND; case OP_MAKE_DICT: { ONE_BYTE_OPERAND; - makeCollection(krk_dict_of, OPERAND); + makeCollection(_thread, krk_dict_of_r, OPERAND); break; } case OP_MAKE_SET_LONG: THREE_BYTE_OPERAND; case OP_MAKE_SET: { ONE_BYTE_OPERAND; - makeCollection(krk_set_of, OPERAND); + makeCollection(_thread, krk_set_of_r, OPERAND); break; } case OP_SLICE_LONG: THREE_BYTE_OPERAND; case OP_SLICE: { ONE_BYTE_OPERAND; - makeCollection(krk_slice_of, OPERAND); + makeCollection(_thread, krk_slice_of_r, OPERAND); break; } case OP_LIST_APPEND_LONG: @@ -2980,7 +2940,7 @@ _finishPopBlock: case OP_LIST_APPEND: { ONE_BYTE_OPERAND; KrkValue list = krk_currentThread.stack[frame->slots + OPERAND]; - FUNC_NAME(list,append)(2,(KrkValue[]){list,krk_peek(0)},0); + FUNC_NAME(list,append)(_thread, 2,(KrkValue[]){list,krk_peek(0)},0); krk_pop(); break; } @@ -2989,7 +2949,7 @@ _finishPopBlock: case OP_DICT_SET: { ONE_BYTE_OPERAND; KrkValue dict = krk_currentThread.stack[frame->slots + OPERAND]; - FUNC_NAME(dict,__setitem__)(3,(KrkValue[]){dict,krk_peek(1),krk_peek(0)},0); + FUNC_NAME(dict,__setitem__)(_thread, 3,(KrkValue[]){dict,krk_peek(1),krk_peek(0)},0); krk_pop(); krk_pop(); break; @@ -2999,7 +2959,7 @@ _finishPopBlock: case OP_SET_ADD: { ONE_BYTE_OPERAND; KrkValue set = krk_currentThread.stack[frame->slots + OPERAND]; - FUNC_NAME(set,add)(2,(KrkValue[]){set,krk_peek(0)},0); + FUNC_NAME(set,add)(_thread, 2,(KrkValue[]){set,krk_peek(0)},0); krk_pop(); break; } @@ -3049,7 +3009,7 @@ _finishPopBlock: THREE_BYTE_OPERAND; case OP_FORMAT_VALUE: { ONE_BYTE_OPERAND; - if (doFormatString(OPERAND)) goto _finishException; + if (doFormatString(_thread, OPERAND)) goto _finishException; break; } @@ -3083,7 +3043,7 @@ _finishPopBlock: } if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) { _finishException: - if (!handleException()) { + if (!handleException(_thread)) { if (!IS_NONE(krk_currentThread.stackTop[-2])) { krk_attachInnerException(krk_currentThread.stackTop[-2]); } @@ -3114,15 +3074,15 @@ _finishException: * can call a native method can call a managed can call a native * and so on (hopefully). */ -KrkValue krk_runNext(void) { +KrkValue krk_runNext_r(KrkThreadState *_thread) { size_t oldExit = krk_currentThread.exitOnFrame; krk_currentThread.exitOnFrame = krk_currentThread.frameCount - 1; - KrkValue result = run(); + KrkValue result = run(_thread); krk_currentThread.exitOnFrame = oldExit; return result; } -KrkInstance * krk_startModule(const char * name) { +KrkInstance * krk_startModule_r(KrkThreadState * _thread, const char * name) { KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass); krk_currentThread.module = module; krk_attachNamedObject(&vm.modules, name, (KrkObj*)module); @@ -3132,10 +3092,10 @@ KrkInstance * krk_startModule(const char * name) { return module; } -KrkValue krk_interpret(const char * src, char * fromFile) { - KrkCodeObject * function = krk_compile(src, fromFile); +KrkValue krk_interpret(KrkThreadState * _thread, const char * src, char * fromFile) { + KrkCodeObject * function = krk_compile(_thread, src, fromFile); if (!function) { - if (!krk_currentThread.frameCount) handleException(); + if (!krk_currentThread.frameCount) handleException(_thread); return NONE_VAL(); } @@ -3149,7 +3109,7 @@ KrkValue krk_interpret(const char * src, char * fromFile) { } #ifndef KRK_NO_FILESYSTEM -KrkValue krk_runfile(const char * fileName, char * fromFile) { +KrkValue krk_runfile(KrkThreadState * _thread, const char * fileName, char * fromFile) { FILE * f = fopen(fileName,"r"); if (!f) { fprintf(stderr, "%s: could not open file '%s': %s\n", "kuroko", fileName, strerror(errno)); @@ -3168,7 +3128,7 @@ KrkValue krk_runfile(const char * fileName, char * fromFile) { fclose(f); buf[size] = '\0'; - KrkValue result = krk_interpret(buf, fromFile); + KrkValue result = krk_interpret(_thread, buf, fromFile); free(buf); return result; diff --git a/tools/compile.c b/tools/compile.c index 22454fd..2f55499 100644 --- a/tools/compile.c +++ b/tools/compile.c @@ -55,7 +55,7 @@ KrkValue SeenFunctions; KrkValue UnseenFunctions; KrkValue StringTable; -static void _initListFunctions(void) { +static void _initListFunctions(KrkThreadState * _thread) { KrkValue _list_pop; KrkValue _list_append; KrkValue _list_contains; @@ -70,24 +70,30 @@ static void _initListFunctions(void) { ListIndex = AS_NATIVE(_list_index)->function; } -static void findInterpreter(char * argv[]) { +static char * findInterpreter(char * argv[]) { #ifdef _WIN32 - vm.binpath = strdup(_pgmptr); + return strdup(_pgmptr); #else /* Try asking /proc */ + char tmp[4096]; char * binpath = realpath("/proc/self/exe", NULL); if (!binpath || (access(binpath, X_OK) != 0)) { + if (binpath) { + free(binpath); + binpath = NULL; + } if (strchr(argv[0], '/')) { binpath = realpath(argv[0], NULL); } else { /* Search PATH for argv[0] */ - char * _path = strdup(getenv("PATH")); + char * p = getenv("PATH"); + if (!p) return NULL; + char * _path = strdup(p); char * path = _path; while (path) { char * next = strchr(path,':'); if (next) *next++ = '\0'; - char tmp[4096]; snprintf(tmp, 4096, "%s/%s", path, argv[0]); if (access(tmp, X_OK) == 0) { binpath = strdup(tmp); @@ -98,9 +104,7 @@ static void findInterpreter(char * argv[]) { free(_path); } } - if (binpath) { - vm.binpath = binpath; - } /* Else, give up at this point and just don't attach it at all. */ + return binpath; #endif } @@ -121,7 +125,7 @@ static size_t internString(KrkString * str) { return count++; } -static int doStringTable(FILE * out) { +static int doStringTable(KrkThreadState * _thread, FILE * out) { uint32_t stringCount = count; fwrite(&stringCount, 1, sizeof(uint32_t), out); @@ -134,8 +138,8 @@ static int doStringTable(FILE * out) { return 0; } -#define WRITE_INTEGER(i) _writeInteger(out, i) -static void _writeInteger(FILE* out, krk_integer_type i) { +#define WRITE_INTEGER(i) _writeInteger(_thread, out, i) +static void _writeInteger(KrkThreadState * _thread, FILE* out, krk_integer_type i) { if (i >= 0 && i < 256) { \ fwrite((uint8_t[]){'i',i}, 1, 2, out); } else { @@ -147,8 +151,8 @@ static void _writeInteger(FILE* out, krk_integer_type i) { } } -#define WRITE_FLOATING(f) _writeFloating(out, f) -static void _writeFloating(FILE * out, double f) { +#define WRITE_FLOATING(f) _writeFloating(_thread, out, f) +static void _writeFloating(KrkThreadState * _thread, FILE * out, double f) { uint64_t doubleOut; memcpy(&doubleOut, &f, sizeof(double)); fwrite("d", 1, 1, out); @@ -157,8 +161,8 @@ static void _writeFloating(FILE * out, double f) { #define WRITE_KWARGS(k) fwrite("k",1,1,out); -#define WRITE_STRING(s) _writeString(out, s) -static void _writeString(FILE * out, KrkString * s) { +#define WRITE_STRING(s) _writeString(_thread, out, s) +static void _writeString(KrkThreadState * _thread, FILE * out, KrkString * s) { uint32_t ind = internString(s); if (ind < 256) { fwrite((uint8_t[]){'s',(uint8_t)ind}, 1, 2, out); @@ -168,8 +172,8 @@ static void _writeString(FILE * out, KrkString * s) { } } -#define WRITE_BYTES(b) _writeBytes(out,b) -static void _writeBytes(FILE * out, KrkBytes * b) { +#define WRITE_BYTES(b) _writeBytes(_thread, out,b) +static void _writeBytes(KrkThreadState * _thread, FILE * out, KrkBytes * b) { if (b->length < 256) { fwrite((uint8_t[]){'b', (uint8_t)b->length}, 1, 2, out); fwrite(b->bytes, 1, b->length, out); @@ -181,11 +185,11 @@ static void _writeBytes(FILE * out, KrkBytes * b) { } } -#define WRITE_FUNCTION(f) _writeFunction(out,f) -static void _writeFunction(FILE * out, KrkCodeObject * f) { +#define WRITE_FUNCTION(f) _writeFunction(_thread,out,f) +static void _writeFunction(KrkThreadState * _thread, FILE * out, KrkCodeObject * f) { /* Find this function in the function table. */ KrkValue this = OBJECT_VAL(f); - KrkValue index = ListIndex(2,(KrkValue[]){SeenFunctions,this},0); + KrkValue index = ListIndex(_thread,2,(KrkValue[]){SeenFunctions,this},0); if (!IS_INTEGER(index)) { fprintf(stderr, "Internal error: Expected int from list.index, got '%s'\n", krk_typeName(index)); exit(1); @@ -204,13 +208,13 @@ static void _writeFunction(FILE * out, KrkCodeObject * f) { } } -static int doFirstPass(FILE * out) { +static int doFirstPass(KrkThreadState * _thread, FILE * out) { /* Go through all functions and build string tables and function index */ while (AS_LIST(UnseenFunctions)->count) { - KrkValue nextFunc = ListPop(2,(KrkValue[]){UnseenFunctions,INTEGER_VAL(0)},0); + KrkValue nextFunc = ListPop(_thread, 2,(KrkValue[]){UnseenFunctions,INTEGER_VAL(0)},0); krk_push(nextFunc); - ListAppend(2,(KrkValue[]){SeenFunctions,nextFunc},0); + ListAppend(_thread,2,(KrkValue[]){SeenFunctions,nextFunc},0); /* Examine */ KrkCodeObject * func = AS_codeobject(nextFunc); @@ -235,9 +239,9 @@ static int doFirstPass(FILE * out) { } else if (IS_codeobject(value)) { /* If we haven't seen this function yet, append it to the list */ krk_push(value); - KrkValue boolResult = ListContains(2,(KrkValue[]){SeenFunctions,value},0); + KrkValue boolResult = ListContains(_thread,2,(KrkValue[]){SeenFunctions,value},0); if (IS_BOOLEAN(boolResult) && AS_BOOLEAN(boolResult) == 0) { - ListAppend(2,(KrkValue[]){UnseenFunctions,value},0); + ListAppend(_thread,2,(KrkValue[]){UnseenFunctions,value},0); } krk_pop(); } @@ -250,7 +254,7 @@ static int doFirstPass(FILE * out) { return 0; } -static int doSecondPass(FILE * out) { +static int doSecondPass(KrkThreadState * _thread, FILE * out) { /* Write the function count */ uint32_t functionCount = AS_LIST(SeenFunctions)->count; @@ -343,7 +347,7 @@ static int doSecondPass(FILE * out) { return 0; } -static int compileFile(char * fileName) { +static int compileFile(KrkThreadState * _thread, char * fileName) { /* Compile source file */ FILE * f = fopen(fileName, "r"); if (!f) { @@ -366,7 +370,7 @@ static int compileFile(char * fileName) { krk_startModule("__main__"); - KrkCodeObject * func = krk_compile(buf, fileName); + KrkCodeObject * func = krk_compile(_thread, buf, fileName); if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) { fprintf(stderr, "%s: exception during compilation:\n", fileName); @@ -382,15 +386,15 @@ static int compileFile(char * fileName) { fwrite(&header, 1, sizeof(header), out); - SeenFunctions = krk_list_of(0,NULL,0); + SeenFunctions = krk_list_of_r(_thread, 0,NULL,0); krk_push(SeenFunctions); - UnseenFunctions = krk_list_of(1,(KrkValue[]){OBJECT_VAL(func)},0); + UnseenFunctions = krk_list_of_r(_thread,1,(KrkValue[]){OBJECT_VAL(func)},0); krk_push(UnseenFunctions); - if (doFirstPass(out)) return 1; - if (doStringTable(out)) return 1; - if (doSecondPass(out)) return 1; + if (doFirstPass(_thread, out)) return 1; + if (doStringTable(_thread, out)) return 1; + if (doSecondPass(_thread, out)) return 1; krk_pop(); /* UnseenFunctions */ krk_pop(); /* SeenFunctions */ @@ -398,7 +402,7 @@ static int compileFile(char * fileName) { return 0; } -static KrkValue valueFromConstant(int i, FILE * inFile) { +static KrkValue valueFromConstant(KrkThreadState * _thread, int i, FILE * inFile) { uint8_t c = fgetc(inFile); DEBUGOUT(" %4lu: ", (unsigned long)i); switch (c) { @@ -444,7 +448,7 @@ static KrkValue valueFromConstant(int i, FILE * inFile) { } } -static int readFile(char * fileName) { +static int readFile(KrkThreadState * _thread, char * fileName) { FILE * inFile = fopen(fileName, "r"); if (!inFile) { @@ -484,7 +488,7 @@ static int readFile(char * fileName) { /* Create a string */ krk_push(OBJECT_VAL(krk_takeString(strVal,strLen))); - ListAppend(2,(KrkValue[]){StringTable, krk_peek(0)},0); + ListAppend(_thread,2,(KrkValue[]){StringTable, krk_peek(0)},0); #ifdef ISDEBUG fprintf(stderr, "%04lu: ", (unsigned long)i); krk_printValueSafe(stderr, krk_peek(0)); @@ -500,7 +504,7 @@ static int readFile(char * fileName) { for (size_t i = 0; i < (size_t)functionCount; ++i) { krk_push(OBJECT_VAL(krk_newCodeObject())); - ListAppend(2,(KrkValue[]){SeenFunctions, krk_peek(0)}, 0); + ListAppend(_thread,2,(KrkValue[]){SeenFunctions, krk_peek(0)}, 0); krk_pop(); } @@ -551,12 +555,12 @@ static int readFile(char * fileName) { /* Read argument names */ DEBUGOUT(" [Required Arguments]\n"); for (size_t i = 0; i < (size_t)function.reqArgs + !!(self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS); i++) { - krk_writeValueArray(&self->requiredArgNames, valueFromConstant(i,inFile)); + krk_writeValueArray(&self->requiredArgNames, valueFromConstant(_thread, i,inFile)); } DEBUGOUT(" [Keyword Arguments]\n"); for (size_t i = 0; i < (size_t)function.kwArgs + !!(self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS); i++) { - krk_writeValueArray(&self->keywordArgNames, valueFromConstant(i,inFile)); + krk_writeValueArray(&self->keywordArgNames, valueFromConstant(_thread, i,inFile)); } /* Skip bytecode for now, we'll look at it later */ @@ -584,7 +588,7 @@ static int readFile(char * fileName) { /* Read constants */ DEBUGOUT(" [Constants Table]\n"); for (size_t i = 0; i < function.ctSize; i++) { - krk_writeValueArray(&self->chunk.constants, valueFromConstant(i, inFile)); + krk_writeValueArray(&self->chunk.constants, valueFromConstant(_thread, i, inFile)); } } @@ -603,10 +607,11 @@ static int readFile(char * fileName) { KrkValue result = krk_runNext(); if (IS_INTEGER(result)) return AS_INTEGER(result); else { - return runSimpleRepl(); + return runSimpleRepl(_thread); } } +extern KrkThreadState * krk_initVM_withBinpath(int flags, char * binpath); int main(int argc, char * argv[]) { if (argc < 2) { fprintf(stderr, "usage: %s path-to-file.krk\n" @@ -616,14 +621,14 @@ int main(int argc, char * argv[]) { } /* Initialize a VM */ - findInterpreter(argv); - krk_initVM(0); - _initListFunctions(); + char * path = findInterpreter(argv); + KrkThreadState * _thread = krk_initVM_withBinpath(0,path); + _initListFunctions(_thread); if (argc < 3) { - return compileFile(argv[1]); + return compileFile(_thread, argv[1]); } else if (argc == 3 && !strcmp(argv[1],"-r")) { - return readFile(argv[2]); + return readFile(_thread, argv[2]); } return 1; diff --git a/tools/demo.c b/tools/demo.c index aa5669c..0fce56a 100644 --- a/tools/demo.c +++ b/tools/demo.c @@ -3,10 +3,10 @@ #include int main(int argc, char *argv[]) { - krk_initVM(0); + KrkThreadState * _thread = krk_initVM(0); krk_startModule("__main__"); - krk_interpret("import kuroko\nprint('Kuroko',kuroko.version)\n", ""); - krk_freeVM(); + krk_interpret(_thread, "import kuroko\nprint('Kuroko',kuroko.version)\n", ""); + krk_freeVM(_thread); return 0; } diff --git a/tools/sandbox.c b/tools/sandbox.c index 03b86aa..240f243 100644 --- a/tools/sandbox.c +++ b/tools/sandbox.c @@ -8,14 +8,14 @@ int main(int argc, char * argv[]) { /* Disable automatic traceback printing, default modules */ - krk_initVM(KRK_GLOBAL_CLEAN_OUTPUT|KRK_GLOBAL_NO_DEFAULT_MODULES); + KrkThreadState * _thread = krk_initVM(KRK_GLOBAL_CLEAN_OUTPUT|KRK_GLOBAL_NO_DEFAULT_MODULES); /* Set up our module context. */ krk_startModule("__main__"); int retval = 0; if (argc > 1) { - KrkValue result = krk_interpret(argv[1], ""); + KrkValue result = krk_interpret(_thread, argv[1], ""); if (!IS_NONE(result)) { if (IS_INTEGER(result)) { retval = AS_INTEGER(result); @@ -33,10 +33,10 @@ int main(int argc, char * argv[]) { retval = 1; } } else { - runSimpleRepl(); + runSimpleRepl(_thread); } - krk_freeVM(); + krk_freeVM(_thread); return retval; } diff --git a/tools/simple-repl.h b/tools/simple-repl.h index 80b7214..96fbd39 100644 --- a/tools/simple-repl.h +++ b/tools/simple-repl.h @@ -1,7 +1,7 @@ #define PROMPT_MAIN ">>> " #define PROMPT_BLOCK " > " -static int runSimpleRepl(void) { +static int runSimpleRepl(KrkThreadState * _thread) { int exitRepl = 0; while (!exitRepl) { size_t lineCapacity = 8; @@ -99,7 +99,7 @@ static int runSimpleRepl(void) { } FREE_ARRAY(char *, lines, lineCapacity); if (valid) { - KrkValue result = krk_interpret(allData, ""); + KrkValue result = krk_interpret(_thread, allData, ""); if (!IS_NONE(result)) { KrkClass * type = krk_getType(result); const char * formatStr = " \033[1;30m=> %s\033[0m\n"; @@ -118,7 +118,7 @@ static int runSimpleRepl(void) { } else if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) { krk_dumpTraceback(); } - krk_resetStack(); + krk_resetStack(_thread); free(allData); }