A reentrant Kuroko

This commit is contained in:
K. Lange 2022-07-31 14:40:58 +09:00
parent bc413b6dae
commit 437d3d9e05
49 changed files with 1034 additions and 916 deletions

View File

@ -10,7 +10,7 @@
FUNC_SIG(list,__init__); FUNC_SIG(list,__init__);
FUNC_SIG(list,sort); 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) if (argc != 1)
return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)",
"dir", "exactly", 1, "", argc); "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); myList = krk_list_of(0,NULL,0);
krk_push(myList); krk_push(myList);
krk_swap(1); krk_swap(1);
FUNC_NAME(list,__init__)(2,(KrkValue[]){krk_peek(1), krk_peek(0)},0); FUNC_NAME(list,__init__)(_thread, 2,(KrkValue[]){krk_peek(1), krk_peek(0)},0);
FUNC_NAME(list,sort)(1,(KrkValue[]){krk_peek(1)},0); FUNC_NAME(list,sort)(_thread, 1,(KrkValue[]){krk_peek(1)},0);
krk_pop(); krk_pop();
return 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_STRING(argv[1])) return krk_runtimeError(vm.exceptions->typeError, "expected str");
if (!IS_INSTANCE(argv[0])) { 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__`? */ /* It's an instance, that presumably does not have a `__setattr__`? */
@ -271,7 +271,7 @@ KRK_Function(dir) {
} }
/* Now sort it */ /* 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 */ 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] : \ ((string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) == (KRK_OBJ_FLAGS_STRING_UCS2) ? ((uint16_t*)string->codes)[offset] : \
((uint32_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 (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)) { } 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)) { } else if (IS_dict(iterable)) {
for (size_t i = 0; i < AS_DICT(iterable)->capacity; ++i) { for (size_t i = 0; i < AS_DICT(iterable)->capacity; ++i) {
if (!IS_KWARGS(AS_DICT(iterable)->entries[i].key)) { 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)) { } else if (IS_STRING(iterable)) {
krk_unicodeString(AS_STRING(iterable)); krk_unicodeString(AS_STRING(iterable));
for (size_t i = 0; i < AS_STRING(iterable)->codesLength; ++i) { 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; if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return 1;
krk_push(s); krk_push(s);
if (callback(context, &s, 1)) { if (callback(_thread, context, &s, 1)) {
krk_pop(); krk_pop();
return 1; return 1;
} }
@ -385,7 +385,7 @@ int krk_unpackIterable(KrkValue iterable, void * context, int callback(void *, c
} }
krk_push(item); krk_push(item);
if (callback(context, &item, 1)) { if (callback(_thread, context, &item, 1)) {
krk_pop(); /* item */ krk_pop(); /* item */
krk_pop(); /* __iter__ */ krk_pop(); /* __iter__ */
return 1; return 1;
@ -402,7 +402,7 @@ struct SimpleContext {
KrkValue base; 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; struct SimpleContext * _context = context;
for (size_t i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) {
if (!krk_isFalsey(values[i])) { if (!krk_isFalsey(values[i])) {
@ -420,7 +420,7 @@ KRK_Function(any) {
return context.base; 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; struct SimpleContext * _context = context;
for (size_t i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) {
if (krk_isFalsey(values[i])) { if (krk_isFalsey(values[i])) {
@ -655,7 +655,7 @@ KRK_Method(enumerate,__iter__) {
return OBJECT_VAL(self); 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__) { KRK_Method(enumerate,__call__) {
METHOD_TAKES_NONE(); METHOD_TAKES_NONE();
size_t stackOffset = krk_currentThread.stackTop - krk_currentThread.stack; 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++] = counter;
tupleOut->values.values[tupleOut->values.count++] = krk_pop(); 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()); krk_attachNamedValue(&self->fields, "_counter", krk_pop());
KrkValue out = krk_pop(); KrkValue out = krk_pop();
@ -694,10 +694,10 @@ KRK_Method(enumerate,__call__) {
return out; 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; struct SimpleContext * _context = context;
for (size_t i = 0; i < count; ++i) { 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; if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return 1;
} }
return 0; return 0;
@ -714,7 +714,7 @@ KRK_Function(sum) {
return context.base; 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; struct SimpleContext * _context = context;
for (size_t i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) {
if (IS_KWARGS(_context->base)) _context->base = values[i]; if (IS_KWARGS(_context->base)) _context->base = values[i];
@ -731,7 +731,7 @@ KRK_Function(min) {
FUNCTION_TAKES_AT_LEAST(1); FUNCTION_TAKES_AT_LEAST(1);
struct SimpleContext context = { KWARGS_VAL(0) }; struct SimpleContext context = { KWARGS_VAL(0) };
if (argc > 1) { if (argc > 1) {
if (_min_callback(&context, argv, argc)) return NONE_VAL(); if (_min_callback(_thread, &context, argv, argc)) return NONE_VAL();
} else { } else {
if (krk_unpackIterable(argv[0], &context, _min_callback)) return NONE_VAL(); if (krk_unpackIterable(argv[0], &context, _min_callback)) return NONE_VAL();
} }
@ -739,7 +739,7 @@ KRK_Function(min) {
return context.base; 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; struct SimpleContext * _context = context;
for (size_t i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) {
if (IS_KWARGS(_context->base)) _context->base = values[i]; if (IS_KWARGS(_context->base)) _context->base = values[i];
@ -756,7 +756,7 @@ KRK_Function(max) {
FUNCTION_TAKES_AT_LEAST(1); FUNCTION_TAKES_AT_LEAST(1);
struct SimpleContext context = { KWARGS_VAL(0) }; struct SimpleContext context = { KWARGS_VAL(0) };
if (argc > 1) { if (argc > 1) {
if (_max_callback(&context, argv, argc)) return NONE_VAL(); if (_max_callback(_thread, &context, argv, argc)) return NONE_VAL();
} else { } else {
if (krk_unpackIterable(argv[0], &context, _max_callback)) return NONE_VAL(); if (krk_unpackIterable(argv[0], &context, _max_callback)) return NONE_VAL();
} }
@ -1131,7 +1131,7 @@ KRK_Function(format) {
return result; return result;
} }
static void module_sweep(KrkInstance * inst) { static void module_sweep(KrkThreadState * _thread, KrkInstance * inst) {
#ifndef STATIC_ONLY #ifndef STATIC_ONLY
struct KrkModule * module = (struct KrkModule*)inst; struct KrkModule * module = (struct KrkModule*)inst;
if (module->libHandle) { if (module->libHandle) {
@ -1141,7 +1141,7 @@ static void module_sweep(KrkInstance * inst) {
} }
_noexport _noexport
void _createAndBind_builtins(void) { void _createAndBind_builtins(KrkThreadState *_thread) {
vm.baseClasses->objectClass = krk_newClass(S("object"), NULL); vm.baseClasses->objectClass = krk_newClass(S("object"), NULL);
krk_push(OBJECT_VAL(vm.baseClasses->objectClass)); krk_push(OBJECT_VAL(vm.baseClasses->objectClass));

View File

@ -4,7 +4,7 @@
#include "opcode_enum.h" #include "opcode_enum.h"
void krk_initChunk(KrkChunk * chunk) { void krk_initChunk_r(struct KrkThreadState * _thread, KrkChunk * chunk) {
chunk->count = 0; chunk->count = 0;
chunk->capacity = 0; chunk->capacity = 0;
chunk->code = NULL; chunk->code = NULL;
@ -16,7 +16,7 @@ void krk_initChunk(KrkChunk * chunk) {
krk_initValueArray(&chunk->constants); 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->linesCount && chunk->lines[chunk->linesCount-1].line == line) return;
if (chunk->linesCapacity < chunk->linesCount + 1) { if (chunk->linesCapacity < chunk->linesCount + 1) {
int old = chunk->linesCapacity; int old = chunk->linesCapacity;
@ -27,7 +27,7 @@ static void addLine(KrkChunk * chunk, size_t line) {
chunk->linesCount++; 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) { if (chunk->capacity < chunk->count + 1) {
int old = chunk->capacity; int old = chunk->capacity;
chunk->capacity = GROW_CAPACITY(old); 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; chunk->code[chunk->count] = byte;
addLine(chunk, line); addLine(_thread, chunk, line);
chunk->count++; 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(uint8_t, chunk->code, chunk->capacity);
FREE_ARRAY(KrkLineMap, chunk->lines, chunk->linesCapacity); FREE_ARRAY(KrkLineMap, chunk->lines, chunk->linesCapacity);
krk_freeValueArray(&chunk->constants); krk_freeValueArray(&chunk->constants);
krk_initChunk(chunk); 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_push(value);
krk_writeValueArray(&chunk->constants, value); krk_writeValueArray(&chunk->constants, value);
krk_pop(); krk_pop();
return chunk->constants.count - 1; 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) { if (ind >= 256) {
krk_writeChunk(chunk, OP_CONSTANT_LONG, line); krk_writeChunk(chunk, OP_CONSTANT_LONG, line);
krk_writeChunk(chunk, 0xFF & (ind >> 16), 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); size_t ind = krk_addConstant(chunk, value);
krk_emitConstant(chunk, ind, line); krk_emitConstant(chunk, ind, line);
return ind; 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; size_t line = 0;
for (size_t i = 0; i < chunk->linesCount; ++i) { for (size_t i = 0; i < chunk->linesCount; ++i) {
if (chunk->lines[i].startOffset > offset) break; if (chunk->lines[i].startOffset > offset) break;

View File

@ -278,9 +278,10 @@ typedef struct GlobalState {
KrkScanner scanner; KrkScanner scanner;
Compiler * current; Compiler * current;
ClassCompiler * currentClass; ClassCompiler * currentClass;
KrkThreadState * thread;
} GlobalState; } GlobalState;
static void _GlobalState_gcscan(KrkInstance * _self) { static void _GlobalState_gcscan(KrkThreadState * _thread, KrkInstance * _self) {
struct GlobalState * self = (void*)_self; struct GlobalState * self = (void*)_self;
Compiler * compiler = self->current; Compiler * compiler = self->current;
while (compiler != NULL) { 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? */ /* nothing to do? */
} }
#undef _thread
#define _thread (state->thread)
#define currentChunk() (&state->current->codeobject->chunk) #define currentChunk() (&state->current->codeobject->chunk)
#define EMIT_OPERAND_OP(opc, arg) do { if (arg < 256) { emitBytes(opc, arg); } \ #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; return function;
} }
static void freeCompiler(Compiler * compiler) { static void freeCompiler(struct GlobalState * state, Compiler * compiler) {
FREE_ARRAY(Local,compiler->locals, compiler->localsSpace); FREE_ARRAY(Local,compiler->locals, compiler->localsSpace);
FREE_ARRAY(Upvalue,compiler->upvalues, compiler->upvaluesSpace); FREE_ARRAY(Upvalue,compiler->upvalues, compiler->upvaluesSpace);
FREE_ARRAY(struct LoopExit,compiler->breaks, compiler->breakSpace); FREE_ARRAY(struct LoopExit,compiler->breaks, compiler->breakSpace);
@ -1414,7 +1418,7 @@ static void functionPrologue(struct GlobalState * state, Compiler * compiler) {
if (compiler->annotationCount) { if (compiler->annotationCount) {
emitByte(OP_ANNOTATE); emitByte(OP_ANNOTATE);
} }
freeCompiler(compiler); freeCompiler(state, compiler);
} }
static int argumentList(struct GlobalState * state, FunctionType type) { static int argumentList(struct GlobalState * state, FunctionType type) {
@ -1704,7 +1708,7 @@ _pop_class:
size_t indFunc = krk_addConstant(currentChunk(), OBJECT_VAL(makeclass)); size_t indFunc = krk_addConstant(currentChunk(), OBJECT_VAL(makeclass));
EMIT_OPERAND_OP(OP_CLOSURE, indFunc); EMIT_OPERAND_OP(OP_CLOSURE, indFunc);
doUpvalues(state, &subcompiler, makeclass); doUpvalues(state, &subcompiler, makeclass);
freeCompiler(&subcompiler); freeCompiler(state, &subcompiler);
emitBytes(OP_CALL, 0); emitBytes(OP_CALL, 0);
return classCompiler.name; return classCompiler.name;
@ -3115,7 +3119,7 @@ static void generatorExpression(struct GlobalState * state, KrkScanner scannerBe
size_t indFunc = krk_addConstant(currentChunk(), OBJECT_VAL(subfunction)); size_t indFunc = krk_addConstant(currentChunk(), OBJECT_VAL(subfunction));
EMIT_OPERAND_OP(OP_CLOSURE, indFunc); EMIT_OPERAND_OP(OP_CLOSURE, indFunc);
doUpvalues(state, &subcompiler, subfunction); doUpvalues(state, &subcompiler, subfunction);
freeCompiler(&subcompiler); freeCompiler(state, &subcompiler);
emitBytes(OP_CALL, 0); 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)); size_t indFunc = krk_addConstant(currentChunk(), OBJECT_VAL(subfunction));
EMIT_OPERAND_OP(OP_CLOSURE, indFunc); EMIT_OPERAND_OP(OP_CLOSURE, indFunc);
doUpvalues(state, &subcompiler, subfunction); doUpvalues(state, &subcompiler, subfunction);
freeCompiler(&subcompiler); freeCompiler(state, &subcompiler);
emitBytes(OP_CALL, 0); emitBytes(OP_CALL, 0);
} }
@ -3732,22 +3736,23 @@ static int maybeSingleExpression(struct GlobalState * state) {
* @return A compiled code object, or NULL on error. * @return A compiled code object, or NULL on error.
* @exception SyntaxError if @p src could not be compiled. * @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)); KrkClass * GlobalState = krk_newClass_r(base_thread, krk_copyString_r(base_thread, "GlobalState", 11), base_thread->owner->baseClasses->objectClass);
krk_push(OBJECT_VAL(GlobalState)); krk_push_r(base_thread, OBJECT_VAL(GlobalState));
GlobalState->allocSize = sizeof(struct GlobalState); GlobalState->allocSize = sizeof(struct GlobalState);
GlobalState->_ongcscan = _GlobalState_gcscan; GlobalState->_ongcscan = _GlobalState_gcscan;
GlobalState->_ongcsweep = _GlobalState_gcsweep; GlobalState->_ongcsweep = _GlobalState_gcsweep;
GlobalState->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT; GlobalState->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
krk_finalizeClass(GlobalState); krk_finalizeClass_r(base_thread, GlobalState);
struct GlobalState * state = (void*)krk_newInstance(GlobalState); struct GlobalState * state = (void*)krk_newInstance_r(base_thread, GlobalState);
krk_push(OBJECT_VAL(state)); krk_push_r(base_thread, OBJECT_VAL(state));
/* Point a new scanner at the source. */ /* Point a new scanner at the source. */
state->scanner = krk_initScanner(src); state->scanner = krk_initScanner(src);
state->thread = base_thread;
/* Reset parser state. */ /* Reset parser state. */
memset(&state->parser, 0, sizeof(state->parser)); memset(&state->parser, 0, sizeof(state->parser));
@ -3777,7 +3782,7 @@ KrkCodeObject * krk_compile(const char * src, char * fileName) {
} }
KrkCodeObject * function = endCompiler(state); KrkCodeObject * function = endCompiler(state);
freeCompiler(&compiler); freeCompiler(state, &compiler);
/* /*
* We'll always get something out of endCompiler even if it * We'll always get something out of endCompiler even if it

View File

@ -18,7 +18,7 @@
* the VM will never be called to produce a string, which would result in * 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! * 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; size_t i = 0;
if (!frame) frame = &krk_currentThread.frames[krk_currentThread.frameCount-1]; if (!frame) frame = &krk_currentThread.frames[krk_currentThread.frameCount-1];
for (KrkValue * slot = krk_currentThread.stack; slot < krk_currentThread.stackTop; slot++) { 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; KrkChunk * chunk = &func->chunk;
/* Function header */ /* Function header */
fprintf(f, "<%s(", name); fprintf(f, "<%s(", name);
@ -93,7 +93,7 @@ static inline const char * opcodeClean(const char * opc) {
return &opc[3]; 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; KrkChunk * chunk = &func->chunk;
size_t offset = 0; 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; KrkChunk * chunk = &func->chunk;
if (offset > 0 && krk_lineNumber(chunk, offset) == krk_lineNumber(chunk, offset - 1)) { if (offset > 0 && krk_lineNumber(chunk, offset) == krk_lineNumber(chunk, offset - 1)) {
fprintf(f, " "); fprintf(f, " ");
@ -219,7 +219,7 @@ size_t krk_disassembleInstruction(FILE * f, KrkCodeObject * func, size_t offset)
if (offset > 0) fprintf(f,"\n"); if (offset > 0) fprintf(f,"\n");
fprintf(f, "%4d ", (int)krk_lineNumber(chunk, offset)); fprintf(f, "%4d ", (int)krk_lineNumber(chunk, offset));
} }
if (isJumpTarget(func,offset)) { if (isJumpTarget(_thread, func,offset)) {
fprintf(f, " >> "); fprintf(f, " >> ");
} else { } else {
fprintf(f, " "); fprintf(f, " ");
@ -284,7 +284,7 @@ struct DebuggerState {
struct BreakpointEntry breakpoints[MAX_BREAKPOINTS]; 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; int index = vm.dbgState->breakpointsCount;
if (vm.dbgState->breakpointsCount == MAX_BREAKPOINTS) { if (vm.dbgState->breakpointsCount == MAX_BREAKPOINTS) {
/* See if any are available */ /* See if any are available */
@ -310,7 +310,7 @@ int krk_debug_addBreakpointCodeOffset(KrkCodeObject * target, size_t offset, int
return index; 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; 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); 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) if (breakIndex < 0 || breakIndex >= vm.dbgState->breakpointsCount || vm.dbgState->breakpoints[breakIndex].inFunction == NULL)
return 1; return 1;
vm.dbgState->breakpoints[breakIndex].inFunction->chunk.code[vm.dbgState->breakpoints[breakIndex].offset] = OP_BREAKPOINT; vm.dbgState->breakpoints[breakIndex].inFunction->chunk.code[vm.dbgState->breakpoints[breakIndex].offset] = OP_BREAKPOINT;
@ -363,7 +363,7 @@ KRK_Function(enablebreakpoint) {
return NONE_VAL(); 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) if (breakIndex < 0 || breakIndex >= vm.dbgState->breakpointsCount || vm.dbgState->breakpoints[breakIndex].inFunction == NULL)
return 1; return 1;
vm.dbgState->breakpoints[breakIndex].inFunction->chunk.code[vm.dbgState->breakpoints[breakIndex].offset] = vm.dbgState->breakpoints[breakIndex].inFunction->chunk.code[vm.dbgState->breakpoints[breakIndex].offset] =
@ -380,7 +380,7 @@ KRK_Function(disablebreakpoint) {
return NONE_VAL(); 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) if (breakIndex < 0 || breakIndex >= vm.dbgState->breakpointsCount || vm.dbgState->breakpoints[breakIndex].inFunction == NULL)
return 1; return 1;
krk_debug_disableBreakpoint(breakIndex); krk_debug_disableBreakpoint(breakIndex);
@ -459,7 +459,7 @@ KRK_Function(addbreakpoint) {
* we clear the debugging bits. Then we make a new exception * we clear the debugging bits. Then we make a new exception
* to attach a traceback to. * to attach a traceback to.
*/ */
void krk_debug_dumpTraceback(void) { void krk_debug_dumpTraceback_r(struct KrkThreadState * _thread) {
int flagsBefore = krk_currentThread.flags; int flagsBefore = krk_currentThread.flags;
krk_debug_disableSingleStep(); krk_debug_disableSingleStep();
krk_push(krk_currentThread.currentException); krk_push(krk_currentThread.currentException);
@ -471,15 +471,15 @@ void krk_debug_dumpTraceback(void) {
krk_currentThread.flags = flagsBefore; krk_currentThread.flags = flagsBefore;
} }
void krk_debug_enableSingleStep(void) { void krk_debug_enableSingleStep_r(struct KrkThreadState * _thread) {
krk_currentThread.flags |= KRK_THREAD_SINGLE_STEP; 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); 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) if (!vm.dbgState->debuggerHook)
abort(); abort();
@ -492,7 +492,7 @@ int krk_debuggerHook(KrkCallFrame * frame) {
vm.dbgState->repeatStack_bottom = -1; vm.dbgState->repeatStack_bottom = -1;
if (!vm.dbgState->thisWasForced) { if (!vm.dbgState->thisWasForced) {
int result = vm.dbgState->debuggerHook(frame); int result = vm.dbgState->debuggerHook(_thread,frame);
switch (result) { switch (result) {
case KRK_DEBUGGER_CONTINUE: case KRK_DEBUGGER_CONTINUE:
krk_debug_disableSingleStep(); krk_debug_disableSingleStep();
@ -525,13 +525,13 @@ int krk_debuggerHook(KrkCallFrame * frame) {
return 0; return 0;
} }
int krk_debug_registerCallback(KrkDebugCallback hook) { int krk_debug_registerCallback_r(struct KrkThreadState * _thread, KrkDebugCallback hook) {
if (vm.dbgState->debuggerHook) return 1; if (vm.dbgState->debuggerHook) return 1;
vm.dbgState->debuggerHook = hook; vm.dbgState->debuggerHook = hook;
return 0; 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) if (breakIndex < 0 || breakIndex >= vm.dbgState->breakpointsCount)
return -1; return -1;
if (vm.dbgState->breakpoints[breakIndex].inFunction == NULL) if (vm.dbgState->breakpoints[breakIndex].inFunction == NULL)
@ -545,7 +545,7 @@ int krk_debug_examineBreakpoint(int breakIndex, KrkCodeObject ** funcOut, size_t
return 0; return 0;
} }
int krk_debugBreakpointHandler(void) { int krk_debugBreakpointHandler_r(struct KrkThreadState * _thread) {
int index = -1; int index = -1;
KrkCallFrame * frame = &krk_currentThread.frames[krk_currentThread.frameCount-1]; KrkCallFrame * frame = &krk_currentThread.frames[krk_currentThread.frameCount-1];
@ -633,7 +633,7 @@ KRK_Function(build) {
krk_push(OBJECT_VAL(krk_currentThread.module)); krk_push(OBJECT_VAL(krk_currentThread.module));
KrkInstance * module = krk_currentThread.module; KrkInstance * module = krk_currentThread.module;
krk_currentThread.module = NULL; krk_currentThread.module = NULL;
KrkCodeObject * c = krk_compile(code->chars,fileName); KrkCodeObject * c = krk_compile(_thread, code->chars,fileName);
krk_currentThread.module = module; krk_currentThread.module = module;
krk_pop(); krk_pop();
if (c) return OBJECT_VAL(c); if (c) return OBJECT_VAL(c);
@ -663,7 +663,7 @@ KRK_Function(build) {
#define EXPAND_ARGS_MORE #define EXPAND_ARGS_MORE
#define FORMAT_VALUE_MORE #define FORMAT_VALUE_MORE
#define LOCAL_MORE local = operand; #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); KrkValue output = krk_list_of(0,NULL,0);
krk_push(output); krk_push(output);
@ -722,7 +722,7 @@ static KrkValue _examineInternal(KrkCodeObject* func) {
KRK_Function(examine) { KRK_Function(examine) {
FUNCTION_TAKES_EXACTLY(1); FUNCTION_TAKES_EXACTLY(1);
CHECK_ARG(0,codeobject,KrkCodeObject*,func); CHECK_ARG(0,codeobject,KrkCodeObject*,func);
return _examineInternal(func); return _examineInternal(_thread, func);
} }
#undef SIMPLE #undef SIMPLE
@ -735,7 +735,7 @@ KRK_Function(examine) {
#undef EXPAND_ARGS_MORE #undef EXPAND_ARGS_MORE
#undef FORMAT_VALUE_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); KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
krk_attachNamedObject(&vm.modules, "dis", (KrkObj*)module); krk_attachNamedObject(&vm.modules, "dis", (KrkObj*)module);
krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("dis")); krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("dis"));

View File

@ -108,7 +108,7 @@ KRK_Method(KeyError,__str__) {
return krk_callDirect(krk_getType(arg)->_reprer, 1); 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 { } else {
krk_push(OBJECT_VAL(S(""))); 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); (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(); /* instr */
krk_pop(); /* class */ krk_pop(); /* class */
@ -181,7 +181,7 @@ _badSyntaxError:
* and bind the native methods for exception objects. * and bind the native methods for exception objects.
*/ */
_noexport _noexport
void _createAndBind_exceptions(void) { void _createAndBind_exceptions(KrkThreadState * _thread) {
/* Add exception classes */ /* Add exception classes */
ADD_EXCEPTION_CLASS(vm.exceptions->baseException, Exception, vm.baseClasses->objectClass); ADD_EXCEPTION_CLASS(vm.exceptions->baseException, Exception, vm.baseClasses->objectClass);
BIND_METHOD(Exception,__init__); BIND_METHOD(Exception,__init__);
@ -211,7 +211,7 @@ void _createAndBind_exceptions(void) {
krk_finalizeClass(SyntaxError); krk_finalizeClass(SyntaxError);
} }
static void dumpInnerException(KrkValue exception, int depth) { static void dumpInnerException(KrkThreadState * _thread, KrkValue exception, int depth) {
if (depth > 10) { if (depth > 10) {
fprintf(stderr, "Too many inner exceptions encountered.\n"); fprintf(stderr, "Too many inner exceptions encountered.\n");
return; return;
@ -224,10 +224,10 @@ static void dumpInnerException(KrkValue exception, int depth) {
/* Print cause or context */ /* Print cause or context */
if (krk_tableGet(&AS_INSTANCE(exception)->fields, OBJECT_VAL(S("__cause__")), &inner) && !IS_NONE(inner)) { 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"); 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)) { } 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"); 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 * and then move inwards; on each call frame we try to open
* the source file and print the corresponding line. * 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())) { 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. * 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)) { if (IS_INSTANCE(krk_currentThread.currentException)) {
KrkInstance * theException = AS_INSTANCE(krk_currentThread.currentException); KrkInstance * theException = AS_INSTANCE(krk_currentThread.currentException);
KrkValue tracebackList; KrkValue tracebackList;
@ -392,7 +392,7 @@ static void attachTraceback(void) {
} /* else: probably a legacy 'raise str', just don't bother. */ } /* 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)) { if (IS_INSTANCE(krk_currentThread.currentException)) {
KrkInstance * theException = AS_INSTANCE(krk_currentThread.currentException); KrkInstance * theException = AS_INSTANCE(krk_currentThread.currentException);
if (krk_valuesSame(krk_currentThread.currentException,innerException)) { 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)) { if (IS_CLASS(base)) {
krk_push(base); krk_push(base);
base = krk_callStack(0); base = krk_callStack(0);
@ -418,7 +418,7 @@ void krk_raiseException(KrkValue base, KrkValue cause) {
krk_attachNamedValue(&AS_INSTANCE(krk_currentThread.currentException)->fields, krk_attachNamedValue(&AS_INSTANCE(krk_currentThread.currentException)->fields,
"__cause__", cause); "__cause__", cause);
} }
attachTraceback(); attachTraceback(_thread);
krk_currentThread.flags |= KRK_THREAD_HAS_EXCEPTION; 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 * and formats a message string to attach to it. Exception classes are
* found in vm.exceptions and are initialized on startup. * 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); KrkValue msg = KWARGS_VAL(0);
struct StringBuilder sb = {0}; struct StringBuilder sb = {0};
@ -568,6 +568,6 @@ _finish:
/* Set the current exception to be picked up by handleException */ /* Set the current exception to be picked up by handleException */
krk_currentThread.currentException = OBJECT_VAL(exceptionObject); krk_currentThread.currentException = OBJECT_VAL(exceptionObject);
attachTraceback(); attachTraceback(_thread);
return NONE_VAL(); return NONE_VAL();
} }

View File

@ -156,7 +156,7 @@ KRK_Method(File,readlines) {
krk_push(myList); krk_push(myList);
for (;;) { 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 (IS_NONE(line)) break;
if (krk_currentThread.flags & KRK_THREAD_SIGNALLED) break; if (krk_currentThread.flags & KRK_THREAD_SIGNALLED) break;
@ -259,10 +259,10 @@ KRK_Method(File,__enter__) {
return NONE_VAL(); return NONE_VAL();
} }
KRK_Method(File,__exit__) { 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)); KrkInstance * fileObject = krk_newInstance(KRK_BASE_CLASS(File));
krk_push(OBJECT_VAL(fileObject)); krk_push(OBJECT_VAL(fileObject));
KrkValue filename = OBJECT_VAL(krk_copyString(name,strlen(name))); KrkValue filename = OBJECT_VAL(krk_copyString(name,strlen(name)));
@ -327,7 +327,7 @@ KRK_Method(BinaryFile,readlines) {
krk_push(myList); krk_push(myList);
for (;;) { 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 (IS_NONE(line)) break;
if (krk_currentThread.flags & KRK_THREAD_SIGNALLED) break; if (krk_currentThread.flags & KRK_THREAD_SIGNALLED) break;
@ -410,7 +410,7 @@ KRK_Method(BinaryFile,write) {
#undef CURRENT_CTYPE #undef CURRENT_CTYPE
static void _file_sweep(KrkInstance * self) { static void _file_sweep(KrkThreadState * _thread, KrkInstance * self) {
struct File * me = (void *)self; struct File * me = (void *)self;
if (me->filePtr && !me->unowned) { if (me->filePtr && !me->unowned) {
fclose(me->filePtr); 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; struct Directory * me = (void *)self;
if (me->dirPtr) { if (me->dirPtr) {
closedir(me->dirPtr); closedir(me->dirPtr);
@ -491,10 +491,10 @@ KRK_Method(Directory,__enter__) {
return NONE_VAL(); return NONE_VAL();
} }
KRK_Method(Directory,__exit__) { 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); KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
krk_attachNamedObject(&vm.modules, "fileio", (KrkObj*)module); krk_attachNamedObject(&vm.modules, "fileio", (KrkObj*)module);
krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("fileio")); krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("fileio"));
@ -558,9 +558,9 @@ void krk_module_init_fileio(void) {
krk_finalizeClass(Directory); krk_finalizeClass(Directory);
/* Make an instance for stdout, stderr, and stdin */ /* Make an instance for stdout, stderr, and stdin */
makeFileInstance(module, "stdin", stdin); makeFileInstance(_thread, module, "stdin", stdin);
makeFileInstance(module, "stdout", stdout); makeFileInstance(_thread, module, "stdout", stdout);
makeFileInstance(module, "stderr", stderr); makeFileInstance(_thread, module, "stderr", stderr);
/* Our base will be the open method */ /* Our base will be the open method */
KRK_DOC(BIND_FUNC(module,open), "@brief Open a file.\n" KRK_DOC(BIND_FUNC(module,open), "@brief Open a file.\n"

View File

@ -35,6 +35,7 @@
#define CALLGRIND_TMP_FILE "/tmp/kuroko.callgrind.tmp" #define CALLGRIND_TMP_FILE "/tmp/kuroko.callgrind.tmp"
static KrkThreadState * _global_thread = NULL;
static int enableRline = 1; static int enableRline = 1;
static int exitRepl = 0; static int exitRepl = 0;
static int pasteEnabled = 0; static int pasteEnabled = 0;
@ -66,7 +67,7 @@ static int doRead(char * buf, size_t bufSize) {
return read(STDIN_FILENO, buf, 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}; struct StringBuilder sb = {0};
#ifndef NO_RLINE #ifndef NO_RLINE
@ -144,7 +145,7 @@ KRK_Function(input) {
} }
} }
return readLine(prompt, promptLength, syntaxHighlighter); return readLine(_thread, prompt, promptLength, syntaxHighlighter);
} }
#ifndef NO_RLINE #ifndef NO_RLINE
@ -156,7 +157,7 @@ KRK_Function(input) {
* We can probably also use valueGetProperty which does correct binding * We can probably also use valueGetProperty which does correct binding
* for native dynamic fields... * 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)); KrkValue member = OBJECT_VAL(krk_copyString(next.start, next.literalWidth));
krk_push(member); krk_push(member);
KrkValue value = krk_valueGetAttribute_default(current, AS_CSTRING(member), NONE_VAL()); 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) { 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. */ /* Figure out where the cursor is and if we should be completing anything. */
if (c->offset) { if (c->offset) {
size_t stackIn = krk_currentThread.stackTop - krk_currentThread.stack; 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; int isGlobal = 1;
while (n > base) { while (n > base) {
/* And look at the potential fields for instances/classes */ /* 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 (IS_NONE(next)) {
/* If we hit None, we found something invalid (or literally hit a None /* If we hit None, we found something invalid (or literally hit a None
* object, but really the difference is minimal in this case: Nothing * 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]); KrkString * s = AS_STRING(AS_LIST(dirList)->values[i]);
krk_push(OBJECT_VAL(s)); krk_push(OBJECT_VAL(s));
KrkToken asToken = {.start = s->chars, .literalWidth = s->length}; KrkToken asToken = {.start = s->chars, .literalWidth = s->length};
KrkValue thisValue = findFromProperty(root, asToken); KrkValue thisValue = findFromProperty(_thread, root, asToken);
krk_push(thisValue); krk_push(thisValue);
if (IS_CLOSURE(thisValue) || IS_BOUND_METHOD(thisValue) || if (IS_CLOSURE(thisValue) || IS_BOUND_METHOD(thisValue) ||
(IS_NATIVE(thisValue) && !((AS_OBJECT(thisValue)->flags & KRK_OBJ_FLAGS_FUNCTION_IS_DYNAMIC_PROPERTY)))) { (IS_NATIVE(thisValue) && !((AS_OBJECT(thisValue)->flags & KRK_OBJ_FLAGS_FUNCTION_IS_DYNAMIC_PROPERTY)))) {
@ -390,7 +392,7 @@ _cleanup:
#ifndef KRK_DISABLE_DEBUG #ifndef KRK_DISABLE_DEBUG
static char * lastDebugCommand = NULL; static char * lastDebugCommand = NULL;
static int debuggerHook(KrkCallFrame * frame) { static int debuggerHook(KrkThreadState *_thread,KrkCallFrame * frame) {
/* File information */ /* File information */
fprintf(stderr, "At offset 0x%04lx of function '%s' from '%s' on line %lu:\n", 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 { } else {
size_t frameCount = krk_currentThread.frameCount; size_t frameCount = krk_currentThread.frameCount;
/* Compile statement */ /* Compile statement */
KrkCodeObject * expression = krk_compile(arg,"<debugger>"); KrkCodeObject * expression = krk_compile(_thread, arg,"<debugger>");
if (expression) { if (expression) {
/* Make sure stepping is disabled first. */ /* Make sure stepping is disabled first. */
krk_debug_disableSingleStep(); krk_debug_disableSingleStep();
@ -640,6 +642,7 @@ _dbgQuit:
#endif #endif
static void handleSigint(int sigNum) { static void handleSigint(int sigNum) {
KrkThreadState * _thread = _global_thread;
/* Don't set the signal flag if the VM is not running */ /* Don't set the signal flag if the VM is not running */
if (!krk_currentThread.frameCount) return; if (!krk_currentThread.frameCount) return;
krk_currentThread.flags |= KRK_THREAD_SIGNALLED; krk_currentThread.flags |= KRK_THREAD_SIGNALLED;
@ -647,6 +650,7 @@ static void handleSigint(int sigNum) {
#ifndef _WIN32 #ifndef _WIN32
static void handleSigtrap(int sigNum) { static void handleSigtrap(int sigNum) {
KrkThreadState * _thread = _global_thread;
if (!krk_currentThread.frameCount) return; if (!krk_currentThread.frameCount) return;
krk_currentThread.flags |= KRK_THREAD_SINGLE_STEP; krk_currentThread.flags |= KRK_THREAD_SINGLE_STEP;
} }
@ -680,9 +684,9 @@ static void bindSignalHandlers(void) {
#endif #endif
} }
static void findInterpreter(char * argv[]) { static char * findInterpreter(char * argv[]) {
#ifdef _WIN32 #ifdef _WIN32
vm.binpath = strdup(_pgmptr); return strdup(_pgmptr);
#else #else
/* Try asking /proc */ /* Try asking /proc */
char tmp[4096]; char tmp[4096];
@ -697,7 +701,7 @@ static void findInterpreter(char * argv[]) {
} else { } else {
/* Search PATH for argv[0] */ /* Search PATH for argv[0] */
char * p = getenv("PATH"); char * p = getenv("PATH");
if (!p) return; if (!p) return NULL;
char * _path = strdup(p); char * _path = strdup(p);
char * path = _path; char * path = _path;
while (path) { while (path) {
@ -714,25 +718,25 @@ static void findInterpreter(char * argv[]) {
free(_path); free(_path);
} }
} }
if (binpath) { return binpath;
vm.binpath = binpath;
} /* Else, give up at this point and just don't attach it at all. */
#endif #endif
} }
extern KrkThreadState * krk_initVM_withBinpath(int flags, char * binpath);
static int runString(char * argv[], int flags, char * string) { static int runString(char * argv[], int flags, char * string) {
findInterpreter(argv); char * path = findInterpreter(argv);
krk_initVM(flags); KrkThreadState * _thread = krk_initVM_withBinpath(flags,path);
krk_startModule("__main__"); krk_startModule("__main__");
krk_attachNamedValue(&krk_currentThread.module->fields,"__doc__", NONE_VAL()); krk_attachNamedValue(&krk_currentThread.module->fields,"__doc__", NONE_VAL());
krk_interpret(string, "<stdin>"); krk_interpret(_thread, string, "<stdin>");
krk_freeVM(); krk_freeVM(_thread);
return 0; return 0;
} }
static int compileFile(char * argv[], int flags, char * fileName) { static int compileFile(char * argv[], int flags, char * fileName) {
findInterpreter(argv); char * path = findInterpreter(argv);
krk_initVM(flags); KrkThreadState * _thread = krk_initVM_withBinpath(flags,path);
/* Open the file. */ /* Open the file. */
FILE * f = fopen(fileName,"r"); FILE * f = fopen(fileName,"r");
@ -754,7 +758,7 @@ static int compileFile(char * argv[], int flags, char * fileName) {
krk_startModule("__main__"); krk_startModule("__main__");
/* Call the compiler directly. */ /* Call the compiler directly. */
KrkCodeObject * func = krk_compile(buf, fileName); KrkCodeObject * func = krk_compile(_thread, buf, fileName);
/* See if there was an exception. */ /* See if there was an exception. */
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) { if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) {
@ -765,7 +769,7 @@ static int compileFile(char * argv[], int flags, char * fileName) {
free(buf); free(buf);
/* Close out the compiler */ /* Close out the compiler */
krk_freeVM(); krk_freeVM(_thread);
return func == NULL; return func == NULL;
} }
@ -791,6 +795,7 @@ int main(int argc, char * argv[]) {
int inspectAfter = 0; int inspectAfter = 0;
int opt; int opt;
int maxDepth = -1; int maxDepth = -1;
FILE * callgrindFile = NULL;
while ((opt = getopt(argc, argv, "+:c:C:dgGim:rR:stTMSV-:")) != -1) { while ((opt = getopt(argc, argv, "+:c:C:dgGim:rR:stTMSV-:")) != -1) {
switch (opt) { switch (opt) {
case 'c': case 'c':
@ -820,7 +825,7 @@ int main(int argc, char * argv[]) {
break; break;
case 'T': { case 'T': {
flags |= KRK_GLOBAL_CALLGRIND; flags |= KRK_GLOBAL_CALLGRIND;
vm.callgrindFile = fopen(CALLGRIND_TMP_FILE,"w"); callgrindFile = fopen(CALLGRIND_TMP_FILE,"w");
break; break;
} }
case 'i': case 'i':
@ -890,9 +895,10 @@ int main(int argc, char * argv[]) {
} }
} }
_finishArgs: _finishArgs: (void)0;
findInterpreter(argv); char * path = findInterpreter(argv);
krk_initVM(flags); KrkThreadState * _thread = krk_initVM_withBinpath(flags,path);
if (callgrindFile) _thread->owner->callgrindFile = callgrindFile;
if (maxDepth != -1) { if (maxDepth != -1) {
krk_setMaximumRecursionDepth(maxDepth); krk_setMaximumRecursionDepth(maxDepth);
@ -907,7 +913,7 @@ _finishArgs:
for (int arg = optind; arg < argc; ++arg) { for (int arg = optind; arg < argc; ++arg) {
krk_push(OBJECT_VAL(krk_copyString(argv[arg],strlen(argv[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_push(argList);
krk_attachNamedValue(&vm.system->fields, "argv", argList); krk_attachNamedValue(&vm.system->fields, "argv", argList);
krk_pop(); krk_pop();
@ -933,7 +939,7 @@ _finishArgs:
krk_push(OBJECT_VAL(S(":"))); krk_push(OBJECT_VAL(S(":")));
/* Split into list */ /* 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_push(list);
krk_swap(2); krk_swap(2);
krk_pop(); /* colon */ krk_pop(); /* colon */
@ -943,7 +949,7 @@ _finishArgs:
krk_push(krk_valueGetAttribute(OBJECT_VAL(vm.system), "module_paths")); krk_push(krk_valueGetAttribute(OBJECT_VAL(vm.system), "module_paths"));
extern FUNC_SIG(list,extend); 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 */ /* Store */
krk_attachNamedValue(&vm.system->fields, "module_paths", list); krk_attachNamedValue(&vm.system->fields, "module_paths", list);
@ -978,7 +984,7 @@ _finishArgs:
AS_STRING(krk_peek(0))); AS_STRING(krk_peek(0)));
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) { if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) {
krk_dumpTraceback(); krk_dumpTraceback();
krk_resetStack(); krk_resetStack(_thread);
} }
if (!inspectAfter) return out; if (!inspectAfter) return out;
if (IS_INSTANCE(krk_peek(0))) { if (IS_INSTANCE(krk_peek(0))) {
@ -986,7 +992,7 @@ _finishArgs:
} }
} else if (optind != argc) { } else if (optind != argc) {
krk_startModule("__main__"); 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); if (IS_NONE(result) && krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) result = INTEGER_VAL(1);
} }
@ -998,7 +1004,7 @@ _finishArgs:
} }
if (runCmd) { if (runCmd) {
result = krk_interpret(runCmd, "<stdin>"); result = krk_interpret(_thread, runCmd, "<stdin>");
} }
if ((!moduleAsMain && !runCmd && optind == argc) || inspectAfter) { if ((!moduleAsMain && !runCmd && optind == argc) || inspectAfter) {
@ -1052,6 +1058,7 @@ _finishArgs:
/* Enable syntax highlight for Kuroko */ /* Enable syntax highlight for Kuroko */
rline_exp_set_syntax("krk"); rline_exp_set_syntax("krk");
/* Bind a callback for \t */ /* Bind a callback for \t */
_global_thread = _thread;
rline_exp_set_tab_complete_func(tab_complete_func); rline_exp_set_tab_complete_func(tab_complete_func);
#endif #endif
@ -1187,7 +1194,7 @@ _finishArgs:
FREE_ARRAY(char *, lines, lineCapacity); FREE_ARRAY(char *, lines, lineCapacity);
if (valid) { if (valid) {
KrkValue result = krk_interpret(allData, "<stdin>"); KrkValue result = krk_interpret(_thread, allData, "<stdin>");
if (!IS_NONE(result)) { if (!IS_NONE(result)) {
krk_attachNamedValue(&vm.builtins->fields, "_", result); krk_attachNamedValue(&vm.builtins->fields, "_", result);
KrkClass * type = krk_getType(result); KrkClass * type = krk_getType(result);
@ -1205,7 +1212,7 @@ _finishArgs:
fprintf(stdout, formatStr, AS_CSTRING(result)); fprintf(stdout, formatStr, AS_CSTRING(result));
} }
} }
krk_resetStack(); krk_resetStack(_thread);
free(allData); free(allData);
} }
@ -1217,17 +1224,17 @@ _finishArgs:
fclose(vm.callgrindFile); fclose(vm.callgrindFile);
vm.globalFlags &= ~(KRK_GLOBAL_CALLGRIND); vm.globalFlags &= ~(KRK_GLOBAL_CALLGRIND);
krk_resetStack(); krk_resetStack(_thread);
krk_startModule("<callgrind>"); krk_startModule("<callgrind>");
krk_attachNamedObject(&krk_currentThread.module->fields, "filename", (KrkObj*)S(CALLGRIND_TMP_FILE)); krk_attachNamedObject(&krk_currentThread.module->fields, "filename", (KrkObj*)S(CALLGRIND_TMP_FILE));
krk_interpret( krk_interpret(_thread,
"from callgrind import processFile\n" "from callgrind import processFile\n"
"import kuroko\n" "import kuroko\n"
"import os\n" "import os\n"
"processFile(filename, os.getpid(), ' '.join(kuroko.argv))","<callgrind>"); "processFile(filename, os.getpid(), ' '.join(kuroko.argv))","<callgrind>");
} }
krk_freeVM(); krk_freeVM(_thread);
if (IS_INTEGER(result)) return AS_INTEGER(result); if (IS_INTEGER(result)) return AS_INTEGER(result);

View File

@ -50,37 +50,43 @@ typedef struct {
* @brief Initialize an opcode chunk. * @brief Initialize an opcode chunk.
* @memberof KrkChunk * @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 * @memberof KrkChunk
* @brief Append a byte to an opcode chunk. * @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. * @brief Release the resources allocated to an opcode chunk.
* @memberof KrkChunk * @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. * @brief Add a new constant value to an opcode chunk.
* @memberof KrkChunk * @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. * @brief Write an OP_CONSTANT(_LONG) instruction.
* @memberof KrkChunk * @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. * @brief Add a new constant and write an instruction for it.
* @memberof KrkChunk * @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. * @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. * @param offset Byte offset of the instruction to locate.
* @return Line number, 1-indexed. * @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)

View File

@ -14,5 +14,5 @@
* @param fileName Path name of the source file or a representative string like "<stdin>" * @param fileName Path name of the source file or a representative string like "<stdin>"
* @return The code object resulting from the compilation, or NULL if compilation failed. * @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);

View File

@ -32,7 +32,8 @@
* @param func Code object to disassemble. * @param func Code object to disassemble.
* @param name Function name to display in disassembly output. * @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. * @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. * @param offset Byte offset of the instruction to disassemble.
* @return The size of the instruction in bytes. * @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. * @brief Called by the VM when a breakpoint is encountered.
* *
* Internal method, should not generally be called. * 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. * @brief Called by the VM on single step.
@ -64,13 +67,14 @@ extern int krk_debugBreakpointHandler(void);
* *
* Internal method, should not generally be called. * 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. * @brief Function pointer for a debugger hook.
* @ref krk_debug_registerCallback() * @ref krk_debug_registerCallback()
*/ */
typedef int (*KrkDebugCallback)(KrkCallFrame *frame); typedef int (*KrkDebugCallback)(struct KrkThreadState * _thread, KrkCallFrame *frame);
/** /**
* @brief Register a debugger callback. * @brief Register a debugger callback.
@ -91,7 +95,8 @@ typedef int (*KrkDebugCallback)(KrkCallFrame *frame);
* already registered, in which case the new hook * already registered, in which case the new hook
* has not been registered. * 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. * @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. * @param flags Allows configuring the disposition of the breakpoint.
* @return A breakpoint identifier handle on success, or -1 on failure. * @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. * @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. * @param flags Allows configuring the disposition of the breakpoint.
* @return A breakpoint identifier handle on success, or -1 on failure. * @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. * @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. * @param breakpointId The breakpoint to remove.
* @return 0 on success, 1 if the breakpoint identifier is invalid. * @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. * @brief Enable a breakpoint.
@ -149,7 +157,8 @@ extern int krk_debug_removeBreakpoint(int breakpointId);
* @param breakpointId The breakpoint to enable. * @param breakpointId The breakpoint to enable.
* @return 0 on success, 1 if the breakpoint identifier is invalid. * @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. * @brief Disable a breakpoint.
@ -162,17 +171,21 @@ extern int krk_debug_enableBreakpoint(int breakpointId);
* @param breakpointId The breakpoint to disable. * @param breakpointId The breakpoint to disable.
* @return 0 on success, 1 if the breakpoint identifier is invalid. * @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. * @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. * @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. * @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 * Wraps @ref krk_dumpTraceback() so it can be safely
* called from a debugger. * 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. * @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. * @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. * @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. * @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 * highlighting @p frame as the activate call point and indicating
* where its arguments start. * 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 * @def KRK_BREAKPOINT_NORMAL

View File

@ -27,7 +27,8 @@
* @param new New size of the object. * @param new New size of the object.
* @return New pointer for heap 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. * @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 * Generally called automatically by krk_freeVM(); releases all of
* the GC-tracked heap objects. * 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. * @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. * @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. * @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. * @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. * @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. * @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. * @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. * @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 * @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 ptr Pointer to take ownership of
* @param size Size of data at @p ptr * @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)

View File

@ -31,6 +31,8 @@ typedef enum {
KRK_OBJ_BYTES, KRK_OBJ_BYTES,
} KrkObjType; } KrkObjType;
struct KrkThreadState;
#undef KrkObj #undef KrkObj
/** /**
* @brief The most basic object type. * @brief The most basic object type.
@ -178,7 +180,7 @@ typedef struct {
KrkTable * globalsTable; /**< @brief Pointer to globals table with owner object */ KrkTable * globalsTable; /**< @brief Pointer to globals table with owner object */
} KrkClosure; } KrkClosure;
typedef void (*KrkCleanupCallback)(struct KrkInstance *); typedef void (*KrkCleanupCallback)(struct KrkThreadState *, struct KrkInstance *);
/** /**
* @brief Type object. * @brief Type object.
@ -269,7 +271,7 @@ typedef struct {
KrkObj * method; /**< @brief Function to call */ KrkObj * method; /**< @brief Function to call */
} KrkBoundMethod; } 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. * @brief Managed binding to a C function.
@ -387,7 +389,8 @@ struct KrkSlice {
* @param length Length of the C string. * @param length Length of the C string.
* @return A string object. * @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 * @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 type Compact type of the string, eg. UCS1, UCS2, UCS4... @see KrkStringType
* @param hash Precalculated string hash. * @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. * @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. * @param length Length of the C string.
* @return A string object. * @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. * @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. * @param string String to obtain the codepoint representation of.
* @return A pointer to the bytes of the codepoint representation. * @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. * @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. * @param index Offset of the codepoint to obtain.
* @return Integer representation of the codepoint at the requested index. * @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. * @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. * @param out Array to write UTF-8 sequence into.
* @return The length of the UTF-8 sequence, in bytes. * @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. * @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 * @param argCount Number of arguments in @p arguments
* @return A new generator object. * @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__ * @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. * @brief Special value for type hint expressions.
@ -504,7 +514,8 @@ extern NativeFn krk_GenericAlias;
* no assigned names or docstrings. This is intended only * no assigned names or docstrings. This is intended only
* to be used by a compiler directly. * 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. * @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 * which can then be used in the same place a function object
* (KrkClosure) would be used. * (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. * @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. * @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. * @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 * process of running compiled bytecode and creating function
* objects from code objects. * 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. * @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, * Generally, you will want to use @ref krk_makeClass instead,
* which handles binding the class to a module. * 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. * @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 * Be sure to populate any fields expected by the class or call
* its __init__ function (eg. with @ref krk_callStack) as needed. * 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. * @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, * and returns a @c method object. When a @c method object is called,
* @p receiver will automatically be provided as the first argument. * @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. * @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 * The actual length of the tuple must be updated after places
* values within it by setting @c value.count. * 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. * @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 * Allocates a bytes object of the given size, optionally copying
* data from @p source. * 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 krk_isObjType(v,t) (IS_OBJECT(v) && (AS_OBJECT(v)->type == (t)))
#define OBJECT_TYPE(value) (AS_OBJECT(value)->type) #define OBJECT_TYPE(value) (AS_OBJECT(value)->type)

View File

@ -41,7 +41,8 @@ typedef struct {
* *
* @param table Hash table to initialize. * @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. * @brief Release resources associated with a hash table.
@ -51,7 +52,8 @@ extern void krk_initTable(KrkTable * table);
* *
* @param table Hash table to release. * @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'. * @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 from Source table.
* @param to Destination 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. * @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. * @param hash Precalculated hash value for the string.
* @return If the string was found, the string object representation, else NULL. * @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. * @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. * @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. * @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. * @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. * @param value Output pointer to place resulting value in.
* @return 0 if the key was not found, 1 if it was. * @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. * @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. * @param value Output pointer to place resulting value in.
* @return 0 if the key was not found, 1 if it was. * @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. * @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. * @param key Key to delete.
* @return 1 if the value was found and deleted, 0 if it was not present. * @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. * @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. * @param key Key to delete.
* @return 1 if the value was found and deleted, 0 if it was not present. * @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. * @brief Internal table scan function.
@ -166,7 +175,8 @@ extern int krk_tableDeleteExact(KrkTable * table, KrkValue key);
* @param key Key to locate. * @param key Key to locate.
* @return A pointer to the entry for 'key'. * @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. * @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. * @param *hashOut An unsigned 32-bit hash value.
* @return Status code 0 for success, 1 for unhashable type. * @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. * @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 table Table to resize.
* @param capacity Target capacity. * @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. * @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. * @param value Value to assign to the key.
* @return 0 if the key was not present, 1 if it was found and updated. * @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)

View File

@ -63,7 +63,7 @@
ctype name __attribute__((unused)) = AS_ ## type (argv[i]) ctype name __attribute__((unused)) = AS_ ## type (argv[i])
#define FUNC_NAME(klass, name) _ ## klass ## _ ## name #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. */ /* These forms are deprecated. */
#define KRK_METHOD(klass, name, ...) FUNC_SIG(klass, name) { \ #define KRK_METHOD(klass, name, ...) FUNC_SIG(klass, name) { \
@ -86,27 +86,27 @@
#define KRK_Method_internal_name(klass, name) \ #define KRK_Method_internal_name(klass, name) \
_krk_method_ ## klass ## _ ## name _krk_method_ ## klass ## _ ## name
#define KRK_Method_internal_sig(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) \ #define KRK_Method(klass, name) \
KRK_Method_internal_sig(klass, name); \ KRK_Method_internal_sig(klass, name); \
FUNC_SIG(klass, name) { \ FUNC_SIG(klass, name) { \
static const char * _method_name = # name; \ static const char * _method_name = # name; \
CHECK_ARG(0,klass,CURRENT_CTYPE,CURRENT_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) KRK_Method_internal_sig(klass,name)
#define KRK_Function_internal_name(name) \ #define KRK_Function_internal_name(name) \
_krk_function_ ## name _krk_function_ ## name
#define KRK_Function_internal_sig(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) \ #define KRK_Function(name) \
KRK_Function_internal_sig(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; \ 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) KRK_Function_internal_sig(name)
@ -125,7 +125,7 @@ struct StringBuilder {
* @param sb String builder to append to. * @param sb String builder to append to.
* @param c Character to append. * @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) { if (sb->capacity < sb->length + 1) {
size_t old = sb->capacity; size_t old = sb->capacity;
sb->capacity = GROW_CAPACITY(old); sb->capacity = GROW_CAPACITY(old);
@ -133,6 +133,7 @@ static inline void pushStringBuilder(struct StringBuilder * sb, char c) {
} }
sb->bytes[sb->length++] = 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. * @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 str C string to add.
* @param len Length of the C string. * @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) { if (sb->capacity < sb->length + len) {
size_t prevcap = sb->capacity; size_t prevcap = sb->capacity;
while (sb->capacity < sb->length + len) { 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++); 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. * @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. * @param sb String builder to finalize.
* @return A value representing a string object. * @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)); KrkValue out = OBJECT_VAL(krk_copyString(sb->bytes, sb->length));
FREE_ARRAY(char,sb->bytes, sb->capacity); FREE_ARRAY(char,sb->bytes, sb->capacity);
return out; return out;
} }
#define finishStringBuilder(sb) finishStringBuilder_r(_thread,sb)
/** /**
* @brief Finalize a string builder in a bytes object. * @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. * @param sb String builder to finalize.
* @return A value representing a bytes object. * @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)); KrkValue out = OBJECT_VAL(krk_newBytes(sb->length, (uint8_t*)sb->bytes));
FREE_ARRAY(char,sb->bytes, sb->capacity); FREE_ARRAY(char,sb->bytes, sb->capacity);
return out; return out;
} }
#define finishStringBuilderBytes(sb) finishStringBuilderBytes_r(_thread,sb)
/** /**
* @brief Discard the contents of a string builder. * @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. * @param sb String builder to discard.
* @return None, as a convenience. * @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); FREE_ARRAY(char,sb->bytes, sb->capacity);
return NONE_VAL(); return NONE_VAL();
} }
#define discardStringBuilder(sb) discardStringBuilder_r(_thread,sb)
#define IS_int(o) (IS_INTEGER(o)) #define IS_int(o) (IS_INTEGER(o))
#define AS_int(o) (AS_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 IS_slice(o) krk_isInstanceOf(o,vm.baseClasses->sliceClass)
#define AS_slice(o) ((struct KrkSlice*)AS_INSTANCE(o)) #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 krk_dict_nth_key_fast(KrkThreadState *,size_t capacity, KrkTableEntry * entries, size_t index);
extern KrkValue FUNC_NAME(str,__getitem__)(int,const KrkValue*,int); extern KrkValue FUNC_NAME(str,__getitem__)(KrkThreadState *,int,const KrkValue*,int);
extern KrkValue FUNC_NAME(str,split)(int,const KrkValue*,int); extern KrkValue FUNC_NAME(str,split)(KrkThreadState *,int,const KrkValue*,int);
extern KrkValue FUNC_NAME(str,format)(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_get FUNC_NAME(str,__getitem__)
#define krk_string_split FUNC_NAME(str,split) #define krk_string_split FUNC_NAME(str,split)
#define krk_string_format FUNC_NAME(str,format) #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); 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)); 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; (void)size;
thing->doc = text; thing->doc = text;
} }
@ -285,17 +290,17 @@ static inline void _setDoc_native(KrkNative * thing, const char * text, size_t s
KrkClass*: _setDoc_class, \ KrkClass*: _setDoc_class, \
KrkInstance*: _setDoc_instance, \ KrkInstance*: _setDoc_instance, \
KrkNative*: _setDoc_native \ KrkNative*: _setDoc_native \
)(thing,text,sizeof(text)-1) )(_thread,thing,text,sizeof(text)-1)
#endif #endif
#define BUILTIN_FUNCTION(name, func, docStr) KRK_DOC(krk_defineNative(&vm.builtins->fields, name, func), docStr) #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) \ #define KRK_SLICER(arg,count) \
krk_integer_type start; \ krk_integer_type start; \
krk_integer_type end; \ krk_integer_type end; \
krk_integer_type step; \ 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. * @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 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. * 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) #define KRK_BASE_CLASS(cls) (vm.baseClasses->cls ## Class)

View File

@ -23,6 +23,8 @@ typedef enum {
KRK_VAL_NOTIMPL = 0x7FFE, KRK_VAL_NOTIMPL = 0x7FFE,
} KrkValueType; } KrkValueType;
struct KrkThreadState;
/* /*
* The following poorly-named macros define bit patterns for identifying * The following poorly-named macros define bit patterns for identifying
* various boxed types. * various boxed types.
@ -83,7 +85,8 @@ typedef struct {
* *
* @param array Value array to initialize. * @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. * @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 array Array to append to.
* @param value Value to append to array. * @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. * @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. * @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. * @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 f Stream to write to.
* @param value Value to display. * @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. * @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 f Stream to write to.
* @param value Value to display. * @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. * @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. * @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. * @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. * @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. * @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. * @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 { typedef union {
KrkValue val; KrkValue val;

View File

@ -171,6 +171,7 @@ typedef struct KrkThreadState {
KrkValue * stackMax; /**< End of allocated stack space. */ 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. */ 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; } KrkThreadState;
/** /**
@ -224,42 +225,13 @@ typedef struct KrkVM {
#define KRK_GLOBAL_THREADS (1 << 13) #define KRK_GLOBAL_THREADS (1 << 13)
#define KRK_GLOBAL_NO_DEFAULT_MODULES (1 << 14) #define KRK_GLOBAL_NO_DEFAULT_MODULES (1 << 14)
#ifndef KRK_DISABLE_THREADS
# define threadLocal __thread
#else
# define threadLocal
#endif
/** /**
* @brief Thread-local VM state. * @brief Thread-local VM state.
* *
* See @c KrkThreadState for more information. * See @c KrkThreadState for more information.
*/ */
#if !defined(KRK_DISABLE_THREADS) && ((defined(__APPLE__)) && defined(__aarch64__)) #define krk_currentThread (*_thread)
extern void krk_forceThreadData(void); #define vm (*_thread->owner)
#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
/** /**
* @brief Initialize the VM at program startup. * @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. * @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. * @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 * heap memory, FILE pointers or descriptors, or various other things which were
* initialized by C extension modules. * 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. * @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 * during normal execution by C extensions. Values on the stack may be lost
* to garbage collection after a call to @c krk_resetStack . * 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. * @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 * indicate @c KRK_THREAD_HAS_EXCEPTION and @c krk_currentThread.currentException
* should contain the raised exception value. * 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. * @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, * @return As with @c krk_interpret, an object representing the newly created module,
* or the final return value of the VM execution. * 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. * @brief Push a stack value.
@ -340,7 +312,8 @@ extern KrkValue krk_runfile(const char * fileName, char * fromFile);
* *
* @param value Value to push. * @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. * @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. * @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. * @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) * @param distance How far down from the top of the stack to peek (0 = the top)
* @return The value from the stack. * @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. * @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) * @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. * @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 * @param value Value to examine
* @return Nul-terminated C string of the type of @p value * @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. * @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 * @param function Native function pointer to attach
* @return A pointer to the object representing the attached function. * @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. * @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 * @param func Native function pointer to attach
* @return A pointer to the property object created. * @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. * @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 name Nil-terminated C string with the name to assign
* @param obj Value to attach. * @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. * @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 name Nil-terminated C string with the name to assign
* @param obj Object to attach. * @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. * @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. * @param fmt Format string.
* @return As a convenience to C extension authors, returns @c None * @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. * @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 base Exception object or class to raise.
* @param cause Exception cause object or class to attach. * @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. * @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. * @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. * @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. * @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. * @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 * returned by the inner function before the VM returned
* to the exit frame. * 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. * @brief Get the class representing a value.
@ -566,7 +552,9 @@ extern KrkValue krk_runNext(void);
* @param value Reference value to examine. * @param value Reference value to examine.
* @return A pointer to the value's type's class object. * @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. * @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. * @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 * @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. * @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. * @param name String object with the name of the method to resolve.
* @return 1 if the method has been bound, 0 if binding failed. * @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. * @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. * 2: The callable was a native function and result should be popped now.
* Else: The call failed. An exception may have already been set. * 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. * @brief Create a list object.
* @memberof KrkList * @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. * @brief Create a dict object.
* @memberof KrkDict * @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. * @brief Create a tuple object.
* @memberof KrkTuple * @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. * @brief Create a set object.
* @memberof Set * @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. * @brief Create a slice object.
* @memberof KrkSlice * @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. * @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. * @param argCount Arguments to collect from the stack.
* @return The return value of the function. * @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. * @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. * @param argCount Arguments to collect from the stack.
* @return The return value of the function. * @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. * @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. * @param base Pointer to class object to inherit from.
* @return A pointer to the class object, equivalent to the value assigned to @p _class. * @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. * @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. * @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 * @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 * open source files to print faulting lines and may call into the VM if the
* exception object has a managed implementation of @c \__str__. * 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. * @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__ * @param name Name of the module, which is assigned to @c \__name__
* @return The instance object representing the module. * @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. * @brief Obtain a list of properties for an object.
* *
* This is the native function bound to @c object.__dir__ * 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. * @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. * @param parent Parent module object, if loaded from a package.
* @return 1 if the module was loaded, 0 if an @ref ImportError occurred. * @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. * @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. * @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. * @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 * @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. * @param runAs Alternative name to attach to @c \__name__ for the module.
* @return 1 on success, 0 on failure. * @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. * @brief Determine the truth of a value.
@ -790,7 +796,8 @@ extern int krk_importModule(KrkString * name, KrkString * runAs);
* @param value Value to examine. * @param value Value to examine.
* @return 1 if falsey, 0 if truthy * @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. * @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 * exception set in the current thread if the attribute was
* not found. * 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 * @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. * @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 * exception set in the current thread if the object can
* not have a property set. * 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. * @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 owner The owner of the property to delete.
* @param name C-string of the property name 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. * @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 * This is a convenience function which calls @c str.__add__ on the top stack
* values. Generally, this should be avoided - use @c StringBuilder instead. * 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. * @brief Compare two values, returning @ref True if the left is less than the right.
* *
* This is equivalent to the opcode instruction OP_LESS. * 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. * @brief Compare to values, returning @ref True if the left is greater than the right.
* *
* This is equivalent to the opcode instruction OP_GREATER. * 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. * @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. * 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. * @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. * 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. * @brief Set the maximum recursion call depth.
* *
* Must not be called while execution is in progress. * 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. * @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 * held stack is reallocated, it will be freed when execution returns to the call
* to @c krk_callNativeOnStack that holds it. * 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__. * @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 * @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. * @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. * @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. * @param name Name of the attribute to look up.
* @return 1 if the attribute was found, 0 otherwise. * @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. * @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. * @param name Name of the attribute to set.
* @return 1 if the attribute could be set, 0 otherwise. * @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. * @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. * @param name Name of the attribute to delete.
* @return 1 if the attribute was found and can be deleted, 0 otherwise. * @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. * @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. * @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. * @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. * @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. * @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. * @brief Initialize the built-in 'dis' module.
* *
* Not available if KRK_DISABLE_DEBUG is set. * 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. * @brief Initialize the built-in 'threading' module.
* *
* Not available if KRK_DISABLE_THREADS is set. * Not available if KRK_DISABLE_THREADS is set.
*/ */
extern void krk_module_init_threading(void); extern void krk_module_init_threading(KrkThreadState *);

View File

@ -143,7 +143,7 @@ static int _debug_mem_has(const void *ptr) {
} }
#endif #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) #if defined(KRK_EXTENSIVE_MEMORY_DEBUGGING)
_debug_mem_set(ptr, size); _debug_mem_set(ptr, size);
#endif #endif
@ -151,7 +151,7 @@ void krk_gcTakeBytes(const void * ptr, size_t size) {
vm.bytesAllocated += 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 -= old;
vm.bytesAllocated += new; vm.bytesAllocated += new;
@ -198,7 +198,7 @@ void * krk_reallocate(void * ptr, size_t old, size_t new) {
return out; return out;
} }
static void freeObject(KrkObj * object) { static void freeObject(KrkThreadState * _thread, KrkObj * object) {
switch (object->type) { switch (object->type) {
case KRK_OBJ_STRING: { case KRK_OBJ_STRING: {
KrkString * string = (KrkString*)object; KrkString * string = (KrkString*)object;
@ -245,7 +245,7 @@ static void freeObject(KrkObj * object) {
case KRK_OBJ_INSTANCE: { case KRK_OBJ_INSTANCE: {
KrkInstance * inst = (KrkInstance*)object; KrkInstance * inst = (KrkInstance*)object;
if (inst->_class->_ongcsweep) { if (inst->_class->_ongcsweep) {
inst->_class->_ongcsweep(inst); inst->_class->_ongcsweep(_thread, inst);
} }
krk_freeTable(&inst->fields); krk_freeTable(&inst->fields);
krk_reallocate(object,inst->_class->allocSize,0); 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 * object = vm.objects;
KrkObj * other = NULL; KrkObj * other = NULL;
while (object) { while (object) {
KrkObj * next = object->next; KrkObj * next = object->next;
if (object->type == KRK_OBJ_INSTANCE) { if (object->type == KRK_OBJ_INSTANCE) {
freeObject(object); freeObject(_thread, object);
} else { } else {
object->next = other; object->next = other;
other = object; other = object;
@ -289,14 +289,14 @@ void krk_freeObjects() {
if (other->type == KRK_OBJ_CLASS) { if (other->type == KRK_OBJ_CLASS) {
((KrkClass*)other)->base = NULL; ((KrkClass*)other)->base = NULL;
} }
freeObject(other); freeObject(_thread, other);
other = next; other = next;
} }
free(vm.grayStack); free(vm.grayStack);
} }
void krk_freeMemoryDebugger(void) { void krk_freeMemoryDebugger_r(KrkThreadState * _thread) {
#if defined(KRK_EXTENSIVE_MEMORY_DEBUGGING) #if defined(KRK_EXTENSIVE_MEMORY_DEBUGGING)
for (unsigned int i = 0; i < DHE_SIZE; ++i) { for (unsigned int i = 0; i < DHE_SIZE; ++i) {
_dhe * x = _debug_mem[i]; _dhe * x = _debug_mem[i];
@ -313,7 +313,7 @@ void krk_freeMemoryDebugger(void) {
#endif #endif
} }
void krk_markObject(KrkObj * object) { void krk_markObject_r(KrkThreadState * _thread, KrkObj * object) {
if (!object) return; if (!object) return;
if (object->flags & KRK_OBJ_FLAGS_IS_MARKED) return; if (object->flags & KRK_OBJ_FLAGS_IS_MARKED) return;
object->flags |= KRK_OBJ_FLAGS_IS_MARKED; object->flags |= KRK_OBJ_FLAGS_IS_MARKED;
@ -326,18 +326,18 @@ void krk_markObject(KrkObj * object) {
vm.grayStack[vm.grayCount++] = object; vm.grayStack[vm.grayCount++] = object;
} }
void krk_markValue(KrkValue value) { void krk_markValue_r(KrkThreadState * _thread, KrkValue value) {
if (!IS_OBJECT(value)) return; if (!IS_OBJECT(value)) return;
krk_markObject(AS_OBJECT(value)); 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) { for (size_t i = 0; i < array->count; ++i) {
krk_markValue(array->values[i]); krk_markValue(array->values[i]);
} }
} }
static void blackenObject(KrkObj * object) { static void blackenObject(KrkThreadState * _thread, KrkObj * object) {
switch (object->type) { switch (object->type) {
case KRK_OBJ_CLOSURE: { case KRK_OBJ_CLOSURE: {
KrkClosure * closure = (KrkClosure *)object; KrkClosure * closure = (KrkClosure *)object;
@ -356,9 +356,9 @@ static void blackenObject(KrkObj * object) {
krk_markObject((KrkObj*)function->qualname); krk_markObject((KrkObj*)function->qualname);
krk_markObject((KrkObj*)function->docstring); krk_markObject((KrkObj*)function->docstring);
krk_markObject((KrkObj*)function->chunk.filename); krk_markObject((KrkObj*)function->chunk.filename);
markArray(&function->requiredArgNames); markArray(_thread, &function->requiredArgNames);
markArray(&function->keywordArgNames); markArray(_thread, &function->keywordArgNames);
markArray(&function->chunk.constants); markArray(_thread, &function->chunk.constants);
for (size_t i = 0; i < function->localNameCount; ++i) { for (size_t i = 0; i < function->localNameCount; ++i) {
krk_markObject((KrkObj*)function->localNames[i].name); krk_markObject((KrkObj*)function->localNames[i].name);
} }
@ -378,7 +378,7 @@ static void blackenObject(KrkObj * object) {
} }
case KRK_OBJ_INSTANCE: { case KRK_OBJ_INSTANCE: {
krk_markObject((KrkObj*)((KrkInstance*)object)->_class); 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); krk_markTable(&((KrkInstance*)object)->fields);
break; break;
} }
@ -390,7 +390,7 @@ static void blackenObject(KrkObj * object) {
} }
case KRK_OBJ_TUPLE: { case KRK_OBJ_TUPLE: {
KrkTuple * tuple = (KrkTuple *)object; KrkTuple * tuple = (KrkTuple *)object;
markArray(&tuple->values); markArray(_thread, &tuple->values);
break; break;
} }
case KRK_OBJ_NATIVE: 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) { while (vm.grayCount > 0) {
KrkObj * object = vm.grayStack[--vm.grayCount]; 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 * previous = NULL;
KrkObj * object = vm.objects; KrkObj * object = vm.objects;
size_t count = 0; size_t count = 0;
@ -424,7 +424,7 @@ static size_t sweep() {
} else { } else {
vm.objects = object; vm.objects = object;
} }
freeObject(unreached); freeObject(_thread, unreached);
count++; count++;
} else { } else {
object->flags |= KRK_OBJ_FLAGS_SECOND_CHANCE; object->flags |= KRK_OBJ_FLAGS_SECOND_CHANCE;
@ -435,7 +435,7 @@ static size_t sweep() {
return count; return count;
} }
void krk_markTable(KrkTable * table) { void krk_markTable_r(KrkThreadState * _thread, KrkTable * table) {
for (size_t i = 0; i < table->capacity; ++i) { for (size_t i = 0; i < table->capacity; ++i) {
KrkTableEntry * entry = &table->entries[i]; KrkTableEntry * entry = &table->entries[i];
krk_markValue(entry->key); 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) { for (size_t i = 0; i < table->capacity; ++i) {
KrkTableEntry * entry = &table->entries[i]; KrkTableEntry * entry = &table->entries[i];
if (IS_OBJECT(entry->key) && !((AS_OBJECT(entry->key))->flags & KRK_OBJ_FLAGS_IS_MARKED)) { 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) { for (KrkValue * slot = thread->stack; slot && slot < thread->stackTop; ++slot) {
krk_markValue(*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; KrkThreadState * thread = vm.threads;
while (thread) { while (thread) {
markThreadRoots(thread); markThreadRoots(_thread, thread);
thread = thread->next; thread = thread->next;
} }
@ -505,7 +505,7 @@ static int smartSize(char _out[100], size_t s) {
} }
#endif #endif
size_t krk_collectGarbage(void) { size_t krk_collectGarbage_r(KrkThreadState * _thread) {
#ifndef KRK_NO_GC_TRACING #ifndef KRK_NO_GC_TRACING
struct timespec outTime, inTime; struct timespec outTime, inTime;
@ -516,10 +516,10 @@ size_t krk_collectGarbage(void) {
size_t bytesBefore = vm.bytesAllocated; size_t bytesBefore = vm.bytesAllocated;
#endif #endif
markRoots(); markRoots(_thread);
traceReferences(); traceReferences(_thread);
tableRemoveWhite(&vm.strings); tableRemoveWhite(_thread, &vm.strings);
size_t out = sweep(); size_t out = sweep(_thread);
/** /**
* The GC scheduling is in need of some improvement. The strategy at the moment * The GC scheduling is in need of some improvement. The strategy at the moment
@ -581,7 +581,7 @@ KRK_Function(resume) {
return NONE_VAL(); return NONE_VAL();
} }
void krk_module_init_gc(void) { void krk_module_init_gc(KrkThreadState * _thread) {
/** /**
* gc = module() * gc = module()
* *

View File

@ -39,7 +39,7 @@
} }
#define MATH_DELEGATE(func) \ #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) \ ONE_ARGUMENT(func) \
if (IS_FLOATING(argv[0])) { \ if (IS_FLOATING(argv[0])) { \
return INTEGER_VAL(func(AS_FLOATING(argv[0]))); \ return INTEGER_VAL(func(AS_FLOATING(argv[0]))); \
@ -58,7 +58,7 @@ MATH_DELEGATE(floor)
MATH_DELEGATE(trunc) MATH_DELEGATE(trunc)
#define MATH_ONE_NAME(func,name) \ #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) \ ONE_ARGUMENT(name) \
FORCE_FLOAT(argv[0],arg_0) \ FORCE_FLOAT(argv[0],arg_0) \
if (IS_FLOATING(arg_0)) { \ if (IS_FLOATING(arg_0)) { \
@ -94,7 +94,7 @@ MATH_ONE(lgamma)
#endif #endif
#define MATH_TWO(func) \ #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) \ TWO_ARGUMENTS(func) \
FORCE_FLOAT(argv[0],arg_0) \ FORCE_FLOAT(argv[0],arg_0) \
FORCE_FLOAT(argv[1],arg_1) \ FORCE_FLOAT(argv[1],arg_1) \
@ -109,7 +109,7 @@ MATH_TWO(remainder)
MATH_TWO(pow) MATH_TWO(pow)
MATH_TWO(atan2) 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__); TWO_ARGUMENTS(__pow__);
if (unlikely(!IS_FLOATING(argv[0]))) return krk_runtimeError(vm.exceptions->typeError, "expected float"); if (unlikely(!IS_FLOATING(argv[0]))) return krk_runtimeError(vm.exceptions->typeError, "expected float");
if (likely(IS_FLOATING(argv[1]))) { 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) ONE_ARGUMENT(frexp)
FORCE_FLOAT(argv[0],arg_0) FORCE_FLOAT(argv[0],arg_0)
if (!IS_FLOATING(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) \ #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) \ ONE_ARGUMENT(func) \
if (!IS_FLOATING(argv[0])) REAL_NUMBER_NOT(func,argv[0]) \ if (!IS_FLOATING(argv[0])) REAL_NUMBER_NOT(func,argv[0]) \
return BOOLEAN_VAL(func(AS_FLOATING(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) #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); KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
krk_push(OBJECT_VAL(module)); krk_push(OBJECT_VAL(module));

View File

@ -58,7 +58,7 @@ KRK_Function(seed) {
return NONE_VAL(); return NONE_VAL();
} }
KrkValue krk_module_onload_random(void) { KrkValue krk_module_onload_random(KrkThreadState * _thread) {
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass); KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
krk_push(OBJECT_VAL(module)); krk_push(OBJECT_VAL(module));
@ -67,7 +67,7 @@ KrkValue krk_module_onload_random(void) {
BIND_FUNC(module, random); BIND_FUNC(module, random);
BIND_FUNC(module, seed); BIND_FUNC(module, seed);
FUNC_NAME(krk,seed)(0,NULL,0); FUNC_NAME(krk,seed)(_thread, 0,NULL,0);
return krk_pop(); return krk_pop();
} }

View File

@ -109,7 +109,7 @@ KRK_Method(socket,__repr__) {
return OBJECT_VAL(krk_copyString(tmp,len)); 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) { if (self->family == AF_INET) {
/* Should be 2-tuple */ /* Should be 2-tuple */
if (!IS_tuple(address)) { if (!IS_tuple(address)) {
@ -186,7 +186,7 @@ KRK_Method(socket,connect) {
socklen_t sock_size = 0; socklen_t sock_size = 0;
/* What do we take? I guess a tuple for AF_INET */ /* 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 (parseResult) {
if (!(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) if (!(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION))
return krk_runtimeError(SocketError, "Unspecified error."); return krk_runtimeError(SocketError, "Unspecified error.");
@ -209,7 +209,7 @@ KRK_Method(socket,bind) {
socklen_t sock_size = 0; socklen_t sock_size = 0;
/* What do we take? I guess a tuple for AF_INET */ /* 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 (parseResult) {
if (!(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) if (!(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION))
return krk_runtimeError(SocketError, "Unspecified error."); return krk_runtimeError(SocketError, "Unspecified error.");
@ -355,7 +355,7 @@ KRK_Method(socket,sendto) {
socklen_t sock_size = 0; socklen_t sock_size = 0;
/* What do we take? I guess a tuple for AF_INET */ /* 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 (parseResult) {
if (!(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) if (!(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION))
return krk_runtimeError(SocketError, "Unspecified error."); return krk_runtimeError(SocketError, "Unspecified error.");
@ -404,7 +404,7 @@ KRK_Function(htons) {
return INTEGER_VAL(htons(value)); 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); KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
krk_push(OBJECT_VAL(module)); krk_push(OBJECT_VAL(module));

View File

@ -34,7 +34,7 @@ KRK_Function(timeit) {
return FLOATING_VAL(after-before); 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); KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
krk_push(OBJECT_VAL(module)); krk_push(OBJECT_VAL(module));

View File

@ -17,7 +17,7 @@ KRK_Function(wcwidth) {
return INTEGER_VAL(wcwidth(codepoint)); 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); KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
krk_push(OBJECT_VAL(module)); krk_push(OBJECT_VAL(module));
KRK_DOC(module, "Character widths."); KRK_DOC(module, "Character widths.");

View File

@ -84,7 +84,7 @@ KRK_Method(type,__getitem__) {
} }
_noexport _noexport
void _createAndBind_type(void) { void _createAndBind_type(KrkThreadState * _thread) {
KrkClass * type = ADD_BASE_CLASS(vm.baseClasses->typeClass, "type", vm.baseClasses->objectClass); KrkClass * type = ADD_BASE_CLASS(vm.baseClasses->typeClass, "type", vm.baseClasses->objectClass);
type->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT; type->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;

View File

@ -193,7 +193,7 @@ struct _bytes_join_context {
int isFirst; 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; struct _bytes_join_context * _context = context;
for (size_t i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) {
@ -247,7 +247,7 @@ KRK_Method(bytes,__iter__) {
KrkInstance * output = krk_newInstance(vm.baseClasses->bytesiteratorClass); KrkInstance * output = krk_newInstance(vm.baseClasses->bytesiteratorClass);
krk_push(OBJECT_VAL(output)); 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(); krk_pop();
return OBJECT_VAL(output); return OBJECT_VAL(output);
@ -265,7 +265,7 @@ struct BytesIterator {
#define IS_bytesiterator(o) krk_isInstanceOf(o,vm.baseClasses->bytesiteratorClass) #define IS_bytesiterator(o) krk_isInstanceOf(o,vm.baseClasses->bytesiteratorClass)
#define AS_bytesiterator(o) (struct BytesIterator*)AS_OBJECT(o) #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); krk_markValue(((struct BytesIterator*)self)->l);
} }
@ -291,7 +291,7 @@ KRK_Method(bytesiterator,__call__) {
#undef CURRENT_CTYPE #undef CURRENT_CTYPE
#define CURRENT_CTYPE struct ByteArray * #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); krk_markValue(((struct ByteArray*)self)->actual);
} }
@ -408,7 +408,7 @@ KRK_Method(bytearray,__iter__) {
KrkInstance * output = krk_newInstance(vm.baseClasses->bytesiteratorClass); KrkInstance * output = krk_newInstance(vm.baseClasses->bytesiteratorClass);
krk_push(OBJECT_VAL(output)); 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(); krk_pop();
return OBJECT_VAL(output); return OBJECT_VAL(output);
@ -416,7 +416,7 @@ KRK_Method(bytearray,__iter__) {
_noexport _noexport
void _createAndBind_bytesClass(void) { void _createAndBind_bytesClass(KrkThreadState * _thread) {
KrkClass * bytes = ADD_BASE_CLASS(vm.baseClasses->bytesClass, "bytes", vm.baseClasses->objectClass); KrkClass * bytes = ADD_BASE_CLASS(vm.baseClasses->bytesClass, "bytes", vm.baseClasses->objectClass);
bytes->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT; bytes->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
KRK_DOC(BIND_METHOD(bytes,__init__), KRK_DOC(BIND_METHOD(bytes,__init__),

View File

@ -8,7 +8,7 @@
* Exposed method called to produce dictionaries from `{expr: expr, ...}` sequences in managed code. * Exposed method called to produce dictionaries from `{expr: expr, ...}` sequences in managed code.
* Expects arguments as `key,value,key,value`... * 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"); 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); KrkInstance * outDict = krk_newInstance(vm.baseClasses->dictClass);
krk_push(OBJECT_VAL(outDict)); krk_push(OBJECT_VAL(outDict));
@ -20,11 +20,11 @@ KrkValue krk_dict_of(int argc, const KrkValue argv[], int hasKw) {
return krk_pop(); return krk_pop();
} }
static void _dict_gcscan(KrkInstance * self) { static void _dict_gcscan(KrkThreadState * _thread, KrkInstance * self) {
krk_markTable(&((KrkDict*)self)->entries); krk_markTable(&((KrkDict*)self)->entries);
} }
static void _dict_gcsweep(KrkInstance * self) { static void _dict_gcsweep(KrkThreadState * _thread, KrkInstance * self) {
krk_freeTable(&((KrkDict*)self)->entries); krk_freeTable(&((KrkDict*)self)->entries);
} }
@ -37,7 +37,7 @@ struct _keyvalue_pair_context {
int counter; 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; struct _keyvalue_pair_context * _context = context;
if (count > 2) { if (count > 2) {
@ -62,7 +62,7 @@ static int _keyvalue_pair_callback(void * context, const KrkValue * entries, siz
return 0; 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 }; struct _keyvalue_pair_context context = { (KrkDict*)self, NONE_VAL(), 0 };
for (size_t i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) {
@ -267,7 +267,7 @@ KRK_Method(dict,keys) {
METHOD_TAKES_NONE(); METHOD_TAKES_NONE();
KrkInstance * output = krk_newInstance(vm.baseClasses->dictkeysClass); KrkInstance * output = krk_newInstance(vm.baseClasses->dictkeysClass);
krk_push(OBJECT_VAL(output)); 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(); krk_pop();
return OBJECT_VAL(output); return OBJECT_VAL(output);
} }
@ -278,7 +278,7 @@ KRK_Method(dict,items) {
METHOD_TAKES_NONE(); METHOD_TAKES_NONE();
KrkInstance * output = krk_newInstance(vm.baseClasses->dictitemsClass); KrkInstance * output = krk_newInstance(vm.baseClasses->dictitemsClass);
krk_push(OBJECT_VAL(output)); 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(); krk_pop();
return OBJECT_VAL(output); return OBJECT_VAL(output);
} }
@ -289,12 +289,12 @@ KRK_Method(dict,values) {
METHOD_TAKES_NONE(); METHOD_TAKES_NONE();
KrkInstance * output = krk_newInstance(vm.baseClasses->dictvaluesClass); KrkInstance * output = krk_newInstance(vm.baseClasses->dictvaluesClass);
krk_push(OBJECT_VAL(output)); 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(); krk_pop();
return OBJECT_VAL(output); 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; size_t found = 0;
for (size_t i = 0; i < capacity; ++i) { for (size_t i = 0; i < capacity; ++i) {
if (IS_KWARGS(entries[i].key)) continue; 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 #undef CURRENT_CTYPE
#define CURRENT_CTYPE struct DictItems * #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); krk_markValue(((struct DictItems*)self)->dict);
} }
@ -391,7 +391,7 @@ KRK_Method(dictitems,__repr__) {
#undef CURRENT_CTYPE #undef CURRENT_CTYPE
#define CURRENT_CTYPE struct DictKeys * #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); krk_markValue(((struct DictKeys*)self)->dict);
} }
@ -457,7 +457,7 @@ KRK_Method(dictkeys,__repr__) {
#undef CURRENT_CTYPE #undef CURRENT_CTYPE
#define CURRENT_CTYPE struct DictValues * #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); krk_markValue(((struct DictValues*)self)->dict);
} }
@ -521,7 +521,7 @@ KRK_Method(dictvalues,__repr__) {
} }
_noexport _noexport
void _createAndBind_dictClass(void) { void _createAndBind_dictClass(KrkThreadState * _thread) {
KrkClass * dict = ADD_BASE_CLASS(vm.baseClasses->dictClass, "dict", vm.baseClasses->objectClass); KrkClass * dict = ADD_BASE_CLASS(vm.baseClasses->dictClass, "dict", vm.baseClasses->objectClass);
dict->allocSize = sizeof(KrkDict); dict->allocSize = sizeof(KrkDict);
dict->_ongcscan = _dict_gcscan; dict->_ongcscan = _dict_gcscan;

View File

@ -6,14 +6,14 @@
#include <kuroko/debug.h> #include <kuroko/debug.h>
/* Check for and return the name of a native function as a string object */ /* 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; const char * string = ((KrkNative*)AS_OBJECT(func))->name;
if (!string) return OBJECT_VAL(S("<unnamed>")); if (!string) return OBJECT_VAL(S("<unnamed>"));
size_t len = strlen(string); size_t len = strlen(string);
return OBJECT_VAL(krk_copyString(string,len)); 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)); 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)); krk_push(OBJECT_VAL(tuple));
@ -109,7 +109,7 @@ KRK_Method(function,__name__) {
ATTRIBUTE_NOT_ASSIGNABLE(); ATTRIBUTE_NOT_ASSIGNABLE();
if (IS_NATIVE(self)) { if (IS_NATIVE(self)) {
return nativeFunctionName(self); return nativeFunctionName(_thread, self);
} else if (IS_CLOSURE(self) && AS_CLOSURE(self)->function->name) { } else if (IS_CLOSURE(self) && AS_CLOSURE(self)->function->name) {
return OBJECT_VAL(AS_CLOSURE(self)->function->name); return OBJECT_VAL(AS_CLOSURE(self)->function->name);
} }
@ -155,9 +155,9 @@ KRK_Method(function,__str__) {
pushStringBuilderStr(&sb, "<function ", 10); pushStringBuilderStr(&sb, "<function ", 10);
/* Do we have a qualified name? */ /* Do we have a qualified name? */
KrkValue name = FUNC_NAME(function,__qualname__)(1,&self,0); KrkValue name = FUNC_NAME(function,__qualname__)(_thread, 1,&self,0);
if (IS_NONE(name)) { if (IS_NONE(name)) {
name = FUNC_NAME(function,__name__)(1,&self,0); name = FUNC_NAME(function,__name__)(_thread, 1,&self,0);
} }
if (!IS_STRING(name)) name = OBJECT_VAL(S("<unnamed>")); if (!IS_STRING(name)) name = OBJECT_VAL(S("<unnamed>"));
@ -188,7 +188,7 @@ KRK_Method(function,__file__) {
KRK_Method(function,__args__) { KRK_Method(function,__args__) {
ATTRIBUTE_NOT_ASSIGNABLE(); ATTRIBUTE_NOT_ASSIGNABLE();
if (!IS_CLOSURE(self)) return OBJECT_VAL(krk_newTuple(0)); 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); return OBJECT_VAL(tuple);
} }
@ -218,7 +218,7 @@ KRK_Method(codeobject,__name__) {
KRK_Method(codeobject,__str__) { KRK_Method(codeobject,__str__) {
METHOD_TAKES_NONE(); 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(); if (!IS_STRING(s)) return NONE_VAL();
krk_push(s); krk_push(s);
@ -290,7 +290,7 @@ KRK_Method(codeobject,co_flags) {
KRK_Method(codeobject,__args__) { KRK_Method(codeobject,__args__) {
ATTRIBUTE_NOT_ASSIGNABLE(); ATTRIBUTE_NOT_ASSIGNABLE();
KrkTuple * tuple = functionArgs(self); KrkTuple * tuple = functionArgs(_thread, self);
return OBJECT_VAL(tuple); return OBJECT_VAL(tuple);
} }
@ -309,23 +309,23 @@ FUNC_SIG(method,__init__) {
KRK_Method(method,__name__) { KRK_Method(method,__name__) {
ATTRIBUTE_NOT_ASSIGNABLE(); 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__) { KRK_Method(method,__qualname__) {
ATTRIBUTE_NOT_ASSIGNABLE(); 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) { KRK_Method(method,_ip_to_line) {
METHOD_TAKES_EXACTLY(1); 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__) { KRK_Method(method,__str__) {
METHOD_TAKES_NONE(); METHOD_TAKES_NONE();
KrkValue s = FUNC_NAME(method,__qualname__)(1,argv,0); KrkValue s = FUNC_NAME(method,__qualname__)(_thread, 1,argv,0);
if (!IS_STRING(s)) s = FUNC_NAME(method,__name__)(1,argv,0); if (!IS_STRING(s)) s = FUNC_NAME(method,__name__)(_thread, 1,argv,0);
if (!IS_STRING(s)) return NONE_VAL(); if (!IS_STRING(s)) return NONE_VAL();
krk_push(s); krk_push(s);
@ -344,27 +344,27 @@ KRK_Method(method,__str__) {
KRK_Method(method,__file__) { KRK_Method(method,__file__) {
ATTRIBUTE_NOT_ASSIGNABLE(); 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__) { KRK_Method(method,__args__) {
ATTRIBUTE_NOT_ASSIGNABLE(); 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__) { KRK_Method(method,__doc__) {
ATTRIBUTE_NOT_ASSIGNABLE(); 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__) { KRK_Method(method,__annotations__) {
ATTRIBUTE_NOT_ASSIGNABLE(); 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__) { KRK_Method(method,__code__) {
ATTRIBUTE_NOT_ASSIGNABLE(); 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__) { KRK_Method(method,__func__) {
@ -394,7 +394,7 @@ KRK_Function(classmethod) {
} }
_noexport _noexport
void _createAndBind_functionClass(void) { void _createAndBind_functionClass(KrkThreadState * _thread) {
KrkClass * codeobject = ADD_BASE_CLASS(vm.baseClasses->codeobjectClass, "codeobject", vm.baseClasses->objectClass); KrkClass * codeobject = ADD_BASE_CLASS(vm.baseClasses->codeobjectClass, "codeobject", vm.baseClasses->objectClass);
codeobject->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT; codeobject->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
BIND_METHOD(codeobject,__init__); BIND_METHOD(codeobject,__init__);

View File

@ -37,7 +37,7 @@ struct generator {
#define CURRENT_CTYPE struct generator * #define CURRENT_CTYPE struct generator *
#define CURRENT_NAME self #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) { while (self->capturedUpvalues) {
KrkUpvalue * upvalue = self->capturedUpvalues; KrkUpvalue * upvalue = self->capturedUpvalues;
upvalue->closed = self->args[upvalue->location]; 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; struct generator * self = (struct generator*)_self;
krk_markObject((KrkObj*)self->closure); krk_markObject((KrkObj*)self->closure);
for (size_t i = 0; i < self->argCount; ++i) { for (size_t i = 0; i < self->argCount; ++i) {
@ -58,14 +58,14 @@ static void _generator_gcscan(KrkInstance * _self) {
krk_markValue(self->result); krk_markValue(self->result);
} }
static void _generator_gcsweep(KrkInstance * self) { static void _generator_gcsweep(KrkThreadState * _thread, KrkInstance * self) {
_generator_close_upvalues((struct generator*)self); _generator_close_upvalues(_thread, (struct generator*)self);
free(((struct generator*)self)->args); 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; 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 * @param argCount Number of arguments in @p argsIn
* @return A @ref generator object. * @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 */ /* Copy the args */
KrkValue * args = malloc(sizeof(KrkValue) * (argCount)); KrkValue * args = malloc(sizeof(KrkValue) * (argCount));
memcpy(args, argsIn, 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) { if (IS_KWARGS(result) && AS_INTEGER(result) == 0) {
self->result = krk_pop(); self->result = krk_pop();
_set_generator_done(self); _set_generator_done(_thread, self);
return OBJECT_VAL(self); return OBJECT_VAL(self);
} }
/* Was there an exception? */ /* Was there an exception? */
if (krk_currentThread.flags & KRK_THREAD_HAS_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; krk_currentThread.stackTop = krk_currentThread.stack + frame->slots;
return NONE_VAL(); return NONE_VAL();
} }
@ -222,7 +222,7 @@ KRK_Method(generator,send) {
if (!self->started && !IS_NONE(argv[1])) { if (!self->started && !IS_NONE(argv[1])) {
return krk_runtimeError(vm.exceptions->typeError, "Can not send non-None value to just-started generator"); 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__) { KRK_Method(generator,__finish__) {
@ -238,7 +238,7 @@ KRK_Method(generator,gi_running) {
return BOOLEAN_VAL(self->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) { if (IS_generator(krk_peek(0)) && AS_generator(krk_peek(0))->type == KRK_OBJ_FLAGS_CODEOBJECT_IS_COROUTINE) {
/* Good to go */ /* Good to go */
return 1; return 1;
@ -265,7 +265,7 @@ int krk_getAwaitable(void) {
} }
_noexport _noexport
void _createAndBind_generatorClass(void) { void _createAndBind_generatorClass(KrkThreadState * _thread) {
KrkClass * generator = ADD_BASE_CLASS(vm.baseClasses->generatorClass, "generator", vm.baseClasses->objectClass); KrkClass * generator = ADD_BASE_CLASS(vm.baseClasses->generatorClass, "generator", vm.baseClasses->objectClass);
generator->allocSize = sizeof(struct generator); generator->allocSize = sizeof(struct generator);
generator->_ongcscan = _generator_gcscan; generator->_ongcscan = _generator_gcscan;

View File

@ -14,20 +14,20 @@
if (val < 0) val = 0; \ if (val < 0) val = 0; \
if (val > (krk_integer_type)self->values.count) val = self->values.count 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) { for (size_t i = 0; i < ((KrkList*)self)->values.count; ++i) {
krk_markValue(((KrkList*)self)->values.values[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); krk_freeValueArray(&((KrkList*)self)->values);
} }
/** /**
* Convenience constructor for the C API. * 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)); KrkValue outList = OBJECT_VAL(krk_newInstance(vm.baseClasses->listClass));
krk_push(outList); krk_push(outList);
krk_initValueArray(AS_LIST(outList)); krk_initValueArray(AS_LIST(outList));
@ -80,7 +80,7 @@ KRK_Method(list,__getitem__) {
} }
/* make into a list */ /* 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; krk_currentThread.stackTop[-len-1] = result;
while (len) { while (len) {
krk_pop(); krk_pop();
@ -158,7 +158,7 @@ KRK_Method(list,__repr__) {
return finishStringBuilder(&sb); 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; KrkValueArray * positionals = context;
if (positionals->count + count > positionals->capacity) { if (positionals->count + count > positionals->capacity) {
size_t old = positionals->capacity; size_t old = positionals->capacity;
@ -193,7 +193,7 @@ KRK_Method(list,__init__) {
krk_initValueArray(AS_LIST(argv[0])); krk_initValueArray(AS_LIST(argv[0]));
pthread_rwlock_init(&self->rwlock, NULL); pthread_rwlock_init(&self->rwlock, NULL);
if (argc == 2) { 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]; return argv[0];
} }
@ -207,7 +207,7 @@ KRK_Method(list,__mul__) {
krk_push(out); krk_push(out);
for (krk_integer_type i = 0; i < howMany; i++) { 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(); return krk_pop();
@ -287,12 +287,12 @@ KRK_Method(list,__setitem__) {
} }
while (len < newLen) { 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++; len++;
} }
while (newLen < 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--; len--;
} }
@ -306,7 +306,7 @@ KRK_Method(list,__delitem__) {
METHOD_TAKES_EXACTLY(1); METHOD_TAKES_EXACTLY(1);
if (IS_INTEGER(argv[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])) { } else if (IS_slice(argv[1])) {
KRK_SLICER(argv[1],self->values.count) { KRK_SLICER(argv[1],self->values.count) {
return NONE_VAL(); return NONE_VAL();
@ -319,7 +319,7 @@ KRK_Method(list,__delitem__) {
krk_integer_type len = end - start; krk_integer_type len = end - start;
while (len > 0) { 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--; len--;
} }
} else { } else {
@ -335,7 +335,7 @@ KRK_Method(list,remove) {
for (size_t i = 0; i < self->values.count; ++i) { for (size_t i = 0; i < self->values.count; ++i) {
if (krk_valuesSameOrEqual(self->values.values[i], argv[1])) { if (krk_valuesSameOrEqual(self->values.values[i], argv[1])) {
pthread_rwlock_unlock(&self->rwlock); 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)) { if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) {
pthread_rwlock_unlock(&self->rwlock); pthread_rwlock_unlock(&self->rwlock);
@ -428,9 +428,15 @@ KRK_Method(list,reverse) {
return NONE_VAL(); 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 a = *(KrkValue*)_a;
KrkValue b = *(KrkValue*)_b; KrkValue b = *(KrkValue*)_b;
KrkThreadState * _thread = t;
/* Avoid actually calling the sort function if there's an active exception */ /* Avoid actually calling the sort function if there's an active exception */
if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return -1; if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return -1;
@ -445,7 +451,7 @@ KRK_Method(list,sort) {
METHOD_TAKES_NONE(); METHOD_TAKES_NONE();
pthread_rwlock_wrlock(&self->rwlock); 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); pthread_rwlock_unlock(&self->rwlock);
return NONE_VAL(); return NONE_VAL();
@ -458,7 +464,7 @@ KRK_Method(list,__add__) {
pthread_rwlock_rdlock(&self->rwlock); pthread_rwlock_rdlock(&self->rwlock);
KrkValue outList = krk_list_of(self->values.count, self->values.values, 0); /* copy */ KrkValue outList = krk_list_of(self->values.count, self->values.values, 0); /* copy */
pthread_rwlock_unlock(&self->rwlock); 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; return outList;
} }
@ -469,7 +475,7 @@ KRK_Method(list,__iter__) {
KrkInstance * output = krk_newInstance(vm.baseClasses->listiteratorClass); KrkInstance * output = krk_newInstance(vm.baseClasses->listiteratorClass);
krk_push(OBJECT_VAL(output)); 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(); krk_pop();
return OBJECT_VAL(output); 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 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) #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); krk_markValue(((struct ListIterator*)self)->l);
} }
@ -544,32 +550,32 @@ _bad:
goto _maybeGood; 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); 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); KrkValue listOut = krk_list_of(0,NULL,0);
krk_push(listOut); 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(); 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(); if (!IS_NONE(krk_currentThread.currentException)) return NONE_VAL();
return krk_pop(); 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; /* 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! */ * 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); 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); KrkValue listOut = krk_list_of(0,NULL,0);
krk_push(listOut); 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(); 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(); if (!IS_NONE(krk_currentThread.currentException)) return NONE_VAL();
return krk_pop(); return krk_pop();
} }
_noexport _noexport
void _createAndBind_listClass(void) { void _createAndBind_listClass(KrkThreadState * _thread) {
KrkClass * list = ADD_BASE_CLASS(vm.baseClasses->listClass, "list", vm.baseClasses->objectClass); KrkClass * list = ADD_BASE_CLASS(vm.baseClasses->listClass, "list", vm.baseClasses->objectClass);
list->allocSize = sizeof(KrkList); list->allocSize = sizeof(KrkList);
list->_ongcscan = _list_gcscan; list->_ongcscan = _list_gcscan;

View File

@ -1175,7 +1175,7 @@ static void make_long(krk_integer_type t, struct BigInt * self) {
krk_long_init_si(self->value, t); 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); krk_long_clear(((struct BigInt*)self)->value);
} }
@ -1224,7 +1224,7 @@ KRK_Method(long,__float__) {
return FLOATING_VAL(krk_long_get_double(self->value)); 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"); if (bottom->width == 0) return krk_runtimeError(vm.exceptions->valueError, "float division by zero");
KrkLong quot, rem; 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)); 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"); if (unlikely(bottom == 0.0)) return krk_runtimeError(vm.exceptions->valueError, "float division by zero");
return FLOATING_VAL(top/bottom); return FLOATING_VAL(top/bottom);
} }
@ -1250,18 +1250,18 @@ KRK_Method(long,__truediv__) {
krk_long tmp; krk_long tmp;
if (IS_long(argv[1])) krk_long_init_copy(tmp, AS_long(argv[1])->value); 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_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(); else return NOTIMPL_VAL();
return _krk_long_truediv(self->value,tmp); return _krk_long_truediv(_thread, self->value,tmp);
} }
KRK_Method(long,__rtruediv__) { KRK_Method(long,__rtruediv__) {
krk_long tmp; krk_long tmp;
if (IS_long(argv[1])) krk_long_init_copy(tmp, AS_long(argv[1])->value); 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_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(); else return NOTIMPL_VAL();
return _krk_long_truediv(tmp,self->value); return _krk_long_truediv(_thread, tmp,self->value);
} }
#define PRINTER(name,base,prefix) \ #define PRINTER(name,base,prefix) \
@ -1280,7 +1280,7 @@ KRK_Method(long,__hash__) {
return INTEGER_VAL((uint32_t)(krk_long_medium(self->value))); 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; krk_integer_type maybe = 0;
if (val->width == 0) { if (val->width == 0) {
maybe = 0; maybe = 0;
@ -1301,8 +1301,9 @@ static KrkValue make_long_obj(KrkLong * val) {
krk_long_clear(val); krk_long_clear(val);
return INTEGER_VAL(maybe); 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; KrkLong _value;
if (krk_long_parse_string(start, &_value, base, width)) { if (krk_long_parse_string(start, &_value, base, width)) {
return NONE_VAL(); return NONE_VAL();
@ -1335,7 +1336,7 @@ KRK_Method(long,__int__) {
return make_long_obj(tmp); \ return make_long_obj(tmp); \
} \ } \
_noexport \ _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 tmp_res, tmp_a, tmp_b; \
krk_long_init_si(tmp_res, 0); \ krk_long_init_si(tmp_res, 0); \
krk_long_init_si(tmp_a, a); \ 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(xor,krk_long_xor)
BASIC_BIN_OP(and,krk_long_and) 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; } if (krk_long_sign(shift) < 0) { krk_runtimeError(vm.exceptions->valueError, "negative shift count"); return; }
krk_long multiplier; krk_long multiplier;
krk_long_init_si(multiplier,0); 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); 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; } if (krk_long_sign(shift) < 0) { krk_runtimeError(vm.exceptions->valueError, "negative shift count"); return; }
krk_long multiplier, garbage; krk_long multiplier, garbage;
krk_long_init_many(multiplier,garbage,NULL); 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); 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; } if (krk_long_sign(b) == 0) { krk_runtimeError(vm.exceptions->valueError, "integer division or modulo by zero"); return; }
krk_long garbage; krk_long garbage;
krk_long_init_si(garbage,0); 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); 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; } if (krk_long_sign(b) == 0) { krk_runtimeError(vm.exceptions->valueError, "integer division or modulo by zero"); return; }
krk_long garbage; krk_long garbage;
krk_long_init_si(garbage,0); 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); 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) { if (krk_long_sign(b) == 0) {
krk_long_clear(out); krk_long_clear(out);
krk_long_init_si(out, 1); 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); FINISH_OUTPUT(out);
} }
BASIC_BIN_OP(lshift,_krk_long_lshift)
BASIC_BIN_OP(rshift,_krk_long_rshift) #define UNBASIC_BIN_OP(name, long_func) \
BASIC_BIN_OP(mod,_krk_long_mod) KRK_Method(long,__ ## name ## __) { \
BASIC_BIN_OP(floordiv,_krk_long_div) krk_long tmp; \
BASIC_BIN_OP(pow,_krk_long_pow) 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) \ #define COMPARE_OP(name, comp) \
KRK_Method(long,__ ## name ## __) { \ KRK_Method(long,__ ## name ## __) { \
@ -1509,9 +1539,9 @@ KRK_Method(long,__pos__) {
return argv[0]; 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); uint32_t result = _div_inplace((KrkLong*)a, base);
*more = krk_long_sign(a); *more = krk_long_sign(a);
return result; return result;
@ -1525,7 +1555,7 @@ KRK_Method(long,__format__) {
krk_long_init_copy(&tmp, self->value); krk_long_init_copy(&tmp, self->value);
krk_long_set_sign(&tmp, 1); 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, krk_long_sign(self->value) >= 0,
&tmp, &tmp,
formatLongCallback); formatLongCallback);
@ -1534,7 +1564,7 @@ KRK_Method(long,__format__) {
return result; return result;
} }
static KrkValue long_bit_count(KrkLong * val) { static KrkValue long_bit_count(KrkThreadState * _thread, KrkLong * val) {
size_t count = 0; size_t count = 0;
size_t bits = _bits_in(val); size_t bits = _bits_in(val);
@ -1548,10 +1578,10 @@ static KrkValue long_bit_count(KrkLong * val) {
} }
KRK_Method(long,bit_count) { 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); size_t bits = _bits_in(val);
KrkLong tmp; KrkLong tmp;
krk_long_init_ui(&tmp, bits); krk_long_init_ui(&tmp, bits);
@ -1559,10 +1589,10 @@ static KrkValue long_bit_length(KrkLong * val) {
} }
KRK_Method(long,bit_length) { 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"; static const char _method_name[] = "to_bytes";
/** /**
* @fn to_bytes(length: int, byteorder: str, *, signed: bool = False) -> 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) { KRK_Method(long,to_bytes) {
METHOD_TAKES_AT_LEAST(2); 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_Method(int,bit_count) {
krk_long value; krk_long value;
krk_long_init_si(value, self); krk_long_init_si(value, self);
KrkValue out = long_bit_count(value); KrkValue out = long_bit_count(_thread,value);
krk_long_clear(value); krk_long_clear(value);
return out; return out;
} }
@ -1755,7 +1785,7 @@ KRK_Method(int,bit_count) {
KRK_Method(int,bit_length) { KRK_Method(int,bit_length) {
krk_long value; krk_long value;
krk_long_init_si(value, self); krk_long_init_si(value, self);
KrkValue out = long_bit_length(value); KrkValue out = long_bit_length(_thread, value);
krk_long_clear(value); krk_long_clear(value);
return out; return out;
} }
@ -1763,7 +1793,7 @@ KRK_Method(int,bit_length) {
KRK_Method(int,to_bytes) { KRK_Method(int,to_bytes) {
krk_long value; krk_long value;
krk_long_init_si(value, self); 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); krk_long_clear(value);
return out; return out;
} }
@ -1776,7 +1806,7 @@ KRK_Method(int,to_bytes) {
BIND_METHOD(klass,__r ## name ## __); \ BIND_METHOD(klass,__r ## name ## __); \
krk_defineNative(&_ ## klass->methods,"__i" #name "__",_ ## klass ## ___ ## name ## __); krk_defineNative(&_ ## klass->methods,"__i" #name "__",_ ## klass ## ___ ## name ## __);
_noexport _noexport
void _createAndBind_longClass(void) { void _createAndBind_longClass(KrkThreadState * _thread) {
KrkClass * _long = ADD_BASE_CLASS(vm.baseClasses->longClass, "long", vm.baseClasses->intClass); KrkClass * _long = ADD_BASE_CLASS(vm.baseClasses->longClass, "long", vm.baseClasses->intClass);
_long->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT; _long->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
_long->allocSize = sizeof(struct BigInt); _long->allocSize = sizeof(struct BigInt);

View File

@ -71,7 +71,7 @@ static inline int matches(char c, const char * options) {
return 0; 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->fill = " ";
result->fillSize = 1; result->fillSize = 1;
@ -147,10 +147,10 @@ const char * krk_parseCommonFormatSpec(struct ParsedFormatSpec *result, const ch
return spec; 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}; 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(); if (!spec) return NONE_VAL();
const char * altPrefix = NULL; const char * altPrefix = NULL;
@ -211,7 +211,7 @@ KrkValue krk_doFormatString(const char * typeName, KrkString * format_spec, int
int more = 0; int more = 0;
do { do {
int digit = callback(abs, base, &more); int digit = callback(_thread, abs, base, &more);
if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) { if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) {
discardStringBuilder(&sb); discardStringBuilder(&sb);
@ -283,7 +283,7 @@ KrkValue krk_doFormatString(const char * typeName, KrkString * format_spec, int
return finishStringBuilder(&sb); 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; krk_integer_type v = *(krk_integer_type*)a;
int digit = v % base; int digit = v % base;
v /= base; v /= base;
@ -299,7 +299,7 @@ KRK_Method(int,__format__) {
krk_integer_type abs = self < 0 ? -self : self; 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, self >= 0,
&abs, &abs,
formatIntCallback); formatIntCallback);
@ -316,15 +316,15 @@ KRK_Method(int,__format__) {
* and then reduce if that still yields something that would fit in our 'int48'. * and then reduce if that still yields something that would fit in our 'int48'.
*/ */
#define OVERFLOW_CHECKED_INT_OPERATION(name,operator) \ #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 \ _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)) { \ if (likely((int32_t)a == a && (int32_t)b == b)) { \
int32_t result_one = a operator b; \ int32_t result_one = a operator b; \
int64_t result_two = a operator b; \ int64_t result_two = a operator b; \
if (likely(result_one == result_two)) return INTEGER_VAL(result_two); \ 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,+) OVERFLOW_CHECKED_INT_OPERATION(add,+)
@ -333,12 +333,12 @@ OVERFLOW_CHECKED_INT_OPERATION(mul,*)
#define BASIC_BIN_OP(name,operator) \ #define BASIC_BIN_OP(name,operator) \
KRK_Method(int,__ ## name ## __) { \ 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])); \ else if (likely(IS_FLOATING(argv[1]))) return FLOATING_VAL((double)self operator AS_FLOATING(argv[1])); \
return NOTIMPL_VAL(); \ return NOTIMPL_VAL(); \
} \ } \
KRK_Method(int,__r ## name ## __) { \ 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); \ else if (likely(IS_FLOATING(argv[1]))) return FLOATING_VAL(AS_FLOATING(argv[1]) operator (double)self); \
return NOTIMPL_VAL(); \ return NOTIMPL_VAL(); \
} }
@ -368,13 +368,13 @@ INT_ONLY_BIN_OP(xor,^)
INT_ONLY_BIN_OP(and,&) INT_ONLY_BIN_OP(and,&)
#define DEFER_TO_LONG(name) \ #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 ## __) { \ 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(); \ return NOTIMPL_VAL(); \
} \ } \
KRK_Method(int,__r ## name ## __) { \ 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(); \ return NOTIMPL_VAL(); \
} }
@ -423,7 +423,7 @@ KRK_Method(int,__rtruediv__) {
* that Python produces, for compatibility, and also because that's * that Python produces, for compatibility, and also because that's
* what our 'long' type does... * 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 (unlikely(b == 0)) return krk_runtimeError(vm.exceptions->zeroDivisionError, "integer division or modulo by zero");
if (a == 0) return INTEGER_VAL(0); if (a == 0) return INTEGER_VAL(0);
int64_t abs_a = a < 0 ? -a : a; 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)); 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 (unlikely(b == 0)) return krk_runtimeError(vm.exceptions->zeroDivisionError, "integer division or modulo by zero");
if (a == 0) return INTEGER_VAL(0); if (a == 0) return INTEGER_VAL(0);
int64_t abs_a = a < 0 ? -a : a; 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__) { KRK_Method(int,__mod__) {
METHOD_TAKES_EXACTLY(1); 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(); return NOTIMPL_VAL();
} }
KRK_Method(int,__rmod__) { KRK_Method(int,__rmod__) {
METHOD_TAKES_EXACTLY(1); 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(); return NOTIMPL_VAL();
} }
@ -469,7 +469,7 @@ KRK_Method(int,__rmod__) {
KRK_Method(int,__floordiv__) { KRK_Method(int,__floordiv__) {
METHOD_TAKES_EXACTLY(1); METHOD_TAKES_EXACTLY(1);
if (likely(IS_INTEGER(argv[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]))) { } else if (likely(IS_FLOATING(argv[1]))) {
double b = AS_FLOATING(argv[1]); double b = AS_FLOATING(argv[1]);
if (unlikely(b == 0.0)) return krk_runtimeError(vm.exceptions->zeroDivisionError, "float division by zero"); 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__) { KRK_Method(int,__rfloordiv__) {
METHOD_TAKES_EXACTLY(1); METHOD_TAKES_EXACTLY(1);
if (unlikely(self == 0)) return krk_runtimeError(vm.exceptions->zeroDivisionError, "integer division by zero"); 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)); else if (likely(IS_FLOATING(argv[1]))) return FLOATING_VAL(__builtin_floor(AS_FLOATING(argv[1]) / (double)self));
return NOTIMPL_VAL(); return NOTIMPL_VAL();
} }
@ -757,7 +757,7 @@ KRK_Method(NotImplementedType,__eq__) {
BIND_METHOD(klass,__r ## name ## __); \ BIND_METHOD(klass,__r ## name ## __); \
krk_defineNative(&_ ## klass->methods,"__i" #name "__",_ ## klass ## ___ ## name ## __); krk_defineNative(&_ ## klass->methods,"__i" #name "__",_ ## klass ## ___ ## name ## __);
_noexport _noexport
void _createAndBind_numericClasses(void) { void _createAndBind_numericClasses(KrkThreadState *_thread) {
KrkClass * _int = ADD_BASE_CLASS(vm.baseClasses->intClass, "int", vm.baseClasses->objectClass); KrkClass * _int = ADD_BASE_CLASS(vm.baseClasses->intClass, "int", vm.baseClasses->objectClass);
_int->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT; _int->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
BIND_METHOD(int,__init__); BIND_METHOD(int,__init__);

View File

@ -80,7 +80,7 @@ KRK_Method(range,__iter__) {
krk_integer_type step = self->step; krk_integer_type step = self->step;
krk_push(OBJECT_VAL(output)); 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(); krk_pop();
return OBJECT_VAL(output); return OBJECT_VAL(output);
@ -112,7 +112,7 @@ KRK_Method(rangeiterator,__call__) {
} }
_noexport _noexport
void _createAndBind_rangeClass(void) { void _createAndBind_rangeClass(KrkThreadState * _thread) {
KrkClass * range = ADD_BASE_CLASS(vm.baseClasses->rangeClass, "range", vm.baseClasses->objectClass); KrkClass * range = ADD_BASE_CLASS(vm.baseClasses->rangeClass, "range", vm.baseClasses->objectClass);
range->allocSize = sizeof(struct Range); range->allocSize = sizeof(struct Range);
range->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT; range->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;

View File

@ -16,11 +16,11 @@ struct Set {
#define IS_set(o) krk_isInstanceOf(o,KRK_BASE_CLASS(set)) #define IS_set(o) krk_isInstanceOf(o,KRK_BASE_CLASS(set))
#define AS_set(o) ((struct Set*)AS_OBJECT(o)) #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); 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); krk_freeTable(&((struct Set*)self)->entries);
} }
@ -36,14 +36,14 @@ struct SetIterator {
#define IS_setiterator(o) krk_isInstanceOf(o,KRK_BASE_CLASS(setiterator)) #define IS_setiterator(o) krk_isInstanceOf(o,KRK_BASE_CLASS(setiterator))
#define AS_setiterator(o) ((struct SetIterator*)AS_OBJECT(o)) #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); krk_markValue(((struct SetIterator*)self)->set);
} }
#define CURRENT_CTYPE struct Set * #define CURRENT_CTYPE struct Set *
#define CURRENT_NAME self #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; struct Set * self = context;
for (size_t i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) {
krk_tableSet(&self->entries, values[i], BOOLEAN_VAL(1)); 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))); KrkValue outSet = OBJECT_VAL(krk_newInstance(KRK_BASE_CLASS(set)));
krk_push(outSet); krk_push(outSet);
FUNC_NAME(set,__init__)(1,&outSet,0); FUNC_NAME(set,__init__)(_thread, 1,&outSet,0);
KrkClass * type = krk_getType(argv[1]); KrkClass * type = krk_getType(argv[1]);
if (!type->_contains) if (!type->_contains)
@ -132,7 +132,7 @@ KRK_Method(set,__xor__) {
KrkValue outSet = OBJECT_VAL(krk_newInstance(KRK_BASE_CLASS(set))); KrkValue outSet = OBJECT_VAL(krk_newInstance(KRK_BASE_CLASS(set)));
krk_push(outSet); krk_push(outSet);
FUNC_NAME(set,__init__)(1,&outSet,0); FUNC_NAME(set,__init__)(_thread, 1,&outSet,0);
KrkClass * type = krk_getType(argv[1]); KrkClass * type = krk_getType(argv[1]);
if (!type->_contains) if (!type->_contains)
@ -177,7 +177,7 @@ KRK_Method(set,__or__) {
KrkValue outSet = OBJECT_VAL(krk_newInstance(KRK_BASE_CLASS(set))); KrkValue outSet = OBJECT_VAL(krk_newInstance(KRK_BASE_CLASS(set)));
krk_push(outSet); 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(&self->entries, &AS_set(outSet)->entries);
krk_tableAddAll(&them->entries, &AS_set(outSet)->entries); krk_tableAddAll(&them->entries, &AS_set(outSet)->entries);
@ -300,7 +300,7 @@ KRK_Method(set,__iter__) {
METHOD_TAKES_NONE(); METHOD_TAKES_NONE();
KrkInstance * output = krk_newInstance(KRK_BASE_CLASS(setiterator)); KrkInstance * output = krk_newInstance(KRK_BASE_CLASS(setiterator));
krk_push(OBJECT_VAL(output)); 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(); return krk_pop();
} }
@ -331,7 +331,7 @@ KRK_Method(setiterator,__call__) {
} while (1); } 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))); KrkValue outSet = OBJECT_VAL(krk_newInstance(KRK_BASE_CLASS(set)));
krk_push(outSet); krk_push(outSet);
krk_initTable(&AS_set(outSet)->entries); krk_initTable(&AS_set(outSet)->entries);
@ -345,7 +345,7 @@ KrkValue krk_set_of(int argc, const KrkValue argv[], int hasKw) {
} }
_noexport _noexport
void _createAndBind_setClass(void) { void _createAndBind_setClass(KrkThreadState * _thread) {
KrkClass * set = krk_makeClass(vm.builtins, &KRK_BASE_CLASS(set), "set", vm.baseClasses->objectClass); KrkClass * set = krk_makeClass(vm.builtins, &KRK_BASE_CLASS(set), "set", vm.baseClasses->objectClass);
set->allocSize = sizeof(struct Set); set->allocSize = sizeof(struct Set);
set->_ongcscan = _set_gcscan; set->_ongcscan = _set_gcscan;

View File

@ -5,13 +5,13 @@
#include <kuroko/memory.h> #include <kuroko/memory.h>
#include <kuroko/util.h> #include <kuroko/util.h>
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)->start);
krk_markValue(((struct KrkSlice*)self)->end); krk_markValue(((struct KrkSlice*)self)->end);
krk_markValue(((struct KrkSlice*)self)->step); 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)); KrkValue outSlice = OBJECT_VAL(krk_newInstance(vm.baseClasses->sliceClass));
krk_push(outSlice); krk_push(outSlice);
@ -36,7 +36,7 @@ static inline krk_integer_type _wrapn(krk_integer_type count, krk_integer_type v
return val; 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))) { if (!(IS_slice(slicerVal))) {
TYPE_ERROR(slice, slicerVal); TYPE_ERROR(slice, slicerVal);
return 1; return 1;
@ -166,7 +166,7 @@ KRK_Method(slice,step) {
} }
_noexport _noexport
void _createAndBind_sliceClass(void) { void _createAndBind_sliceClass(KrkThreadState * _thread) {
KrkClass * slice = ADD_BASE_CLASS(vm.baseClasses->sliceClass, "slice", vm.baseClasses->objectClass); KrkClass * slice = ADD_BASE_CLASS(vm.baseClasses->sliceClass, "slice", vm.baseClasses->objectClass);
slice->allocSize = sizeof(struct KrkSlice); slice->allocSize = sizeof(struct KrkSlice);
slice->_ongcscan = _slice_gcscan; slice->_ongcscan = _slice_gcscan;

View File

@ -6,7 +6,7 @@
#include "private.h" #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_CTYPE KrkString *
#define CURRENT_NAME self #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__) { KRK_Method(str,__format__) {
METHOD_TAKES_EXACTLY(1); METHOD_TAKES_EXACTLY(1);
CHECK_ARG(1,str,KrkString*,format_spec); CHECK_ARG(1,str,KrkString*,format_spec);
struct ParsedFormatSpec opts = {0}; 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(); if (!spec) return NONE_VAL();
switch (*spec) { switch (*spec) {
@ -408,7 +408,7 @@ KRK_Method(str,__mul__) {
KRK_Method(str,__rmul__) { KRK_Method(str,__rmul__) {
METHOD_TAKES_EXACTLY(1); 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(); return NOTIMPL_VAL();
} }
@ -418,7 +418,7 @@ struct _str_join_context {
int isFirst; 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; struct _str_join_context * _context = context;
for (size_t i = 0; i < count; ++i) { 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. * Implements all three of strip, lstrip, rstrip.
* Set which = 0, 1, 2 respectively * 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]); KrkString * subset = AS_STRING(vm.specialMethodNames[METHOD_STRSTRIP]);
if (argc > 1) { if (argc > 1) {
if (IS_STRING(argv[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) { KRK_Method(str,strip) {
METHOD_TAKES_AT_MOST(1); /* TODO */ 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) { KRK_Method(str,lstrip) {
METHOD_TAKES_AT_MOST(1); /* TODO */ 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) { KRK_Method(str,rstrip) {
METHOD_TAKES_AT_MOST(1); /* TODO */ 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) \ #define strCompare(name,lop,iop,rop) \
@ -831,7 +831,7 @@ KRK_Method(str,find) {
} }
KRK_Method(str,index) { 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) { if (IS_INTEGER(result) && AS_INTEGER(result) == -1) {
return krk_runtimeError(vm.exceptions->valueError, "substring not found"); return krk_runtimeError(vm.exceptions->valueError, "substring not found");
} }
@ -924,8 +924,8 @@ KRK_Method(str,__str__) {
return argv[0]; return argv[0];
} }
void krk_addObjects(void) { void krk_addObjects_r(KrkThreadState * _thread) {
KrkValue tmp = FUNC_NAME(str,__add__)(2, (KrkValue[]){krk_peek(1), krk_peek(0)},0); KrkValue tmp = FUNC_NAME(str,__add__)(_thread, 2, (KrkValue[]){krk_peek(1), krk_peek(0)},0);
krk_pop(); krk_pop(); krk_pop(); krk_pop();
krk_push(tmp); krk_push(tmp);
} }
@ -935,7 +935,7 @@ KRK_Method(str,__iter__) {
KrkInstance * output = krk_newInstance(vm.baseClasses->striteratorClass); KrkInstance * output = krk_newInstance(vm.baseClasses->striteratorClass);
krk_push(OBJECT_VAL(output)); 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(); krk_pop();
return OBJECT_VAL(output); return OBJECT_VAL(output);
@ -1057,14 +1057,14 @@ KRK_Method(striterator,__call__) {
return argv[0]; return argv[0];
} else { } else {
krk_attachNamedValue(&self->fields, "i", INTEGER_VAL(AS_INTEGER(_counter)+1)); 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: _corrupt:
return krk_runtimeError(vm.exceptions->typeError, "Corrupt str iterator: %s", errorStr); return krk_runtimeError(vm.exceptions->typeError, "Corrupt str iterator: %s", errorStr);
} }
_noexport _noexport
void _createAndBind_strClass(void) { void _createAndBind_strClass(KrkThreadState * _thread) {
KrkClass * str = ADD_BASE_CLASS(vm.baseClasses->strClass, "str", vm.baseClasses->objectClass); KrkClass * str = ADD_BASE_CLASS(vm.baseClasses->strClass, "str", vm.baseClasses->objectClass);
str->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT; str->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
BIND_METHOD(str,__init__); BIND_METHOD(str,__init__);

View File

@ -9,7 +9,7 @@
if (index < 0) index += self->values.count; \ 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) 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; KrkValueArray * positionals = context;
if (positionals->count + count > positionals->capacity) { if (positionals->count + count > positionals->capacity) {
size_t old = 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; 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) { if (argc == 1) {
return OBJECT_VAL(krk_newTuple(0)); return OBJECT_VAL(krk_newTuple(0));
} else if (argc == 2) { } else if (argc == 2) {
@ -42,7 +42,7 @@ static KrkValue _tuple_init(int argc, const KrkValue argv[], int hasKw) {
} }
/* tuple creator */ /* 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); KrkTuple * self = krk_newTuple(argc);
krk_push(OBJECT_VAL(self)); krk_push(OBJECT_VAL(self));
for (size_t i = 0; i < (size_t)argc; ++i) { for (size_t i = 0; i < (size_t)argc; ++i) {
@ -99,7 +99,7 @@ KRK_Method(tuple,__getitem__) {
} }
/* make into a list */ /* 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; krk_currentThread.stackTop[-len-1] = result;
while (len) { while (len) {
krk_pop(); krk_pop();
@ -201,18 +201,18 @@ struct TupleIter {
int i; 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]); struct TupleIter * self = (struct TupleIter *)AS_OBJECT(argv[0]);
self->myTuple = argv[1]; self->myTuple = argv[1];
self->i = 0; self->i = 0;
return argv[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); 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]); struct TupleIter * self = (struct TupleIter *)AS_OBJECT(argv[0]);
KrkValue t = self->myTuple; /* Tuple to iterate */ KrkValue t = self->myTuple; /* Tuple to iterate */
int i = self->i; int i = self->i;
@ -227,7 +227,7 @@ static KrkValue _tuple_iter_call(int argc, const KrkValue argv[], int hasKw) {
KRK_Method(tuple,__iter__) { KRK_Method(tuple,__iter__) {
KrkInstance * output = krk_newInstance(vm.baseClasses->tupleiteratorClass); KrkInstance * output = krk_newInstance(vm.baseClasses->tupleiteratorClass);
krk_push(OBJECT_VAL(output)); 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(); krk_pop();
return OBJECT_VAL(output); return OBJECT_VAL(output);
} }
@ -270,7 +270,7 @@ KRK_Method(tuple,__mul__) {
} }
_noexport _noexport
void _createAndBind_tupleClass(void) { void _createAndBind_tupleClass(KrkThreadState *_thread) {
KrkClass * tuple = ADD_BASE_CLASS(vm.baseClasses->tupleClass, "tuple", vm.baseClasses->objectClass); KrkClass * tuple = ADD_BASE_CLASS(vm.baseClasses->tupleClass, "tuple", vm.baseClasses->objectClass);
tuple->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT; tuple->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
BIND_METHOD(tuple,__repr__); BIND_METHOD(tuple,__repr__);

View File

@ -20,7 +20,7 @@
* So if you specify list[int], you'll get 'list[int]'. * 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)) { if (IS_CLASS(val)) {
return OBJECT_VAL(AS_CLASS(val)->name); return OBJECT_VAL(AS_CLASS(val)->name);
} else if (IS_STRING(val)) { } else if (IS_STRING(val)) {
@ -30,7 +30,7 @@ static KrkValue typeToString(KrkValue val) {
struct StringBuilder sb = {0}; struct StringBuilder sb = {0};
for (size_t i = 0; i < AS_TUPLE(val)->values.count; ++i) { 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); pushStringBuilderStr(&sb, AS_CSTRING(krk_peek(0)), AS_STRING(krk_peek(0))->length);
krk_pop(); krk_pop();
if (i < AS_TUPLE(val)->values.count - 1) { 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); pushStringBuilderStr(&sb, AS_CLASS(argv[0])->name->chars, AS_CLASS(argv[0])->name->length);
pushStringBuilder(&sb,'['); 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); pushStringBuilderStr(&sb, AS_CSTRING(krk_peek(0)), AS_STRING(krk_peek(0))->length);
krk_pop(); krk_pop();
pushStringBuilder(&sb,']'); pushStringBuilder(&sb,']');

View File

@ -9,14 +9,14 @@
#include <kuroko/table.h> #include <kuroko/table.h>
#define ALLOCATE_OBJECT(type, objectType) \ #define ALLOCATE_OBJECT(type, objectType) \
(type*)allocateObject(sizeof(type), objectType) (type*)allocateObject(_thread,sizeof(type), objectType)
#ifndef KRK_DISABLE_THREADS #ifndef KRK_DISABLE_THREADS
static volatile int _stringLock = 0; static volatile int _stringLock = 0;
static volatile int _objectLock = 0; static volatile int _objectLock = 0;
#endif #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); KrkObj * object = (KrkObj*)krk_reallocate(NULL, 0, size);
memset(object,0,size); memset(object,0,size);
object->type = type; object->type = type;
@ -32,7 +32,7 @@ static KrkObj * allocateObject(size_t size, KrkObjType type) {
return object; 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) { if (value > 0xFFFF) {
out[0] = (0xF0 | (value >> 18)); out[0] = (0xF0 | (value >> 18));
out[1] = (0x80 | ((value >> 12) & 0x3F)); out[1] = (0x80 | ((value >> 12) & 0x3F));
@ -100,7 +100,7 @@ _reject:
return *state; 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 state = 0;
uint32_t codepoint = 0; uint32_t codepoint = 0;
unsigned char * end = (unsigned char *)chars + length; unsigned char * end = (unsigned char *)chars + length;
@ -147,7 +147,7 @@ GENREADY(2,uint16_t)
GENREADY(4,uint32_t) GENREADY(4,uint32_t)
#undef GENREADY #undef GENREADY
void * krk_unicodeString(KrkString * string) { void * krk_unicodeString_r(KrkThreadState * _thread, KrkString * string) {
if (string->codes) return string->codes; 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_UCS1) _readyUCS1(string);
else if ((string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) == KRK_OBJ_FLAGS_STRING_UCS2) _readyUCS2(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; 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); krk_unicodeString(string);
switch (string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) { switch (string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) {
case KRK_OBJ_FLAGS_STRING_ASCII: 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; size_t codesLength = 0;
int type = checkString(chars,length,&codesLength); int type = checkString(_thread, chars,length,&codesLength);
if (type == -1) { if (type == -1) {
return krk_copyString("",0); return krk_copyString("",0);
} }
@ -190,7 +190,7 @@ static KrkString * allocateString(char * chars, size_t length, uint32_t hash) {
return string; 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; uint32_t hash = 0;
/* This is the so-called "sdbm" hash. It comes from a piece of /* This is the so-called "sdbm" hash. It comes from a piece of
* public domain code from a clone of ndbm. */ * public domain code from a clone of ndbm. */
@ -200,8 +200,8 @@ static uint32_t hashString(const char * key, size_t length) {
return hash; return hash;
} }
KrkString * krk_takeString(char * chars, size_t length) { KrkString * krk_takeString_r(KrkThreadState * _thread, char * chars, size_t length) {
uint32_t hash = hashString(chars, length); uint32_t hash = hashString(_thread, chars, length);
_obtain_lock(_stringLock); _obtain_lock(_stringLock);
KrkString * interned = krk_tableFindString(&vm.strings, chars, length, hash); KrkString * interned = krk_tableFindString(&vm.strings, chars, length, hash);
if (interned != NULL) { 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 */ /* Part of taking ownership of this string is that we track its memory usage */
krk_gcTakeBytes(chars, length + 1); krk_gcTakeBytes(chars, length + 1);
KrkString * result = allocateString(chars, length, hash); KrkString * result = allocateString(_thread, chars, length, hash);
return result; return result;
} }
KrkString * krk_copyString(const char * chars, size_t length) { KrkString * krk_copyString_r(KrkThreadState * _thread, const char * chars, size_t length) {
uint32_t hash = hashString(chars, length); uint32_t hash = hashString(_thread, chars, length);
_obtain_lock(_stringLock); _obtain_lock(_stringLock);
KrkString * interned = krk_tableFindString(&vm.strings, chars ? chars : "", length, hash); KrkString * interned = krk_tableFindString(&vm.strings, chars ? chars : "", length, hash);
if (interned) { if (interned) {
@ -227,13 +227,13 @@ KrkString * krk_copyString(const char * chars, size_t length) {
char * heapChars = ALLOCATE(char, length + 1); char * heapChars = ALLOCATE(char, length + 1);
memcpy(heapChars, chars ? chars : "", length); memcpy(heapChars, chars ? chars : "", length);
heapChars[length] = '\0'; heapChars[length] = '\0';
KrkString * result = allocateString(heapChars, length, hash); KrkString * result = allocateString(_thread, heapChars, length, hash);
if (result->chars != heapChars) free(heapChars); if (result->chars != heapChars) free(heapChars);
_release_lock(_stringLock); _release_lock(_stringLock);
return result; 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); _obtain_lock(_stringLock);
KrkString * interned = krk_tableFindString(&vm.strings, chars, length, hash); KrkString * interned = krk_tableFindString(&vm.strings, chars, length, hash);
if (interned != NULL) { if (interned != NULL) {
@ -256,7 +256,7 @@ KrkString * krk_takeStringVetted(char * chars, size_t length, size_t codesLength
return string; return string;
} }
KrkCodeObject * krk_newCodeObject(void) { KrkCodeObject * krk_newCodeObject_r(KrkThreadState * _thread) {
KrkCodeObject * codeobject = ALLOCATE_OBJECT(KrkCodeObject, KRK_OBJ_CODEOBJECT); KrkCodeObject * codeobject = ALLOCATE_OBJECT(KrkCodeObject, KRK_OBJ_CODEOBJECT);
codeobject->requiredArgs = 0; codeobject->requiredArgs = 0;
codeobject->keywordArgs = 0; codeobject->keywordArgs = 0;
@ -271,7 +271,7 @@ KrkCodeObject * krk_newCodeObject(void) {
return codeobject; 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); KrkNative * native = ALLOCATE_OBJECT(KrkNative, KRK_OBJ_NATIVE);
native->function = function; native->function = function;
native->obj.flags = type; native->obj.flags = type;
@ -280,7 +280,7 @@ KrkNative * krk_newNative(NativeFn function, const char * name, int type) {
return native; 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); KrkUpvalue ** upvalues = ALLOCATE(KrkUpvalue*, function->upvalueCount);
for (size_t i = 0; i < function->upvalueCount; ++i) { for (size_t i = 0; i < function->upvalueCount; ++i) {
upvalues[i] = NULL; upvalues[i] = NULL;
@ -305,7 +305,7 @@ KrkClosure * krk_newClosure(KrkCodeObject * function, KrkValue globals) {
return closure; return closure;
} }
KrkUpvalue * krk_newUpvalue(int slot) { KrkUpvalue * krk_newUpvalue_r(KrkThreadState * _thread, int slot) {
KrkUpvalue * upvalue = ALLOCATE_OBJECT(KrkUpvalue, KRK_OBJ_UPVALUE); KrkUpvalue * upvalue = ALLOCATE_OBJECT(KrkUpvalue, KRK_OBJ_UPVALUE);
upvalue->location = slot; upvalue->location = slot;
upvalue->next = NULL; upvalue->next = NULL;
@ -314,7 +314,7 @@ KrkUpvalue * krk_newUpvalue(int slot) {
return upvalue; 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); KrkClass * _class = ALLOCATE_OBJECT(KrkClass, KRK_OBJ_CLASS);
_class->name = name; _class->name = name;
_class->allocSize = sizeof(KrkInstance); _class->allocSize = sizeof(KrkInstance);
@ -333,21 +333,21 @@ KrkClass * krk_newClass(KrkString * name, KrkClass * baseClass) {
return _class; return _class;
} }
KrkInstance * krk_newInstance(KrkClass * _class) { KrkInstance * krk_newInstance_r(KrkThreadState * _thread, KrkClass * _class) {
KrkInstance * instance = (KrkInstance*)allocateObject(_class->allocSize, KRK_OBJ_INSTANCE); KrkInstance * instance = (KrkInstance*)allocateObject(_thread, _class->allocSize, KRK_OBJ_INSTANCE);
instance->_class = _class; instance->_class = _class;
krk_initTable(&instance->fields); krk_initTable(&instance->fields);
return instance; 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); KrkBoundMethod * bound = ALLOCATE_OBJECT(KrkBoundMethod, KRK_OBJ_BOUND_METHOD);
bound->receiver = receiver; bound->receiver = receiver;
bound->method = method; bound->method = method;
return bound; 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); KrkTuple * tuple = ALLOCATE_OBJECT(KrkTuple, KRK_OBJ_TUPLE);
krk_initValueArray(&tuple->values); krk_initValueArray(&tuple->values);
krk_push(OBJECT_VAL(tuple)); krk_push(OBJECT_VAL(tuple));
@ -357,7 +357,7 @@ KrkTuple * krk_newTuple(size_t length) {
return tuple; 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); KrkBytes * bytes = ALLOCATE_OBJECT(KrkBytes, KRK_OBJ_BYTES);
bytes->length = length; bytes->length = length;
bytes->bytes = NULL; bytes->bytes = NULL;

View File

@ -139,7 +139,7 @@ KRK_Method(Environ,__delitem__) {
return krk_callDirect(vm.baseClasses->dictClass->_delitem, 2); 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` */ /* Create a new class to subclass `dict` */
KrkClass * Environ = krk_makeClass(module, &KRK_BASE_CLASS(Environ), "_Environ", vm.baseClasses->dictClass); KrkClass * Environ = krk_makeClass(module, &KRK_BASE_CLASS(Environ), "_Environ", vm.baseClasses->dictClass);
krk_attachNamedObject(&module->fields, "_Environ", (KrkObj*)Environ); krk_attachNamedObject(&module->fields, "_Environ", (KrkObj*)Environ);
@ -463,7 +463,7 @@ KRK_Function(get_terminal_size) {
} }
#endif #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)); char ** out = malloc(sizeof(char*)*(count+1));
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
if (!IS_STRING(values[i])) { if (!IS_STRING(values[i])) {
@ -477,6 +477,7 @@ static int makeArgs(int count, const KrkValue * values, char *** argsOut, const
*argsOut = out; *argsOut = out;
return 0; return 0;
} }
#define makeArgs(c,v,a,m) makeArgs_r(_thread,c,v,a,m)
KRK_Function(execl) { KRK_Function(execl) {
FUNCTION_TAKES_AT_LEAST(1); FUNCTION_TAKES_AT_LEAST(1);
@ -661,7 +662,7 @@ KRK_Function(S_ISSOCK) {
} }
#endif #endif
void krk_module_init_os(void) { void krk_module_init_os(KrkThreadState * _thread) {
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass); KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
krk_attachNamedObject(&vm.modules, "os", (KrkObj*)module); krk_attachNamedObject(&vm.modules, "os", (KrkObj*)module);
krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("os")); 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."); "Obtain the size of the host terminal as a tuple of columns and lines.");
#endif #endif
_loadEnviron(module); _loadEnviron(_thread, module);
/* Nothing special */ /* Nothing special */
KrkClass * stat_result = krk_makeClass(module, &KRK_BASE_CLASS(stat_result), "stat_result", vm.baseClasses->objectClass); KrkClass * stat_result = krk_makeClass(module, &KRK_BASE_CLASS(stat_result), "stat_result", vm.baseClasses->objectClass);

View File

@ -7,21 +7,21 @@
*/ */
#include "kuroko/kuroko.h" #include "kuroko/kuroko.h"
extern void _createAndBind_numericClasses(void); extern void _createAndBind_numericClasses(KrkThreadState*);
extern void _createAndBind_strClass(void); extern void _createAndBind_strClass(KrkThreadState*);
extern void _createAndBind_listClass(void); extern void _createAndBind_listClass(KrkThreadState*);
extern void _createAndBind_tupleClass(void); extern void _createAndBind_tupleClass(KrkThreadState*);
extern void _createAndBind_bytesClass(void); extern void _createAndBind_bytesClass(KrkThreadState*);
extern void _createAndBind_dictClass(void); extern void _createAndBind_dictClass(KrkThreadState*);
extern void _createAndBind_functionClass(void); extern void _createAndBind_functionClass(KrkThreadState*);
extern void _createAndBind_rangeClass(void); extern void _createAndBind_rangeClass(KrkThreadState*);
extern void _createAndBind_setClass(void); extern void _createAndBind_setClass(KrkThreadState*);
extern void _createAndBind_generatorClass(void); extern void _createAndBind_generatorClass(KrkThreadState*);
extern void _createAndBind_sliceClass(void); extern void _createAndBind_sliceClass(KrkThreadState*);
extern void _createAndBind_builtins(void); extern void _createAndBind_builtins(KrkThreadState*);
extern void _createAndBind_type(void); extern void _createAndBind_type(KrkThreadState*);
extern void _createAndBind_exceptions(void); extern void _createAndBind_exceptions(KrkThreadState*);
extern void _createAndBind_longClass(void); extern void _createAndBind_longClass(KrkThreadState*);
/** /**
* @brief Index numbers for always-available interned strings representing important method and member names. * @brief Index numbers for always-available interned strings representing important method and member names.

View File

@ -177,7 +177,7 @@ KRK_Function(inspect_value) {
return OBJECT_VAL(krk_newBytes(sizeof(KrkValue),(uint8_t*)&argv[0])); 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() * kuroko = module()
* *

View File

@ -11,18 +11,18 @@
#define TABLE_MAX_LOAD 0.75 #define TABLE_MAX_LOAD 0.75
void krk_initTable(KrkTable * table) { void krk_initTable_r(struct KrkThreadState * _thread, KrkTable * table) {
table->count = 0; table->count = 0;
table->capacity = 0; table->capacity = 0;
table->entries = NULL; table->entries = NULL;
} }
void krk_freeTable(KrkTable * table) { void krk_freeTable_r(struct KrkThreadState * _thread, KrkTable * table) {
FREE_ARRAY(KrkTableEntry, table->entries, table->capacity); FREE_ARRAY(KrkTableEntry, table->entries, table->capacity);
krk_initTable(table); 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)) { switch (KRK_VAL_TYPE(value)) {
case KRK_VAL_BOOLEAN: case KRK_VAL_BOOLEAN:
case KRK_VAL_INTEGER: case KRK_VAL_INTEGER:
@ -59,7 +59,7 @@ _unhashable:
return 1; 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; uint32_t index;
if (krk_hashValue(key, &index)) { if (krk_hashValue(key, &index)) {
return NULL; 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; uint32_t index;
if (krk_hashValue(key, &index)) { if (krk_hashValue(key, &index)) {
return NULL; return NULL;
@ -113,7 +113,7 @@ int __builtin_clz(unsigned int x) {
} }
#endif #endif
void krk_tableAdjustCapacity(KrkTable * table, size_t capacity) { void krk_tableAdjustCapacity_r(struct KrkThreadState * _thread, KrkTable * table, size_t capacity) {
if (capacity) { if (capacity) {
/* Fast power-of-two calculation */ /* Fast power-of-two calculation */
size_t powerOfTwoCapacity = __builtin_clz(1) - __builtin_clz(capacity); size_t powerOfTwoCapacity = __builtin_clz(1) - __builtin_clz(capacity);
@ -142,7 +142,7 @@ void krk_tableAdjustCapacity(KrkTable * table, size_t capacity) {
table->capacity = 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) { if (table->count + 1 > table->capacity * TABLE_MAX_LOAD) {
size_t capacity = GROW_CAPACITY(table->capacity); size_t capacity = GROW_CAPACITY(table->capacity);
krk_tableAdjustCapacity(table, capacity); krk_tableAdjustCapacity(table, capacity);
@ -156,7 +156,7 @@ int krk_tableSet(KrkTable * table, KrkValue key, KrkValue value) {
return isNewKey; 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; if (table->count == 0) return 0;
KrkTableEntry * entry = krk_findEntry(table->entries, table->capacity, key); KrkTableEntry * entry = krk_findEntry(table->entries, table->capacity, key);
if (!entry) return 0; if (!entry) return 0;
@ -166,7 +166,7 @@ int krk_tableSetIfExists(KrkTable * table, KrkValue key, KrkValue value) {
return 1; 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) { for (size_t i = 0; i < from->capacity; ++i) {
KrkTableEntry * entry = &from->entries[i]; KrkTableEntry * entry = &from->entries[i];
if (!IS_KWARGS(entry->key)) { 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; if (table->count == 0) return 0;
KrkTableEntry * entry = krk_findEntry(table->entries, table->capacity, key); KrkTableEntry * entry = krk_findEntry(table->entries, table->capacity, key);
if (!entry || IS_KWARGS(entry->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; if (unlikely(table->count == 0)) return 0;
uint32_t index = str->obj.hash & (table->capacity-1); uint32_t index = str->obj.hash & (table->capacity-1);
for (;;) { 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; if (table->count == 0) return 0;
KrkTableEntry * entry = krk_findEntry(table->entries, table->capacity, key); KrkTableEntry * entry = krk_findEntry(table->entries, table->capacity, key);
if (!entry || IS_KWARGS(entry->key)) { if (!entry || IS_KWARGS(entry->key)) {
@ -212,9 +212,9 @@ int krk_tableDelete(KrkTable * table, KrkValue key) {
return 1; 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; 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)) { if (!entry || IS_KWARGS(entry->key)) {
return 0; return 0;
} }
@ -224,7 +224,7 @@ int krk_tableDeleteExact(KrkTable * table, KrkValue key) {
return 1; 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; if (table->count == 0) return NULL;
uint32_t index = hash & (table->capacity-1); uint32_t index = hash & (table->capacity-1);

View File

@ -32,6 +32,7 @@
struct Thread { struct Thread {
KrkInstance inst; KrkInstance inst;
KrkThreadState * threadState; KrkThreadState * threadState;
KrkVM * owner;
pthread_t nativeRef; pthread_t nativeRef;
pid_t tid; pid_t tid;
unsigned int started:1; unsigned int started:1;
@ -61,10 +62,11 @@ KRK_Function(current_thread) {
static volatile int _threadLock = 0; static volatile int _threadLock = 0;
static void * _startthread(void * _threadObj) { static void * _startthread(void * _threadObj) {
#if defined(__APPLE__) && defined(__aarch64__) struct Thread * self = _threadObj;
krk_forceThreadData(); self->threadState = calloc(1,sizeof(KrkThreadState));
#endif KrkThreadState * _thread = self->threadState;
memset(&krk_currentThread, 0, sizeof(KrkThreadState)); _thread->owner = self->owner;
krk_currentThread.frames = calloc(vm.maximumCallDepth,sizeof(KrkCallFrame)); krk_currentThread.frames = calloc(vm.maximumCallDepth,sizeof(KrkCallFrame));
vm.globalFlags |= KRK_GLOBAL_THREADS; vm.globalFlags |= KRK_GLOBAL_THREADS;
_obtain_lock(_threadLock); _obtain_lock(_threadLock);
@ -75,8 +77,6 @@ static void * _startthread(void * _threadObj) {
_release_lock(_threadLock); _release_lock(_threadLock);
/* Get our run function */ /* Get our run function */
struct Thread * self = _threadObj;
self->threadState = &krk_currentThread;
self->tid = gettid(); self->tid = gettid();
KrkValue runMethod = NONE_VAL(); 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 */ /* Remove this thread from the thread pool, its stack is garbage anyway */
_obtain_lock(_threadLock); _obtain_lock(_threadLock);
krk_resetStack(); krk_resetStack(_thread);
KrkThreadState * previous = vm.threads; KrkThreadState * previous = vm.threads;
while (previous) { while (previous) {
if (previous->next == &krk_currentThread) { if (previous->next == &krk_currentThread) {
@ -133,6 +133,7 @@ KRK_Method(Thread,start) {
self->started = 1; self->started = 1;
self->alive = 1; self->alive = 1;
self->owner = _thread->owner;
pthread_create(&self->nativeRef, NULL, _startthread, (void*)self); pthread_create(&self->nativeRef, NULL, _startthread, (void*)self);
return argv[0]; return argv[0];
@ -155,7 +156,7 @@ KRK_Method(Lock,__init__) {
return argv[0]; 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__ #ifdef __GLIBC__
{ {
if (self->mutex.__data.__owner) { if (self->mutex.__data.__owner) {
@ -182,7 +183,7 @@ KRK_Method(Lock,__repr__) {
pushStringBuilderStr(&sb, tmp, len); pushStringBuilderStr(&sb, tmp, len);
} }
_pushLockStatus(self,&sb); _pushLockStatus(_thread, self,&sb);
pushStringBuilder(&sb,'>'); pushStringBuilder(&sb,'>');
return finishStringBuilder(&sb); return finishStringBuilder(&sb);
@ -199,7 +200,7 @@ KRK_Method(Lock,__exit__) {
return NONE_VAL(); return NONE_VAL();
} }
void krk_module_init_threading(void) { void krk_module_init_threading(KrkThreadState * _thread) {
/** /**
* threads = module() * threads = module()
* *

View File

@ -38,7 +38,7 @@ KRK_Function(time) {
return FLOATING_VAL(out); return FLOATING_VAL(out);
} }
void krk_module_init_time(void) { void krk_module_init_time(KrkThreadState * _thread) {
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass); KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
krk_attachNamedObject(&vm.modules, "time", (KrkObj*)module); krk_attachNamedObject(&vm.modules, "time", (KrkObj*)module);
krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("time")); krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("time"));

View File

@ -8,13 +8,13 @@
#include "opcode_enum.h" #include "opcode_enum.h"
void krk_initValueArray(KrkValueArray * array) { void krk_initValueArray_r(KrkThreadState * _thread, KrkValueArray * array) {
array->values = NULL; array->values = NULL;
array->capacity = 0; array->capacity = 0;
array->count = 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) { if (array->capacity < array->count + 1) {
int old = array->capacity; int old = array->capacity;
array->capacity = GROW_CAPACITY(old); array->capacity = GROW_CAPACITY(old);
@ -25,12 +25,12 @@ void krk_writeValueArray(KrkValueArray * array, KrkValue value) {
array->count++; array->count++;
} }
void krk_freeValueArray(KrkValueArray * array) { void krk_freeValueArray_r(KrkThreadState * _thread, KrkValueArray * array) {
FREE_ARRAY(KrkValue, array->values, array->capacity); FREE_ARRAY(KrkValue, array->values, array->capacity);
krk_initValueArray(array); 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); KrkClass * type = krk_getType(printable);
if (type->_tostr) { if (type->_tostr) {
krk_push(printable); krk_push(printable);
@ -49,7 +49,7 @@ void krk_printValue(FILE * f, KrkValue printable) {
#define STRING_DEBUG_TRUNCATE 50 #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)) { if (!IS_OBJECT(printable)) {
switch (KRK_VAL_TYPE(printable)) { switch (KRK_VAL_TYPE(printable)) {
case KRK_VAL_INTEGER: fprintf(f, PRIkrk_int, AS_INTEGER(printable)); break; 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... * 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; 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); KrkClass * type = krk_getType(a);
if (likely(type && type->_eq)) { if (likely(type && type->_eq)) {
krk_push(a); krk_push(a);
@ -173,7 +173,7 @@ static inline int _krk_method_equivalence(KrkValue a, KrkValue b) {
return 0; 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) { switch (valtype) {
case KRK_VAL_BOOLEAN: case KRK_VAL_BOOLEAN:
case KRK_VAL_INTEGER: case KRK_VAL_INTEGER:
@ -184,11 +184,11 @@ static inline int _krk_same_type_equivalence(uint16_t valtype, KrkValue a, KrkVa
return a == b; return a == b;
case KRK_VAL_OBJECT: case KRK_VAL_OBJECT:
default: 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) { switch (valtype) {
case KRK_VAL_BOOLEAN: case KRK_VAL_BOOLEAN:
case KRK_VAL_INTEGER: case KRK_VAL_INTEGER:
@ -199,33 +199,33 @@ static inline int _krk_same_type_equivalence_b(uint16_t valtype, KrkValue a, Krk
return 0; return 0;
case KRK_VAL_OBJECT: case KRK_VAL_OBJECT:
default: 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. */ /* 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; if (val_b == KRK_VAL_KWARGS || val_a == KRK_VAL_KWARGS) return 0;
/* Fall back to methods */ /* Fall back to methods */
return _krk_method_equivalence(a,b); return _krk_method_equivalence(_thread,a,b);
} }
__attribute__((hot)) __attribute__((hot))
int krk_valuesSameOrEqual(KrkValue a, KrkValue b) { int krk_valuesSameOrEqual_r(KrkThreadState * _thread, KrkValue a, KrkValue b) {
if (a == b) return 1; if (a == b) return 1;
uint16_t val_a = KRK_VAL_TYPE(a); uint16_t val_a = KRK_VAL_TYPE(a);
uint16_t val_b = KRK_VAL_TYPE(b); uint16_t val_b = KRK_VAL_TYPE(b);
return (val_a == val_b) return (val_a == val_b)
? _krk_same_type_equivalence_b(val_a, a, b) ? _krk_same_type_equivalence_b(_thread, val_a, a, b)
: _krk_diff_type_equivalence(val_a, val_b, a, b); : _krk_diff_type_equivalence(_thread, val_a, val_b, a, b);
} }
__attribute__((hot)) __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_a = KRK_VAL_TYPE(a);
uint16_t val_b = KRK_VAL_TYPE(b); uint16_t val_b = KRK_VAL_TYPE(b);
return (val_a == val_b) return (val_a == val_b)
? _krk_same_type_equivalence(val_a,a,b) ? _krk_same_type_equivalence(_thread,val_a,a,b)
: _krk_diff_type_equivalence(val_a,val_b,a,b); : _krk_diff_type_equivalence(_thread,val_a,val_b,a,b);
} }

426
src/vm.c

File diff suppressed because it is too large Load Diff

View File

@ -55,7 +55,7 @@ KrkValue SeenFunctions;
KrkValue UnseenFunctions; KrkValue UnseenFunctions;
KrkValue StringTable; KrkValue StringTable;
static void _initListFunctions(void) { static void _initListFunctions(KrkThreadState * _thread) {
KrkValue _list_pop; KrkValue _list_pop;
KrkValue _list_append; KrkValue _list_append;
KrkValue _list_contains; KrkValue _list_contains;
@ -70,24 +70,30 @@ static void _initListFunctions(void) {
ListIndex = AS_NATIVE(_list_index)->function; ListIndex = AS_NATIVE(_list_index)->function;
} }
static void findInterpreter(char * argv[]) { static char * findInterpreter(char * argv[]) {
#ifdef _WIN32 #ifdef _WIN32
vm.binpath = strdup(_pgmptr); return strdup(_pgmptr);
#else #else
/* Try asking /proc */ /* Try asking /proc */
char tmp[4096];
char * binpath = realpath("/proc/self/exe", NULL); char * binpath = realpath("/proc/self/exe", NULL);
if (!binpath || (access(binpath, X_OK) != 0)) { if (!binpath || (access(binpath, X_OK) != 0)) {
if (binpath) {
free(binpath);
binpath = NULL;
}
if (strchr(argv[0], '/')) { if (strchr(argv[0], '/')) {
binpath = realpath(argv[0], NULL); binpath = realpath(argv[0], NULL);
} else { } else {
/* Search PATH for argv[0] */ /* 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; char * path = _path;
while (path) { while (path) {
char * next = strchr(path,':'); char * next = strchr(path,':');
if (next) *next++ = '\0'; if (next) *next++ = '\0';
char tmp[4096];
snprintf(tmp, 4096, "%s/%s", path, argv[0]); snprintf(tmp, 4096, "%s/%s", path, argv[0]);
if (access(tmp, X_OK) == 0) { if (access(tmp, X_OK) == 0) {
binpath = strdup(tmp); binpath = strdup(tmp);
@ -98,9 +104,7 @@ static void findInterpreter(char * argv[]) {
free(_path); free(_path);
} }
} }
if (binpath) { return binpath;
vm.binpath = binpath;
} /* Else, give up at this point and just don't attach it at all. */
#endif #endif
} }
@ -121,7 +125,7 @@ static size_t internString(KrkString * str) {
return count++; return count++;
} }
static int doStringTable(FILE * out) { static int doStringTable(KrkThreadState * _thread, FILE * out) {
uint32_t stringCount = count; uint32_t stringCount = count;
fwrite(&stringCount, 1, sizeof(uint32_t), out); fwrite(&stringCount, 1, sizeof(uint32_t), out);
@ -134,8 +138,8 @@ static int doStringTable(FILE * out) {
return 0; return 0;
} }
#define WRITE_INTEGER(i) _writeInteger(out, i) #define WRITE_INTEGER(i) _writeInteger(_thread, out, i)
static void _writeInteger(FILE* out, krk_integer_type i) { static void _writeInteger(KrkThreadState * _thread, FILE* out, krk_integer_type i) {
if (i >= 0 && i < 256) { \ if (i >= 0 && i < 256) { \
fwrite((uint8_t[]){'i',i}, 1, 2, out); fwrite((uint8_t[]){'i',i}, 1, 2, out);
} else { } else {
@ -147,8 +151,8 @@ static void _writeInteger(FILE* out, krk_integer_type i) {
} }
} }
#define WRITE_FLOATING(f) _writeFloating(out, f) #define WRITE_FLOATING(f) _writeFloating(_thread, out, f)
static void _writeFloating(FILE * out, double f) { static void _writeFloating(KrkThreadState * _thread, FILE * out, double f) {
uint64_t doubleOut; uint64_t doubleOut;
memcpy(&doubleOut, &f, sizeof(double)); memcpy(&doubleOut, &f, sizeof(double));
fwrite("d", 1, 1, out); 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_KWARGS(k) fwrite("k",1,1,out);
#define WRITE_STRING(s) _writeString(out, s) #define WRITE_STRING(s) _writeString(_thread, out, s)
static void _writeString(FILE * out, KrkString * s) { static void _writeString(KrkThreadState * _thread, FILE * out, KrkString * s) {
uint32_t ind = internString(s); uint32_t ind = internString(s);
if (ind < 256) { if (ind < 256) {
fwrite((uint8_t[]){'s',(uint8_t)ind}, 1, 2, out); 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) #define WRITE_BYTES(b) _writeBytes(_thread, out,b)
static void _writeBytes(FILE * out, KrkBytes * b) { static void _writeBytes(KrkThreadState * _thread, FILE * out, KrkBytes * b) {
if (b->length < 256) { if (b->length < 256) {
fwrite((uint8_t[]){'b', (uint8_t)b->length}, 1, 2, out); fwrite((uint8_t[]){'b', (uint8_t)b->length}, 1, 2, out);
fwrite(b->bytes, 1, b->length, 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) #define WRITE_FUNCTION(f) _writeFunction(_thread,out,f)
static void _writeFunction(FILE * out, KrkCodeObject * f) { static void _writeFunction(KrkThreadState * _thread, FILE * out, KrkCodeObject * f) {
/* Find this function in the function table. */ /* Find this function in the function table. */
KrkValue this = OBJECT_VAL(f); 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)) { if (!IS_INTEGER(index)) {
fprintf(stderr, "Internal error: Expected int from list.index, got '%s'\n", krk_typeName(index)); fprintf(stderr, "Internal error: Expected int from list.index, got '%s'\n", krk_typeName(index));
exit(1); 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 */ /* Go through all functions and build string tables and function index */
while (AS_LIST(UnseenFunctions)->count) { 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); krk_push(nextFunc);
ListAppend(2,(KrkValue[]){SeenFunctions,nextFunc},0); ListAppend(_thread,2,(KrkValue[]){SeenFunctions,nextFunc},0);
/* Examine */ /* Examine */
KrkCodeObject * func = AS_codeobject(nextFunc); KrkCodeObject * func = AS_codeobject(nextFunc);
@ -235,9 +239,9 @@ static int doFirstPass(FILE * out) {
} else if (IS_codeobject(value)) { } else if (IS_codeobject(value)) {
/* If we haven't seen this function yet, append it to the list */ /* If we haven't seen this function yet, append it to the list */
krk_push(value); 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) { if (IS_BOOLEAN(boolResult) && AS_BOOLEAN(boolResult) == 0) {
ListAppend(2,(KrkValue[]){UnseenFunctions,value},0); ListAppend(_thread,2,(KrkValue[]){UnseenFunctions,value},0);
} }
krk_pop(); krk_pop();
} }
@ -250,7 +254,7 @@ static int doFirstPass(FILE * out) {
return 0; return 0;
} }
static int doSecondPass(FILE * out) { static int doSecondPass(KrkThreadState * _thread, FILE * out) {
/* Write the function count */ /* Write the function count */
uint32_t functionCount = AS_LIST(SeenFunctions)->count; uint32_t functionCount = AS_LIST(SeenFunctions)->count;
@ -343,7 +347,7 @@ static int doSecondPass(FILE * out) {
return 0; return 0;
} }
static int compileFile(char * fileName) { static int compileFile(KrkThreadState * _thread, char * fileName) {
/* Compile source file */ /* Compile source file */
FILE * f = fopen(fileName, "r"); FILE * f = fopen(fileName, "r");
if (!f) { if (!f) {
@ -366,7 +370,7 @@ static int compileFile(char * fileName) {
krk_startModule("__main__"); krk_startModule("__main__");
KrkCodeObject * func = krk_compile(buf, fileName); KrkCodeObject * func = krk_compile(_thread, buf, fileName);
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) { if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) {
fprintf(stderr, "%s: exception during compilation:\n", fileName); fprintf(stderr, "%s: exception during compilation:\n", fileName);
@ -382,15 +386,15 @@ static int compileFile(char * fileName) {
fwrite(&header, 1, sizeof(header), out); 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); 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); krk_push(UnseenFunctions);
if (doFirstPass(out)) return 1; if (doFirstPass(_thread, out)) return 1;
if (doStringTable(out)) return 1; if (doStringTable(_thread, out)) return 1;
if (doSecondPass(out)) return 1; if (doSecondPass(_thread, out)) return 1;
krk_pop(); /* UnseenFunctions */ krk_pop(); /* UnseenFunctions */
krk_pop(); /* SeenFunctions */ krk_pop(); /* SeenFunctions */
@ -398,7 +402,7 @@ static int compileFile(char * fileName) {
return 0; return 0;
} }
static KrkValue valueFromConstant(int i, FILE * inFile) { static KrkValue valueFromConstant(KrkThreadState * _thread, int i, FILE * inFile) {
uint8_t c = fgetc(inFile); uint8_t c = fgetc(inFile);
DEBUGOUT(" %4lu: ", (unsigned long)i); DEBUGOUT(" %4lu: ", (unsigned long)i);
switch (c) { 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"); FILE * inFile = fopen(fileName, "r");
if (!inFile) { if (!inFile) {
@ -484,7 +488,7 @@ static int readFile(char * fileName) {
/* Create a string */ /* Create a string */
krk_push(OBJECT_VAL(krk_takeString(strVal,strLen))); 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 #ifdef ISDEBUG
fprintf(stderr, "%04lu: ", (unsigned long)i); fprintf(stderr, "%04lu: ", (unsigned long)i);
krk_printValueSafe(stderr, krk_peek(0)); 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) { for (size_t i = 0; i < (size_t)functionCount; ++i) {
krk_push(OBJECT_VAL(krk_newCodeObject())); 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(); krk_pop();
} }
@ -551,12 +555,12 @@ static int readFile(char * fileName) {
/* Read argument names */ /* Read argument names */
DEBUGOUT(" [Required Arguments]\n"); DEBUGOUT(" [Required Arguments]\n");
for (size_t i = 0; i < (size_t)function.reqArgs + !!(self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS); i++) { 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"); DEBUGOUT(" [Keyword Arguments]\n");
for (size_t i = 0; i < (size_t)function.kwArgs + !!(self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS); i++) { 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 */ /* Skip bytecode for now, we'll look at it later */
@ -584,7 +588,7 @@ static int readFile(char * fileName) {
/* Read constants */ /* Read constants */
DEBUGOUT(" [Constants Table]\n"); DEBUGOUT(" [Constants Table]\n");
for (size_t i = 0; i < function.ctSize; i++) { 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(); KrkValue result = krk_runNext();
if (IS_INTEGER(result)) return AS_INTEGER(result); if (IS_INTEGER(result)) return AS_INTEGER(result);
else { else {
return runSimpleRepl(); return runSimpleRepl(_thread);
} }
} }
extern KrkThreadState * krk_initVM_withBinpath(int flags, char * binpath);
int main(int argc, char * argv[]) { int main(int argc, char * argv[]) {
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "usage: %s path-to-file.krk\n" fprintf(stderr, "usage: %s path-to-file.krk\n"
@ -616,14 +621,14 @@ int main(int argc, char * argv[]) {
} }
/* Initialize a VM */ /* Initialize a VM */
findInterpreter(argv); char * path = findInterpreter(argv);
krk_initVM(0); KrkThreadState * _thread = krk_initVM_withBinpath(0,path);
_initListFunctions(); _initListFunctions(_thread);
if (argc < 3) { if (argc < 3) {
return compileFile(argv[1]); return compileFile(_thread, argv[1]);
} else if (argc == 3 && !strcmp(argv[1],"-r")) { } else if (argc == 3 && !strcmp(argv[1],"-r")) {
return readFile(argv[2]); return readFile(_thread, argv[2]);
} }
return 1; return 1;

View File

@ -3,10 +3,10 @@
#include <kuroko/vm.h> #include <kuroko/vm.h>
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
krk_initVM(0); KrkThreadState * _thread = krk_initVM(0);
krk_startModule("__main__"); krk_startModule("__main__");
krk_interpret("import kuroko\nprint('Kuroko',kuroko.version)\n", "<stdin>"); krk_interpret(_thread, "import kuroko\nprint('Kuroko',kuroko.version)\n", "<stdin>");
krk_freeVM(); krk_freeVM(_thread);
return 0; return 0;
} }

View File

@ -8,14 +8,14 @@
int main(int argc, char * argv[]) { int main(int argc, char * argv[]) {
/* Disable automatic traceback printing, default modules */ /* 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. */ /* Set up our module context. */
krk_startModule("__main__"); krk_startModule("__main__");
int retval = 0; int retval = 0;
if (argc > 1) { if (argc > 1) {
KrkValue result = krk_interpret(argv[1], "<stdin>"); KrkValue result = krk_interpret(_thread, argv[1], "<stdin>");
if (!IS_NONE(result)) { if (!IS_NONE(result)) {
if (IS_INTEGER(result)) { if (IS_INTEGER(result)) {
retval = AS_INTEGER(result); retval = AS_INTEGER(result);
@ -33,10 +33,10 @@ int main(int argc, char * argv[]) {
retval = 1; retval = 1;
} }
} else { } else {
runSimpleRepl(); runSimpleRepl(_thread);
} }
krk_freeVM(); krk_freeVM(_thread);
return retval; return retval;
} }

View File

@ -1,7 +1,7 @@
#define PROMPT_MAIN ">>> " #define PROMPT_MAIN ">>> "
#define PROMPT_BLOCK " > " #define PROMPT_BLOCK " > "
static int runSimpleRepl(void) { static int runSimpleRepl(KrkThreadState * _thread) {
int exitRepl = 0; int exitRepl = 0;
while (!exitRepl) { while (!exitRepl) {
size_t lineCapacity = 8; size_t lineCapacity = 8;
@ -99,7 +99,7 @@ static int runSimpleRepl(void) {
} }
FREE_ARRAY(char *, lines, lineCapacity); FREE_ARRAY(char *, lines, lineCapacity);
if (valid) { if (valid) {
KrkValue result = krk_interpret(allData, "<stdin>"); KrkValue result = krk_interpret(_thread, allData, "<stdin>");
if (!IS_NONE(result)) { if (!IS_NONE(result)) {
KrkClass * type = krk_getType(result); KrkClass * type = krk_getType(result);
const char * formatStr = " \033[1;30m=> %s\033[0m\n"; 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) { } else if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) {
krk_dumpTraceback(); krk_dumpTraceback();
} }
krk_resetStack(); krk_resetStack(_thread);
free(allData); free(allData);
} }