Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
437d3d9e05 |
@ -10,7 +10,7 @@
|
||||
FUNC_SIG(list,__init__);
|
||||
FUNC_SIG(list,sort);
|
||||
|
||||
KrkValue krk_dirObject(int argc, const KrkValue argv[], int hasKw) {
|
||||
KrkValue krk_dirObject_r(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) {
|
||||
if (argc != 1)
|
||||
return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)",
|
||||
"dir", "exactly", 1, "", argc);
|
||||
@ -71,8 +71,8 @@ KrkValue krk_dirObject(int argc, const KrkValue argv[], int hasKw) {
|
||||
myList = krk_list_of(0,NULL,0);
|
||||
krk_push(myList);
|
||||
krk_swap(1);
|
||||
FUNC_NAME(list,__init__)(2,(KrkValue[]){krk_peek(1), krk_peek(0)},0);
|
||||
FUNC_NAME(list,sort)(1,(KrkValue[]){krk_peek(1)},0);
|
||||
FUNC_NAME(list,__init__)(_thread, 2,(KrkValue[]){krk_peek(1), krk_peek(0)},0);
|
||||
FUNC_NAME(list,sort)(_thread, 1,(KrkValue[]){krk_peek(1)},0);
|
||||
krk_pop();
|
||||
|
||||
return krk_pop();
|
||||
@ -169,7 +169,7 @@ KRK_Method(object,__setattr__) {
|
||||
if (!IS_STRING(argv[1])) return krk_runtimeError(vm.exceptions->typeError, "expected str");
|
||||
|
||||
if (!IS_INSTANCE(argv[0])) {
|
||||
return FUNC_NAME(krk,setattr)(argc,argv,hasKw);
|
||||
return FUNC_NAME(krk,setattr)(_thread, argc,argv,hasKw);
|
||||
}
|
||||
|
||||
/* It's an instance, that presumably does not have a `__setattr__`? */
|
||||
@ -271,7 +271,7 @@ KRK_Function(dir) {
|
||||
}
|
||||
|
||||
/* Now sort it */
|
||||
FUNC_NAME(list,sort)(1,(KrkValue[]){krk_peek(0)},0);
|
||||
FUNC_NAME(list,sort)(_thread, 1,(KrkValue[]){krk_peek(0)},0);
|
||||
return krk_pop(); /* Return the list */
|
||||
}
|
||||
}
|
||||
@ -332,24 +332,24 @@ KRK_Function(bin) {
|
||||
((string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) == (KRK_OBJ_FLAGS_STRING_UCS2) ? ((uint16_t*)string->codes)[offset] : \
|
||||
((uint32_t*)string->codes)[offset]))
|
||||
|
||||
int krk_unpackIterable(KrkValue iterable, void * context, int callback(void *, const KrkValue *, size_t)) {
|
||||
int krk_unpackIterable_r(KrkThreadState * _thread, KrkValue iterable, void * context, int callback(KrkThreadState *, void *, const KrkValue *, size_t)) {
|
||||
if (IS_TUPLE(iterable)) {
|
||||
if (callback(context, AS_TUPLE(iterable)->values.values, AS_TUPLE(iterable)->values.count)) return 1;
|
||||
if (callback(_thread, context, AS_TUPLE(iterable)->values.values, AS_TUPLE(iterable)->values.count)) return 1;
|
||||
} else if (IS_list(iterable)) {
|
||||
if (callback(context, AS_LIST(iterable)->values, AS_LIST(iterable)->count)) return 1;
|
||||
if (callback(_thread, context, AS_LIST(iterable)->values, AS_LIST(iterable)->count)) return 1;
|
||||
} else if (IS_dict(iterable)) {
|
||||
for (size_t i = 0; i < AS_DICT(iterable)->capacity; ++i) {
|
||||
if (!IS_KWARGS(AS_DICT(iterable)->entries[i].key)) {
|
||||
if (callback(context, &AS_DICT(iterable)->entries[i].key, 1)) return 1;
|
||||
if (callback(_thread, context, &AS_DICT(iterable)->entries[i].key, 1)) return 1;
|
||||
}
|
||||
}
|
||||
} else if (IS_STRING(iterable)) {
|
||||
krk_unicodeString(AS_STRING(iterable));
|
||||
for (size_t i = 0; i < AS_STRING(iterable)->codesLength; ++i) {
|
||||
KrkValue s = krk_string_get(2, (KrkValue[]){iterable,INTEGER_VAL(i)}, i);
|
||||
KrkValue s = krk_string_get(_thread, 2, (KrkValue[]){iterable,INTEGER_VAL(i)}, i);
|
||||
if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return 1;
|
||||
krk_push(s);
|
||||
if (callback(context, &s, 1)) {
|
||||
if (callback(_thread, context, &s, 1)) {
|
||||
krk_pop();
|
||||
return 1;
|
||||
}
|
||||
@ -385,7 +385,7 @@ int krk_unpackIterable(KrkValue iterable, void * context, int callback(void *, c
|
||||
}
|
||||
|
||||
krk_push(item);
|
||||
if (callback(context, &item, 1)) {
|
||||
if (callback(_thread, context, &item, 1)) {
|
||||
krk_pop(); /* item */
|
||||
krk_pop(); /* __iter__ */
|
||||
return 1;
|
||||
@ -402,7 +402,7 @@ struct SimpleContext {
|
||||
KrkValue base;
|
||||
};
|
||||
|
||||
static int _any_callback(void * context, const KrkValue * values, size_t count) {
|
||||
static int _any_callback(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) {
|
||||
struct SimpleContext * _context = context;
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
if (!krk_isFalsey(values[i])) {
|
||||
@ -420,7 +420,7 @@ KRK_Function(any) {
|
||||
return context.base;
|
||||
}
|
||||
|
||||
static int _all_callback(void * context, const KrkValue * values, size_t count) {
|
||||
static int _all_callback(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) {
|
||||
struct SimpleContext * _context = context;
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
if (krk_isFalsey(values[i])) {
|
||||
@ -655,7 +655,7 @@ KRK_Method(enumerate,__iter__) {
|
||||
return OBJECT_VAL(self);
|
||||
}
|
||||
|
||||
extern KrkValue krk_operator_add (KrkValue a, KrkValue b);
|
||||
extern KrkValue krk_operator_add_r (KrkThreadState *, KrkValue a, KrkValue b);
|
||||
KRK_Method(enumerate,__call__) {
|
||||
METHOD_TAKES_NONE();
|
||||
size_t stackOffset = krk_currentThread.stackTop - krk_currentThread.stack;
|
||||
@ -686,7 +686,7 @@ KRK_Method(enumerate,__call__) {
|
||||
tupleOut->values.values[tupleOut->values.count++] = counter;
|
||||
tupleOut->values.values[tupleOut->values.count++] = krk_pop();
|
||||
|
||||
krk_push(krk_operator_add(counter, INTEGER_VAL(1)));
|
||||
krk_push(krk_operator_add_r(_thread, counter, INTEGER_VAL(1)));
|
||||
krk_attachNamedValue(&self->fields, "_counter", krk_pop());
|
||||
|
||||
KrkValue out = krk_pop();
|
||||
@ -694,10 +694,10 @@ KRK_Method(enumerate,__call__) {
|
||||
return out;
|
||||
}
|
||||
|
||||
static int _sum_callback(void * context, const KrkValue * values, size_t count) {
|
||||
static int _sum_callback(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) {
|
||||
struct SimpleContext * _context = context;
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
_context->base = krk_operator_add(_context->base, values[i]);
|
||||
_context->base = krk_operator_add_r(_thread,_context->base, values[i]);
|
||||
if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return 1;
|
||||
}
|
||||
return 0;
|
||||
@ -714,7 +714,7 @@ KRK_Function(sum) {
|
||||
return context.base;
|
||||
}
|
||||
|
||||
static int _min_callback(void * context, const KrkValue * values, size_t count) {
|
||||
static int _min_callback(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) {
|
||||
struct SimpleContext * _context = context;
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
if (IS_KWARGS(_context->base)) _context->base = values[i];
|
||||
@ -731,7 +731,7 @@ KRK_Function(min) {
|
||||
FUNCTION_TAKES_AT_LEAST(1);
|
||||
struct SimpleContext context = { KWARGS_VAL(0) };
|
||||
if (argc > 1) {
|
||||
if (_min_callback(&context, argv, argc)) return NONE_VAL();
|
||||
if (_min_callback(_thread, &context, argv, argc)) return NONE_VAL();
|
||||
} else {
|
||||
if (krk_unpackIterable(argv[0], &context, _min_callback)) return NONE_VAL();
|
||||
}
|
||||
@ -739,7 +739,7 @@ KRK_Function(min) {
|
||||
return context.base;
|
||||
}
|
||||
|
||||
static int _max_callback(void * context, const KrkValue * values, size_t count) {
|
||||
static int _max_callback(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) {
|
||||
struct SimpleContext * _context = context;
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
if (IS_KWARGS(_context->base)) _context->base = values[i];
|
||||
@ -756,7 +756,7 @@ KRK_Function(max) {
|
||||
FUNCTION_TAKES_AT_LEAST(1);
|
||||
struct SimpleContext context = { KWARGS_VAL(0) };
|
||||
if (argc > 1) {
|
||||
if (_max_callback(&context, argv, argc)) return NONE_VAL();
|
||||
if (_max_callback(_thread, &context, argv, argc)) return NONE_VAL();
|
||||
} else {
|
||||
if (krk_unpackIterable(argv[0], &context, _max_callback)) return NONE_VAL();
|
||||
}
|
||||
@ -1131,7 +1131,7 @@ KRK_Function(format) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static void module_sweep(KrkInstance * inst) {
|
||||
static void module_sweep(KrkThreadState * _thread, KrkInstance * inst) {
|
||||
#ifndef STATIC_ONLY
|
||||
struct KrkModule * module = (struct KrkModule*)inst;
|
||||
if (module->libHandle) {
|
||||
@ -1141,7 +1141,7 @@ static void module_sweep(KrkInstance * inst) {
|
||||
}
|
||||
|
||||
_noexport
|
||||
void _createAndBind_builtins(void) {
|
||||
void _createAndBind_builtins(KrkThreadState *_thread) {
|
||||
vm.baseClasses->objectClass = krk_newClass(S("object"), NULL);
|
||||
krk_push(OBJECT_VAL(vm.baseClasses->objectClass));
|
||||
|
||||
|
18
src/chunk.c
18
src/chunk.c
@ -4,7 +4,7 @@
|
||||
|
||||
#include "opcode_enum.h"
|
||||
|
||||
void krk_initChunk(KrkChunk * chunk) {
|
||||
void krk_initChunk_r(struct KrkThreadState * _thread, KrkChunk * chunk) {
|
||||
chunk->count = 0;
|
||||
chunk->capacity = 0;
|
||||
chunk->code = NULL;
|
||||
@ -16,7 +16,7 @@ void krk_initChunk(KrkChunk * chunk) {
|
||||
krk_initValueArray(&chunk->constants);
|
||||
}
|
||||
|
||||
static void addLine(KrkChunk * chunk, size_t line) {
|
||||
static void addLine(struct KrkThreadState * _thread, KrkChunk * chunk, size_t line) {
|
||||
if (chunk->linesCount && chunk->lines[chunk->linesCount-1].line == line) return;
|
||||
if (chunk->linesCapacity < chunk->linesCount + 1) {
|
||||
int old = chunk->linesCapacity;
|
||||
@ -27,7 +27,7 @@ static void addLine(KrkChunk * chunk, size_t line) {
|
||||
chunk->linesCount++;
|
||||
}
|
||||
|
||||
void krk_writeChunk(KrkChunk * chunk, uint8_t byte, size_t line) {
|
||||
void krk_writeChunk_r(struct KrkThreadState * _thread, KrkChunk * chunk, uint8_t byte, size_t line) {
|
||||
if (chunk->capacity < chunk->count + 1) {
|
||||
int old = chunk->capacity;
|
||||
chunk->capacity = GROW_CAPACITY(old);
|
||||
@ -35,25 +35,25 @@ void krk_writeChunk(KrkChunk * chunk, uint8_t byte, size_t line) {
|
||||
}
|
||||
|
||||
chunk->code[chunk->count] = byte;
|
||||
addLine(chunk, line);
|
||||
addLine(_thread, chunk, line);
|
||||
chunk->count++;
|
||||
}
|
||||
|
||||
void krk_freeChunk(KrkChunk * chunk) {
|
||||
void krk_freeChunk_r(struct KrkThreadState * _thread, KrkChunk * chunk) {
|
||||
FREE_ARRAY(uint8_t, chunk->code, chunk->capacity);
|
||||
FREE_ARRAY(KrkLineMap, chunk->lines, chunk->linesCapacity);
|
||||
krk_freeValueArray(&chunk->constants);
|
||||
krk_initChunk(chunk);
|
||||
}
|
||||
|
||||
size_t krk_addConstant(KrkChunk * chunk, KrkValue value) {
|
||||
size_t krk_addConstant_r(struct KrkThreadState * _thread, KrkChunk * chunk, KrkValue value) {
|
||||
krk_push(value);
|
||||
krk_writeValueArray(&chunk->constants, value);
|
||||
krk_pop();
|
||||
return chunk->constants.count - 1;
|
||||
}
|
||||
|
||||
void krk_emitConstant(KrkChunk * chunk, size_t ind, size_t line) {
|
||||
void krk_emitConstant_r(struct KrkThreadState * _thread, KrkChunk * chunk, size_t ind, size_t line) {
|
||||
if (ind >= 256) {
|
||||
krk_writeChunk(chunk, OP_CONSTANT_LONG, line);
|
||||
krk_writeChunk(chunk, 0xFF & (ind >> 16), line);
|
||||
@ -65,13 +65,13 @@ void krk_emitConstant(KrkChunk * chunk, size_t ind, size_t line) {
|
||||
}
|
||||
}
|
||||
|
||||
size_t krk_writeConstant(KrkChunk * chunk, KrkValue value, size_t line) {
|
||||
size_t krk_writeConstant_r(struct KrkThreadState * _thread, KrkChunk * chunk, KrkValue value, size_t line) {
|
||||
size_t ind = krk_addConstant(chunk, value);
|
||||
krk_emitConstant(chunk, ind, line);
|
||||
return ind;
|
||||
}
|
||||
|
||||
size_t krk_lineNumber(KrkChunk * chunk, size_t offset) {
|
||||
size_t krk_lineNumber_r(struct KrkThreadState * _thread, KrkChunk * chunk, size_t offset) {
|
||||
size_t line = 0;
|
||||
for (size_t i = 0; i < chunk->linesCount; ++i) {
|
||||
if (chunk->lines[i].startOffset > offset) break;
|
||||
|
@ -278,9 +278,10 @@ typedef struct GlobalState {
|
||||
KrkScanner scanner;
|
||||
Compiler * current;
|
||||
ClassCompiler * currentClass;
|
||||
KrkThreadState * thread;
|
||||
} GlobalState;
|
||||
|
||||
static void _GlobalState_gcscan(KrkInstance * _self) {
|
||||
static void _GlobalState_gcscan(KrkThreadState * _thread, KrkInstance * _self) {
|
||||
struct GlobalState * self = (void*)_self;
|
||||
Compiler * compiler = self->current;
|
||||
while (compiler != NULL) {
|
||||
@ -290,10 +291,13 @@ static void _GlobalState_gcscan(KrkInstance * _self) {
|
||||
}
|
||||
}
|
||||
|
||||
static void _GlobalState_gcsweep(KrkInstance * _self) {
|
||||
static void _GlobalState_gcsweep(KrkThreadState * _thread, KrkInstance * _self) {
|
||||
/* nothing to do? */
|
||||
}
|
||||
|
||||
#undef _thread
|
||||
#define _thread (state->thread)
|
||||
|
||||
#define currentChunk() (&state->current->codeobject->chunk)
|
||||
|
||||
#define EMIT_OPERAND_OP(opc, arg) do { if (arg < 256) { emitBytes(opc, arg); } \
|
||||
@ -619,7 +623,7 @@ static KrkCodeObject * endCompiler(struct GlobalState * state) {
|
||||
return function;
|
||||
}
|
||||
|
||||
static void freeCompiler(Compiler * compiler) {
|
||||
static void freeCompiler(struct GlobalState * state, Compiler * compiler) {
|
||||
FREE_ARRAY(Local,compiler->locals, compiler->localsSpace);
|
||||
FREE_ARRAY(Upvalue,compiler->upvalues, compiler->upvaluesSpace);
|
||||
FREE_ARRAY(struct LoopExit,compiler->breaks, compiler->breakSpace);
|
||||
@ -1414,7 +1418,7 @@ static void functionPrologue(struct GlobalState * state, Compiler * compiler) {
|
||||
if (compiler->annotationCount) {
|
||||
emitByte(OP_ANNOTATE);
|
||||
}
|
||||
freeCompiler(compiler);
|
||||
freeCompiler(state, compiler);
|
||||
}
|
||||
|
||||
static int argumentList(struct GlobalState * state, FunctionType type) {
|
||||
@ -1704,7 +1708,7 @@ _pop_class:
|
||||
size_t indFunc = krk_addConstant(currentChunk(), OBJECT_VAL(makeclass));
|
||||
EMIT_OPERAND_OP(OP_CLOSURE, indFunc);
|
||||
doUpvalues(state, &subcompiler, makeclass);
|
||||
freeCompiler(&subcompiler);
|
||||
freeCompiler(state, &subcompiler);
|
||||
emitBytes(OP_CALL, 0);
|
||||
|
||||
return classCompiler.name;
|
||||
@ -3115,7 +3119,7 @@ static void generatorExpression(struct GlobalState * state, KrkScanner scannerBe
|
||||
size_t indFunc = krk_addConstant(currentChunk(), OBJECT_VAL(subfunction));
|
||||
EMIT_OPERAND_OP(OP_CLOSURE, indFunc);
|
||||
doUpvalues(state, &subcompiler, subfunction);
|
||||
freeCompiler(&subcompiler);
|
||||
freeCompiler(state, &subcompiler);
|
||||
emitBytes(OP_CALL, 0);
|
||||
}
|
||||
|
||||
@ -3150,7 +3154,7 @@ static void comprehensionExpression(struct GlobalState * state, KrkScanner scann
|
||||
size_t indFunc = krk_addConstant(currentChunk(), OBJECT_VAL(subfunction));
|
||||
EMIT_OPERAND_OP(OP_CLOSURE, indFunc);
|
||||
doUpvalues(state, &subcompiler, subfunction);
|
||||
freeCompiler(&subcompiler);
|
||||
freeCompiler(state, &subcompiler);
|
||||
emitBytes(OP_CALL, 0);
|
||||
}
|
||||
|
||||
@ -3732,22 +3736,23 @@ static int maybeSingleExpression(struct GlobalState * state) {
|
||||
* @return A compiled code object, or NULL on error.
|
||||
* @exception SyntaxError if @p src could not be compiled.
|
||||
*/
|
||||
KrkCodeObject * krk_compile(const char * src, char * fileName) {
|
||||
KrkCodeObject * krk_compile(KrkThreadState * base_thread, const char * src, char * fileName) {
|
||||
|
||||
KrkClass * GlobalState = krk_newClass(S("GlobalState"), KRK_BASE_CLASS(object));
|
||||
krk_push(OBJECT_VAL(GlobalState));
|
||||
KrkClass * GlobalState = krk_newClass_r(base_thread, krk_copyString_r(base_thread, "GlobalState", 11), base_thread->owner->baseClasses->objectClass);
|
||||
krk_push_r(base_thread, OBJECT_VAL(GlobalState));
|
||||
|
||||
GlobalState->allocSize = sizeof(struct GlobalState);
|
||||
GlobalState->_ongcscan = _GlobalState_gcscan;
|
||||
GlobalState->_ongcsweep = _GlobalState_gcsweep;
|
||||
GlobalState->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
|
||||
krk_finalizeClass(GlobalState);
|
||||
krk_finalizeClass_r(base_thread, GlobalState);
|
||||
|
||||
struct GlobalState * state = (void*)krk_newInstance(GlobalState);
|
||||
krk_push(OBJECT_VAL(state));
|
||||
struct GlobalState * state = (void*)krk_newInstance_r(base_thread, GlobalState);
|
||||
krk_push_r(base_thread, OBJECT_VAL(state));
|
||||
|
||||
/* Point a new scanner at the source. */
|
||||
state->scanner = krk_initScanner(src);
|
||||
state->thread = base_thread;
|
||||
|
||||
/* Reset parser state. */
|
||||
memset(&state->parser, 0, sizeof(state->parser));
|
||||
@ -3777,7 +3782,7 @@ KrkCodeObject * krk_compile(const char * src, char * fileName) {
|
||||
}
|
||||
|
||||
KrkCodeObject * function = endCompiler(state);
|
||||
freeCompiler(&compiler);
|
||||
freeCompiler(state, &compiler);
|
||||
|
||||
/*
|
||||
* We'll always get something out of endCompiler even if it
|
||||
|
44
src/debug.c
44
src/debug.c
@ -18,7 +18,7 @@
|
||||
* the VM will never be called to produce a string, which would result in
|
||||
* a nasty infinite recursion if we did it while trying to trace the VM!
|
||||
*/
|
||||
void krk_debug_dumpStack(FILE * file, KrkCallFrame * frame) {
|
||||
void krk_debug_dumpStack_r(struct KrkThreadState * _thread, FILE * file, KrkCallFrame * frame) {
|
||||
size_t i = 0;
|
||||
if (!frame) frame = &krk_currentThread.frames[krk_currentThread.frameCount-1];
|
||||
for (KrkValue * slot = krk_currentThread.stack; slot < krk_currentThread.stackTop; slot++) {
|
||||
@ -64,7 +64,7 @@ void krk_debug_dumpStack(FILE * file, KrkCallFrame * frame) {
|
||||
}
|
||||
|
||||
|
||||
void krk_disassembleCodeObject(FILE * f, KrkCodeObject * func, const char * name) {
|
||||
void krk_disassembleCodeObject_r(struct KrkThreadState * _thread, FILE * f, KrkCodeObject * func, const char * name) {
|
||||
KrkChunk * chunk = &func->chunk;
|
||||
/* Function header */
|
||||
fprintf(f, "<%s(", name);
|
||||
@ -93,7 +93,7 @@ static inline const char * opcodeClean(const char * opc) {
|
||||
return &opc[3];
|
||||
}
|
||||
|
||||
static int isJumpTarget(KrkCodeObject * func, size_t startPoint) {
|
||||
static int isJumpTarget(KrkThreadState * _thread, KrkCodeObject * func, size_t startPoint) {
|
||||
KrkChunk * chunk = &func->chunk;
|
||||
size_t offset = 0;
|
||||
|
||||
@ -211,7 +211,7 @@ static int isJumpTarget(KrkCodeObject * func, size_t startPoint) {
|
||||
} \
|
||||
}
|
||||
|
||||
size_t krk_disassembleInstruction(FILE * f, KrkCodeObject * func, size_t offset) {
|
||||
size_t krk_disassembleInstruction_r(struct KrkThreadState * _thread, FILE * f, KrkCodeObject * func, size_t offset) {
|
||||
KrkChunk * chunk = &func->chunk;
|
||||
if (offset > 0 && krk_lineNumber(chunk, offset) == krk_lineNumber(chunk, offset - 1)) {
|
||||
fprintf(f, " ");
|
||||
@ -219,7 +219,7 @@ size_t krk_disassembleInstruction(FILE * f, KrkCodeObject * func, size_t offset)
|
||||
if (offset > 0) fprintf(f,"\n");
|
||||
fprintf(f, "%4d ", (int)krk_lineNumber(chunk, offset));
|
||||
}
|
||||
if (isJumpTarget(func,offset)) {
|
||||
if (isJumpTarget(_thread, func,offset)) {
|
||||
fprintf(f, " >> ");
|
||||
} else {
|
||||
fprintf(f, " ");
|
||||
@ -284,7 +284,7 @@ struct DebuggerState {
|
||||
struct BreakpointEntry breakpoints[MAX_BREAKPOINTS];
|
||||
};
|
||||
|
||||
int krk_debug_addBreakpointCodeOffset(KrkCodeObject * target, size_t offset, int flags) {
|
||||
int krk_debug_addBreakpointCodeOffset_r(struct KrkThreadState * _thread, KrkCodeObject * target, size_t offset, int flags) {
|
||||
int index = vm.dbgState->breakpointsCount;
|
||||
if (vm.dbgState->breakpointsCount == MAX_BREAKPOINTS) {
|
||||
/* See if any are available */
|
||||
@ -310,7 +310,7 @@ int krk_debug_addBreakpointCodeOffset(KrkCodeObject * target, size_t offset, int
|
||||
return index;
|
||||
}
|
||||
|
||||
int krk_debug_addBreakpointFileLine(KrkString * filename, size_t line, int flags) {
|
||||
int krk_debug_addBreakpointFileLine_r(struct KrkThreadState * _thread, KrkString * filename, size_t line, int flags) {
|
||||
|
||||
KrkCodeObject * target = NULL;
|
||||
|
||||
@ -350,7 +350,7 @@ int krk_debug_addBreakpointFileLine(KrkString * filename, size_t line, int flags
|
||||
return krk_debug_addBreakpointCodeOffset(target, offset, flags);
|
||||
}
|
||||
|
||||
int krk_debug_enableBreakpoint(int breakIndex) {
|
||||
int krk_debug_enableBreakpoint_r(struct KrkThreadState * _thread, int breakIndex) {
|
||||
if (breakIndex < 0 || breakIndex >= vm.dbgState->breakpointsCount || vm.dbgState->breakpoints[breakIndex].inFunction == NULL)
|
||||
return 1;
|
||||
vm.dbgState->breakpoints[breakIndex].inFunction->chunk.code[vm.dbgState->breakpoints[breakIndex].offset] = OP_BREAKPOINT;
|
||||
@ -363,7 +363,7 @@ KRK_Function(enablebreakpoint) {
|
||||
return NONE_VAL();
|
||||
}
|
||||
|
||||
int krk_debug_disableBreakpoint(int breakIndex) {
|
||||
int krk_debug_disableBreakpoint_r(struct KrkThreadState * _thread, int breakIndex) {
|
||||
if (breakIndex < 0 || breakIndex >= vm.dbgState->breakpointsCount || vm.dbgState->breakpoints[breakIndex].inFunction == NULL)
|
||||
return 1;
|
||||
vm.dbgState->breakpoints[breakIndex].inFunction->chunk.code[vm.dbgState->breakpoints[breakIndex].offset] =
|
||||
@ -380,7 +380,7 @@ KRK_Function(disablebreakpoint) {
|
||||
return NONE_VAL();
|
||||
}
|
||||
|
||||
int krk_debug_removeBreakpoint(int breakIndex) {
|
||||
int krk_debug_removeBreakpoint_r(struct KrkThreadState * _thread, int breakIndex) {
|
||||
if (breakIndex < 0 || breakIndex >= vm.dbgState->breakpointsCount || vm.dbgState->breakpoints[breakIndex].inFunction == NULL)
|
||||
return 1;
|
||||
krk_debug_disableBreakpoint(breakIndex);
|
||||
@ -459,7 +459,7 @@ KRK_Function(addbreakpoint) {
|
||||
* we clear the debugging bits. Then we make a new exception
|
||||
* to attach a traceback to.
|
||||
*/
|
||||
void krk_debug_dumpTraceback(void) {
|
||||
void krk_debug_dumpTraceback_r(struct KrkThreadState * _thread) {
|
||||
int flagsBefore = krk_currentThread.flags;
|
||||
krk_debug_disableSingleStep();
|
||||
krk_push(krk_currentThread.currentException);
|
||||
@ -471,15 +471,15 @@ void krk_debug_dumpTraceback(void) {
|
||||
krk_currentThread.flags = flagsBefore;
|
||||
}
|
||||
|
||||
void krk_debug_enableSingleStep(void) {
|
||||
void krk_debug_enableSingleStep_r(struct KrkThreadState * _thread) {
|
||||
krk_currentThread.flags |= KRK_THREAD_SINGLE_STEP;
|
||||
}
|
||||
|
||||
void krk_debug_disableSingleStep(void) {
|
||||
void krk_debug_disableSingleStep_r(struct KrkThreadState * _thread) {
|
||||
krk_currentThread.flags &= ~(KRK_THREAD_SINGLE_STEP);
|
||||
}
|
||||
|
||||
int krk_debuggerHook(KrkCallFrame * frame) {
|
||||
int krk_debuggerHook_r(struct KrkThreadState * _thread, KrkCallFrame * frame) {
|
||||
if (!vm.dbgState->debuggerHook)
|
||||
abort();
|
||||
|
||||
@ -492,7 +492,7 @@ int krk_debuggerHook(KrkCallFrame * frame) {
|
||||
vm.dbgState->repeatStack_bottom = -1;
|
||||
|
||||
if (!vm.dbgState->thisWasForced) {
|
||||
int result = vm.dbgState->debuggerHook(frame);
|
||||
int result = vm.dbgState->debuggerHook(_thread,frame);
|
||||
switch (result) {
|
||||
case KRK_DEBUGGER_CONTINUE:
|
||||
krk_debug_disableSingleStep();
|
||||
@ -525,13 +525,13 @@ int krk_debuggerHook(KrkCallFrame * frame) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int krk_debug_registerCallback(KrkDebugCallback hook) {
|
||||
int krk_debug_registerCallback_r(struct KrkThreadState * _thread, KrkDebugCallback hook) {
|
||||
if (vm.dbgState->debuggerHook) return 1;
|
||||
vm.dbgState->debuggerHook = hook;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int krk_debug_examineBreakpoint(int breakIndex, KrkCodeObject ** funcOut, size_t * offsetOut, int * flagsOut, int * enabled) {
|
||||
int krk_debug_examineBreakpoint_r(struct KrkThreadState * _thread, int breakIndex, KrkCodeObject ** funcOut, size_t * offsetOut, int * flagsOut, int * enabled) {
|
||||
if (breakIndex < 0 || breakIndex >= vm.dbgState->breakpointsCount)
|
||||
return -1;
|
||||
if (vm.dbgState->breakpoints[breakIndex].inFunction == NULL)
|
||||
@ -545,7 +545,7 @@ int krk_debug_examineBreakpoint(int breakIndex, KrkCodeObject ** funcOut, size_t
|
||||
return 0;
|
||||
}
|
||||
|
||||
int krk_debugBreakpointHandler(void) {
|
||||
int krk_debugBreakpointHandler_r(struct KrkThreadState * _thread) {
|
||||
int index = -1;
|
||||
|
||||
KrkCallFrame * frame = &krk_currentThread.frames[krk_currentThread.frameCount-1];
|
||||
@ -633,7 +633,7 @@ KRK_Function(build) {
|
||||
krk_push(OBJECT_VAL(krk_currentThread.module));
|
||||
KrkInstance * module = krk_currentThread.module;
|
||||
krk_currentThread.module = NULL;
|
||||
KrkCodeObject * c = krk_compile(code->chars,fileName);
|
||||
KrkCodeObject * c = krk_compile(_thread, code->chars,fileName);
|
||||
krk_currentThread.module = module;
|
||||
krk_pop();
|
||||
if (c) return OBJECT_VAL(c);
|
||||
@ -663,7 +663,7 @@ KRK_Function(build) {
|
||||
#define EXPAND_ARGS_MORE
|
||||
#define FORMAT_VALUE_MORE
|
||||
#define LOCAL_MORE local = operand;
|
||||
static KrkValue _examineInternal(KrkCodeObject* func) {
|
||||
static KrkValue _examineInternal(KrkThreadState * _thread, KrkCodeObject* func) {
|
||||
KrkValue output = krk_list_of(0,NULL,0);
|
||||
krk_push(output);
|
||||
|
||||
@ -722,7 +722,7 @@ static KrkValue _examineInternal(KrkCodeObject* func) {
|
||||
KRK_Function(examine) {
|
||||
FUNCTION_TAKES_EXACTLY(1);
|
||||
CHECK_ARG(0,codeobject,KrkCodeObject*,func);
|
||||
return _examineInternal(func);
|
||||
return _examineInternal(_thread, func);
|
||||
}
|
||||
|
||||
#undef SIMPLE
|
||||
@ -735,7 +735,7 @@ KRK_Function(examine) {
|
||||
#undef EXPAND_ARGS_MORE
|
||||
#undef FORMAT_VALUE_MORE
|
||||
|
||||
void krk_module_init_dis(void) {
|
||||
void krk_module_init_dis(struct KrkThreadState * _thread) {
|
||||
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
|
||||
krk_attachNamedObject(&vm.modules, "dis", (KrkObj*)module);
|
||||
krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("dis"));
|
||||
|
@ -108,7 +108,7 @@ KRK_Method(KeyError,__str__) {
|
||||
return krk_callDirect(krk_getType(arg)->_reprer, 1);
|
||||
}
|
||||
}
|
||||
return FUNC_NAME(Exception,__str__)(argc,argv,hasKw);
|
||||
return FUNC_NAME(Exception,__str__)(_thread, argc,argv,hasKw);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -159,7 +159,7 @@ KRK_Method(SyntaxError,__str__) {
|
||||
} else {
|
||||
krk_push(OBJECT_VAL(S("")));
|
||||
}
|
||||
KrkValue formattedString = krk_string_format(9,
|
||||
KrkValue formattedString = krk_string_format(_thread, 9,
|
||||
(KrkValue[]){krk_peek(3), file, lineno, krk_peek(0), line, krk_peek(2), krk_peek(4), krk_peek(1), arg}, 0);
|
||||
krk_pop(); /* instr */
|
||||
krk_pop(); /* class */
|
||||
@ -181,7 +181,7 @@ _badSyntaxError:
|
||||
* and bind the native methods for exception objects.
|
||||
*/
|
||||
_noexport
|
||||
void _createAndBind_exceptions(void) {
|
||||
void _createAndBind_exceptions(KrkThreadState * _thread) {
|
||||
/* Add exception classes */
|
||||
ADD_EXCEPTION_CLASS(vm.exceptions->baseException, Exception, vm.baseClasses->objectClass);
|
||||
BIND_METHOD(Exception,__init__);
|
||||
@ -211,7 +211,7 @@ void _createAndBind_exceptions(void) {
|
||||
krk_finalizeClass(SyntaxError);
|
||||
}
|
||||
|
||||
static void dumpInnerException(KrkValue exception, int depth) {
|
||||
static void dumpInnerException(KrkThreadState * _thread, KrkValue exception, int depth) {
|
||||
if (depth > 10) {
|
||||
fprintf(stderr, "Too many inner exceptions encountered.\n");
|
||||
return;
|
||||
@ -224,10 +224,10 @@ static void dumpInnerException(KrkValue exception, int depth) {
|
||||
|
||||
/* Print cause or context */
|
||||
if (krk_tableGet(&AS_INSTANCE(exception)->fields, OBJECT_VAL(S("__cause__")), &inner) && !IS_NONE(inner)) {
|
||||
dumpInnerException(inner, depth + 1);
|
||||
dumpInnerException(_thread, inner, depth + 1);
|
||||
fprintf(stderr, "\nThe above exception was the direct cause of the following exception:\n\n");
|
||||
} else if (krk_tableGet(&AS_INSTANCE(exception)->fields, OBJECT_VAL(S("__context__")), &inner) && !IS_NONE(inner)) {
|
||||
dumpInnerException(inner, depth + 1);
|
||||
dumpInnerException(_thread, inner, depth + 1);
|
||||
fprintf(stderr, "\nDuring handling of the above exception, another exception occurred:\n\n");
|
||||
}
|
||||
|
||||
@ -335,16 +335,16 @@ static void dumpInnerException(KrkValue exception, int depth) {
|
||||
* and then move inwards; on each call frame we try to open
|
||||
* the source file and print the corresponding line.
|
||||
*/
|
||||
void krk_dumpTraceback(void) {
|
||||
void krk_dumpTraceback_r(KrkThreadState * _thread) {
|
||||
if (!krk_valuesEqual(krk_currentThread.currentException,NONE_VAL())) {
|
||||
dumpInnerException(krk_currentThread.currentException, 0);
|
||||
dumpInnerException(_thread, krk_currentThread.currentException, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach a traceback to the current exception object, if it doesn't already have one.
|
||||
*/
|
||||
static void attachTraceback(void) {
|
||||
static void attachTraceback(KrkThreadState * _thread) {
|
||||
if (IS_INSTANCE(krk_currentThread.currentException)) {
|
||||
KrkInstance * theException = AS_INSTANCE(krk_currentThread.currentException);
|
||||
KrkValue tracebackList;
|
||||
@ -392,7 +392,7 @@ static void attachTraceback(void) {
|
||||
} /* else: probably a legacy 'raise str', just don't bother. */
|
||||
}
|
||||
|
||||
void krk_attachInnerException(KrkValue innerException) {
|
||||
void krk_attachInnerException_r(KrkThreadState * _thread, KrkValue innerException) {
|
||||
if (IS_INSTANCE(krk_currentThread.currentException)) {
|
||||
KrkInstance * theException = AS_INSTANCE(krk_currentThread.currentException);
|
||||
if (krk_valuesSame(krk_currentThread.currentException,innerException)) {
|
||||
@ -404,7 +404,7 @@ void krk_attachInnerException(KrkValue innerException) {
|
||||
}
|
||||
}
|
||||
|
||||
void krk_raiseException(KrkValue base, KrkValue cause) {
|
||||
void krk_raiseException_r(KrkThreadState * _thread, KrkValue base, KrkValue cause) {
|
||||
if (IS_CLASS(base)) {
|
||||
krk_push(base);
|
||||
base = krk_callStack(0);
|
||||
@ -418,7 +418,7 @@ void krk_raiseException(KrkValue base, KrkValue cause) {
|
||||
krk_attachNamedValue(&AS_INSTANCE(krk_currentThread.currentException)->fields,
|
||||
"__cause__", cause);
|
||||
}
|
||||
attachTraceback();
|
||||
attachTraceback(_thread);
|
||||
krk_currentThread.flags |= KRK_THREAD_HAS_EXCEPTION;
|
||||
}
|
||||
|
||||
@ -427,7 +427,7 @@ void krk_raiseException(KrkValue base, KrkValue cause) {
|
||||
* and formats a message string to attach to it. Exception classes are
|
||||
* found in vm.exceptions and are initialized on startup.
|
||||
*/
|
||||
KrkValue krk_runtimeError(KrkClass * type, const char * fmt, ...) {
|
||||
KrkValue krk_runtimeError_r(KrkThreadState * _thread, KrkClass * type, const char * fmt, ...) {
|
||||
KrkValue msg = KWARGS_VAL(0);
|
||||
struct StringBuilder sb = {0};
|
||||
|
||||
@ -568,6 +568,6 @@ _finish:
|
||||
|
||||
/* Set the current exception to be picked up by handleException */
|
||||
krk_currentThread.currentException = OBJECT_VAL(exceptionObject);
|
||||
attachTraceback();
|
||||
attachTraceback(_thread);
|
||||
return NONE_VAL();
|
||||
}
|
||||
|
22
src/fileio.c
22
src/fileio.c
@ -156,7 +156,7 @@ KRK_Method(File,readlines) {
|
||||
krk_push(myList);
|
||||
|
||||
for (;;) {
|
||||
KrkValue line = FUNC_NAME(File,readline)(1, argv, 0);
|
||||
KrkValue line = FUNC_NAME(File,readline)(_thread, 1, argv, 0);
|
||||
if (IS_NONE(line)) break;
|
||||
if (krk_currentThread.flags & KRK_THREAD_SIGNALLED) break;
|
||||
|
||||
@ -259,10 +259,10 @@ KRK_Method(File,__enter__) {
|
||||
return NONE_VAL();
|
||||
}
|
||||
KRK_Method(File,__exit__) {
|
||||
return FUNC_NAME(File,close)(1,argv,0);
|
||||
return FUNC_NAME(File,close)(_thread, 1,argv,0);
|
||||
}
|
||||
|
||||
static void makeFileInstance(KrkInstance * module, const char name[], FILE * file) {
|
||||
static void makeFileInstance(KrkThreadState * _thread, KrkInstance * module, const char name[], FILE * file) {
|
||||
KrkInstance * fileObject = krk_newInstance(KRK_BASE_CLASS(File));
|
||||
krk_push(OBJECT_VAL(fileObject));
|
||||
KrkValue filename = OBJECT_VAL(krk_copyString(name,strlen(name)));
|
||||
@ -327,7 +327,7 @@ KRK_Method(BinaryFile,readlines) {
|
||||
krk_push(myList);
|
||||
|
||||
for (;;) {
|
||||
KrkValue line = FUNC_NAME(BinaryFile,readline)(1, argv, 0);
|
||||
KrkValue line = FUNC_NAME(BinaryFile,readline)(_thread, 1, argv, 0);
|
||||
if (IS_NONE(line)) break;
|
||||
if (krk_currentThread.flags & KRK_THREAD_SIGNALLED) break;
|
||||
|
||||
@ -410,7 +410,7 @@ KRK_Method(BinaryFile,write) {
|
||||
|
||||
#undef CURRENT_CTYPE
|
||||
|
||||
static void _file_sweep(KrkInstance * self) {
|
||||
static void _file_sweep(KrkThreadState * _thread, KrkInstance * self) {
|
||||
struct File * me = (void *)self;
|
||||
if (me->filePtr && !me->unowned) {
|
||||
fclose(me->filePtr);
|
||||
@ -418,7 +418,7 @@ static void _file_sweep(KrkInstance * self) {
|
||||
}
|
||||
}
|
||||
|
||||
static void _dir_sweep(KrkInstance * self) {
|
||||
static void _dir_sweep(KrkThreadState * _thread, KrkInstance * self) {
|
||||
struct Directory * me = (void *)self;
|
||||
if (me->dirPtr) {
|
||||
closedir(me->dirPtr);
|
||||
@ -491,10 +491,10 @@ KRK_Method(Directory,__enter__) {
|
||||
return NONE_VAL();
|
||||
}
|
||||
KRK_Method(Directory,__exit__) {
|
||||
return FUNC_NAME(Directory,close)(1,argv,0);
|
||||
return FUNC_NAME(Directory,close)(_thread, 1,argv,0);
|
||||
}
|
||||
|
||||
void krk_module_init_fileio(void) {
|
||||
void krk_module_init_fileio(KrkThreadState * _thread) {
|
||||
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
|
||||
krk_attachNamedObject(&vm.modules, "fileio", (KrkObj*)module);
|
||||
krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("fileio"));
|
||||
@ -558,9 +558,9 @@ void krk_module_init_fileio(void) {
|
||||
krk_finalizeClass(Directory);
|
||||
|
||||
/* Make an instance for stdout, stderr, and stdin */
|
||||
makeFileInstance(module, "stdin", stdin);
|
||||
makeFileInstance(module, "stdout", stdout);
|
||||
makeFileInstance(module, "stderr", stderr);
|
||||
makeFileInstance(_thread, module, "stdin", stdin);
|
||||
makeFileInstance(_thread, module, "stdout", stdout);
|
||||
makeFileInstance(_thread, module, "stderr", stderr);
|
||||
|
||||
/* Our base will be the open method */
|
||||
KRK_DOC(BIND_FUNC(module,open), "@brief Open a file.\n"
|
||||
|
79
src/kuroko.c
79
src/kuroko.c
@ -35,6 +35,7 @@
|
||||
|
||||
#define CALLGRIND_TMP_FILE "/tmp/kuroko.callgrind.tmp"
|
||||
|
||||
static KrkThreadState * _global_thread = NULL;
|
||||
static int enableRline = 1;
|
||||
static int exitRepl = 0;
|
||||
static int pasteEnabled = 0;
|
||||
@ -66,7 +67,7 @@ static int doRead(char * buf, size_t bufSize) {
|
||||
return read(STDIN_FILENO, buf, bufSize);
|
||||
}
|
||||
|
||||
static KrkValue readLine(char * prompt, int promptWidth, char * syntaxHighlighter) {
|
||||
static KrkValue readLine(KrkThreadState * _thread, char * prompt, int promptWidth, char * syntaxHighlighter) {
|
||||
struct StringBuilder sb = {0};
|
||||
|
||||
#ifndef NO_RLINE
|
||||
@ -144,7 +145,7 @@ KRK_Function(input) {
|
||||
}
|
||||
}
|
||||
|
||||
return readLine(prompt, promptLength, syntaxHighlighter);
|
||||
return readLine(_thread, prompt, promptLength, syntaxHighlighter);
|
||||
}
|
||||
|
||||
#ifndef NO_RLINE
|
||||
@ -156,7 +157,7 @@ KRK_Function(input) {
|
||||
* We can probably also use valueGetProperty which does correct binding
|
||||
* for native dynamic fields...
|
||||
*/
|
||||
static KrkValue findFromProperty(KrkValue current, KrkToken next) {
|
||||
static KrkValue findFromProperty(KrkThreadState * _thread, KrkValue current, KrkToken next) {
|
||||
KrkValue member = OBJECT_VAL(krk_copyString(next.start, next.literalWidth));
|
||||
krk_push(member);
|
||||
KrkValue value = krk_valueGetAttribute_default(current, AS_CSTRING(member), NONE_VAL());
|
||||
@ -174,6 +175,7 @@ static char * syn_krk_keywords[] = {
|
||||
};
|
||||
|
||||
static void tab_complete_func(rline_context_t * c) {
|
||||
KrkThreadState * _thread = _global_thread;
|
||||
/* Figure out where the cursor is and if we should be completing anything. */
|
||||
if (c->offset) {
|
||||
size_t stackIn = krk_currentThread.stackTop - krk_currentThread.stack;
|
||||
@ -224,7 +226,7 @@ static void tab_complete_func(rline_context_t * c) {
|
||||
int isGlobal = 1;
|
||||
while (n > base) {
|
||||
/* And look at the potential fields for instances/classes */
|
||||
KrkValue next = findFromProperty(root, space[count-n]);
|
||||
KrkValue next = findFromProperty(_thread, root, space[count-n]);
|
||||
if (IS_NONE(next)) {
|
||||
/* If we hit None, we found something invalid (or literally hit a None
|
||||
* object, but really the difference is minimal in this case: Nothing
|
||||
@ -274,7 +276,7 @@ static void tab_complete_func(rline_context_t * c) {
|
||||
KrkString * s = AS_STRING(AS_LIST(dirList)->values[i]);
|
||||
krk_push(OBJECT_VAL(s));
|
||||
KrkToken asToken = {.start = s->chars, .literalWidth = s->length};
|
||||
KrkValue thisValue = findFromProperty(root, asToken);
|
||||
KrkValue thisValue = findFromProperty(_thread, root, asToken);
|
||||
krk_push(thisValue);
|
||||
if (IS_CLOSURE(thisValue) || IS_BOUND_METHOD(thisValue) ||
|
||||
(IS_NATIVE(thisValue) && !((AS_OBJECT(thisValue)->flags & KRK_OBJ_FLAGS_FUNCTION_IS_DYNAMIC_PROPERTY)))) {
|
||||
@ -390,7 +392,7 @@ _cleanup:
|
||||
|
||||
#ifndef KRK_DISABLE_DEBUG
|
||||
static char * lastDebugCommand = NULL;
|
||||
static int debuggerHook(KrkCallFrame * frame) {
|
||||
static int debuggerHook(KrkThreadState *_thread,KrkCallFrame * frame) {
|
||||
|
||||
/* File information */
|
||||
fprintf(stderr, "At offset 0x%04lx of function '%s' from '%s' on line %lu:\n",
|
||||
@ -474,7 +476,7 @@ static int debuggerHook(KrkCallFrame * frame) {
|
||||
} else {
|
||||
size_t frameCount = krk_currentThread.frameCount;
|
||||
/* Compile statement */
|
||||
KrkCodeObject * expression = krk_compile(arg,"<debugger>");
|
||||
KrkCodeObject * expression = krk_compile(_thread, arg,"<debugger>");
|
||||
if (expression) {
|
||||
/* Make sure stepping is disabled first. */
|
||||
krk_debug_disableSingleStep();
|
||||
@ -640,6 +642,7 @@ _dbgQuit:
|
||||
#endif
|
||||
|
||||
static void handleSigint(int sigNum) {
|
||||
KrkThreadState * _thread = _global_thread;
|
||||
/* Don't set the signal flag if the VM is not running */
|
||||
if (!krk_currentThread.frameCount) return;
|
||||
krk_currentThread.flags |= KRK_THREAD_SIGNALLED;
|
||||
@ -647,6 +650,7 @@ static void handleSigint(int sigNum) {
|
||||
|
||||
#ifndef _WIN32
|
||||
static void handleSigtrap(int sigNum) {
|
||||
KrkThreadState * _thread = _global_thread;
|
||||
if (!krk_currentThread.frameCount) return;
|
||||
krk_currentThread.flags |= KRK_THREAD_SINGLE_STEP;
|
||||
}
|
||||
@ -680,9 +684,9 @@ static void bindSignalHandlers(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static void findInterpreter(char * argv[]) {
|
||||
static char * findInterpreter(char * argv[]) {
|
||||
#ifdef _WIN32
|
||||
vm.binpath = strdup(_pgmptr);
|
||||
return strdup(_pgmptr);
|
||||
#else
|
||||
/* Try asking /proc */
|
||||
char tmp[4096];
|
||||
@ -697,7 +701,7 @@ static void findInterpreter(char * argv[]) {
|
||||
} else {
|
||||
/* Search PATH for argv[0] */
|
||||
char * p = getenv("PATH");
|
||||
if (!p) return;
|
||||
if (!p) return NULL;
|
||||
char * _path = strdup(p);
|
||||
char * path = _path;
|
||||
while (path) {
|
||||
@ -714,25 +718,25 @@ static void findInterpreter(char * argv[]) {
|
||||
free(_path);
|
||||
}
|
||||
}
|
||||
if (binpath) {
|
||||
vm.binpath = binpath;
|
||||
} /* Else, give up at this point and just don't attach it at all. */
|
||||
return binpath;
|
||||
#endif
|
||||
}
|
||||
|
||||
extern KrkThreadState * krk_initVM_withBinpath(int flags, char * binpath);
|
||||
|
||||
static int runString(char * argv[], int flags, char * string) {
|
||||
findInterpreter(argv);
|
||||
krk_initVM(flags);
|
||||
char * path = findInterpreter(argv);
|
||||
KrkThreadState * _thread = krk_initVM_withBinpath(flags,path);
|
||||
krk_startModule("__main__");
|
||||
krk_attachNamedValue(&krk_currentThread.module->fields,"__doc__", NONE_VAL());
|
||||
krk_interpret(string, "<stdin>");
|
||||
krk_freeVM();
|
||||
krk_interpret(_thread, string, "<stdin>");
|
||||
krk_freeVM(_thread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int compileFile(char * argv[], int flags, char * fileName) {
|
||||
findInterpreter(argv);
|
||||
krk_initVM(flags);
|
||||
char * path = findInterpreter(argv);
|
||||
KrkThreadState * _thread = krk_initVM_withBinpath(flags,path);
|
||||
|
||||
/* Open the file. */
|
||||
FILE * f = fopen(fileName,"r");
|
||||
@ -754,7 +758,7 @@ static int compileFile(char * argv[], int flags, char * fileName) {
|
||||
krk_startModule("__main__");
|
||||
|
||||
/* Call the compiler directly. */
|
||||
KrkCodeObject * func = krk_compile(buf, fileName);
|
||||
KrkCodeObject * func = krk_compile(_thread, buf, fileName);
|
||||
|
||||
/* See if there was an exception. */
|
||||
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) {
|
||||
@ -765,7 +769,7 @@ static int compileFile(char * argv[], int flags, char * fileName) {
|
||||
free(buf);
|
||||
|
||||
/* Close out the compiler */
|
||||
krk_freeVM();
|
||||
krk_freeVM(_thread);
|
||||
|
||||
return func == NULL;
|
||||
}
|
||||
@ -791,6 +795,7 @@ int main(int argc, char * argv[]) {
|
||||
int inspectAfter = 0;
|
||||
int opt;
|
||||
int maxDepth = -1;
|
||||
FILE * callgrindFile = NULL;
|
||||
while ((opt = getopt(argc, argv, "+:c:C:dgGim:rR:stTMSV-:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
@ -820,7 +825,7 @@ int main(int argc, char * argv[]) {
|
||||
break;
|
||||
case 'T': {
|
||||
flags |= KRK_GLOBAL_CALLGRIND;
|
||||
vm.callgrindFile = fopen(CALLGRIND_TMP_FILE,"w");
|
||||
callgrindFile = fopen(CALLGRIND_TMP_FILE,"w");
|
||||
break;
|
||||
}
|
||||
case 'i':
|
||||
@ -890,9 +895,10 @@ int main(int argc, char * argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
_finishArgs:
|
||||
findInterpreter(argv);
|
||||
krk_initVM(flags);
|
||||
_finishArgs: (void)0;
|
||||
char * path = findInterpreter(argv);
|
||||
KrkThreadState * _thread = krk_initVM_withBinpath(flags,path);
|
||||
if (callgrindFile) _thread->owner->callgrindFile = callgrindFile;
|
||||
|
||||
if (maxDepth != -1) {
|
||||
krk_setMaximumRecursionDepth(maxDepth);
|
||||
@ -907,7 +913,7 @@ _finishArgs:
|
||||
for (int arg = optind; arg < argc; ++arg) {
|
||||
krk_push(OBJECT_VAL(krk_copyString(argv[arg],strlen(argv[arg]))));
|
||||
}
|
||||
KrkValue argList = krk_callNativeOnStack(argc - optind + (optind == argc), &krk_currentThread.stackTop[-(argc - optind + (optind == argc))], 0, krk_list_of);
|
||||
KrkValue argList = krk_callNativeOnStack(argc - optind + (optind == argc), &krk_currentThread.stackTop[-(argc - optind + (optind == argc))], 0, krk_list_of_r);
|
||||
krk_push(argList);
|
||||
krk_attachNamedValue(&vm.system->fields, "argv", argList);
|
||||
krk_pop();
|
||||
@ -933,7 +939,7 @@ _finishArgs:
|
||||
krk_push(OBJECT_VAL(S(":")));
|
||||
|
||||
/* Split into list */
|
||||
KrkValue list = krk_string_split(2,(KrkValue[]){krk_peek(1),krk_peek(0)},0);
|
||||
KrkValue list = krk_string_split(_thread, 2,(KrkValue[]){krk_peek(1),krk_peek(0)},0);
|
||||
krk_push(list);
|
||||
krk_swap(2);
|
||||
krk_pop(); /* colon */
|
||||
@ -943,7 +949,7 @@ _finishArgs:
|
||||
krk_push(krk_valueGetAttribute(OBJECT_VAL(vm.system), "module_paths"));
|
||||
|
||||
extern FUNC_SIG(list,extend);
|
||||
FUNC_NAME(list,extend)(2,(KrkValue[]){krk_peek(1),krk_peek(0)},0);
|
||||
FUNC_NAME(list,extend)(_thread,2,(KrkValue[]){krk_peek(1),krk_peek(0)},0);
|
||||
|
||||
/* Store */
|
||||
krk_attachNamedValue(&vm.system->fields, "module_paths", list);
|
||||
@ -978,7 +984,7 @@ _finishArgs:
|
||||
AS_STRING(krk_peek(0)));
|
||||
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) {
|
||||
krk_dumpTraceback();
|
||||
krk_resetStack();
|
||||
krk_resetStack(_thread);
|
||||
}
|
||||
if (!inspectAfter) return out;
|
||||
if (IS_INSTANCE(krk_peek(0))) {
|
||||
@ -986,7 +992,7 @@ _finishArgs:
|
||||
}
|
||||
} else if (optind != argc) {
|
||||
krk_startModule("__main__");
|
||||
result = krk_runfile(argv[optind],argv[optind]);
|
||||
result = krk_runfile(_thread, argv[optind],argv[optind]);
|
||||
if (IS_NONE(result) && krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) result = INTEGER_VAL(1);
|
||||
}
|
||||
|
||||
@ -998,7 +1004,7 @@ _finishArgs:
|
||||
}
|
||||
|
||||
if (runCmd) {
|
||||
result = krk_interpret(runCmd, "<stdin>");
|
||||
result = krk_interpret(_thread, runCmd, "<stdin>");
|
||||
}
|
||||
|
||||
if ((!moduleAsMain && !runCmd && optind == argc) || inspectAfter) {
|
||||
@ -1052,6 +1058,7 @@ _finishArgs:
|
||||
/* Enable syntax highlight for Kuroko */
|
||||
rline_exp_set_syntax("krk");
|
||||
/* Bind a callback for \t */
|
||||
_global_thread = _thread;
|
||||
rline_exp_set_tab_complete_func(tab_complete_func);
|
||||
#endif
|
||||
|
||||
@ -1187,7 +1194,7 @@ _finishArgs:
|
||||
FREE_ARRAY(char *, lines, lineCapacity);
|
||||
|
||||
if (valid) {
|
||||
KrkValue result = krk_interpret(allData, "<stdin>");
|
||||
KrkValue result = krk_interpret(_thread, allData, "<stdin>");
|
||||
if (!IS_NONE(result)) {
|
||||
krk_attachNamedValue(&vm.builtins->fields, "_", result);
|
||||
KrkClass * type = krk_getType(result);
|
||||
@ -1205,7 +1212,7 @@ _finishArgs:
|
||||
fprintf(stdout, formatStr, AS_CSTRING(result));
|
||||
}
|
||||
}
|
||||
krk_resetStack();
|
||||
krk_resetStack(_thread);
|
||||
free(allData);
|
||||
}
|
||||
|
||||
@ -1217,17 +1224,17 @@ _finishArgs:
|
||||
fclose(vm.callgrindFile);
|
||||
vm.globalFlags &= ~(KRK_GLOBAL_CALLGRIND);
|
||||
|
||||
krk_resetStack();
|
||||
krk_resetStack(_thread);
|
||||
krk_startModule("<callgrind>");
|
||||
krk_attachNamedObject(&krk_currentThread.module->fields, "filename", (KrkObj*)S(CALLGRIND_TMP_FILE));
|
||||
krk_interpret(
|
||||
krk_interpret(_thread,
|
||||
"from callgrind import processFile\n"
|
||||
"import kuroko\n"
|
||||
"import os\n"
|
||||
"processFile(filename, os.getpid(), ' '.join(kuroko.argv))","<callgrind>");
|
||||
}
|
||||
|
||||
krk_freeVM();
|
||||
krk_freeVM(_thread);
|
||||
|
||||
if (IS_INTEGER(result)) return AS_INTEGER(result);
|
||||
|
||||
|
@ -50,37 +50,43 @@ typedef struct {
|
||||
* @brief Initialize an opcode chunk.
|
||||
* @memberof KrkChunk
|
||||
*/
|
||||
extern void krk_initChunk(KrkChunk * chunk);
|
||||
extern void krk_initChunk_r(struct KrkThreadState * _thread, KrkChunk * chunk);
|
||||
#define krk_initChunk(c) krk_initChunk_r(_thread, c)
|
||||
|
||||
/**
|
||||
* @memberof KrkChunk
|
||||
* @brief Append a byte to an opcode chunk.
|
||||
*/
|
||||
extern void krk_writeChunk(KrkChunk * chunk, uint8_t byte, size_t line);
|
||||
extern void krk_writeChunk_r(struct KrkThreadState * _thread, KrkChunk * chunk, uint8_t byte, size_t line);
|
||||
#define krk_writeChunk(c,b,l) krk_writeChunk_r(_thread,c,b,l)
|
||||
|
||||
/**
|
||||
* @brief Release the resources allocated to an opcode chunk.
|
||||
* @memberof KrkChunk
|
||||
*/
|
||||
extern void krk_freeChunk(KrkChunk * chunk);
|
||||
extern void krk_freeChunk_r(struct KrkThreadState * _thread, KrkChunk * chunk);
|
||||
#define krk_freeChunk(c) krk_freeChunk_r(_thread,c)
|
||||
|
||||
/**
|
||||
* @brief Add a new constant value to an opcode chunk.
|
||||
* @memberof KrkChunk
|
||||
*/
|
||||
extern size_t krk_addConstant(KrkChunk * chunk, KrkValue value);
|
||||
extern size_t krk_addConstant_r(struct KrkThreadState * _thread, KrkChunk * chunk, KrkValue value);
|
||||
#define krk_addConstant(c,v) krk_addConstant_r(_thread,c,v)
|
||||
|
||||
/**
|
||||
* @brief Write an OP_CONSTANT(_LONG) instruction.
|
||||
* @memberof KrkChunk
|
||||
*/
|
||||
extern void krk_emitConstant(KrkChunk * chunk, size_t ind, size_t line);
|
||||
extern void krk_emitConstant_r(struct KrkThreadState * _thread, KrkChunk * chunk, size_t ind, size_t line);
|
||||
#define krk_emitConstant(c,i,l) krk_emitConstant_r(_thread,c,i,l)
|
||||
|
||||
/**
|
||||
* @brief Add a new constant and write an instruction for it.
|
||||
* @memberof KrkChunk
|
||||
*/
|
||||
extern size_t krk_writeConstant(KrkChunk * chunk, KrkValue value, size_t line);
|
||||
extern size_t krk_writeConstant_r(struct KrkThreadState * _thread, KrkChunk * chunk, KrkValue value, size_t line);
|
||||
#define krk_writeConstant(c,v,l) krk_writeConstant_r(_thread,c,v,l)
|
||||
|
||||
/**
|
||||
* @brief Obtain the line number for a byte offset into a bytecode chunk.
|
||||
@ -94,4 +100,6 @@ extern size_t krk_writeConstant(KrkChunk * chunk, KrkValue value, size_t line);
|
||||
* @param offset Byte offset of the instruction to locate.
|
||||
* @return Line number, 1-indexed.
|
||||
*/
|
||||
extern size_t krk_lineNumber(KrkChunk * chunk, size_t offset);
|
||||
extern size_t krk_lineNumber_r(struct KrkThreadState * _thread, KrkChunk * chunk, size_t offset);
|
||||
#define krk_lineNumber(c,o) krk_lineNumber_r(_thread,c,o)
|
||||
|
||||
|
@ -14,5 +14,5 @@
|
||||
* @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.
|
||||
*/
|
||||
extern KrkCodeObject * krk_compile(const char * src, char * fileName);
|
||||
extern KrkCodeObject * krk_compile(struct KrkThreadState * _thread, const char * src, char * fileName);
|
||||
|
||||
|
@ -32,7 +32,8 @@
|
||||
* @param func Code object to disassemble.
|
||||
* @param name Function name to display in disassembly output.
|
||||
*/
|
||||
extern void krk_disassembleCodeObject(FILE * f, KrkCodeObject * func, const char * name);
|
||||
extern void krk_disassembleCodeObject_r(struct KrkThreadState * _thread, FILE * f, KrkCodeObject * func, const char * name);
|
||||
#define krk_disassembleCodeObject(f,fn,n) krk_disassembleCodeObject_r(_thread,f,fn,n)
|
||||
|
||||
/**
|
||||
* @brief Print a disassembly of a single opcode instruction.
|
||||
@ -46,14 +47,16 @@ extern void krk_disassembleCodeObject(FILE * f, KrkCodeObject * func, const char
|
||||
* @param offset Byte offset of the instruction to disassemble.
|
||||
* @return The size of the instruction in bytes.
|
||||
*/
|
||||
extern size_t krk_disassembleInstruction(FILE * f, KrkCodeObject * func, size_t offset);
|
||||
extern size_t krk_disassembleInstruction_r(struct KrkThreadState * _thread, FILE * f, KrkCodeObject * func, size_t offset);
|
||||
#define krk_disassembleInstruction(f,fn,o) krk_disassembleInstruction_r(_thread,f,fn,o)
|
||||
|
||||
/**
|
||||
* @brief Called by the VM when a breakpoint is encountered.
|
||||
*
|
||||
* Internal method, should not generally be called.
|
||||
*/
|
||||
extern int krk_debugBreakpointHandler(void);
|
||||
extern int krk_debugBreakpointHandler_r(struct KrkThreadState * _thread);
|
||||
#define krk_debugBreakpointHandler() krk_debugBreakpointHandler_r(_thread)
|
||||
|
||||
/**
|
||||
* @brief Called by the VM on single step.
|
||||
@ -64,13 +67,14 @@ extern int krk_debugBreakpointHandler(void);
|
||||
*
|
||||
* Internal method, should not generally be called.
|
||||
*/
|
||||
extern int krk_debuggerHook(KrkCallFrame * frame);
|
||||
extern int krk_debuggerHook_r(struct KrkThreadState * _thread, KrkCallFrame * frame);
|
||||
#define krk_debuggerHook(f) krk_debuggerHook_r(_thread,f)
|
||||
|
||||
/**
|
||||
* @brief Function pointer for a debugger hook.
|
||||
* @ref krk_debug_registerCallback()
|
||||
*/
|
||||
typedef int (*KrkDebugCallback)(KrkCallFrame *frame);
|
||||
typedef int (*KrkDebugCallback)(struct KrkThreadState * _thread, KrkCallFrame *frame);
|
||||
|
||||
/**
|
||||
* @brief Register a debugger callback.
|
||||
@ -91,7 +95,8 @@ typedef int (*KrkDebugCallback)(KrkCallFrame *frame);
|
||||
* already registered, in which case the new hook
|
||||
* has not been registered.
|
||||
*/
|
||||
extern int krk_debug_registerCallback(KrkDebugCallback hook);
|
||||
extern int krk_debug_registerCallback_r(struct KrkThreadState * _thread, KrkDebugCallback hook);
|
||||
#define krk_debug_registerCallback(h) krk_debug_registerCallback_r(_thread,h)
|
||||
|
||||
/**
|
||||
* @brief Add a breakpoint to the given line of a file.
|
||||
@ -108,7 +113,8 @@ extern int krk_debug_registerCallback(KrkDebugCallback hook);
|
||||
* @param flags Allows configuring the disposition of the breakpoint.
|
||||
* @return A breakpoint identifier handle on success, or -1 on failure.
|
||||
*/
|
||||
extern int krk_debug_addBreakpointFileLine(KrkString * filename, size_t line, int flags);
|
||||
extern int krk_debug_addBreakpointFileLine_r(struct KrkThreadState * _thread, KrkString * filename, size_t line, int flags);
|
||||
#define krk_debug_addBreakpointFileLine(f,l,fl) krk_debug_addBreakpointFileLine_r(_thread,f,l,fl)
|
||||
|
||||
/**
|
||||
* @brief Add a breakpoint to the given code object.
|
||||
@ -126,7 +132,8 @@ extern int krk_debug_addBreakpointFileLine(KrkString * filename, size_t line, in
|
||||
* @param flags Allows configuring the disposition of the breakpoint.
|
||||
* @return A breakpoint identifier handle on success, or -1 on failure.
|
||||
*/
|
||||
extern int krk_debug_addBreakpointCodeOffset(KrkCodeObject * codeObject, size_t offset, int flags);
|
||||
extern int krk_debug_addBreakpointCodeOffset_r(struct KrkThreadState * _thread, KrkCodeObject * codeObject, size_t offset, int flags);
|
||||
#define krk_debug_addBreakpointCodeOffset(c,o,f) krk_debug_addBreakpointCodeOffset_r(_thread,c,o,f)
|
||||
|
||||
/**
|
||||
* @brief Remove a breakpoint from the breakpoint table.
|
||||
@ -138,7 +145,8 @@ extern int krk_debug_addBreakpointCodeOffset(KrkCodeObject * codeObject, size_t
|
||||
* @param breakpointId The breakpoint to remove.
|
||||
* @return 0 on success, 1 if the breakpoint identifier is invalid.
|
||||
*/
|
||||
extern int krk_debug_removeBreakpoint(int breakpointId);
|
||||
extern int krk_debug_removeBreakpoint_r(struct KrkThreadState * _thread, int breakpointId);
|
||||
#define krk_debug_removeBreakpoint(b) krk_debug_removeBreakpoint_r(_thread,b)
|
||||
|
||||
/**
|
||||
* @brief Enable a breakpoint.
|
||||
@ -149,7 +157,8 @@ extern int krk_debug_removeBreakpoint(int breakpointId);
|
||||
* @param breakpointId The breakpoint to enable.
|
||||
* @return 0 on success, 1 if the breakpoint identifier is invalid.
|
||||
*/
|
||||
extern int krk_debug_enableBreakpoint(int breakpointId);
|
||||
extern int krk_debug_enableBreakpoint_r(struct KrkThreadState * _thread, int breakpointId);
|
||||
#define krk_debug_enableBreakpoint(b) krk_debug_enableBreakpoint_r(_thread,b)
|
||||
|
||||
/**
|
||||
* @brief Disable a breakpoint.
|
||||
@ -162,17 +171,21 @@ extern int krk_debug_enableBreakpoint(int breakpointId);
|
||||
* @param breakpointId The breakpoint to disable.
|
||||
* @return 0 on success, 1 if the breakpoint identifier is invalid.
|
||||
*/
|
||||
extern int krk_debug_disableBreakpoint(int breakpointId);
|
||||
extern int krk_debug_disableBreakpoint_r(struct KrkThreadState * _thread, int breakpointId);
|
||||
#define krk_debug_disableBreakpoint(b) krk_debug_disableBreakpoint_r(_thread,b)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable single stepping in the current thread.
|
||||
*/
|
||||
extern void krk_debug_enableSingleStep(void);
|
||||
extern void krk_debug_enableSingleStep_r(struct KrkThreadState * _thread);
|
||||
#define krk_debug_enableSingleStep() krk_debug_enableSingleStep_r(_thread);
|
||||
|
||||
/**
|
||||
* @brief Disable single stepping in the current thread.
|
||||
*/
|
||||
extern void krk_debug_disableSingleStep(void);
|
||||
extern void krk_debug_disableSingleStep_r(struct KrkThreadState * _thread);
|
||||
#define krk_debug_disableSingleStep() krk_debug_disableSingleStep_r(_thread)
|
||||
|
||||
/**
|
||||
* @brief Safely dump a traceback to stderr.
|
||||
@ -180,7 +193,8 @@ extern void krk_debug_disableSingleStep(void);
|
||||
* Wraps @ref krk_dumpTraceback() so it can be safely
|
||||
* called from a debugger.
|
||||
*/
|
||||
extern void krk_debug_dumpTraceback(void);
|
||||
extern void krk_debug_dumpTraceback_r(struct KrkThreadState * _thread);
|
||||
#define krk_debug_dumpTraceback() krk_debug_dumpTraceback_r(_thread);
|
||||
|
||||
/**
|
||||
* @brief Retreive information on a breakpoint.
|
||||
@ -195,7 +209,8 @@ extern void krk_debug_dumpTraceback(void);
|
||||
* @param enabledOut (Out) Whether the breakpoint is enabled or not.
|
||||
* @return 0 on success, -1 on out of range, -2 if the selected slot was removed.
|
||||
*/
|
||||
extern int krk_debug_examineBreakpoint(int breakIndex, KrkCodeObject ** funcOut, size_t * offsetOut, int * flagsOut, int *enabledOut);
|
||||
extern int krk_debug_examineBreakpoint_r(struct KrkThreadState * _thread, int breakIndex, KrkCodeObject ** funcOut, size_t * offsetOut, int * flagsOut, int *enabledOut);
|
||||
#define krk_debug_examineBreakpoint(b,f,o,fl,e) krk_debug_examineBreakpoint_r(_thread,b,f,o,fl,e)
|
||||
|
||||
/**
|
||||
* @brief Print the elements on the stack.
|
||||
@ -204,7 +219,8 @@ extern int krk_debug_examineBreakpoint(int breakIndex, KrkCodeObject ** funcOut,
|
||||
* highlighting @p frame as the activate call point and indicating
|
||||
* where its arguments start.
|
||||
*/
|
||||
extern void krk_debug_dumpStack(FILE * f, KrkCallFrame * frame);
|
||||
extern void krk_debug_dumpStack_r(struct KrkThreadState * _thread, FILE * f, KrkCallFrame * frame);
|
||||
#define krk_debug_dumpStack(f,fr) krk_debug_dumpStack_r(_thread,f,fr)
|
||||
|
||||
/**
|
||||
* @def KRK_BREAKPOINT_NORMAL
|
||||
|
@ -27,7 +27,8 @@
|
||||
* @param new New size of the object.
|
||||
* @return New pointer for heap object.
|
||||
*/
|
||||
extern void * krk_reallocate(void * ptr, size_t old, size_t new);
|
||||
extern void * krk_reallocate_r(struct KrkThreadState * _thread, void * ptr, size_t old, size_t new);
|
||||
#define krk_reallocate(p,o,n) krk_reallocate_r(_thread,p,o,n)
|
||||
|
||||
/**
|
||||
* @brief Release all objects.
|
||||
@ -35,7 +36,8 @@ extern void * krk_reallocate(void * ptr, size_t old, size_t new);
|
||||
* Generally called automatically by krk_freeVM(); releases all of
|
||||
* the GC-tracked heap objects.
|
||||
*/
|
||||
extern void krk_freeObjects(void);
|
||||
extern void krk_freeObjects_r(struct KrkThreadState * _thread);
|
||||
#define krk_freeObjects() krk_freeObjects_r(_thread)
|
||||
|
||||
/**
|
||||
* @brief Run a cycle of the garbage collector.
|
||||
@ -46,7 +48,8 @@ extern void krk_freeObjects(void);
|
||||
*
|
||||
* @return The number of bytes released by this collection cycle.
|
||||
*/
|
||||
extern size_t krk_collectGarbage(void);
|
||||
extern size_t krk_collectGarbage_r(struct KrkThreadState * _thread);
|
||||
#define krk_collectGarbage() krk_collectGarbage_r(_thread)
|
||||
|
||||
/**
|
||||
* @brief During a GC scan cycle, mark a value as used.
|
||||
@ -57,7 +60,8 @@ extern size_t krk_collectGarbage(void);
|
||||
*
|
||||
* @param value The value to mark.
|
||||
*/
|
||||
extern void krk_markValue(KrkValue value);
|
||||
extern void krk_markValue_r(struct KrkThreadState * _thread, KrkValue value);
|
||||
#define krk_markValue(v) krk_markValue_r(_thread,v)
|
||||
|
||||
/**
|
||||
* @brief During a GC scan cycle, mark an object as used.
|
||||
@ -66,7 +70,8 @@ extern void krk_markValue(KrkValue value);
|
||||
*
|
||||
* @param object The object to mark.
|
||||
*/
|
||||
extern void krk_markObject(KrkObj * object);
|
||||
extern void krk_markObject_r(struct KrkThreadState * _thread, KrkObj * object);
|
||||
#define krk_markObject(o) krk_markObject_r(_thread,o)
|
||||
|
||||
/**
|
||||
* @brief During a GC scan cycle, mark the contents of a table as used.
|
||||
@ -76,7 +81,8 @@ extern void krk_markObject(KrkObj * object);
|
||||
*
|
||||
* @param table The table to mark.
|
||||
*/
|
||||
extern void krk_markTable(KrkTable * table);
|
||||
extern void krk_markTable_r(struct KrkThreadState * _thread, KrkTable * table);
|
||||
#define krk_markTable(t) krk_markTable_r(_thread,t)
|
||||
|
||||
/**
|
||||
* @brief Assume ownership of @p size bytes at @p ptr
|
||||
@ -89,4 +95,5 @@ extern void krk_markTable(KrkTable * table);
|
||||
* @param ptr Pointer to take ownership of
|
||||
* @param size Size of data at @p ptr
|
||||
*/
|
||||
extern void krk_gcTakeBytes(const void * ptr, size_t size);
|
||||
extern void krk_gcTakeBytes_r(struct KrkThreadState * _thread, const void * ptr, size_t size);
|
||||
#define krk_gcTakeBytes(p,s) krk_gcTakeBytes_r(_thread,p,s)
|
||||
|
@ -31,6 +31,8 @@ typedef enum {
|
||||
KRK_OBJ_BYTES,
|
||||
} KrkObjType;
|
||||
|
||||
struct KrkThreadState;
|
||||
|
||||
#undef KrkObj
|
||||
/**
|
||||
* @brief The most basic object type.
|
||||
@ -178,7 +180,7 @@ typedef struct {
|
||||
KrkTable * globalsTable; /**< @brief Pointer to globals table with owner object */
|
||||
} KrkClosure;
|
||||
|
||||
typedef void (*KrkCleanupCallback)(struct KrkInstance *);
|
||||
typedef void (*KrkCleanupCallback)(struct KrkThreadState *, struct KrkInstance *);
|
||||
|
||||
/**
|
||||
* @brief Type object.
|
||||
@ -269,7 +271,7 @@ typedef struct {
|
||||
KrkObj * method; /**< @brief Function to call */
|
||||
} KrkBoundMethod;
|
||||
|
||||
typedef KrkValue (*NativeFn)(int argCount, const KrkValue* args, int hasKwargs);
|
||||
typedef KrkValue (*NativeFn)(struct KrkThreadState *, int argCount, const KrkValue* args, int hasKwargs);
|
||||
|
||||
/**
|
||||
* @brief Managed binding to a C function.
|
||||
@ -387,7 +389,8 @@ struct KrkSlice {
|
||||
* @param length Length of the C string.
|
||||
* @return A string object.
|
||||
*/
|
||||
extern KrkString * krk_takeString(char * chars, size_t length);
|
||||
extern KrkString * krk_takeString_r(struct KrkThreadState * _thread, char * chars, size_t length);
|
||||
#define krk_takeString(c,l) krk_takeString_r(_thread,c,l)
|
||||
|
||||
/**
|
||||
* @brief Like @ref krk_takeString but for when the caller has already calculated
|
||||
@ -405,7 +408,8 @@ extern KrkString * krk_takeString(char * chars, size_t length);
|
||||
* @param type Compact type of the string, eg. UCS1, UCS2, UCS4... @see KrkStringType
|
||||
* @param hash Precalculated string hash.
|
||||
*/
|
||||
extern KrkString * krk_takeStringVetted(char * chars, size_t length, size_t codesLength, KrkStringType type, uint32_t hash);
|
||||
extern KrkString * krk_takeStringVetted_r(struct KrkThreadState * _thread, char * chars, size_t length, size_t codesLength, KrkStringType type, uint32_t hash);
|
||||
#define krk_takeStringVetted(c,l,cl,t,h) krk_takeStringVetted_r(_thread,c,l,cl,t,h)
|
||||
|
||||
/**
|
||||
* @brief Obtain a string object representation of the given C string.
|
||||
@ -422,7 +426,8 @@ extern KrkString * krk_takeStringVetted(char * chars, size_t length, size_t code
|
||||
* @param length Length of the C string.
|
||||
* @return A string object.
|
||||
*/
|
||||
extern KrkString * krk_copyString(const char * chars, size_t length);
|
||||
extern KrkString * krk_copyString_r(struct KrkThreadState * _thread, const char * chars, size_t length);
|
||||
#define krk_copyString(c,l) krk_copyString_r(_thread,c,l)
|
||||
|
||||
/**
|
||||
* @brief Ensure that a codepoint representation of a string is available.
|
||||
@ -436,7 +441,8 @@ extern KrkString * krk_copyString(const char * chars, size_t length);
|
||||
* @param string String to obtain the codepoint representation of.
|
||||
* @return A pointer to the bytes of the codepoint representation.
|
||||
*/
|
||||
extern void * krk_unicodeString(KrkString * string);
|
||||
extern void * krk_unicodeString_r(struct KrkThreadState * _thread, KrkString * string);
|
||||
#define krk_unicodeString(s) krk_unicodeString_r(_thread,s)
|
||||
|
||||
/**
|
||||
* @brief Obtain the codepoint at a given index in a string.
|
||||
@ -454,7 +460,8 @@ extern void * krk_unicodeString(KrkString * string);
|
||||
* @param index Offset of the codepoint to obtain.
|
||||
* @return Integer representation of the codepoint at the requested index.
|
||||
*/
|
||||
extern uint32_t krk_unicodeCodepoint(KrkString * string, size_t index);
|
||||
extern uint32_t krk_unicodeCodepoint_r(struct KrkThreadState * _thread, KrkString * string, size_t index);
|
||||
#define krk_unicodeCodepoint(s,i) krk_unicodeCodepoint_r(_thread,s,i)
|
||||
|
||||
/**
|
||||
* @brief Convert an integer codepoint to a UTF-8 byte representation.
|
||||
@ -467,7 +474,8 @@ extern uint32_t krk_unicodeCodepoint(KrkString * string, size_t index);
|
||||
* @param out Array to write UTF-8 sequence into.
|
||||
* @return The length of the UTF-8 sequence, in bytes.
|
||||
*/
|
||||
extern size_t krk_codepointToBytes(krk_integer_type value, unsigned char * out);
|
||||
extern size_t krk_codepointToBytes_r(struct KrkThreadState * _thread, krk_integer_type value, unsigned char * out);
|
||||
#define krk_codepointToBytes(v,o) krk_codepointToBytes_r(_thread,v,o)
|
||||
|
||||
/**
|
||||
* @brief Convert a function into a generator with the given arguments.
|
||||
@ -481,12 +489,14 @@ extern size_t krk_codepointToBytes(krk_integer_type value, unsigned char * out);
|
||||
* @param argCount Number of arguments in @p arguments
|
||||
* @return A new generator object.
|
||||
*/
|
||||
extern KrkInstance * krk_buildGenerator(KrkClosure * function, KrkValue * arguments, size_t argCount);
|
||||
extern KrkInstance * krk_buildGenerator_r(struct KrkThreadState * _thread, KrkClosure * function, KrkValue * arguments, size_t argCount);
|
||||
#define krk_buildGenerator(f,a,c) krk_buildGenerator_r(_thread,f,a,c)
|
||||
|
||||
/**
|
||||
* @brief Calls __await__
|
||||
*/
|
||||
extern int krk_getAwaitable(void);
|
||||
extern int krk_getAwaitable_r(struct KrkThreadState * _thread);
|
||||
#define krk_getAwaitable() krk_getAwaitable_r(_thread)
|
||||
|
||||
/**
|
||||
* @brief Special value for type hint expressions.
|
||||
@ -504,7 +514,8 @@ extern NativeFn krk_GenericAlias;
|
||||
* no assigned names or docstrings. This is intended only
|
||||
* to be used by a compiler directly.
|
||||
*/
|
||||
extern KrkCodeObject * krk_newCodeObject(void);
|
||||
extern KrkCodeObject * krk_newCodeObject_r(struct KrkThreadState * _thread);
|
||||
#define krk_newCodeObject() krk_newCodeObject_r(_thread)
|
||||
|
||||
/**
|
||||
* @brief Create a native function binding object.
|
||||
@ -514,7 +525,8 @@ extern KrkCodeObject * krk_newCodeObject(void);
|
||||
* which can then be used in the same place a function object
|
||||
* (KrkClosure) would be used.
|
||||
*/
|
||||
extern KrkNative * krk_newNative(NativeFn function, const char * name, int type);
|
||||
extern KrkNative * krk_newNative_r(struct KrkThreadState * _thread, NativeFn function, const char * name, int type);
|
||||
#define krk_newNative(f,n,t) krk_newNative_r(_thread,f,n,t)
|
||||
|
||||
/**
|
||||
* @brief Create a new function object.
|
||||
@ -527,7 +539,8 @@ extern KrkNative * krk_newNative(NativeFn function, const char * name, int
|
||||
*
|
||||
* @param function Code object to assign to the new function object.
|
||||
*/
|
||||
extern KrkClosure * krk_newClosure(KrkCodeObject * function, KrkValue globals);
|
||||
extern KrkClosure * krk_newClosure_r(struct KrkThreadState * _thread, KrkCodeObject * function, KrkValue globals);
|
||||
#define krk_newClosure(f,g) krk_newClosure_r(_thread,f,g)
|
||||
|
||||
/**
|
||||
* @brief Create an upvalue slot.
|
||||
@ -538,7 +551,8 @@ extern KrkClosure * krk_newClosure(KrkCodeObject * function, KrkValue global
|
||||
* process of running compiled bytecode and creating function
|
||||
* objects from code objects.
|
||||
*/
|
||||
extern KrkUpvalue * krk_newUpvalue(int slot);
|
||||
extern KrkUpvalue * krk_newUpvalue_r(struct KrkThreadState * _thread, int slot);
|
||||
#define krk_newUpvalue(s) krk_newUpvalue_r(_thread, s)
|
||||
|
||||
/**
|
||||
* @brief Create a new class object.
|
||||
@ -548,7 +562,8 @@ extern KrkUpvalue * krk_newUpvalue(int slot);
|
||||
* Generally, you will want to use @ref krk_makeClass instead,
|
||||
* which handles binding the class to a module.
|
||||
*/
|
||||
extern KrkClass * krk_newClass(KrkString * name, KrkClass * base);
|
||||
extern KrkClass * krk_newClass_r(struct KrkThreadState * _thread, KrkString * name, KrkClass * base);
|
||||
#define krk_newClass(n,b) krk_newClass_r(_thread,n,b)
|
||||
|
||||
/**
|
||||
* @brief Create a new instance of the given class.
|
||||
@ -558,7 +573,8 @@ extern KrkClass * krk_newClass(KrkString * name, KrkClass * base);
|
||||
* Be sure to populate any fields expected by the class or call
|
||||
* its __init__ function (eg. with @ref krk_callStack) as needed.
|
||||
*/
|
||||
extern KrkInstance * krk_newInstance(KrkClass * _class);
|
||||
extern KrkInstance * krk_newInstance_r(struct KrkThreadState * _thread, KrkClass * _class);
|
||||
#define krk_newInstance(c) krk_newInstance_r(_thread,c)
|
||||
|
||||
/**
|
||||
* @brief Create a new bound method.
|
||||
@ -568,7 +584,8 @@ extern KrkInstance * krk_newInstance(KrkClass * _class);
|
||||
* and returns a @c method object. When a @c method object is called,
|
||||
* @p receiver will automatically be provided as the first argument.
|
||||
*/
|
||||
extern KrkBoundMethod * krk_newBoundMethod(KrkValue receiver, KrkObj * method);
|
||||
extern KrkBoundMethod * krk_newBoundMethod_r(struct KrkThreadState * _thread, KrkValue receiver, KrkObj * method);
|
||||
#define krk_newBoundMethod(r,m) krk_newBoundMethod_r(_thread,r,m)
|
||||
|
||||
/**
|
||||
* @brief Create a new tuple.
|
||||
@ -578,7 +595,8 @@ extern KrkBoundMethod * krk_newBoundMethod(KrkValue receiver, KrkObj * method);
|
||||
* The actual length of the tuple must be updated after places
|
||||
* values within it by setting @c value.count.
|
||||
*/
|
||||
extern KrkTuple * krk_newTuple(size_t length);
|
||||
extern KrkTuple * krk_newTuple_r(struct KrkThreadState * _thread, size_t length);
|
||||
#define krk_newTuple(l) krk_newTuple_r(_thread,l)
|
||||
|
||||
/**
|
||||
* @brief Create a new byte array.
|
||||
@ -587,7 +605,8 @@ extern KrkTuple * krk_newTuple(size_t length);
|
||||
* Allocates a bytes object of the given size, optionally copying
|
||||
* data from @p source.
|
||||
*/
|
||||
extern KrkBytes * krk_newBytes(size_t length, uint8_t * source);
|
||||
extern KrkBytes * krk_newBytes_r(struct KrkThreadState * _thread, size_t length, uint8_t * source);
|
||||
#define krk_newBytes(l,s) krk_newBytes_r(_thread,l,s)
|
||||
|
||||
#define krk_isObjType(v,t) (IS_OBJECT(v) && (AS_OBJECT(v)->type == (t)))
|
||||
#define OBJECT_TYPE(value) (AS_OBJECT(value)->type)
|
||||
|
@ -41,7 +41,8 @@ typedef struct {
|
||||
*
|
||||
* @param table Hash table to initialize.
|
||||
*/
|
||||
extern void krk_initTable(KrkTable * table);
|
||||
extern void krk_initTable_r(struct KrkThreadState * _thread, KrkTable * table);
|
||||
#define krk_initTable(t) krk_initTable_r(_thread,t)
|
||||
|
||||
/**
|
||||
* @brief Release resources associated with a hash table.
|
||||
@ -51,7 +52,8 @@ extern void krk_initTable(KrkTable * table);
|
||||
*
|
||||
* @param table Hash table to release.
|
||||
*/
|
||||
extern void krk_freeTable(KrkTable * table);
|
||||
extern void krk_freeTable_r(struct KrkThreadState * _thread, KrkTable * table);
|
||||
#define krk_freeTable(t) krk_freeTable_r(_thread,t)
|
||||
|
||||
/**
|
||||
* @brief Add all key-value pairs from 'from' into 'to'.
|
||||
@ -64,7 +66,8 @@ extern void krk_freeTable(KrkTable * table);
|
||||
* @param from Source table.
|
||||
* @param to Destination table.
|
||||
*/
|
||||
extern void krk_tableAddAll(KrkTable * from, KrkTable * to);
|
||||
extern void krk_tableAddAll_r(struct KrkThreadState * _thread, KrkTable * from, KrkTable * to);
|
||||
#define krk_tableAddAll(f,t) krk_tableAddAll_r(_thread,f,t)
|
||||
|
||||
/**
|
||||
* @brief Find a character sequence in the string interning table.
|
||||
@ -80,7 +83,8 @@ extern void krk_tableAddAll(KrkTable * from, KrkTable * to);
|
||||
* @param hash Precalculated hash value for the string.
|
||||
* @return If the string was found, the string object representation, else NULL.
|
||||
*/
|
||||
extern struct KrkString * krk_tableFindString(KrkTable * table, const char * chars, size_t length, uint32_t hash);
|
||||
extern struct KrkString * krk_tableFindString_r(struct KrkThreadState * _thread, KrkTable * table, const char * chars, size_t length, uint32_t hash);
|
||||
#define krk_tableFindString(t,c,l,h) krk_tableFindString_r(_thread,t,c,l,h)
|
||||
|
||||
/**
|
||||
* @brief Assign a value to a key in a table.
|
||||
@ -95,7 +99,8 @@ extern struct KrkString * krk_tableFindString(KrkTable * table, const char * cha
|
||||
* @param value Value to assign to the key.
|
||||
* @return 0 if the key was already present and has been overwritten, 1 if the key is new to the table.
|
||||
*/
|
||||
extern int krk_tableSet(KrkTable * table, KrkValue key, KrkValue value);
|
||||
extern int krk_tableSet_r(struct KrkThreadState * _thread, KrkTable * table, KrkValue key, KrkValue value);
|
||||
#define krk_tableSet(t,k,v) krk_tableSet_r(_thread,t,k,v)
|
||||
|
||||
/**
|
||||
* @brief Obtain the value associated with a key in a table.
|
||||
@ -110,7 +115,8 @@ extern int krk_tableSet(KrkTable * table, KrkValue key, KrkValue value);
|
||||
* @param value Output pointer to place resulting value in.
|
||||
* @return 0 if the key was not found, 1 if it was.
|
||||
*/
|
||||
extern int krk_tableGet(KrkTable * table, KrkValue key, KrkValue * value);
|
||||
extern int krk_tableGet_r(struct KrkThreadState * _thread, KrkTable * table, KrkValue key, KrkValue * value);
|
||||
#define krk_tableGet(t,k,v) krk_tableGet_r(_thread,t,k,v)
|
||||
|
||||
/**
|
||||
* @brief Obtain the value associated with a string key in a table.
|
||||
@ -125,7 +131,8 @@ extern int krk_tableGet(KrkTable * table, KrkValue key, KrkValue * value);
|
||||
* @param value Output pointer to place resulting value in.
|
||||
* @return 0 if the key was not found, 1 if it was.
|
||||
*/
|
||||
extern int krk_tableGet_fast(KrkTable * table, struct KrkString * str, KrkValue * value);
|
||||
extern int krk_tableGet_fast_r(struct KrkThreadState * _thread, KrkTable * table, struct KrkString * str, KrkValue * value);
|
||||
#define krk_tableGet_fast(t,s,v) krk_tableGet_fast_r(_thread,t,s,v)
|
||||
|
||||
/**
|
||||
* @brief Remove a key from a hash table.
|
||||
@ -138,7 +145,8 @@ extern int krk_tableGet_fast(KrkTable * table, struct KrkString * str, KrkValue
|
||||
* @param key Key to delete.
|
||||
* @return 1 if the value was found and deleted, 0 if it was not present.
|
||||
*/
|
||||
extern int krk_tableDelete(KrkTable * table, KrkValue key);
|
||||
extern int krk_tableDelete_r(struct KrkThreadState * _thread, KrkTable * table, KrkValue key);
|
||||
#define krk_tableDelete(t,k) krk_tableDelete_r(_thread,t,k)
|
||||
|
||||
/**
|
||||
* @brief Remove a key from a hash table, with identity lookup.
|
||||
@ -151,7 +159,8 @@ extern int krk_tableDelete(KrkTable * table, KrkValue key);
|
||||
* @param key Key to delete.
|
||||
* @return 1 if the value was found and deleted, 0 if it was not present.
|
||||
*/
|
||||
extern int krk_tableDeleteExact(KrkTable * table, KrkValue key);
|
||||
extern int krk_tableDeleteExact_r(struct KrkThreadState * _thread, KrkTable * table, KrkValue key);
|
||||
#define krk_tableDeleteExact(t,k) krk_tableDeleteExact_r(_thread,t,k)
|
||||
|
||||
/**
|
||||
* @brief Internal table scan function.
|
||||
@ -166,7 +175,8 @@ extern int krk_tableDeleteExact(KrkTable * table, KrkValue key);
|
||||
* @param key Key to locate.
|
||||
* @return A pointer to the entry for 'key'.
|
||||
*/
|
||||
extern KrkTableEntry * krk_findEntry(KrkTableEntry * entries, size_t capacity, KrkValue key);
|
||||
extern KrkTableEntry * krk_findEntry_r(struct KrkThreadState * _thread, KrkTableEntry * entries, size_t capacity, KrkValue key);
|
||||
#define krk_findEntry(e,c,k) krk_findEntry_r(_thread,e,c,k)
|
||||
|
||||
/**
|
||||
* @brief Calculate the hash for a value.
|
||||
@ -178,7 +188,8 @@ extern KrkTableEntry * krk_findEntry(KrkTableEntry * entries, size_t capacity, K
|
||||
* @param *hashOut An unsigned 32-bit hash value.
|
||||
* @return Status code 0 for success, 1 for unhashable type.
|
||||
*/
|
||||
extern int krk_hashValue(KrkValue value, uint32_t *hashOut);
|
||||
extern int krk_hashValue_r(struct KrkThreadState * _thread, KrkValue value, uint32_t *hashOut);
|
||||
#define krk_hashValue(v,h) krk_hashValue_r(_thread,v,h)
|
||||
|
||||
/**
|
||||
* @brief Preset the size of a table.
|
||||
@ -189,7 +200,8 @@ extern int krk_hashValue(KrkValue value, uint32_t *hashOut);
|
||||
* @param table Table to resize.
|
||||
* @param capacity Target capacity.
|
||||
*/
|
||||
extern void krk_tableAdjustCapacity(KrkTable * table, size_t capacity);
|
||||
extern void krk_tableAdjustCapacity_r(struct KrkThreadState * _thread, KrkTable * table, size_t capacity);
|
||||
#define krk_tableAdjustCapacity(t,c) krk_tableAdjustCapacity_r(_thread,t,c)
|
||||
|
||||
/**
|
||||
* @brief Update the value of a table entry only if it is found.
|
||||
@ -205,4 +217,5 @@ extern void krk_tableAdjustCapacity(KrkTable * table, size_t capacity);
|
||||
* @param value Value to assign to the key.
|
||||
* @return 0 if the key was not present, 1 if it was found and updated.
|
||||
*/
|
||||
extern int krk_tableSetIfExists(KrkTable * table, KrkValue key, KrkValue value);
|
||||
extern int krk_tableSetIfExists_r(struct KrkThreadState * _thread, KrkTable * table, KrkValue key, KrkValue value);
|
||||
#define krk_tableSetIfExists(t,k,v) krk_tableSetIfExists_r(_thread,t,k,v)
|
||||
|
@ -63,7 +63,7 @@
|
||||
ctype name __attribute__((unused)) = AS_ ## type (argv[i])
|
||||
|
||||
#define FUNC_NAME(klass, name) _ ## klass ## _ ## name
|
||||
#define FUNC_SIG(klass, name) _noexport KrkValue FUNC_NAME(klass,name) (int argc, const KrkValue argv[], int hasKw)
|
||||
#define FUNC_SIG(klass, name) _noexport KrkValue FUNC_NAME(klass,name) (KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw)
|
||||
|
||||
/* These forms are deprecated. */
|
||||
#define KRK_METHOD(klass, name, ...) FUNC_SIG(klass, name) { \
|
||||
@ -86,27 +86,27 @@
|
||||
#define KRK_Method_internal_name(klass, name) \
|
||||
_krk_method_ ## klass ## _ ## name
|
||||
#define KRK_Method_internal_sig(klass, name) \
|
||||
static inline KrkValue KRK_Method_internal_name(klass,name) (const char * _method_name, CURRENT_CTYPE CURRENT_NAME, int argc, const KrkValue argv[], int hasKw)
|
||||
static inline KrkValue KRK_Method_internal_name(klass,name) (const char * _method_name, CURRENT_CTYPE CURRENT_NAME, KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw)
|
||||
|
||||
#define KRK_Method(klass, name) \
|
||||
KRK_Method_internal_sig(klass, name); \
|
||||
FUNC_SIG(klass, name) { \
|
||||
static const char * _method_name = # name; \
|
||||
CHECK_ARG(0,klass,CURRENT_CTYPE,CURRENT_NAME); \
|
||||
return KRK_Method_internal_name(klass,name)(_method_name, CURRENT_NAME, argc, argv, hasKw); \
|
||||
return KRK_Method_internal_name(klass,name)(_method_name, CURRENT_NAME, _thread, argc, argv, hasKw); \
|
||||
} \
|
||||
KRK_Method_internal_sig(klass,name)
|
||||
|
||||
#define KRK_Function_internal_name(name) \
|
||||
_krk_function_ ## name
|
||||
#define KRK_Function_internal_sig(name) \
|
||||
static inline KrkValue KRK_Function_internal_name(name) (const char * _method_name, int argc, const KrkValue argv[], int hasKw)
|
||||
static inline KrkValue KRK_Function_internal_name(name) (const char * _method_name, KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw)
|
||||
|
||||
#define KRK_Function(name) \
|
||||
KRK_Function_internal_sig(name); \
|
||||
static KrkValue _krk_ ## name (int argc, const KrkValue argv[], int hasKw) { \
|
||||
static KrkValue _krk_ ## name (KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { \
|
||||
static const char* _method_name = # name; \
|
||||
return KRK_Function_internal_name(name)(_method_name,argc,argv,hasKw); \
|
||||
return KRK_Function_internal_name(name)(_method_name,_thread, argc,argv,hasKw); \
|
||||
} \
|
||||
KRK_Function_internal_sig(name)
|
||||
|
||||
@ -125,7 +125,7 @@ struct StringBuilder {
|
||||
* @param sb String builder to append to.
|
||||
* @param c Character to append.
|
||||
*/
|
||||
static inline void pushStringBuilder(struct StringBuilder * sb, char c) {
|
||||
static inline void pushStringBuilder_r(struct KrkThreadState * _thread, struct StringBuilder * sb, char c) {
|
||||
if (sb->capacity < sb->length + 1) {
|
||||
size_t old = sb->capacity;
|
||||
sb->capacity = GROW_CAPACITY(old);
|
||||
@ -133,6 +133,7 @@ static inline void pushStringBuilder(struct StringBuilder * sb, char c) {
|
||||
}
|
||||
sb->bytes[sb->length++] = c;
|
||||
}
|
||||
#define pushStringBuilder(sb,c) pushStringBuilder_r(_thread,sb,c)
|
||||
|
||||
/**
|
||||
* @brief Append a string to the end of a string builder.
|
||||
@ -141,7 +142,7 @@ static inline void pushStringBuilder(struct StringBuilder * sb, char c) {
|
||||
* @param str C string to add.
|
||||
* @param len Length of the C string.
|
||||
*/
|
||||
static inline void pushStringBuilderStr(struct StringBuilder * sb, const char *str, size_t len) {
|
||||
static inline void pushStringBuilderStr_r(struct KrkThreadState * _thread, struct StringBuilder * sb, const char *str, size_t len) {
|
||||
if (sb->capacity < sb->length + len) {
|
||||
size_t prevcap = sb->capacity;
|
||||
while (sb->capacity < sb->length + len) {
|
||||
@ -154,6 +155,7 @@ static inline void pushStringBuilderStr(struct StringBuilder * sb, const char *s
|
||||
sb->bytes[sb->length++] = *(str++);
|
||||
}
|
||||
}
|
||||
#define pushStringBuilderStr(sb,st,l) pushStringBuilderStr_r(_thread,sb,st,l)
|
||||
|
||||
/**
|
||||
* @brief Finalize a string builder into a string object.
|
||||
@ -165,11 +167,12 @@ static inline void pushStringBuilderStr(struct StringBuilder * sb, const char *s
|
||||
* @param sb String builder to finalize.
|
||||
* @return A value representing a string object.
|
||||
*/
|
||||
static inline KrkValue finishStringBuilder(struct StringBuilder * sb) {
|
||||
static inline KrkValue finishStringBuilder_r(struct KrkThreadState * _thread, struct StringBuilder * sb) {
|
||||
KrkValue out = OBJECT_VAL(krk_copyString(sb->bytes, sb->length));
|
||||
FREE_ARRAY(char,sb->bytes, sb->capacity);
|
||||
return out;
|
||||
}
|
||||
#define finishStringBuilder(sb) finishStringBuilder_r(_thread,sb)
|
||||
|
||||
/**
|
||||
* @brief Finalize a string builder in a bytes object.
|
||||
@ -180,11 +183,12 @@ static inline KrkValue finishStringBuilder(struct StringBuilder * sb) {
|
||||
* @param sb String builder to finalize.
|
||||
* @return A value representing a bytes object.
|
||||
*/
|
||||
static inline KrkValue finishStringBuilderBytes(struct StringBuilder * sb) {
|
||||
static inline KrkValue finishStringBuilderBytes_r(struct KrkThreadState * _thread, struct StringBuilder * sb) {
|
||||
KrkValue out = OBJECT_VAL(krk_newBytes(sb->length, (uint8_t*)sb->bytes));
|
||||
FREE_ARRAY(char,sb->bytes, sb->capacity);
|
||||
return out;
|
||||
}
|
||||
#define finishStringBuilderBytes(sb) finishStringBuilderBytes_r(_thread,sb)
|
||||
|
||||
/**
|
||||
* @brief Discard the contents of a string builder.
|
||||
@ -196,10 +200,11 @@ static inline KrkValue finishStringBuilderBytes(struct StringBuilder * sb) {
|
||||
* @param sb String builder to discard.
|
||||
* @return None, as a convenience.
|
||||
*/
|
||||
static inline KrkValue discardStringBuilder(struct StringBuilder * sb) {
|
||||
static inline KrkValue discardStringBuilder_r(struct KrkThreadState * _thread, struct StringBuilder * sb) {
|
||||
FREE_ARRAY(char,sb->bytes, sb->capacity);
|
||||
return NONE_VAL();
|
||||
}
|
||||
#define discardStringBuilder(sb) discardStringBuilder_r(_thread,sb)
|
||||
|
||||
#define IS_int(o) (IS_INTEGER(o))
|
||||
#define AS_int(o) (AS_INTEGER(o))
|
||||
@ -246,21 +251,21 @@ static inline KrkValue discardStringBuilder(struct StringBuilder * sb) {
|
||||
#define IS_slice(o) krk_isInstanceOf(o,vm.baseClasses->sliceClass)
|
||||
#define AS_slice(o) ((struct KrkSlice*)AS_INSTANCE(o))
|
||||
|
||||
extern KrkValue krk_dict_nth_key_fast(size_t capacity, KrkTableEntry * entries, size_t index);
|
||||
extern KrkValue FUNC_NAME(str,__getitem__)(int,const KrkValue*,int);
|
||||
extern KrkValue FUNC_NAME(str,split)(int,const KrkValue*,int);
|
||||
extern KrkValue FUNC_NAME(str,format)(int,const KrkValue*,int);
|
||||
extern KrkValue krk_dict_nth_key_fast(KrkThreadState *,size_t capacity, KrkTableEntry * entries, size_t index);
|
||||
extern KrkValue FUNC_NAME(str,__getitem__)(KrkThreadState *,int,const KrkValue*,int);
|
||||
extern KrkValue FUNC_NAME(str,split)(KrkThreadState *,int,const KrkValue*,int);
|
||||
extern KrkValue FUNC_NAME(str,format)(KrkThreadState *,int,const KrkValue*,int);
|
||||
#define krk_string_get FUNC_NAME(str,__getitem__)
|
||||
#define krk_string_split FUNC_NAME(str,split)
|
||||
#define krk_string_format FUNC_NAME(str,format)
|
||||
|
||||
static inline void _setDoc_class(KrkClass * thing, const char * text, size_t size) {
|
||||
static inline void _setDoc_class(struct KrkThreadState * _thread, KrkClass * thing, const char * text, size_t size) {
|
||||
thing->docstring = krk_copyString(text, size);
|
||||
}
|
||||
static inline void _setDoc_instance(KrkInstance * thing, const char * text, size_t size) {
|
||||
static inline void _setDoc_instance(struct KrkThreadState * _thread, KrkInstance * thing, const char * text, size_t size) {
|
||||
krk_attachNamedObject(&thing->fields, "__doc__", (KrkObj*)krk_copyString(text, size));
|
||||
}
|
||||
static inline void _setDoc_native(KrkNative * thing, const char * text, size_t size) {
|
||||
static inline void _setDoc_native(struct KrkThreadState * _thread, KrkNative * thing, const char * text, size_t size) {
|
||||
(void)size;
|
||||
thing->doc = text;
|
||||
}
|
||||
@ -285,17 +290,17 @@ static inline void _setDoc_native(KrkNative * thing, const char * text, size_t s
|
||||
KrkClass*: _setDoc_class, \
|
||||
KrkInstance*: _setDoc_instance, \
|
||||
KrkNative*: _setDoc_native \
|
||||
)(thing,text,sizeof(text)-1)
|
||||
)(_thread,thing,text,sizeof(text)-1)
|
||||
#endif
|
||||
|
||||
#define BUILTIN_FUNCTION(name, func, docStr) KRK_DOC(krk_defineNative(&vm.builtins->fields, name, func), docStr)
|
||||
|
||||
extern int krk_extractSlicer(const char * _method_name, KrkValue slicerVal, krk_integer_type count, krk_integer_type *start, krk_integer_type *end, krk_integer_type *step);
|
||||
extern int krk_extractSlicer(KrkThreadState * _thread, const char * _method_name, KrkValue slicerVal, krk_integer_type count, krk_integer_type *start, krk_integer_type *end, krk_integer_type *step);
|
||||
#define KRK_SLICER(arg,count) \
|
||||
krk_integer_type start; \
|
||||
krk_integer_type end; \
|
||||
krk_integer_type step; \
|
||||
if (krk_extractSlicer(_method_name, arg, count, &start, &end, &step))
|
||||
if (krk_extractSlicer(_thread, _method_name, arg, count, &start, &end, &step))
|
||||
|
||||
/**
|
||||
* @brief Unpack an iterable.
|
||||
@ -308,7 +313,8 @@ extern int krk_extractSlicer(const char * _method_name, KrkValue slicerVal, krk_
|
||||
* If @p iterable is not iterable, an exception is set and 1 is returned.
|
||||
* If @p callback returns non-zero, unpacking stops and 1 is returned, with no additional exception.
|
||||
*/
|
||||
extern int krk_unpackIterable(KrkValue iterable, void * context, int callback(void *, const KrkValue *, size_t));
|
||||
extern int krk_unpackIterable_r(KrkThreadState * _thread, KrkValue iterable, void * context, int callback(KrkThreadState *, void *, const KrkValue *, size_t));
|
||||
#define krk_unpackIterable(i,c,cb) krk_unpackIterable_r(_thread,i,c,cb)
|
||||
|
||||
|
||||
#define KRK_BASE_CLASS(cls) (vm.baseClasses->cls ## Class)
|
||||
|
@ -23,6 +23,8 @@ typedef enum {
|
||||
KRK_VAL_NOTIMPL = 0x7FFE,
|
||||
} KrkValueType;
|
||||
|
||||
struct KrkThreadState;
|
||||
|
||||
/*
|
||||
* The following poorly-named macros define bit patterns for identifying
|
||||
* various boxed types.
|
||||
@ -83,7 +85,8 @@ typedef struct {
|
||||
*
|
||||
* @param array Value array to initialize.
|
||||
*/
|
||||
extern void krk_initValueArray(KrkValueArray * array);
|
||||
extern void krk_initValueArray_r(struct KrkThreadState * _thread, KrkValueArray * array);
|
||||
#define krk_initValueArray(a) krk_initValueArray_r(_thread,a)
|
||||
|
||||
/**
|
||||
* @brief Add a value to a value array.
|
||||
@ -95,7 +98,8 @@ extern void krk_initValueArray(KrkValueArray * array);
|
||||
* @param array Array to append to.
|
||||
* @param value Value to append to array.
|
||||
*/
|
||||
extern void krk_writeValueArray(KrkValueArray * array, KrkValue value);
|
||||
extern void krk_writeValueArray_r(struct KrkThreadState * _thread, KrkValueArray * array, KrkValue value);
|
||||
#define krk_writeValueArray(a,v) krk_writeValueArray_r(_thread,a,v)
|
||||
|
||||
/**
|
||||
* @brief Release relesources used by a value array.
|
||||
@ -108,7 +112,8 @@ extern void krk_writeValueArray(KrkValueArray * array, KrkValue value);
|
||||
*
|
||||
* @param array Array to release.
|
||||
*/
|
||||
extern void krk_freeValueArray(KrkValueArray * array);
|
||||
extern void krk_freeValueArray_r(struct KrkThreadState * _thread, KrkValueArray * array);
|
||||
#define krk_freeValueArray(a) krk_freeValueArray_r(_thread,a)
|
||||
|
||||
/**
|
||||
* @brief Print a string representation of a value.
|
||||
@ -126,7 +131,8 @@ extern void krk_freeValueArray(KrkValueArray * array);
|
||||
* @param f Stream to write to.
|
||||
* @param value Value to display.
|
||||
*/
|
||||
extern void krk_printValue(FILE * f, KrkValue value);
|
||||
extern void krk_printValue_r(struct KrkThreadState * _thread, FILE * f, KrkValue value);
|
||||
#define krk_printValue(f,v) krk_printValue_r(_thread,f,v)
|
||||
|
||||
/**
|
||||
* @brief Print a value without calling the VM.
|
||||
@ -144,7 +150,8 @@ extern void krk_printValue(FILE * f, KrkValue value);
|
||||
* @param f Stream to write to.
|
||||
* @param value Value to display.
|
||||
*/
|
||||
extern void krk_printValueSafe(FILE * f, KrkValue value);
|
||||
extern void krk_printValueSafe_r(struct KrkThreadState * _thread, FILE * f, KrkValue value);
|
||||
#define krk_printValueSafe(f,v) krk_printValueSafe_r(_thread,f,v)
|
||||
|
||||
/**
|
||||
* @brief Compare two values for equality.
|
||||
@ -156,7 +163,8 @@ extern void krk_printValueSafe(FILE * f, KrkValue value);
|
||||
*
|
||||
* @return 1 if values are equivalent, 0 otherwise.
|
||||
*/
|
||||
extern int krk_valuesEqual(KrkValue a, KrkValue b);
|
||||
extern int krk_valuesEqual_r(struct KrkThreadState * _thread, KrkValue a, KrkValue b);
|
||||
#define krk_valuesEqual(a,b) krk_valuesEqual_r(_thread,a,b)
|
||||
|
||||
/**
|
||||
* @brief Compare two values by identity.
|
||||
@ -169,7 +177,8 @@ extern int krk_valuesEqual(KrkValue a, KrkValue b);
|
||||
*
|
||||
* @return 1 if values represent the same object or value, 0 otherwise.
|
||||
*/
|
||||
extern int krk_valuesSame(KrkValue a, KrkValue b);
|
||||
extern int krk_valuesSame_r(struct KrkThreadState * _thread, KrkValue a, KrkValue b);
|
||||
#define krk_valuesSame(a,b) krk_valuesSame_r(_thread,a,b)
|
||||
|
||||
/**
|
||||
* @brief Compare two values by identity, then by equality.
|
||||
@ -179,9 +188,11 @@ extern int krk_valuesSame(KrkValue a, KrkValue b);
|
||||
*
|
||||
* @return 1 if values represent the same object or value, 0 otherwise.
|
||||
*/
|
||||
extern int krk_valuesSameOrEqual(KrkValue a, KrkValue b);
|
||||
extern int krk_valuesSameOrEqual_r(struct KrkThreadState * _thread, KrkValue a, KrkValue b);
|
||||
#define krk_valuesSameOrEqual(a,b) krk_valuesSameOrEqual_r(_thread,a,b)
|
||||
|
||||
extern KrkValue krk_parse_int(const char * start, size_t width, unsigned int base);
|
||||
extern KrkValue krk_parse_int_r(struct KrkThreadState * _thread, const char * start, size_t width, unsigned int base);
|
||||
#define krk_parse_int(s,w,b) krk_parse_int_r(_thread,s,w,b)
|
||||
|
||||
typedef union {
|
||||
KrkValue val;
|
||||
|
207
src/kuroko/vm.h
207
src/kuroko/vm.h
@ -171,6 +171,7 @@ typedef struct KrkThreadState {
|
||||
KrkValue * stackMax; /**< End of allocated stack space. */
|
||||
|
||||
KrkValue scratchSpace[KRK_THREAD_SCRATCH_SIZE]; /**< A place to store a few values to keep them from being prematurely GC'd. */
|
||||
struct KrkVM * owner;
|
||||
} KrkThreadState;
|
||||
|
||||
/**
|
||||
@ -224,42 +225,13 @@ typedef struct KrkVM {
|
||||
#define KRK_GLOBAL_THREADS (1 << 13)
|
||||
#define KRK_GLOBAL_NO_DEFAULT_MODULES (1 << 14)
|
||||
|
||||
#ifndef KRK_DISABLE_THREADS
|
||||
# define threadLocal __thread
|
||||
#else
|
||||
# define threadLocal
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Thread-local VM state.
|
||||
*
|
||||
* See @c KrkThreadState for more information.
|
||||
*/
|
||||
#if !defined(KRK_DISABLE_THREADS) && ((defined(__APPLE__)) && defined(__aarch64__))
|
||||
extern void krk_forceThreadData(void);
|
||||
#define krk_currentThread (*_macos_currentThread())
|
||||
#pragma clang diagnostic ignored "-Wlanguage-extension-token"
|
||||
inline KrkThreadState * _macos_currentThread(void) {
|
||||
extern const uint64_t tls_desc[] asm("_krk_currentThread");
|
||||
const uintptr_t * threadptr; asm ("mrs %0, TPIDRRO_EL0" : "=r"(threadptr));
|
||||
return (KrkThreadState*)(threadptr[tls_desc[1]] + tls_desc[2]);
|
||||
}
|
||||
#elif !defined(KRK_DISABLE_THREADS) && ((defined(_WIN32) && !defined(KRKINLIB)) || defined(KRK_MEDIOCRE_TLS))
|
||||
#define krk_currentThread (*krk_getCurrentThread())
|
||||
#else
|
||||
extern threadLocal KrkThreadState krk_currentThread;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Singleton instance of the shared VM state.
|
||||
*/
|
||||
extern KrkVM krk_vm;
|
||||
|
||||
/**
|
||||
* @def vm
|
||||
* @brief Convenience macro for namespacing.
|
||||
*/
|
||||
#define vm krk_vm
|
||||
#define krk_currentThread (*_thread)
|
||||
#define vm (*_thread->owner)
|
||||
|
||||
/**
|
||||
* @brief Initialize the VM at program startup.
|
||||
@ -273,7 +245,7 @@ extern KrkVM krk_vm;
|
||||
*
|
||||
* @param flags Combination of global VM flags and initial thread flags.
|
||||
*/
|
||||
extern void krk_initVM(int flags);
|
||||
extern KrkThreadState * krk_initVM(int flags);
|
||||
|
||||
/**
|
||||
* @brief Release resources from the VM.
|
||||
@ -285,7 +257,7 @@ extern void krk_initVM(int flags);
|
||||
* heap memory, FILE pointers or descriptors, or various other things which were
|
||||
* initialized by C extension modules.
|
||||
*/
|
||||
extern void krk_freeVM(void);
|
||||
extern void krk_freeVM(KrkThreadState*);
|
||||
|
||||
/**
|
||||
* @brief Reset the current thread's stack state to the top level.
|
||||
@ -295,7 +267,7 @@ extern void krk_freeVM(void);
|
||||
* during normal execution by C extensions. Values on the stack may be lost
|
||||
* to garbage collection after a call to @c krk_resetStack .
|
||||
*/
|
||||
extern void krk_resetStack(void);
|
||||
extern void krk_resetStack(KrkThreadState *);
|
||||
|
||||
/**
|
||||
* @brief Compile and execute a source code input.
|
||||
@ -316,7 +288,7 @@ extern void krk_resetStack(void);
|
||||
* indicate @c KRK_THREAD_HAS_EXCEPTION and @c krk_currentThread.currentException
|
||||
* should contain the raised exception value.
|
||||
*/
|
||||
extern KrkValue krk_interpret(const char * src, char * fromFile);
|
||||
extern KrkValue krk_interpret(KrkThreadState *, const char * src, char * fromFile);
|
||||
|
||||
/**
|
||||
* @brief Load and run a source file and return when execution completes.
|
||||
@ -330,7 +302,7 @@ extern KrkValue krk_interpret(const char * src, char * fromFile);
|
||||
* @return As with @c krk_interpret, an object representing the newly created module,
|
||||
* or the final return value of the VM execution.
|
||||
*/
|
||||
extern KrkValue krk_runfile(const char * fileName, char * fromFile);
|
||||
extern KrkValue krk_runfile(KrkThreadState *, const char * fileName, char * fromFile);
|
||||
|
||||
/**
|
||||
* @brief Push a stack value.
|
||||
@ -340,7 +312,8 @@ extern KrkValue krk_runfile(const char * fileName, char * fromFile);
|
||||
*
|
||||
* @param value Value to push.
|
||||
*/
|
||||
extern void krk_push(KrkValue value);
|
||||
extern void krk_push_r(KrkThreadState *, KrkValue value);
|
||||
#define krk_push(v) krk_push_r(_thread, v)
|
||||
|
||||
/**
|
||||
* @brief Pop the top of the stack.
|
||||
@ -352,7 +325,8 @@ extern void krk_push(KrkValue value);
|
||||
*
|
||||
* @return The value previously at the top of the stack.
|
||||
*/
|
||||
extern KrkValue krk_pop(void);
|
||||
extern KrkValue krk_pop_r(KrkThreadState *);
|
||||
#define krk_pop() krk_pop_r(_thread)
|
||||
|
||||
/**
|
||||
* @brief Peek down from the top of the stack.
|
||||
@ -362,7 +336,8 @@ extern KrkValue krk_pop(void);
|
||||
* @param distance How far down from the top of the stack to peek (0 = the top)
|
||||
* @return The value from the stack.
|
||||
*/
|
||||
extern KrkValue krk_peek(int distance);
|
||||
extern KrkValue krk_peek_r(KrkThreadState *, int distance);
|
||||
#define krk_peek(d) krk_peek_r(_thread, d)
|
||||
|
||||
/**
|
||||
* @brief Swap the top of the stack of the value @p distance slots down.
|
||||
@ -372,7 +347,8 @@ extern KrkValue krk_peek(int distance);
|
||||
*
|
||||
* @param distance How from down from the top of the stack to swap (0 = the top)
|
||||
*/
|
||||
extern void krk_swap(int distance);
|
||||
extern void krk_swap_r(KrkThreadState *, int distance);
|
||||
#define krk_swap(d) krk_swap_r(_thread, d)
|
||||
|
||||
/**
|
||||
* @brief Get the name of the type of a value.
|
||||
@ -385,7 +361,8 @@ extern void krk_swap(int distance);
|
||||
* @param value Value to examine
|
||||
* @return Nul-terminated C string of the type of @p value
|
||||
*/
|
||||
extern const char * krk_typeName(KrkValue value);
|
||||
extern const char * krk_typeName_r(KrkThreadState *, KrkValue value);
|
||||
#define krk_typeName(v) krk_typeName_r(_thread, v)
|
||||
|
||||
/**
|
||||
* @brief Attach a native C function to an attribute table.
|
||||
@ -402,7 +379,8 @@ extern const char * krk_typeName(KrkValue value);
|
||||
* @param function Native function pointer to attach
|
||||
* @return A pointer to the object representing the attached function.
|
||||
*/
|
||||
extern KrkNative * krk_defineNative(KrkTable * table, const char * name, NativeFn function);
|
||||
extern KrkNative * krk_defineNative_r(KrkThreadState *, KrkTable * table, const char * name, NativeFn function);
|
||||
#define krk_defineNative(t,n,f) krk_defineNative_r(_thread,t,n,f)
|
||||
|
||||
/**
|
||||
* @brief Attach a native dynamic property to an attribute table.
|
||||
@ -417,7 +395,8 @@ extern KrkNative * krk_defineNative(KrkTable * table, const char * name, NativeF
|
||||
* @param func Native function pointer to attach
|
||||
* @return A pointer to the property object created.
|
||||
*/
|
||||
extern KrkNative * krk_defineNativeProperty(KrkTable * table, const char * name, NativeFn func);
|
||||
extern KrkNative * krk_defineNativeProperty_r(KrkThreadState *, KrkTable * table, const char * name, NativeFn func);
|
||||
#define krk_defineNativeProperty(t,n,f) krk_defineNativeProperty_r(_thread,t,n,f)
|
||||
|
||||
/**
|
||||
* @brief Attach a value to an attribute table.
|
||||
@ -441,7 +420,8 @@ extern KrkNative * krk_defineNativeProperty(KrkTable * table, const char * name,
|
||||
* @param name Nil-terminated C string with the name to assign
|
||||
* @param obj Value to attach.
|
||||
*/
|
||||
extern void krk_attachNamedValue(KrkTable * table, const char name[], KrkValue obj);
|
||||
extern void krk_attachNamedValue_r(KrkThreadState *, KrkTable * table, const char name[], KrkValue obj);
|
||||
#define krk_attachNamedValue(t,n,o) krk_attachNamedValue_r(_thread,t,n,o)
|
||||
|
||||
/**
|
||||
* @brief Attach an object to an attribute table.
|
||||
@ -467,7 +447,8 @@ extern void krk_attachNamedValue(KrkTable * table, const char name[], KrkValue o
|
||||
* @param name Nil-terminated C string with the name to assign
|
||||
* @param obj Object to attach.
|
||||
*/
|
||||
extern void krk_attachNamedObject(KrkTable * table, const char name[], KrkObj * obj);
|
||||
extern void krk_attachNamedObject_r(KrkThreadState *, KrkTable * table, const char name[], KrkObj * obj);
|
||||
#define krk_attachNamedObject(t,n,o) krk_attachNamedObject_r(_thread,t,n,o)
|
||||
|
||||
/**
|
||||
* @brief Produce and raise an exception with a formatted message.
|
||||
@ -498,7 +479,8 @@ extern void krk_attachNamedObject(KrkTable * table, const char name[], KrkObj *
|
||||
* @param fmt Format string.
|
||||
* @return As a convenience to C extension authors, returns @c None
|
||||
*/
|
||||
extern KrkValue krk_runtimeError(KrkClass * type, const char * fmt, ...);
|
||||
extern KrkValue krk_runtimeError_r(KrkThreadState *, KrkClass * type, const char * fmt, ...);
|
||||
#define krk_runtimeError(t,...) krk_runtimeError_r(_thread, t, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Raise an exception value.
|
||||
@ -516,7 +498,8 @@ extern KrkValue krk_runtimeError(KrkClass * type, const char * fmt, ...);
|
||||
* @param base Exception object or class to raise.
|
||||
* @param cause Exception cause object or class to attach.
|
||||
*/
|
||||
extern void krk_raiseException(KrkValue base, KrkValue cause);
|
||||
extern void krk_raiseException_r(KrkThreadState *, KrkValue base, KrkValue cause);
|
||||
#define krk_raiseException(b,c) krk_raiseException_r(_thread,b,c)
|
||||
|
||||
/**
|
||||
* @brief Attach an inner exception to the current exception object.
|
||||
@ -527,7 +510,8 @@ extern void krk_raiseException(KrkValue base, KrkValue cause);
|
||||
*
|
||||
* @param innerException \__context__ to set.
|
||||
*/
|
||||
extern void krk_attachInnerException(KrkValue innerException);
|
||||
extern void krk_attachInnerException_r(KrkThreadState *, KrkValue innerException);
|
||||
#define krk_attachInnerException(i) krk_attachInnerException_r(_thread,i)
|
||||
|
||||
/**
|
||||
* @brief Get a pointer to the current thread state.
|
||||
@ -538,7 +522,8 @@ extern void krk_attachInnerException(KrkValue innerException);
|
||||
*
|
||||
* @return Pointer to current thread's thread state.
|
||||
*/
|
||||
extern KrkThreadState * krk_getCurrentThread(void);
|
||||
//extern KrkThreadState * krk_getCurrentThread(void);
|
||||
#define krk_getCurrentThread() (_thread)
|
||||
|
||||
/**
|
||||
* @brief Continue VM execution until the next exit trigger.
|
||||
@ -553,7 +538,8 @@ extern KrkThreadState * krk_getCurrentThread(void);
|
||||
* returned by the inner function before the VM returned
|
||||
* to the exit frame.
|
||||
*/
|
||||
extern KrkValue krk_runNext(void);
|
||||
extern KrkValue krk_runNext_r(KrkThreadState *);
|
||||
#define krk_runNext() krk_runNext_r(_thread);
|
||||
|
||||
/**
|
||||
* @brief Get the class representing a value.
|
||||
@ -566,7 +552,9 @@ extern KrkValue krk_runNext(void);
|
||||
* @param value Reference value to examine.
|
||||
* @return A pointer to the value's type's class object.
|
||||
*/
|
||||
extern KrkClass * krk_getType(KrkValue value);
|
||||
extern KrkClass * krk_getType_r(KrkThreadState *, KrkValue value);
|
||||
#define krk_getType(v) krk_getType_r(_thread,v)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Determine if a class is an instance or subclass of a given type.
|
||||
@ -585,7 +573,8 @@ extern KrkClass * krk_getType(KrkValue value);
|
||||
* @param type Class object to test for membership of.
|
||||
* @return 1 if @p obj is an instance of @p type or of a subclass of @p type
|
||||
*/
|
||||
extern int krk_isInstanceOf(KrkValue obj, const KrkClass * type);
|
||||
extern int krk_isInstanceOf_r(KrkThreadState *, KrkValue obj, const KrkClass * type);
|
||||
#define krk_isInstanceOf(o,t) krk_isInstanceOf_r(_thread,o,t)
|
||||
|
||||
/**
|
||||
* @brief Perform method binding on the stack.
|
||||
@ -601,7 +590,8 @@ extern int krk_isInstanceOf(KrkValue obj, const KrkClass * type);
|
||||
* @param name String object with the name of the method to resolve.
|
||||
* @return 1 if the method has been bound, 0 if binding failed.
|
||||
*/
|
||||
extern int krk_bindMethod(KrkClass * _class, KrkString * name);
|
||||
extern int krk_bindMethod_r(KrkThreadState *, KrkClass * _class, KrkString * name);
|
||||
#define krk_bindMethod(c,n) krk_bindMethod_r(_thread,c,n)
|
||||
|
||||
/**
|
||||
* @brief Call a callable value in the current stack context.
|
||||
@ -621,37 +611,43 @@ extern int krk_bindMethod(KrkClass * _class, KrkString * name);
|
||||
* 2: The callable was a native function and result should be popped now.
|
||||
* Else: The call failed. An exception may have already been set.
|
||||
*/
|
||||
extern int krk_callValue(KrkValue callee, int argCount, int callableOnStack);
|
||||
extern int krk_callValue_r(KrkThreadState *, KrkValue callee, int argCount, int callableOnStack);
|
||||
#define krk_callValue(c,a,s) krk_callValue_r(_thread,c,a,s)
|
||||
|
||||
/**
|
||||
* @brief Create a list object.
|
||||
* @memberof KrkList
|
||||
*/
|
||||
extern KrkValue krk_list_of(int argc, const KrkValue argv[], int hasKw);
|
||||
extern KrkValue krk_list_of_r(KrkThreadState *, int argc, const KrkValue argv[], int hasKw);
|
||||
#define krk_list_of(c,v,k) krk_list_of_r(_thread,c,v,k)
|
||||
|
||||
/**
|
||||
* @brief Create a dict object.
|
||||
* @memberof KrkDict
|
||||
*/
|
||||
extern KrkValue krk_dict_of(int argc, const KrkValue argv[], int hasKw);
|
||||
extern KrkValue krk_dict_of_r(KrkThreadState *, int argc, const KrkValue argv[], int hasKw);
|
||||
#define krk_dict_of(c,v,k) krk_dict_of_r(_thread,c,v,k)
|
||||
|
||||
/**
|
||||
* @brief Create a tuple object.
|
||||
* @memberof KrkTuple
|
||||
*/
|
||||
extern KrkValue krk_tuple_of(int argc, const KrkValue argv[], int hasKw);
|
||||
extern KrkValue krk_tuple_of_r(KrkThreadState *, int argc, const KrkValue argv[], int hasKw);
|
||||
#define krk_tuple_of(c,v,k) krk_tuple_of_r(_thread,c,v,k)
|
||||
|
||||
/**
|
||||
* @brief Create a set object.
|
||||
* @memberof Set
|
||||
*/
|
||||
extern KrkValue krk_set_of(int argc, const KrkValue argv[], int hasKw);
|
||||
extern KrkValue krk_set_of_r(KrkThreadState *, int argc, const KrkValue argv[], int hasKw);
|
||||
#define krk_set_of(c,v,k) krk_set_of_r(_thread,c,v,k)
|
||||
|
||||
/**
|
||||
* @brief Create a slice object.
|
||||
* @memberof KrkSlice
|
||||
*/
|
||||
extern KrkValue krk_slice_of(int argc, const KrkValue argv[], int hasKw);
|
||||
extern KrkValue krk_slice_of_r(KrkThreadState *, int argc, const KrkValue argv[], int hasKw);
|
||||
#define krk_slice_of(c,v,k) krk_slice_of_r(_thread,c,v,k)
|
||||
|
||||
/**
|
||||
* @brief Call a callable on the stack with @p argCount arguments.
|
||||
@ -665,7 +661,8 @@ extern KrkValue krk_slice_of(int argc, const KrkValue argv[], int hasKw);
|
||||
* @param argCount Arguments to collect from the stack.
|
||||
* @return The return value of the function.
|
||||
*/
|
||||
extern KrkValue krk_callStack(int argCount);
|
||||
extern KrkValue krk_callStack_r(KrkThreadState *, int argCount);
|
||||
#define krk_callStack(a) krk_callStack_r(_thread,a)
|
||||
|
||||
/**
|
||||
* @brief Call a closure or native function with @p argCount arguments.
|
||||
@ -678,7 +675,8 @@ extern KrkValue krk_callStack(int argCount);
|
||||
* @param argCount Arguments to collect from the stack.
|
||||
* @return The return value of the function.
|
||||
*/
|
||||
extern KrkValue krk_callDirect(KrkObj * callable, int argCount);
|
||||
extern KrkValue krk_callDirect_r(KrkThreadState *, KrkObj * callable, int argCount);
|
||||
#define krk_callDirect(c,a) krk_callDirect_r(_thread,c,a)
|
||||
|
||||
/**
|
||||
* @brief Convenience function for creating new types.
|
||||
@ -693,7 +691,8 @@ extern KrkValue krk_callDirect(KrkObj * callable, int argCount);
|
||||
* @param base Pointer to class object to inherit from.
|
||||
* @return A pointer to the class object, equivalent to the value assigned to @p _class.
|
||||
*/
|
||||
extern KrkClass * krk_makeClass(KrkInstance * module, KrkClass ** _class, const char * name, KrkClass * base);
|
||||
extern KrkClass * krk_makeClass_r(KrkThreadState *, KrkInstance * module, KrkClass ** _class, const char * name, KrkClass * base);
|
||||
#define krk_makeClass(m,c,n,b) krk_makeClass_r(_thread,m,c,n,b)
|
||||
|
||||
/**
|
||||
* @brief Finalize a class by collecting pointers to core methods.
|
||||
@ -705,7 +704,8 @@ extern KrkClass * krk_makeClass(KrkInstance * module, KrkClass ** _class, const
|
||||
*
|
||||
* @param _class Class object to finalize.
|
||||
*/
|
||||
extern void krk_finalizeClass(KrkClass * _class);
|
||||
extern void krk_finalizeClass_r(KrkThreadState *, KrkClass * _class);
|
||||
#define krk_finalizeClass(c) krk_finalizeClass_r(_thread,c)
|
||||
|
||||
/**
|
||||
* @brief If there is an active exception, print a traceback to @c stderr
|
||||
@ -718,7 +718,8 @@ extern void krk_finalizeClass(KrkClass * _class);
|
||||
* open source files to print faulting lines and may call into the VM if the
|
||||
* exception object has a managed implementation of @c \__str__.
|
||||
*/
|
||||
extern void krk_dumpTraceback(void);
|
||||
extern void krk_dumpTraceback_r(KrkThreadState *);
|
||||
#define krk_dumpTraceback() krk_dumpTraceback_r(_thread)
|
||||
|
||||
/**
|
||||
* @brief Set up a new module object in the current thread.
|
||||
@ -730,14 +731,16 @@ extern void krk_dumpTraceback(void);
|
||||
* @param name Name of the module, which is assigned to @c \__name__
|
||||
* @return The instance object representing the module.
|
||||
*/
|
||||
extern KrkInstance * krk_startModule(const char * name);
|
||||
extern KrkInstance * krk_startModule_r(KrkThreadState *, const char * name);
|
||||
#define krk_startModule(n) krk_startModule_r(_thread,n)
|
||||
|
||||
/**
|
||||
* @brief Obtain a list of properties for an object.
|
||||
*
|
||||
* This is the native function bound to @c object.__dir__
|
||||
*/
|
||||
extern KrkValue krk_dirObject(int argc, const KrkValue argv[], int hasKw);
|
||||
extern KrkValue krk_dirObject_r(KrkThreadState *, int argc, const KrkValue argv[], int hasKw);
|
||||
#define krk_dirObject(c,v,k) krk_dirObject_r(_thread,c,v,k)
|
||||
|
||||
/**
|
||||
* @brief Load a module from a file with a specified name.
|
||||
@ -752,7 +755,8 @@ extern KrkValue krk_dirObject(int argc, const KrkValue argv[], int hasKw);
|
||||
* @param parent Parent module object, if loaded from a package.
|
||||
* @return 1 if the module was loaded, 0 if an @ref ImportError occurred.
|
||||
*/
|
||||
extern int krk_loadModule(KrkString * path, KrkValue * moduleOut, KrkString * runAs, KrkValue parent);
|
||||
extern int krk_loadModule_r(KrkThreadState *, KrkString * path, KrkValue * moduleOut, KrkString * runAs, KrkValue parent);
|
||||
#define krk_loadModule(f,m,r,p) krk_loadModule_r(_thread,f,m,r,p)
|
||||
|
||||
/**
|
||||
* @brief Load a module by a dotted name.
|
||||
@ -763,7 +767,8 @@ extern int krk_loadModule(KrkString * path, KrkValue * moduleOut, KrkString * ru
|
||||
* @param name String object of the dot-separated package path to import.
|
||||
* @return 1 if the module was loaded, 0 if an @ref ImportError occurred.
|
||||
*/
|
||||
extern int krk_doRecursiveModuleLoad(KrkString * name);
|
||||
extern int krk_doRecursiveModuleLoad_r(KrkThreadState *, KrkString * name);
|
||||
#define krk_doRecursiveModuleLoad(n) krk_doRecursiveModuleLoad_r(_thread,n)
|
||||
|
||||
/**
|
||||
* @brief Load the dotted name @p name with the final element as @p runAs
|
||||
@ -777,7 +782,8 @@ extern int krk_doRecursiveModuleLoad(KrkString * name);
|
||||
* @param runAs Alternative name to attach to @c \__name__ for the module.
|
||||
* @return 1 on success, 0 on failure.
|
||||
*/
|
||||
extern int krk_importModule(KrkString * name, KrkString * runAs);
|
||||
extern int krk_importModule_r(KrkThreadState *, KrkString * name, KrkString * runAs);
|
||||
#define krk_importModule(n,r) krk_importModule_r(_thread,n,r)
|
||||
|
||||
/**
|
||||
* @brief Determine the truth of a value.
|
||||
@ -790,7 +796,8 @@ extern int krk_importModule(KrkString * name, KrkString * runAs);
|
||||
* @param value Value to examine.
|
||||
* @return 1 if falsey, 0 if truthy
|
||||
*/
|
||||
extern int krk_isFalsey(KrkValue value);
|
||||
extern int krk_isFalsey_r(KrkThreadState *, KrkValue value);
|
||||
#define krk_isFalsey(v) krk_isFalsey_r(_thread,v)
|
||||
|
||||
/**
|
||||
* @brief Obtain a property of an object by name.
|
||||
@ -808,12 +815,14 @@ extern int krk_isFalsey(KrkValue value);
|
||||
* exception set in the current thread if the attribute was
|
||||
* not found.
|
||||
*/
|
||||
extern KrkValue krk_valueGetAttribute(KrkValue value, char * name);
|
||||
extern KrkValue krk_valueGetAttribute_r(KrkThreadState *, KrkValue value, char * name);
|
||||
#define krk_valueGetAttribute(v,n) krk_valueGetAttribute_r(_thread,v,n)
|
||||
|
||||
/**
|
||||
* @brief See @ref krk_valueGetAttribute
|
||||
*/
|
||||
extern KrkValue krk_valueGetAttribute_default(KrkValue value, char * name, KrkValue defaultVal);
|
||||
extern KrkValue krk_valueGetAttribute_default_r(KrkThreadState *, KrkValue value, char * name, KrkValue defaultVal);
|
||||
#define krk_valueGetAttribute_default(v,n,d) krk_valueGetAttribute_default_r(_thread,v,n,d)
|
||||
|
||||
/**
|
||||
* @brief Set a property of an object by name.
|
||||
@ -832,7 +841,8 @@ extern KrkValue krk_valueGetAttribute_default(KrkValue value, char * name, KrkVa
|
||||
* exception set in the current thread if the object can
|
||||
* not have a property set.
|
||||
*/
|
||||
extern KrkValue krk_valueSetAttribute(KrkValue owner, char * name, KrkValue to);
|
||||
extern KrkValue krk_valueSetAttribute_r(KrkThreadState *, KrkValue owner, char * name, KrkValue to);
|
||||
#define krk_valueSetAttribute(o,n,t) krk_valueSetAttribute_r(_thread,o,n,t)
|
||||
|
||||
/**
|
||||
* @brief Delete a property of an object by name.
|
||||
@ -847,7 +857,8 @@ extern KrkValue krk_valueSetAttribute(KrkValue owner, char * name, KrkValue to);
|
||||
* @param owner The owner of the property to delete.
|
||||
* @param name C-string of the property name to delete.
|
||||
*/
|
||||
extern KrkValue krk_valueDelAttribute(KrkValue owner, char * name);
|
||||
extern KrkValue krk_valueDelAttribute_r(KrkThreadState *, KrkValue owner, char * name);
|
||||
#define krk_valueDelAttribute(o,n) krk_valueDelAttribute_r(_thread,o,n)
|
||||
|
||||
/**
|
||||
* @brief Concatenate two strings.
|
||||
@ -855,42 +866,48 @@ extern KrkValue krk_valueDelAttribute(KrkValue owner, char * name);
|
||||
* This is a convenience function which calls @c str.__add__ on the top stack
|
||||
* values. Generally, this should be avoided - use @c StringBuilder instead.
|
||||
*/
|
||||
extern void krk_addObjects(void);
|
||||
extern void krk_addObjects_r(KrkThreadState *);
|
||||
#define krk_addObjects() krk_addObjects_r(_thread)
|
||||
|
||||
/**
|
||||
* @brief Compare two values, returning @ref True if the left is less than the right.
|
||||
*
|
||||
* This is equivalent to the opcode instruction OP_LESS.
|
||||
*/
|
||||
extern KrkValue krk_operator_lt(KrkValue,KrkValue);
|
||||
extern KrkValue krk_operator_lt_r(KrkThreadState *, KrkValue,KrkValue);
|
||||
#define krk_operator_lt(a,b) krk_operator_lt_r(_thread,a,b)
|
||||
|
||||
/**
|
||||
* @brief Compare to values, returning @ref True if the left is greater than the right.
|
||||
*
|
||||
* This is equivalent to the opcode instruction OP_GREATER.
|
||||
*/
|
||||
extern KrkValue krk_operator_gt(KrkValue,KrkValue);
|
||||
extern KrkValue krk_operator_gt_r(KrkThreadState *, KrkValue,KrkValue);
|
||||
#define krk_operator_gt(a,b) krk_operator_gt_r(_thread,a,b)
|
||||
|
||||
/**
|
||||
* @brief Compare two values, returning @ref True if the left is less than or equal to the right.
|
||||
*
|
||||
* This is equivalent to the opcode instruction OP_LESS_EQUAL.
|
||||
*/
|
||||
extern KrkValue krk_operator_le(KrkValue,KrkValue);
|
||||
extern KrkValue krk_operator_le_r(KrkThreadState *, KrkValue,KrkValue);
|
||||
#define krk_operator_le(a,b) krk_operator_le_r(_thread,a,b)
|
||||
|
||||
/**
|
||||
* @brief Compare to values, returning @ref True if the left is greater than or equal to the right.
|
||||
*
|
||||
* This is equivalent to the opcode instruction OP_GREATER_EQUAL.
|
||||
*/
|
||||
extern KrkValue krk_operator_ge(KrkValue,KrkValue);
|
||||
extern KrkValue krk_operator_ge_r(KrkThreadState *, KrkValue,KrkValue);
|
||||
#define krk_operator_ge(a,b) krk_operator_ge_r(_thread,a,b)
|
||||
|
||||
/**
|
||||
* @brief Set the maximum recursion call depth.
|
||||
*
|
||||
* Must not be called while execution is in progress.
|
||||
*/
|
||||
extern void krk_setMaximumRecursionDepth(size_t maxDepth);
|
||||
extern void krk_setMaximumRecursionDepth_r(KrkThreadState *, size_t maxDepth);
|
||||
#define krk_setMaximumRecursionDepth(m) krk_setMaximumRecursionDepth_r(_thread,m)
|
||||
|
||||
/**
|
||||
* @brief Call a native function using a reference to stack arguments safely.
|
||||
@ -902,7 +919,8 @@ extern void krk_setMaximumRecursionDepth(size_t maxDepth);
|
||||
* held stack is reallocated, it will be freed when execution returns to the call
|
||||
* to @c krk_callNativeOnStack that holds it.
|
||||
*/
|
||||
extern KrkValue krk_callNativeOnStack(size_t argCount, const KrkValue *stackArgs, int hasKw, NativeFn native);
|
||||
extern KrkValue krk_callNativeOnStack_r(KrkThreadState *, size_t argCount, const KrkValue *stackArgs, int hasKw, NativeFn native);
|
||||
#define krk_callNativeOnStack(c,v,k,n) krk_callNativeOnStack_r(_thread,c,v,k,n)
|
||||
|
||||
/**
|
||||
* @brief Set an attribute of an instance object, bypassing \__setattr__.
|
||||
@ -918,7 +936,8 @@ extern KrkValue krk_callNativeOnStack(size_t argCount, const KrkValue *stackArgs
|
||||
* @param to New value for the attribute
|
||||
* @return The value set, which is likely @p to but may be the returned value of a descriptor \__set__ method.
|
||||
*/
|
||||
extern KrkValue krk_instanceSetAttribute_wrapper(KrkValue owner, KrkString * name, KrkValue to);
|
||||
extern KrkValue krk_instanceSetAttribute_wrapper_r(KrkThreadState *, KrkValue owner, KrkString * name, KrkValue to);
|
||||
#define krk_instanceSetAttribute_wrapper(o,n,t) krk_instanceSetAttribute_wrapper_r(_thread,o,n,t)
|
||||
|
||||
/**
|
||||
* @brief Implementation of the GET_PROPERTY instruction.
|
||||
@ -933,7 +952,9 @@ extern KrkValue krk_instanceSetAttribute_wrapper(KrkValue owner, KrkString * nam
|
||||
* @param name Name of the attribute to look up.
|
||||
* @return 1 if the attribute was found, 0 otherwise.
|
||||
*/
|
||||
extern int krk_getAttribute(KrkString * name);
|
||||
extern int krk_getAttribute_r(KrkThreadState *, KrkString * name);
|
||||
#define krk_getAttribute(n) krk_getAttribute_r(_thread,n)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Implementation of the SET_PROPERTY instruction.
|
||||
@ -950,7 +971,8 @@ extern int krk_getAttribute(KrkString * name);
|
||||
* @param name Name of the attribute to set.
|
||||
* @return 1 if the attribute could be set, 0 otherwise.
|
||||
*/
|
||||
extern int krk_setAttribute(KrkString * name);
|
||||
extern int krk_setAttribute_r(KrkThreadState *, KrkString * name);
|
||||
#define krk_setAttribute(n) krk_setAttribute_r(_thread,n)
|
||||
|
||||
/**
|
||||
* @brief Implementation of the DEL_PROPERTY instruction.
|
||||
@ -965,45 +987,46 @@ extern int krk_setAttribute(KrkString * name);
|
||||
* @param name Name of the attribute to delete.
|
||||
* @return 1 if the attribute was found and can be deleted, 0 otherwise.
|
||||
*/
|
||||
extern int krk_delAttribute(KrkString * name);
|
||||
extern int krk_delAttribute_r(KrkThreadState *, KrkString * name);
|
||||
#define krk_delAttribute(n) krk_delAttribute_r(_thread,n)
|
||||
|
||||
/**
|
||||
* @brief Initialize the built-in 'kuroko' module.
|
||||
*/
|
||||
extern void krk_module_init_kuroko(void);
|
||||
extern void krk_module_init_kuroko(KrkThreadState *);
|
||||
|
||||
/**
|
||||
* @brief Initialize the built-in 'gc' module.
|
||||
*/
|
||||
extern void krk_module_init_gc(void);
|
||||
extern void krk_module_init_gc(KrkThreadState *);
|
||||
|
||||
/**
|
||||
* @brief Initialize the built-in 'time' module.
|
||||
*/
|
||||
extern void krk_module_init_time(void);
|
||||
extern void krk_module_init_time(KrkThreadState *);
|
||||
|
||||
/**
|
||||
* @brief Initialize the built-in 'os' module.
|
||||
*/
|
||||
extern void krk_module_init_os(void);
|
||||
extern void krk_module_init_os(KrkThreadState *);
|
||||
|
||||
/**
|
||||
* @brief Initialize the built-in 'fileio' module.
|
||||
*/
|
||||
extern void krk_module_init_fileio(void);
|
||||
extern void krk_module_init_fileio(KrkThreadState *);
|
||||
|
||||
/**
|
||||
* @brief Initialize the built-in 'dis' module.
|
||||
*
|
||||
* Not available if KRK_DISABLE_DEBUG is set.
|
||||
*/
|
||||
extern void krk_module_init_dis(void);
|
||||
extern void krk_module_init_dis(KrkThreadState *);
|
||||
|
||||
/**
|
||||
* @brief Initialize the built-in 'threading' module.
|
||||
*
|
||||
* Not available if KRK_DISABLE_THREADS is set.
|
||||
*/
|
||||
extern void krk_module_init_threading(void);
|
||||
extern void krk_module_init_threading(KrkThreadState *);
|
||||
|
||||
|
||||
|
64
src/memory.c
64
src/memory.c
@ -143,7 +143,7 @@ static int _debug_mem_has(const void *ptr) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void krk_gcTakeBytes(const void * ptr, size_t size) {
|
||||
void krk_gcTakeBytes_r(KrkThreadState * _thread, const void * ptr, size_t size) {
|
||||
#if defined(KRK_EXTENSIVE_MEMORY_DEBUGGING)
|
||||
_debug_mem_set(ptr, size);
|
||||
#endif
|
||||
@ -151,7 +151,7 @@ void krk_gcTakeBytes(const void * ptr, size_t size) {
|
||||
vm.bytesAllocated += size;
|
||||
}
|
||||
|
||||
void * krk_reallocate(void * ptr, size_t old, size_t new) {
|
||||
void * krk_reallocate_r(KrkThreadState * _thread, void * ptr, size_t old, size_t new) {
|
||||
|
||||
vm.bytesAllocated -= old;
|
||||
vm.bytesAllocated += new;
|
||||
@ -198,7 +198,7 @@ void * krk_reallocate(void * ptr, size_t old, size_t new) {
|
||||
return out;
|
||||
}
|
||||
|
||||
static void freeObject(KrkObj * object) {
|
||||
static void freeObject(KrkThreadState * _thread, KrkObj * object) {
|
||||
switch (object->type) {
|
||||
case KRK_OBJ_STRING: {
|
||||
KrkString * string = (KrkString*)object;
|
||||
@ -245,7 +245,7 @@ static void freeObject(KrkObj * object) {
|
||||
case KRK_OBJ_INSTANCE: {
|
||||
KrkInstance * inst = (KrkInstance*)object;
|
||||
if (inst->_class->_ongcsweep) {
|
||||
inst->_class->_ongcsweep(inst);
|
||||
inst->_class->_ongcsweep(_thread, inst);
|
||||
}
|
||||
krk_freeTable(&inst->fields);
|
||||
krk_reallocate(object,inst->_class->allocSize,0);
|
||||
@ -269,14 +269,14 @@ static void freeObject(KrkObj * object) {
|
||||
}
|
||||
}
|
||||
|
||||
void krk_freeObjects() {
|
||||
void krk_freeObjects_r(KrkThreadState * _thread) {
|
||||
KrkObj * object = vm.objects;
|
||||
KrkObj * other = NULL;
|
||||
|
||||
while (object) {
|
||||
KrkObj * next = object->next;
|
||||
if (object->type == KRK_OBJ_INSTANCE) {
|
||||
freeObject(object);
|
||||
freeObject(_thread, object);
|
||||
} else {
|
||||
object->next = other;
|
||||
other = object;
|
||||
@ -289,14 +289,14 @@ void krk_freeObjects() {
|
||||
if (other->type == KRK_OBJ_CLASS) {
|
||||
((KrkClass*)other)->base = NULL;
|
||||
}
|
||||
freeObject(other);
|
||||
freeObject(_thread, other);
|
||||
other = next;
|
||||
}
|
||||
|
||||
free(vm.grayStack);
|
||||
}
|
||||
|
||||
void krk_freeMemoryDebugger(void) {
|
||||
void krk_freeMemoryDebugger_r(KrkThreadState * _thread) {
|
||||
#if defined(KRK_EXTENSIVE_MEMORY_DEBUGGING)
|
||||
for (unsigned int i = 0; i < DHE_SIZE; ++i) {
|
||||
_dhe * x = _debug_mem[i];
|
||||
@ -313,7 +313,7 @@ void krk_freeMemoryDebugger(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void krk_markObject(KrkObj * object) {
|
||||
void krk_markObject_r(KrkThreadState * _thread, KrkObj * object) {
|
||||
if (!object) return;
|
||||
if (object->flags & KRK_OBJ_FLAGS_IS_MARKED) return;
|
||||
object->flags |= KRK_OBJ_FLAGS_IS_MARKED;
|
||||
@ -326,18 +326,18 @@ void krk_markObject(KrkObj * object) {
|
||||
vm.grayStack[vm.grayCount++] = object;
|
||||
}
|
||||
|
||||
void krk_markValue(KrkValue value) {
|
||||
void krk_markValue_r(KrkThreadState * _thread, KrkValue value) {
|
||||
if (!IS_OBJECT(value)) return;
|
||||
krk_markObject(AS_OBJECT(value));
|
||||
}
|
||||
|
||||
static void markArray(KrkValueArray * array) {
|
||||
static void markArray(KrkThreadState * _thread, KrkValueArray * array) {
|
||||
for (size_t i = 0; i < array->count; ++i) {
|
||||
krk_markValue(array->values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void blackenObject(KrkObj * object) {
|
||||
static void blackenObject(KrkThreadState * _thread, KrkObj * object) {
|
||||
switch (object->type) {
|
||||
case KRK_OBJ_CLOSURE: {
|
||||
KrkClosure * closure = (KrkClosure *)object;
|
||||
@ -356,9 +356,9 @@ static void blackenObject(KrkObj * object) {
|
||||
krk_markObject((KrkObj*)function->qualname);
|
||||
krk_markObject((KrkObj*)function->docstring);
|
||||
krk_markObject((KrkObj*)function->chunk.filename);
|
||||
markArray(&function->requiredArgNames);
|
||||
markArray(&function->keywordArgNames);
|
||||
markArray(&function->chunk.constants);
|
||||
markArray(_thread, &function->requiredArgNames);
|
||||
markArray(_thread, &function->keywordArgNames);
|
||||
markArray(_thread, &function->chunk.constants);
|
||||
for (size_t i = 0; i < function->localNameCount; ++i) {
|
||||
krk_markObject((KrkObj*)function->localNames[i].name);
|
||||
}
|
||||
@ -378,7 +378,7 @@ static void blackenObject(KrkObj * object) {
|
||||
}
|
||||
case KRK_OBJ_INSTANCE: {
|
||||
krk_markObject((KrkObj*)((KrkInstance*)object)->_class);
|
||||
if (((KrkInstance*)object)->_class->_ongcscan) ((KrkInstance*)object)->_class->_ongcscan((KrkInstance*)object);
|
||||
if (((KrkInstance*)object)->_class->_ongcscan) ((KrkInstance*)object)->_class->_ongcscan(_thread, (KrkInstance*)object);
|
||||
krk_markTable(&((KrkInstance*)object)->fields);
|
||||
break;
|
||||
}
|
||||
@ -390,7 +390,7 @@ static void blackenObject(KrkObj * object) {
|
||||
}
|
||||
case KRK_OBJ_TUPLE: {
|
||||
KrkTuple * tuple = (KrkTuple *)object;
|
||||
markArray(&tuple->values);
|
||||
markArray(_thread, &tuple->values);
|
||||
break;
|
||||
}
|
||||
case KRK_OBJ_NATIVE:
|
||||
@ -400,14 +400,14 @@ static void blackenObject(KrkObj * object) {
|
||||
}
|
||||
}
|
||||
|
||||
static void traceReferences() {
|
||||
static void traceReferences(KrkThreadState * _thread) {
|
||||
while (vm.grayCount > 0) {
|
||||
KrkObj * object = vm.grayStack[--vm.grayCount];
|
||||
blackenObject(object);
|
||||
blackenObject(_thread, object);
|
||||
}
|
||||
}
|
||||
|
||||
static size_t sweep() {
|
||||
static size_t sweep(KrkThreadState * _thread) {
|
||||
KrkObj * previous = NULL;
|
||||
KrkObj * object = vm.objects;
|
||||
size_t count = 0;
|
||||
@ -424,7 +424,7 @@ static size_t sweep() {
|
||||
} else {
|
||||
vm.objects = object;
|
||||
}
|
||||
freeObject(unreached);
|
||||
freeObject(_thread, unreached);
|
||||
count++;
|
||||
} else {
|
||||
object->flags |= KRK_OBJ_FLAGS_SECOND_CHANCE;
|
||||
@ -435,7 +435,7 @@ static size_t sweep() {
|
||||
return count;
|
||||
}
|
||||
|
||||
void krk_markTable(KrkTable * table) {
|
||||
void krk_markTable_r(KrkThreadState * _thread, KrkTable * table) {
|
||||
for (size_t i = 0; i < table->capacity; ++i) {
|
||||
KrkTableEntry * entry = &table->entries[i];
|
||||
krk_markValue(entry->key);
|
||||
@ -443,7 +443,7 @@ void krk_markTable(KrkTable * table) {
|
||||
}
|
||||
}
|
||||
|
||||
static void tableRemoveWhite(KrkTable * table) {
|
||||
static void tableRemoveWhite(KrkThreadState * _thread, KrkTable * table) {
|
||||
for (size_t i = 0; i < table->capacity; ++i) {
|
||||
KrkTableEntry * entry = &table->entries[i];
|
||||
if (IS_OBJECT(entry->key) && !((AS_OBJECT(entry->key))->flags & KRK_OBJ_FLAGS_IS_MARKED)) {
|
||||
@ -452,7 +452,7 @@ static void tableRemoveWhite(KrkTable * table) {
|
||||
}
|
||||
}
|
||||
|
||||
static void markThreadRoots(KrkThreadState * thread) {
|
||||
static void markThreadRoots(KrkThreadState * _thread, KrkThreadState * thread) {
|
||||
for (KrkValue * slot = thread->stack; slot && slot < thread->stackTop; ++slot) {
|
||||
krk_markValue(*slot);
|
||||
}
|
||||
@ -468,10 +468,10 @@ static void markThreadRoots(KrkThreadState * thread) {
|
||||
}
|
||||
}
|
||||
|
||||
static void markRoots() {
|
||||
static void markRoots(KrkThreadState * _thread) {
|
||||
KrkThreadState * thread = vm.threads;
|
||||
while (thread) {
|
||||
markThreadRoots(thread);
|
||||
markThreadRoots(_thread, thread);
|
||||
thread = thread->next;
|
||||
}
|
||||
|
||||
@ -505,7 +505,7 @@ static int smartSize(char _out[100], size_t s) {
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t krk_collectGarbage(void) {
|
||||
size_t krk_collectGarbage_r(KrkThreadState * _thread) {
|
||||
#ifndef KRK_NO_GC_TRACING
|
||||
struct timespec outTime, inTime;
|
||||
|
||||
@ -516,10 +516,10 @@ size_t krk_collectGarbage(void) {
|
||||
size_t bytesBefore = vm.bytesAllocated;
|
||||
#endif
|
||||
|
||||
markRoots();
|
||||
traceReferences();
|
||||
tableRemoveWhite(&vm.strings);
|
||||
size_t out = sweep();
|
||||
markRoots(_thread);
|
||||
traceReferences(_thread);
|
||||
tableRemoveWhite(_thread, &vm.strings);
|
||||
size_t out = sweep(_thread);
|
||||
|
||||
/**
|
||||
* The GC scheduling is in need of some improvement. The strategy at the moment
|
||||
@ -581,7 +581,7 @@ KRK_Function(resume) {
|
||||
return NONE_VAL();
|
||||
}
|
||||
|
||||
void krk_module_init_gc(void) {
|
||||
void krk_module_init_gc(KrkThreadState * _thread) {
|
||||
/**
|
||||
* gc = module()
|
||||
*
|
||||
|
@ -39,7 +39,7 @@
|
||||
}
|
||||
|
||||
#define MATH_DELEGATE(func) \
|
||||
static KrkValue _math_ ## func(int argc, const KrkValue argv[], int hasKw) { \
|
||||
static KrkValue _math_ ## func(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { \
|
||||
ONE_ARGUMENT(func) \
|
||||
if (IS_FLOATING(argv[0])) { \
|
||||
return INTEGER_VAL(func(AS_FLOATING(argv[0]))); \
|
||||
@ -58,7 +58,7 @@ MATH_DELEGATE(floor)
|
||||
MATH_DELEGATE(trunc)
|
||||
|
||||
#define MATH_ONE_NAME(func,name) \
|
||||
static KrkValue _math_ ## name(int argc, const KrkValue argv[], int hasKw) { \
|
||||
static KrkValue _math_ ## name(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { \
|
||||
ONE_ARGUMENT(name) \
|
||||
FORCE_FLOAT(argv[0],arg_0) \
|
||||
if (IS_FLOATING(arg_0)) { \
|
||||
@ -94,7 +94,7 @@ MATH_ONE(lgamma)
|
||||
#endif
|
||||
|
||||
#define MATH_TWO(func) \
|
||||
static KrkValue _math_ ## func(int argc, const KrkValue argv[], int hasKw) { \
|
||||
static KrkValue _math_ ## func(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { \
|
||||
TWO_ARGUMENTS(func) \
|
||||
FORCE_FLOAT(argv[0],arg_0) \
|
||||
FORCE_FLOAT(argv[1],arg_1) \
|
||||
@ -109,7 +109,7 @@ MATH_TWO(remainder)
|
||||
MATH_TWO(pow)
|
||||
MATH_TWO(atan2)
|
||||
|
||||
static KrkValue _float_pow(int argc, const KrkValue argv[], int hasKw) {
|
||||
static KrkValue _float_pow(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) {
|
||||
TWO_ARGUMENTS(__pow__);
|
||||
if (unlikely(!IS_FLOATING(argv[0]))) return krk_runtimeError(vm.exceptions->typeError, "expected float");
|
||||
if (likely(IS_FLOATING(argv[1]))) {
|
||||
@ -121,7 +121,7 @@ static KrkValue _float_pow(int argc, const KrkValue argv[], int hasKw) {
|
||||
}
|
||||
|
||||
|
||||
static KrkValue _math_frexp(int argc, const KrkValue argv[], int hasKw) {
|
||||
static KrkValue _math_frexp(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) {
|
||||
ONE_ARGUMENT(frexp)
|
||||
FORCE_FLOAT(argv[0],arg_0)
|
||||
if (!IS_FLOATING(arg_0)) {
|
||||
@ -137,7 +137,7 @@ static KrkValue _math_frexp(int argc, const KrkValue argv[], int hasKw) {
|
||||
}
|
||||
|
||||
#define MATH_IS(func) \
|
||||
static KrkValue _math_ ## func(int argc, const KrkValue argv[], int hasKw) { \
|
||||
static KrkValue _math_ ## func(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) { \
|
||||
ONE_ARGUMENT(func) \
|
||||
if (!IS_FLOATING(argv[0])) REAL_NUMBER_NOT(func,argv[0]) \
|
||||
return BOOLEAN_VAL(func(AS_FLOATING(argv[0]))); \
|
||||
@ -149,7 +149,7 @@ MATH_IS(isnan)
|
||||
|
||||
#define bind(name) krk_defineNative(&module->fields, #name, _math_ ## name)
|
||||
|
||||
KrkValue krk_module_onload_math(void) {
|
||||
KrkValue krk_module_onload_math(KrkThreadState * _thread) {
|
||||
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
|
||||
krk_push(OBJECT_VAL(module));
|
||||
|
||||
|
@ -58,7 +58,7 @@ KRK_Function(seed) {
|
||||
return NONE_VAL();
|
||||
}
|
||||
|
||||
KrkValue krk_module_onload_random(void) {
|
||||
KrkValue krk_module_onload_random(KrkThreadState * _thread) {
|
||||
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
|
||||
krk_push(OBJECT_VAL(module));
|
||||
|
||||
@ -67,7 +67,7 @@ KrkValue krk_module_onload_random(void) {
|
||||
BIND_FUNC(module, random);
|
||||
BIND_FUNC(module, seed);
|
||||
|
||||
FUNC_NAME(krk,seed)(0,NULL,0);
|
||||
FUNC_NAME(krk,seed)(_thread, 0,NULL,0);
|
||||
|
||||
return krk_pop();
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ KRK_Method(socket,__repr__) {
|
||||
return OBJECT_VAL(krk_copyString(tmp,len));
|
||||
}
|
||||
|
||||
static int socket_parse_address(struct socket * self, KrkValue address, struct sockaddr_storage *sock_addr, socklen_t *sock_size) {
|
||||
static int socket_parse_address(KrkThreadState * _thread, struct socket * self, KrkValue address, struct sockaddr_storage *sock_addr, socklen_t *sock_size) {
|
||||
if (self->family == AF_INET) {
|
||||
/* Should be 2-tuple */
|
||||
if (!IS_tuple(address)) {
|
||||
@ -186,7 +186,7 @@ KRK_Method(socket,connect) {
|
||||
socklen_t sock_size = 0;
|
||||
|
||||
/* What do we take? I guess a tuple for AF_INET */
|
||||
int parseResult = socket_parse_address(self, argv[1], &sock_addr, &sock_size);
|
||||
int parseResult = socket_parse_address(_thread, self, argv[1], &sock_addr, &sock_size);
|
||||
if (parseResult) {
|
||||
if (!(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION))
|
||||
return krk_runtimeError(SocketError, "Unspecified error.");
|
||||
@ -209,7 +209,7 @@ KRK_Method(socket,bind) {
|
||||
socklen_t sock_size = 0;
|
||||
|
||||
/* What do we take? I guess a tuple for AF_INET */
|
||||
int parseResult = socket_parse_address(self, argv[1], &sock_addr, &sock_size);
|
||||
int parseResult = socket_parse_address(_thread, self, argv[1], &sock_addr, &sock_size);
|
||||
if (parseResult) {
|
||||
if (!(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION))
|
||||
return krk_runtimeError(SocketError, "Unspecified error.");
|
||||
@ -355,7 +355,7 @@ KRK_Method(socket,sendto) {
|
||||
socklen_t sock_size = 0;
|
||||
|
||||
/* What do we take? I guess a tuple for AF_INET */
|
||||
int parseResult = socket_parse_address(self, argv[argc-1], &sock_addr, &sock_size);
|
||||
int parseResult = socket_parse_address(_thread, self, argv[argc-1], &sock_addr, &sock_size);
|
||||
if (parseResult) {
|
||||
if (!(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION))
|
||||
return krk_runtimeError(SocketError, "Unspecified error.");
|
||||
@ -404,7 +404,7 @@ KRK_Function(htons) {
|
||||
return INTEGER_VAL(htons(value));
|
||||
}
|
||||
|
||||
KrkValue krk_module_onload_socket(void) {
|
||||
KrkValue krk_module_onload_socket(KrkThreadState * _thread) {
|
||||
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
|
||||
krk_push(OBJECT_VAL(module));
|
||||
|
||||
|
@ -34,7 +34,7 @@ KRK_Function(timeit) {
|
||||
return FLOATING_VAL(after-before);
|
||||
}
|
||||
|
||||
KrkValue krk_module_onload_timeit(void) {
|
||||
KrkValue krk_module_onload_timeit(KrkThreadState * _thread) {
|
||||
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
|
||||
krk_push(OBJECT_VAL(module));
|
||||
|
||||
|
@ -17,7 +17,7 @@ KRK_Function(wcwidth) {
|
||||
return INTEGER_VAL(wcwidth(codepoint));
|
||||
}
|
||||
|
||||
KrkValue krk_module_onload_wcwidth(void) {
|
||||
KrkValue krk_module_onload_wcwidth(KrkThreadState * _thread) {
|
||||
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
|
||||
krk_push(OBJECT_VAL(module));
|
||||
KRK_DOC(module, "Character widths.");
|
||||
|
@ -84,7 +84,7 @@ KRK_Method(type,__getitem__) {
|
||||
}
|
||||
|
||||
_noexport
|
||||
void _createAndBind_type(void) {
|
||||
void _createAndBind_type(KrkThreadState * _thread) {
|
||||
KrkClass * type = ADD_BASE_CLASS(vm.baseClasses->typeClass, "type", vm.baseClasses->objectClass);
|
||||
type->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
|
||||
|
||||
|
@ -193,7 +193,7 @@ struct _bytes_join_context {
|
||||
int isFirst;
|
||||
};
|
||||
|
||||
static int _bytes_join_callback(void * context, const KrkValue * values, size_t count) {
|
||||
static int _bytes_join_callback(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) {
|
||||
struct _bytes_join_context * _context = context;
|
||||
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
@ -247,7 +247,7 @@ KRK_Method(bytes,__iter__) {
|
||||
KrkInstance * output = krk_newInstance(vm.baseClasses->bytesiteratorClass);
|
||||
|
||||
krk_push(OBJECT_VAL(output));
|
||||
FUNC_NAME(bytesiterator,__init__)(2, (KrkValue[]){krk_peek(0), argv[0]},0);
|
||||
FUNC_NAME(bytesiterator,__init__)(_thread, 2, (KrkValue[]){krk_peek(0), argv[0]},0);
|
||||
krk_pop();
|
||||
|
||||
return OBJECT_VAL(output);
|
||||
@ -265,7 +265,7 @@ struct BytesIterator {
|
||||
#define IS_bytesiterator(o) krk_isInstanceOf(o,vm.baseClasses->bytesiteratorClass)
|
||||
#define AS_bytesiterator(o) (struct BytesIterator*)AS_OBJECT(o)
|
||||
|
||||
static void _bytesiterator_gcscan(KrkInstance * self) {
|
||||
static void _bytesiterator_gcscan(KrkThreadState * _thread, KrkInstance * self) {
|
||||
krk_markValue(((struct BytesIterator*)self)->l);
|
||||
}
|
||||
|
||||
@ -291,7 +291,7 @@ KRK_Method(bytesiterator,__call__) {
|
||||
#undef CURRENT_CTYPE
|
||||
#define CURRENT_CTYPE struct ByteArray *
|
||||
|
||||
static void _bytearray_gcscan(KrkInstance * self) {
|
||||
static void _bytearray_gcscan(KrkThreadState * _thread, KrkInstance * self) {
|
||||
krk_markValue(((struct ByteArray*)self)->actual);
|
||||
}
|
||||
|
||||
@ -408,7 +408,7 @@ KRK_Method(bytearray,__iter__) {
|
||||
KrkInstance * output = krk_newInstance(vm.baseClasses->bytesiteratorClass);
|
||||
|
||||
krk_push(OBJECT_VAL(output));
|
||||
FUNC_NAME(bytesiterator,__init__)(2, (KrkValue[]){krk_peek(0), self->actual},0);
|
||||
FUNC_NAME(bytesiterator,__init__)(_thread, 2, (KrkValue[]){krk_peek(0), self->actual},0);
|
||||
krk_pop();
|
||||
|
||||
return OBJECT_VAL(output);
|
||||
@ -416,7 +416,7 @@ KRK_Method(bytearray,__iter__) {
|
||||
|
||||
|
||||
_noexport
|
||||
void _createAndBind_bytesClass(void) {
|
||||
void _createAndBind_bytesClass(KrkThreadState * _thread) {
|
||||
KrkClass * bytes = ADD_BASE_CLASS(vm.baseClasses->bytesClass, "bytes", vm.baseClasses->objectClass);
|
||||
bytes->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
|
||||
KRK_DOC(BIND_METHOD(bytes,__init__),
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Exposed method called to produce dictionaries from `{expr: expr, ...}` sequences in managed code.
|
||||
* Expects arguments as `key,value,key,value`...
|
||||
*/
|
||||
KrkValue krk_dict_of(int argc, const KrkValue argv[], int hasKw) {
|
||||
KrkValue krk_dict_of_r(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) {
|
||||
if (argc % 2 != 0) return krk_runtimeError(vm.exceptions->argumentError, "Expected even number of arguments to krk_dict_of");
|
||||
KrkInstance * outDict = krk_newInstance(vm.baseClasses->dictClass);
|
||||
krk_push(OBJECT_VAL(outDict));
|
||||
@ -20,11 +20,11 @@ KrkValue krk_dict_of(int argc, const KrkValue argv[], int hasKw) {
|
||||
return krk_pop();
|
||||
}
|
||||
|
||||
static void _dict_gcscan(KrkInstance * self) {
|
||||
static void _dict_gcscan(KrkThreadState * _thread, KrkInstance * self) {
|
||||
krk_markTable(&((KrkDict*)self)->entries);
|
||||
}
|
||||
|
||||
static void _dict_gcsweep(KrkInstance * self) {
|
||||
static void _dict_gcsweep(KrkThreadState * _thread, KrkInstance * self) {
|
||||
krk_freeTable(&((KrkDict*)self)->entries);
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ struct _keyvalue_pair_context {
|
||||
int counter;
|
||||
};
|
||||
|
||||
static int _keyvalue_pair_callback(void * context, const KrkValue * entries, size_t count) {
|
||||
static int _keyvalue_pair_callback(KrkThreadState * _thread, void * context, const KrkValue * entries, size_t count) {
|
||||
struct _keyvalue_pair_context * _context = context;
|
||||
|
||||
if (count > 2) {
|
||||
@ -62,7 +62,7 @@ static int _keyvalue_pair_callback(void * context, const KrkValue * entries, siz
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unpackKeyValuePair(void * self, const KrkValue * pairs, size_t count) {
|
||||
static int unpackKeyValuePair(KrkThreadState * _thread, void * self, const KrkValue * pairs, size_t count) {
|
||||
struct _keyvalue_pair_context context = { (KrkDict*)self, NONE_VAL(), 0 };
|
||||
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
@ -267,7 +267,7 @@ KRK_Method(dict,keys) {
|
||||
METHOD_TAKES_NONE();
|
||||
KrkInstance * output = krk_newInstance(vm.baseClasses->dictkeysClass);
|
||||
krk_push(OBJECT_VAL(output));
|
||||
FUNC_NAME(dictkeys,__init__)(2, (KrkValue[]){krk_peek(0), argv[0]},0);
|
||||
FUNC_NAME(dictkeys,__init__)(_thread, 2, (KrkValue[]){krk_peek(0), argv[0]},0);
|
||||
krk_pop();
|
||||
return OBJECT_VAL(output);
|
||||
}
|
||||
@ -278,7 +278,7 @@ KRK_Method(dict,items) {
|
||||
METHOD_TAKES_NONE();
|
||||
KrkInstance * output = krk_newInstance(vm.baseClasses->dictitemsClass);
|
||||
krk_push(OBJECT_VAL(output));
|
||||
FUNC_NAME(dictitems,__init__)(2, (KrkValue[]){krk_peek(0), argv[0]},0);
|
||||
FUNC_NAME(dictitems,__init__)(_thread, 2, (KrkValue[]){krk_peek(0), argv[0]},0);
|
||||
krk_pop();
|
||||
return OBJECT_VAL(output);
|
||||
}
|
||||
@ -289,12 +289,12 @@ KRK_Method(dict,values) {
|
||||
METHOD_TAKES_NONE();
|
||||
KrkInstance * output = krk_newInstance(vm.baseClasses->dictvaluesClass);
|
||||
krk_push(OBJECT_VAL(output));
|
||||
FUNC_NAME(dictvalues,__init__)(2, (KrkValue[]){krk_peek(0), argv[0]},0);
|
||||
FUNC_NAME(dictvalues,__init__)(_thread, 2, (KrkValue[]){krk_peek(0), argv[0]},0);
|
||||
krk_pop();
|
||||
return OBJECT_VAL(output);
|
||||
}
|
||||
|
||||
KrkValue krk_dict_nth_key_fast(size_t capacity, KrkTableEntry * entries, size_t index) {
|
||||
KrkValue krk_dict_nth_key_fast(KrkThreadState * _thread, size_t capacity, KrkTableEntry * entries, size_t index) {
|
||||
size_t found = 0;
|
||||
for (size_t i = 0; i < capacity; ++i) {
|
||||
if (IS_KWARGS(entries[i].key)) continue;
|
||||
@ -307,7 +307,7 @@ KrkValue krk_dict_nth_key_fast(size_t capacity, KrkTableEntry * entries, size_t
|
||||
#undef CURRENT_CTYPE
|
||||
#define CURRENT_CTYPE struct DictItems *
|
||||
|
||||
static void _dictitems_gcscan(KrkInstance * self) {
|
||||
static void _dictitems_gcscan(KrkThreadState * _thread, KrkInstance * self) {
|
||||
krk_markValue(((struct DictItems*)self)->dict);
|
||||
}
|
||||
|
||||
@ -391,7 +391,7 @@ KRK_Method(dictitems,__repr__) {
|
||||
#undef CURRENT_CTYPE
|
||||
#define CURRENT_CTYPE struct DictKeys *
|
||||
|
||||
static void _dictkeys_gcscan(KrkInstance * self) {
|
||||
static void _dictkeys_gcscan(KrkThreadState * _thread, KrkInstance * self) {
|
||||
krk_markValue(((struct DictKeys*)self)->dict);
|
||||
}
|
||||
|
||||
@ -457,7 +457,7 @@ KRK_Method(dictkeys,__repr__) {
|
||||
#undef CURRENT_CTYPE
|
||||
#define CURRENT_CTYPE struct DictValues *
|
||||
|
||||
static void _dictvalues_gcscan(KrkInstance * self) {
|
||||
static void _dictvalues_gcscan(KrkThreadState * _thread, KrkInstance * self) {
|
||||
krk_markValue(((struct DictValues*)self)->dict);
|
||||
}
|
||||
|
||||
@ -521,7 +521,7 @@ KRK_Method(dictvalues,__repr__) {
|
||||
}
|
||||
|
||||
_noexport
|
||||
void _createAndBind_dictClass(void) {
|
||||
void _createAndBind_dictClass(KrkThreadState * _thread) {
|
||||
KrkClass * dict = ADD_BASE_CLASS(vm.baseClasses->dictClass, "dict", vm.baseClasses->objectClass);
|
||||
dict->allocSize = sizeof(KrkDict);
|
||||
dict->_ongcscan = _dict_gcscan;
|
||||
|
@ -6,14 +6,14 @@
|
||||
#include <kuroko/debug.h>
|
||||
|
||||
/* Check for and return the name of a native function as a string object */
|
||||
static KrkValue nativeFunctionName(KrkValue func) {
|
||||
static KrkValue nativeFunctionName(KrkThreadState * _thread, KrkValue func) {
|
||||
const char * string = ((KrkNative*)AS_OBJECT(func))->name;
|
||||
if (!string) return OBJECT_VAL(S("<unnamed>"));
|
||||
size_t len = strlen(string);
|
||||
return OBJECT_VAL(krk_copyString(string,len));
|
||||
}
|
||||
|
||||
static KrkTuple * functionArgs(KrkCodeObject * _self) {
|
||||
static KrkTuple * functionArgs(KrkThreadState * _thread, KrkCodeObject * _self) {
|
||||
KrkTuple * tuple = krk_newTuple(_self->requiredArgs + _self->keywordArgs + !!(_self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) + !!(_self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS));
|
||||
krk_push(OBJECT_VAL(tuple));
|
||||
|
||||
@ -109,7 +109,7 @@ KRK_Method(function,__name__) {
|
||||
ATTRIBUTE_NOT_ASSIGNABLE();
|
||||
|
||||
if (IS_NATIVE(self)) {
|
||||
return nativeFunctionName(self);
|
||||
return nativeFunctionName(_thread, self);
|
||||
} else if (IS_CLOSURE(self) && AS_CLOSURE(self)->function->name) {
|
||||
return OBJECT_VAL(AS_CLOSURE(self)->function->name);
|
||||
}
|
||||
@ -155,9 +155,9 @@ KRK_Method(function,__str__) {
|
||||
pushStringBuilderStr(&sb, "<function ", 10);
|
||||
|
||||
/* 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)) {
|
||||
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>"));
|
||||
@ -188,7 +188,7 @@ KRK_Method(function,__file__) {
|
||||
KRK_Method(function,__args__) {
|
||||
ATTRIBUTE_NOT_ASSIGNABLE();
|
||||
if (!IS_CLOSURE(self)) return OBJECT_VAL(krk_newTuple(0));
|
||||
KrkTuple * tuple = functionArgs(AS_CLOSURE(self)->function);
|
||||
KrkTuple * tuple = functionArgs(_thread, AS_CLOSURE(self)->function);
|
||||
return OBJECT_VAL(tuple);
|
||||
}
|
||||
|
||||
@ -218,7 +218,7 @@ KRK_Method(codeobject,__name__) {
|
||||
|
||||
KRK_Method(codeobject,__str__) {
|
||||
METHOD_TAKES_NONE();
|
||||
KrkValue s = FUNC_NAME(codeobject,__name__)(1,argv,0);
|
||||
KrkValue s = FUNC_NAME(codeobject,__name__)(_thread, 1,argv,0);
|
||||
if (!IS_STRING(s)) return NONE_VAL();
|
||||
krk_push(s);
|
||||
|
||||
@ -290,7 +290,7 @@ KRK_Method(codeobject,co_flags) {
|
||||
|
||||
KRK_Method(codeobject,__args__) {
|
||||
ATTRIBUTE_NOT_ASSIGNABLE();
|
||||
KrkTuple * tuple = functionArgs(self);
|
||||
KrkTuple * tuple = functionArgs(_thread, self);
|
||||
return OBJECT_VAL(tuple);
|
||||
}
|
||||
|
||||
@ -309,23 +309,23 @@ FUNC_SIG(method,__init__) {
|
||||
|
||||
KRK_Method(method,__name__) {
|
||||
ATTRIBUTE_NOT_ASSIGNABLE();
|
||||
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__name__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
|
||||
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__name__)(_thread, 1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
|
||||
}
|
||||
|
||||
KRK_Method(method,__qualname__) {
|
||||
ATTRIBUTE_NOT_ASSIGNABLE();
|
||||
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__qualname__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
|
||||
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__qualname__)(_thread, 1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
|
||||
}
|
||||
|
||||
KRK_Method(method,_ip_to_line) {
|
||||
METHOD_TAKES_EXACTLY(1);
|
||||
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,_ip_to_line)(2,(KrkValue[]){OBJECT_VAL(self->method),argv[1]},0) : OBJECT_VAL(S("?"));
|
||||
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,_ip_to_line)(_thread, 2,(KrkValue[]){OBJECT_VAL(self->method),argv[1]},0) : OBJECT_VAL(S("?"));
|
||||
}
|
||||
|
||||
KRK_Method(method,__str__) {
|
||||
METHOD_TAKES_NONE();
|
||||
KrkValue s = FUNC_NAME(method,__qualname__)(1,argv,0);
|
||||
if (!IS_STRING(s)) s = FUNC_NAME(method,__name__)(1,argv,0);
|
||||
KrkValue s = FUNC_NAME(method,__qualname__)(_thread, 1,argv,0);
|
||||
if (!IS_STRING(s)) s = FUNC_NAME(method,__name__)(_thread, 1,argv,0);
|
||||
if (!IS_STRING(s)) return NONE_VAL();
|
||||
krk_push(s);
|
||||
|
||||
@ -344,27 +344,27 @@ KRK_Method(method,__str__) {
|
||||
|
||||
KRK_Method(method,__file__) {
|
||||
ATTRIBUTE_NOT_ASSIGNABLE();
|
||||
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__file__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
|
||||
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__file__)(_thread, 1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
|
||||
}
|
||||
|
||||
KRK_Method(method,__args__) {
|
||||
ATTRIBUTE_NOT_ASSIGNABLE();
|
||||
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__args__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
|
||||
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__args__)(_thread, 1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
|
||||
}
|
||||
|
||||
KRK_Method(method,__doc__) {
|
||||
ATTRIBUTE_NOT_ASSIGNABLE();
|
||||
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__doc__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
|
||||
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__doc__)(_thread, 1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
|
||||
}
|
||||
|
||||
KRK_Method(method,__annotations__) {
|
||||
ATTRIBUTE_NOT_ASSIGNABLE();
|
||||
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__annotations__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
|
||||
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__annotations__)(_thread, 1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
|
||||
}
|
||||
|
||||
KRK_Method(method,__code__) {
|
||||
ATTRIBUTE_NOT_ASSIGNABLE();
|
||||
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__code__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
|
||||
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__code__)(_thread, 1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
|
||||
}
|
||||
|
||||
KRK_Method(method,__func__) {
|
||||
@ -394,7 +394,7 @@ KRK_Function(classmethod) {
|
||||
}
|
||||
|
||||
_noexport
|
||||
void _createAndBind_functionClass(void) {
|
||||
void _createAndBind_functionClass(KrkThreadState * _thread) {
|
||||
KrkClass * codeobject = ADD_BASE_CLASS(vm.baseClasses->codeobjectClass, "codeobject", vm.baseClasses->objectClass);
|
||||
codeobject->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
|
||||
BIND_METHOD(codeobject,__init__);
|
||||
|
@ -37,7 +37,7 @@ struct generator {
|
||||
#define CURRENT_CTYPE struct generator *
|
||||
#define CURRENT_NAME self
|
||||
|
||||
static void _generator_close_upvalues(struct generator * self) {
|
||||
static void _generator_close_upvalues(KrkThreadState * _thread, struct generator * self) {
|
||||
while (self->capturedUpvalues) {
|
||||
KrkUpvalue * upvalue = self->capturedUpvalues;
|
||||
upvalue->closed = self->args[upvalue->location];
|
||||
@ -46,7 +46,7 @@ static void _generator_close_upvalues(struct generator * self) {
|
||||
}
|
||||
}
|
||||
|
||||
static void _generator_gcscan(KrkInstance * _self) {
|
||||
static void _generator_gcscan(KrkThreadState * _thread, KrkInstance * _self) {
|
||||
struct generator * self = (struct generator*)_self;
|
||||
krk_markObject((KrkObj*)self->closure);
|
||||
for (size_t i = 0; i < self->argCount; ++i) {
|
||||
@ -58,14 +58,14 @@ static void _generator_gcscan(KrkInstance * _self) {
|
||||
krk_markValue(self->result);
|
||||
}
|
||||
|
||||
static void _generator_gcsweep(KrkInstance * self) {
|
||||
_generator_close_upvalues((struct generator*)self);
|
||||
static void _generator_gcsweep(KrkThreadState * _thread, KrkInstance * self) {
|
||||
_generator_close_upvalues(_thread, (struct generator*)self);
|
||||
free(((struct generator*)self)->args);
|
||||
}
|
||||
|
||||
static void _set_generator_done(struct generator * self) {
|
||||
static void _set_generator_done(KrkThreadState * _thread, struct generator * self) {
|
||||
self->ip = NULL;
|
||||
_generator_close_upvalues(self);
|
||||
_generator_close_upvalues(_thread, self);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -79,7 +79,7 @@ static void _set_generator_done(struct generator * self) {
|
||||
* @param argCount Number of arguments in @p argsIn
|
||||
* @return A @ref generator object.
|
||||
*/
|
||||
KrkInstance * krk_buildGenerator(KrkClosure * closure, KrkValue * argsIn, size_t argCount) {
|
||||
KrkInstance * krk_buildGenerator_r(KrkThreadState * _thread, KrkClosure * closure, KrkValue * argsIn, size_t argCount) {
|
||||
/* Copy the args */
|
||||
KrkValue * args = malloc(sizeof(KrkValue) * (argCount));
|
||||
memcpy(args, argsIn, sizeof(KrkValue) * argCount);
|
||||
@ -175,13 +175,13 @@ KRK_Method(generator,__call__) {
|
||||
|
||||
if (IS_KWARGS(result) && AS_INTEGER(result) == 0) {
|
||||
self->result = krk_pop();
|
||||
_set_generator_done(self);
|
||||
_set_generator_done(_thread, self);
|
||||
return OBJECT_VAL(self);
|
||||
}
|
||||
|
||||
/* Was there an exception? */
|
||||
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) {
|
||||
_set_generator_done(self);
|
||||
_set_generator_done(_thread, self);
|
||||
krk_currentThread.stackTop = krk_currentThread.stack + frame->slots;
|
||||
return NONE_VAL();
|
||||
}
|
||||
@ -222,7 +222,7 @@ KRK_Method(generator,send) {
|
||||
if (!self->started && !IS_NONE(argv[1])) {
|
||||
return krk_runtimeError(vm.exceptions->typeError, "Can not send non-None value to just-started generator");
|
||||
}
|
||||
return FUNC_NAME(generator,__call__)(argc,argv,0);
|
||||
return FUNC_NAME(generator,__call__)(_thread, argc,argv,0);
|
||||
}
|
||||
|
||||
KRK_Method(generator,__finish__) {
|
||||
@ -238,7 +238,7 @@ KRK_Method(generator,gi_running) {
|
||||
return BOOLEAN_VAL(self->running);
|
||||
}
|
||||
|
||||
int krk_getAwaitable(void) {
|
||||
int krk_getAwaitable_r(KrkThreadState * _thread) {
|
||||
if (IS_generator(krk_peek(0)) && AS_generator(krk_peek(0))->type == KRK_OBJ_FLAGS_CODEOBJECT_IS_COROUTINE) {
|
||||
/* Good to go */
|
||||
return 1;
|
||||
@ -265,7 +265,7 @@ int krk_getAwaitable(void) {
|
||||
}
|
||||
|
||||
_noexport
|
||||
void _createAndBind_generatorClass(void) {
|
||||
void _createAndBind_generatorClass(KrkThreadState * _thread) {
|
||||
KrkClass * generator = ADD_BASE_CLASS(vm.baseClasses->generatorClass, "generator", vm.baseClasses->objectClass);
|
||||
generator->allocSize = sizeof(struct generator);
|
||||
generator->_ongcscan = _generator_gcscan;
|
||||
|
@ -14,20 +14,20 @@
|
||||
if (val < 0) val = 0; \
|
||||
if (val > (krk_integer_type)self->values.count) val = self->values.count
|
||||
|
||||
static void _list_gcscan(KrkInstance * self) {
|
||||
static void _list_gcscan(KrkThreadState * _thread, KrkInstance * self) {
|
||||
for (size_t i = 0; i < ((KrkList*)self)->values.count; ++i) {
|
||||
krk_markValue(((KrkList*)self)->values.values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void _list_gcsweep(KrkInstance * self) {
|
||||
static void _list_gcsweep(KrkThreadState * _thread, KrkInstance * self) {
|
||||
krk_freeValueArray(&((KrkList*)self)->values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience constructor for the C API.
|
||||
*/
|
||||
KrkValue krk_list_of(int argc, const KrkValue argv[], int hasKw) {
|
||||
KrkValue krk_list_of_r(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) {
|
||||
KrkValue outList = OBJECT_VAL(krk_newInstance(vm.baseClasses->listClass));
|
||||
krk_push(outList);
|
||||
krk_initValueArray(AS_LIST(outList));
|
||||
@ -80,7 +80,7 @@ KRK_Method(list,__getitem__) {
|
||||
}
|
||||
|
||||
/* make into a list */
|
||||
KrkValue result = krk_callNativeOnStack(len, &krk_currentThread.stackTop[-len], 0, krk_list_of);
|
||||
KrkValue result = krk_callNativeOnStack(len, &krk_currentThread.stackTop[-len], 0, krk_list_of_r);
|
||||
krk_currentThread.stackTop[-len-1] = result;
|
||||
while (len) {
|
||||
krk_pop();
|
||||
@ -158,7 +158,7 @@ KRK_Method(list,__repr__) {
|
||||
return finishStringBuilder(&sb);
|
||||
}
|
||||
|
||||
static int _list_extend_callback(void * context, const KrkValue * values, size_t count) {
|
||||
static int _list_extend_callback(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) {
|
||||
KrkValueArray * positionals = context;
|
||||
if (positionals->count + count > positionals->capacity) {
|
||||
size_t old = positionals->capacity;
|
||||
@ -193,7 +193,7 @@ KRK_Method(list,__init__) {
|
||||
krk_initValueArray(AS_LIST(argv[0]));
|
||||
pthread_rwlock_init(&self->rwlock, NULL);
|
||||
if (argc == 2) {
|
||||
_list_extend(2,(KrkValue[]){argv[0],argv[1]},0);
|
||||
FUNC_NAME(list,extend)(_thread, 2,(KrkValue[]){argv[0],argv[1]},0);
|
||||
}
|
||||
return argv[0];
|
||||
}
|
||||
@ -207,7 +207,7 @@ KRK_Method(list,__mul__) {
|
||||
krk_push(out);
|
||||
|
||||
for (krk_integer_type i = 0; i < howMany; i++) {
|
||||
_list_extend(2, (KrkValue[]){out,argv[0]},0);
|
||||
FUNC_NAME(list,extend)(_thread, 2, (KrkValue[]){out,argv[0]},0);
|
||||
}
|
||||
|
||||
return krk_pop();
|
||||
@ -287,12 +287,12 @@ KRK_Method(list,__setitem__) {
|
||||
}
|
||||
|
||||
while (len < newLen) {
|
||||
FUNC_NAME(list,insert)(3, (KrkValue[]){argv[0], INTEGER_VAL(start + len), AS_LIST(argv[2])->values[len]}, 0);
|
||||
FUNC_NAME(list,insert)(_thread, 3, (KrkValue[]){argv[0], INTEGER_VAL(start + len), AS_LIST(argv[2])->values[len]}, 0);
|
||||
len++;
|
||||
}
|
||||
|
||||
while (newLen < len) {
|
||||
FUNC_NAME(list,pop)(2, (KrkValue[]){argv[0], INTEGER_VAL(start + len - 1)}, 0);
|
||||
FUNC_NAME(list,pop)(_thread, 2, (KrkValue[]){argv[0], INTEGER_VAL(start + len - 1)}, 0);
|
||||
len--;
|
||||
}
|
||||
|
||||
@ -306,7 +306,7 @@ KRK_Method(list,__delitem__) {
|
||||
METHOD_TAKES_EXACTLY(1);
|
||||
|
||||
if (IS_INTEGER(argv[1])) {
|
||||
FUNC_NAME(list,pop)(2,(KrkValue[]){argv[0],INTEGER_VAL(argv[1])},0);
|
||||
FUNC_NAME(list,pop)(_thread, 2,(KrkValue[]){argv[0],INTEGER_VAL(argv[1])},0);
|
||||
} else if (IS_slice(argv[1])) {
|
||||
KRK_SLICER(argv[1],self->values.count) {
|
||||
return NONE_VAL();
|
||||
@ -319,7 +319,7 @@ KRK_Method(list,__delitem__) {
|
||||
krk_integer_type len = end - start;
|
||||
|
||||
while (len > 0) {
|
||||
FUNC_NAME(list,pop)(2,(KrkValue[]){argv[0],INTEGER_VAL(start)},0);
|
||||
FUNC_NAME(list,pop)(_thread, 2,(KrkValue[]){argv[0],INTEGER_VAL(start)},0);
|
||||
len--;
|
||||
}
|
||||
} else {
|
||||
@ -335,7 +335,7 @@ KRK_Method(list,remove) {
|
||||
for (size_t i = 0; i < self->values.count; ++i) {
|
||||
if (krk_valuesSameOrEqual(self->values.values[i], argv[1])) {
|
||||
pthread_rwlock_unlock(&self->rwlock);
|
||||
return FUNC_NAME(list,pop)(2,(KrkValue[]){argv[0], INTEGER_VAL(i)},0);
|
||||
return FUNC_NAME(list,pop)(_thread, 2,(KrkValue[]){argv[0], INTEGER_VAL(i)},0);
|
||||
}
|
||||
if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) {
|
||||
pthread_rwlock_unlock(&self->rwlock);
|
||||
@ -428,9 +428,15 @@ KRK_Method(list,reverse) {
|
||||
return NONE_VAL();
|
||||
}
|
||||
|
||||
static int _list_sorter(const void * _a, const void * _b) {
|
||||
extern void qsort_r(void *base, size_t nmemb, size_t size,
|
||||
int (*compar)(const void *, const void *, void *),
|
||||
void *arg);
|
||||
|
||||
|
||||
static int _list_sorter(const void * _a, const void * _b, void * t) {
|
||||
KrkValue a = *(KrkValue*)_a;
|
||||
KrkValue b = *(KrkValue*)_b;
|
||||
KrkThreadState * _thread = t;
|
||||
|
||||
/* Avoid actually calling the sort function if there's an active exception */
|
||||
if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return -1;
|
||||
@ -445,7 +451,7 @@ KRK_Method(list,sort) {
|
||||
METHOD_TAKES_NONE();
|
||||
|
||||
pthread_rwlock_wrlock(&self->rwlock);
|
||||
qsort(self->values.values, self->values.count, sizeof(KrkValue), _list_sorter);
|
||||
qsort_r(self->values.values, self->values.count, sizeof(KrkValue), _list_sorter, _thread);
|
||||
pthread_rwlock_unlock(&self->rwlock);
|
||||
|
||||
return NONE_VAL();
|
||||
@ -458,7 +464,7 @@ KRK_Method(list,__add__) {
|
||||
pthread_rwlock_rdlock(&self->rwlock);
|
||||
KrkValue outList = krk_list_of(self->values.count, self->values.values, 0); /* copy */
|
||||
pthread_rwlock_unlock(&self->rwlock);
|
||||
FUNC_NAME(list,extend)(2,(KrkValue[]){outList,argv[1]},0); /* extend */
|
||||
FUNC_NAME(list,extend)(_thread, 2,(KrkValue[]){outList,argv[1]},0); /* extend */
|
||||
return outList;
|
||||
}
|
||||
|
||||
@ -469,7 +475,7 @@ KRK_Method(list,__iter__) {
|
||||
KrkInstance * output = krk_newInstance(vm.baseClasses->listiteratorClass);
|
||||
|
||||
krk_push(OBJECT_VAL(output));
|
||||
FUNC_NAME(listiterator,__init__)(2, (KrkValue[]){krk_peek(0), argv[0]},0);
|
||||
FUNC_NAME(listiterator,__init__)(_thread, 2, (KrkValue[]){krk_peek(0), argv[0]},0);
|
||||
krk_pop();
|
||||
|
||||
return OBJECT_VAL(output);
|
||||
@ -508,7 +514,7 @@ struct ListIterator {
|
||||
#define IS_listiterator(o) (likely(IS_INSTANCE(o) && AS_INSTANCE(o)->_class == vm.baseClasses->listiteratorClass) || krk_isInstanceOf(o,vm.baseClasses->listiteratorClass))
|
||||
#define AS_listiterator(o) (struct ListIterator*)AS_OBJECT(o)
|
||||
|
||||
static void _listiterator_gcscan(KrkInstance * self) {
|
||||
static void _listiterator_gcscan(KrkThreadState * _thread, KrkInstance * self) {
|
||||
krk_markValue(((struct ListIterator*)self)->l);
|
||||
}
|
||||
|
||||
@ -544,32 +550,32 @@ _bad:
|
||||
goto _maybeGood;
|
||||
}
|
||||
|
||||
static KrkValue _sorted(int argc, const KrkValue argv[], int hasKw) {
|
||||
static KrkValue _sorted(KrkThreadState *_thread, int argc, const KrkValue argv[], int hasKw) {
|
||||
if (argc != 1) return krk_runtimeError(vm.exceptions->argumentError,"%s() takes %s %d argument%s (%d given)","sorted","exactly",1,"",argc);
|
||||
KrkValue listOut = krk_list_of(0,NULL,0);
|
||||
krk_push(listOut);
|
||||
FUNC_NAME(list,extend)(2,(KrkValue[]){listOut,argv[0]},0);
|
||||
FUNC_NAME(list,extend)(_thread, 2,(KrkValue[]){listOut,argv[0]},0);
|
||||
if (!IS_NONE(krk_currentThread.currentException)) return NONE_VAL();
|
||||
FUNC_NAME(list,sort)(1,&listOut,0);
|
||||
FUNC_NAME(list,sort)(_thread, 1,&listOut,0);
|
||||
if (!IS_NONE(krk_currentThread.currentException)) return NONE_VAL();
|
||||
return krk_pop();
|
||||
}
|
||||
|
||||
static KrkValue _reversed(int argc, const KrkValue argv[], int hasKw) {
|
||||
static KrkValue _reversed(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) {
|
||||
/* FIXME The Python reversed() function produces an iterator and only works for things with indexing or a __reversed__ method;
|
||||
* Building a list and reversing it like we do here is not correct! */
|
||||
if (argc != 1) return krk_runtimeError(vm.exceptions->argumentError,"%s() takes %s %d argument%s (%d given)","reversed","exactly",1,"",argc);
|
||||
KrkValue listOut = krk_list_of(0,NULL,0);
|
||||
krk_push(listOut);
|
||||
FUNC_NAME(list,extend)(2,(KrkValue[]){listOut,argv[0]},0);
|
||||
FUNC_NAME(list,extend)(_thread, 2,(KrkValue[]){listOut,argv[0]},0);
|
||||
if (!IS_NONE(krk_currentThread.currentException)) return NONE_VAL();
|
||||
FUNC_NAME(list,reverse)(1,&listOut,0);
|
||||
FUNC_NAME(list,reverse)(_thread, 1,&listOut,0);
|
||||
if (!IS_NONE(krk_currentThread.currentException)) return NONE_VAL();
|
||||
return krk_pop();
|
||||
}
|
||||
|
||||
_noexport
|
||||
void _createAndBind_listClass(void) {
|
||||
void _createAndBind_listClass(KrkThreadState * _thread) {
|
||||
KrkClass * list = ADD_BASE_CLASS(vm.baseClasses->listClass, "list", vm.baseClasses->objectClass);
|
||||
list->allocSize = sizeof(KrkList);
|
||||
list->_ongcscan = _list_gcscan;
|
||||
|
@ -1175,7 +1175,7 @@ static void make_long(krk_integer_type t, struct BigInt * self) {
|
||||
krk_long_init_si(self->value, t);
|
||||
}
|
||||
|
||||
static void _long_gcsweep(KrkInstance * self) {
|
||||
static void _long_gcsweep(KrkThreadState * _thread, KrkInstance * self) {
|
||||
krk_long_clear(((struct BigInt*)self)->value);
|
||||
}
|
||||
|
||||
@ -1224,7 +1224,7 @@ KRK_Method(long,__float__) {
|
||||
return FLOATING_VAL(krk_long_get_double(self->value));
|
||||
}
|
||||
|
||||
static KrkValue _krk_long_truediv(KrkLong * top, KrkLong * bottom) {
|
||||
static KrkValue _krk_long_truediv(KrkThreadState * _thread, KrkLong * top, KrkLong * bottom) {
|
||||
if (bottom->width == 0) return krk_runtimeError(vm.exceptions->valueError, "float division by zero");
|
||||
|
||||
KrkLong quot, rem;
|
||||
@ -1241,7 +1241,7 @@ static KrkValue _krk_long_truediv(KrkLong * top, KrkLong * bottom) {
|
||||
return FLOATING_VAL(quot_float + (rem_float / div_float));
|
||||
}
|
||||
|
||||
static KrkValue checked_float_div(double top, double bottom) {
|
||||
static KrkValue checked_float_div(KrkThreadState * _thread, double top, double bottom) {
|
||||
if (unlikely(bottom == 0.0)) return krk_runtimeError(vm.exceptions->valueError, "float division by zero");
|
||||
return FLOATING_VAL(top/bottom);
|
||||
}
|
||||
@ -1250,18 +1250,18 @@ KRK_Method(long,__truediv__) {
|
||||
krk_long tmp;
|
||||
if (IS_long(argv[1])) krk_long_init_copy(tmp, AS_long(argv[1])->value);
|
||||
else if (IS_INTEGER(argv[1])) krk_long_init_si(tmp, AS_INTEGER(argv[1]));
|
||||
else if (IS_FLOATING(argv[1])) return checked_float_div(krk_long_get_double(self->value), AS_FLOATING(argv[1]));
|
||||
else if (IS_FLOATING(argv[1])) return checked_float_div(_thread, krk_long_get_double(self->value), AS_FLOATING(argv[1]));
|
||||
else return NOTIMPL_VAL();
|
||||
return _krk_long_truediv(self->value,tmp);
|
||||
return _krk_long_truediv(_thread, self->value,tmp);
|
||||
}
|
||||
|
||||
KRK_Method(long,__rtruediv__) {
|
||||
krk_long tmp;
|
||||
if (IS_long(argv[1])) krk_long_init_copy(tmp, AS_long(argv[1])->value);
|
||||
else if (IS_INTEGER(argv[1])) krk_long_init_si(tmp, AS_INTEGER(argv[1]));
|
||||
else if (IS_FLOATING(argv[1])) return checked_float_div(AS_FLOATING(argv[1]), krk_long_get_double(self->value));
|
||||
else if (IS_FLOATING(argv[1])) return checked_float_div(_thread, AS_FLOATING(argv[1]), krk_long_get_double(self->value));
|
||||
else return NOTIMPL_VAL();
|
||||
return _krk_long_truediv(tmp,self->value);
|
||||
return _krk_long_truediv(_thread, tmp,self->value);
|
||||
}
|
||||
|
||||
#define PRINTER(name,base,prefix) \
|
||||
@ -1280,7 +1280,7 @@ KRK_Method(long,__hash__) {
|
||||
return INTEGER_VAL((uint32_t)(krk_long_medium(self->value)));
|
||||
}
|
||||
|
||||
static KrkValue make_long_obj(KrkLong * val) {
|
||||
static KrkValue make_long_obj_r(KrkThreadState * _thread, KrkLong * val) {
|
||||
krk_integer_type maybe = 0;
|
||||
if (val->width == 0) {
|
||||
maybe = 0;
|
||||
@ -1301,8 +1301,9 @@ static KrkValue make_long_obj(KrkLong * val) {
|
||||
krk_long_clear(val);
|
||||
return INTEGER_VAL(maybe);
|
||||
}
|
||||
#define make_long_obj(v) make_long_obj_r(_thread, v)
|
||||
|
||||
KrkValue krk_parse_int(const char * start, size_t width, unsigned int base) {
|
||||
KrkValue krk_parse_int_r(KrkThreadState * _thread, const char * start, size_t width, unsigned int base) {
|
||||
KrkLong _value;
|
||||
if (krk_long_parse_string(start, &_value, base, width)) {
|
||||
return NONE_VAL();
|
||||
@ -1335,7 +1336,7 @@ KRK_Method(long,__int__) {
|
||||
return make_long_obj(tmp); \
|
||||
} \
|
||||
_noexport \
|
||||
KrkValue krk_long_coerced_ ## name (krk_integer_type a, krk_integer_type b) { \
|
||||
KrkValue krk_long_coerced_ ## name (KrkThreadState * _thread, krk_integer_type a, krk_integer_type b) { \
|
||||
krk_long tmp_res, tmp_a, tmp_b; \
|
||||
krk_long_init_si(tmp_res, 0); \
|
||||
krk_long_init_si(tmp_a, a); \
|
||||
@ -1357,7 +1358,7 @@ BASIC_BIN_OP(or, krk_long_or)
|
||||
BASIC_BIN_OP(xor,krk_long_xor)
|
||||
BASIC_BIN_OP(and,krk_long_and)
|
||||
|
||||
static void _krk_long_lshift(krk_long out, krk_long val, krk_long shift) {
|
||||
static void _krk_long_lshift(KrkThreadState * _thread, krk_long out, krk_long val, krk_long shift) {
|
||||
if (krk_long_sign(shift) < 0) { krk_runtimeError(vm.exceptions->valueError, "negative shift count"); return; }
|
||||
krk_long multiplier;
|
||||
krk_long_init_si(multiplier,0);
|
||||
@ -1366,7 +1367,7 @@ static void _krk_long_lshift(krk_long out, krk_long val, krk_long shift) {
|
||||
krk_long_clear(multiplier);
|
||||
}
|
||||
|
||||
static void _krk_long_rshift(krk_long out, krk_long val, krk_long shift) {
|
||||
static void _krk_long_rshift(KrkThreadState * _thread, krk_long out, krk_long val, krk_long shift) {
|
||||
if (krk_long_sign(shift) < 0) { krk_runtimeError(vm.exceptions->valueError, "negative shift count"); return; }
|
||||
krk_long multiplier, garbage;
|
||||
krk_long_init_many(multiplier,garbage,NULL);
|
||||
@ -1375,7 +1376,7 @@ static void _krk_long_rshift(krk_long out, krk_long val, krk_long shift) {
|
||||
krk_long_clear_many(multiplier,garbage,NULL);
|
||||
}
|
||||
|
||||
static void _krk_long_mod(krk_long out, krk_long a, krk_long b) {
|
||||
static void _krk_long_mod(KrkThreadState * _thread, krk_long out, krk_long a, krk_long b) {
|
||||
if (krk_long_sign(b) == 0) { krk_runtimeError(vm.exceptions->valueError, "integer division or modulo by zero"); return; }
|
||||
krk_long garbage;
|
||||
krk_long_init_si(garbage,0);
|
||||
@ -1383,7 +1384,7 @@ static void _krk_long_mod(krk_long out, krk_long a, krk_long b) {
|
||||
krk_long_clear(garbage);
|
||||
}
|
||||
|
||||
static void _krk_long_div(krk_long out, krk_long a, krk_long b) {
|
||||
static void _krk_long_div(KrkThreadState * _thread, krk_long out, krk_long a, krk_long b) {
|
||||
if (krk_long_sign(b) == 0) { krk_runtimeError(vm.exceptions->valueError, "integer division or modulo by zero"); return; }
|
||||
krk_long garbage;
|
||||
krk_long_init_si(garbage,0);
|
||||
@ -1391,7 +1392,7 @@ static void _krk_long_div(krk_long out, krk_long a, krk_long b) {
|
||||
krk_long_clear(garbage);
|
||||
}
|
||||
|
||||
static void _krk_long_pow(krk_long out, krk_long a, krk_long b) {
|
||||
static void _krk_long_pow(KrkThreadState * _thread, krk_long out, krk_long a, krk_long b) {
|
||||
if (krk_long_sign(b) == 0) {
|
||||
krk_long_clear(out);
|
||||
krk_long_init_si(out, 1);
|
||||
@ -1450,11 +1451,40 @@ static void _krk_long_pow(krk_long out, krk_long a, krk_long b) {
|
||||
FINISH_OUTPUT(out);
|
||||
}
|
||||
|
||||
BASIC_BIN_OP(lshift,_krk_long_lshift)
|
||||
BASIC_BIN_OP(rshift,_krk_long_rshift)
|
||||
BASIC_BIN_OP(mod,_krk_long_mod)
|
||||
BASIC_BIN_OP(floordiv,_krk_long_div)
|
||||
BASIC_BIN_OP(pow,_krk_long_pow)
|
||||
|
||||
#define UNBASIC_BIN_OP(name, long_func) \
|
||||
KRK_Method(long,__ ## name ## __) { \
|
||||
krk_long tmp; \
|
||||
if (IS_long(argv[1])) krk_long_init_copy(tmp, AS_long(argv[1])->value); \
|
||||
else if (IS_INTEGER(argv[1])) krk_long_init_si(tmp, AS_INTEGER(argv[1])); \
|
||||
else return NOTIMPL_VAL(); \
|
||||
long_func(_thread,tmp,self->value,tmp); \
|
||||
return make_long_obj(tmp); \
|
||||
} \
|
||||
KRK_Method(long,__r ## name ## __) { \
|
||||
krk_long tmp; \
|
||||
if (IS_long(argv[1])) krk_long_init_copy(tmp, AS_long(argv[1])->value); \
|
||||
else if (IS_INTEGER(argv[1])) krk_long_init_si(tmp, AS_INTEGER(argv[1])); \
|
||||
else return NOTIMPL_VAL(); \
|
||||
long_func(_thread,tmp,tmp,self->value); \
|
||||
return make_long_obj(tmp); \
|
||||
} \
|
||||
_noexport \
|
||||
KrkValue krk_long_coerced_ ## name (KrkThreadState * _thread, krk_integer_type a, krk_integer_type b) { \
|
||||
krk_long tmp_res, tmp_a, tmp_b; \
|
||||
krk_long_init_si(tmp_res, 0); \
|
||||
krk_long_init_si(tmp_a, a); \
|
||||
krk_long_init_si(tmp_b, b); \
|
||||
long_func(_thread,tmp_res, tmp_a, tmp_b); \
|
||||
krk_long_clear_many(tmp_a, tmp_b, NULL); \
|
||||
return make_long_obj(tmp_res); \
|
||||
}
|
||||
|
||||
UNBASIC_BIN_OP(lshift,_krk_long_lshift)
|
||||
UNBASIC_BIN_OP(rshift,_krk_long_rshift)
|
||||
UNBASIC_BIN_OP(mod,_krk_long_mod)
|
||||
UNBASIC_BIN_OP(floordiv,_krk_long_div)
|
||||
UNBASIC_BIN_OP(pow,_krk_long_pow)
|
||||
|
||||
#define COMPARE_OP(name, comp) \
|
||||
KRK_Method(long,__ ## name ## __) { \
|
||||
@ -1509,9 +1539,9 @@ KRK_Method(long,__pos__) {
|
||||
return argv[0];
|
||||
}
|
||||
|
||||
extern KrkValue krk_doFormatString(const char * typeName, KrkString * format_spec, int positive, void* abs, int (*callback)(void *,int,int*));
|
||||
extern KrkValue krk_doFormatString(KrkThreadState *, const char * typeName, KrkString * format_spec, int positive, void* abs, int (*callback)(KrkThreadState *,void *,int,int*));
|
||||
|
||||
static int formatLongCallback(void * a, int base, int *more) {
|
||||
static int formatLongCallback(KrkThreadState * _thread, void * a, int base, int *more) {
|
||||
uint32_t result = _div_inplace((KrkLong*)a, base);
|
||||
*more = krk_long_sign(a);
|
||||
return result;
|
||||
@ -1525,7 +1555,7 @@ KRK_Method(long,__format__) {
|
||||
krk_long_init_copy(&tmp, self->value);
|
||||
krk_long_set_sign(&tmp, 1);
|
||||
|
||||
KrkValue result = krk_doFormatString("long",format_spec,
|
||||
KrkValue result = krk_doFormatString(_thread, "long",format_spec,
|
||||
krk_long_sign(self->value) >= 0,
|
||||
&tmp,
|
||||
formatLongCallback);
|
||||
@ -1534,7 +1564,7 @@ KRK_Method(long,__format__) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static KrkValue long_bit_count(KrkLong * val) {
|
||||
static KrkValue long_bit_count(KrkThreadState * _thread, KrkLong * val) {
|
||||
size_t count = 0;
|
||||
size_t bits = _bits_in(val);
|
||||
|
||||
@ -1548,10 +1578,10 @@ static KrkValue long_bit_count(KrkLong * val) {
|
||||
}
|
||||
|
||||
KRK_Method(long,bit_count) {
|
||||
return long_bit_count(self->value);
|
||||
return long_bit_count(_thread,self->value);
|
||||
}
|
||||
|
||||
static KrkValue long_bit_length(KrkLong * val) {
|
||||
static KrkValue long_bit_length(KrkThreadState * _thread, KrkLong * val) {
|
||||
size_t bits = _bits_in(val);
|
||||
KrkLong tmp;
|
||||
krk_long_init_ui(&tmp, bits);
|
||||
@ -1559,10 +1589,10 @@ static KrkValue long_bit_length(KrkLong * val) {
|
||||
}
|
||||
|
||||
KRK_Method(long,bit_length) {
|
||||
return long_bit_length(self->value);
|
||||
return long_bit_length(_thread, self->value);
|
||||
}
|
||||
|
||||
static KrkValue long_to_bytes(KrkLong * val, size_t argc, const KrkValue argv[], int hasKw) {
|
||||
static KrkValue long_to_bytes(KrkThreadState * _thread, KrkLong * val, size_t argc, const KrkValue argv[], int hasKw) {
|
||||
static const char _method_name[] = "to_bytes";
|
||||
/**
|
||||
* @fn to_bytes(length: int, byteorder: str, *, signed: bool = False) -> bytes
|
||||
@ -1681,7 +1711,7 @@ static KrkValue long_to_bytes(KrkLong * val, size_t argc, const KrkValue argv[],
|
||||
|
||||
KRK_Method(long,to_bytes) {
|
||||
METHOD_TAKES_AT_LEAST(2);
|
||||
return long_to_bytes(self->value, argc, argv, hasKw);
|
||||
return long_to_bytes(_thread, self->value, argc, argv, hasKw);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1747,7 +1777,7 @@ KRK_Method(long,_get_digit) {
|
||||
KRK_Method(int,bit_count) {
|
||||
krk_long value;
|
||||
krk_long_init_si(value, self);
|
||||
KrkValue out = long_bit_count(value);
|
||||
KrkValue out = long_bit_count(_thread,value);
|
||||
krk_long_clear(value);
|
||||
return out;
|
||||
}
|
||||
@ -1755,7 +1785,7 @@ KRK_Method(int,bit_count) {
|
||||
KRK_Method(int,bit_length) {
|
||||
krk_long value;
|
||||
krk_long_init_si(value, self);
|
||||
KrkValue out = long_bit_length(value);
|
||||
KrkValue out = long_bit_length(_thread, value);
|
||||
krk_long_clear(value);
|
||||
return out;
|
||||
}
|
||||
@ -1763,7 +1793,7 @@ KRK_Method(int,bit_length) {
|
||||
KRK_Method(int,to_bytes) {
|
||||
krk_long value;
|
||||
krk_long_init_si(value, self);
|
||||
KrkValue out = long_to_bytes(value, argc, argv, hasKw);
|
||||
KrkValue out = long_to_bytes(_thread, value, argc, argv, hasKw);
|
||||
krk_long_clear(value);
|
||||
return out;
|
||||
}
|
||||
@ -1776,7 +1806,7 @@ KRK_Method(int,to_bytes) {
|
||||
BIND_METHOD(klass,__r ## name ## __); \
|
||||
krk_defineNative(&_ ## klass->methods,"__i" #name "__",_ ## klass ## ___ ## name ## __);
|
||||
_noexport
|
||||
void _createAndBind_longClass(void) {
|
||||
void _createAndBind_longClass(KrkThreadState * _thread) {
|
||||
KrkClass * _long = ADD_BASE_CLASS(vm.baseClasses->longClass, "long", vm.baseClasses->intClass);
|
||||
_long->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
|
||||
_long->allocSize = sizeof(struct BigInt);
|
||||
|
@ -71,7 +71,7 @@ static inline int matches(char c, const char * options) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char * krk_parseCommonFormatSpec(struct ParsedFormatSpec *result, const char * spec, size_t length) {
|
||||
const char * krk_parseCommonFormatSpec(KrkThreadState * _thread, struct ParsedFormatSpec *result, const char * spec, size_t length) {
|
||||
result->fill = " ";
|
||||
result->fillSize = 1;
|
||||
|
||||
@ -147,10 +147,10 @@ const char * krk_parseCommonFormatSpec(struct ParsedFormatSpec *result, const ch
|
||||
return spec;
|
||||
}
|
||||
|
||||
KrkValue krk_doFormatString(const char * typeName, KrkString * format_spec, int positive, void * abs, int (*callback)(void *,int,int*)) {
|
||||
KrkValue krk_doFormatString(KrkThreadState * _thread, const char * typeName, KrkString * format_spec, int positive, void * abs, int (*callback)(KrkThreadState*,void *,int,int*)) {
|
||||
|
||||
struct ParsedFormatSpec opts = {0};
|
||||
const char * spec = krk_parseCommonFormatSpec(&opts, format_spec->chars, format_spec->length);
|
||||
const char * spec = krk_parseCommonFormatSpec(_thread, &opts, format_spec->chars, format_spec->length);
|
||||
if (!spec) return NONE_VAL();
|
||||
|
||||
const char * altPrefix = NULL;
|
||||
@ -211,7 +211,7 @@ KrkValue krk_doFormatString(const char * typeName, KrkString * format_spec, int
|
||||
int more = 0;
|
||||
|
||||
do {
|
||||
int digit = callback(abs, base, &more);
|
||||
int digit = callback(_thread, abs, base, &more);
|
||||
|
||||
if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) {
|
||||
discardStringBuilder(&sb);
|
||||
@ -283,7 +283,7 @@ KrkValue krk_doFormatString(const char * typeName, KrkString * format_spec, int
|
||||
return finishStringBuilder(&sb);
|
||||
}
|
||||
|
||||
static int formatIntCallback(void * a, int base, int *more) {
|
||||
static int formatIntCallback(KrkThreadState *_thread,void * a, int base, int *more) {
|
||||
krk_integer_type v = *(krk_integer_type*)a;
|
||||
int digit = v % base;
|
||||
v /= base;
|
||||
@ -299,7 +299,7 @@ KRK_Method(int,__format__) {
|
||||
|
||||
krk_integer_type abs = self < 0 ? -self : self;
|
||||
|
||||
return krk_doFormatString(krk_typeName(argv[0]), format_spec,
|
||||
return krk_doFormatString(_thread, krk_typeName(argv[0]), format_spec,
|
||||
self >= 0,
|
||||
&abs,
|
||||
formatIntCallback);
|
||||
@ -316,15 +316,15 @@ KRK_Method(int,__format__) {
|
||||
* and then reduce if that still yields something that would fit in our 'int48'.
|
||||
*/
|
||||
#define OVERFLOW_CHECKED_INT_OPERATION(name,operator) \
|
||||
extern KrkValue krk_long_coerced_ ## name (krk_integer_type a, krk_integer_type b); \
|
||||
extern KrkValue krk_long_coerced_ ## name (KrkThreadState *, krk_integer_type a, krk_integer_type b); \
|
||||
_noexport \
|
||||
KrkValue krk_int_op_ ## name (krk_integer_type a, krk_integer_type b) { \
|
||||
KrkValue krk_int_op_ ## name (KrkThreadState * _thread, krk_integer_type a, krk_integer_type b) { \
|
||||
if (likely((int32_t)a == a && (int32_t)b == b)) { \
|
||||
int32_t result_one = a operator b; \
|
||||
int64_t result_two = a operator b; \
|
||||
if (likely(result_one == result_two)) return INTEGER_VAL(result_two); \
|
||||
} \
|
||||
return krk_long_coerced_ ## name (a, b); \
|
||||
return krk_long_coerced_ ## name (_thread, a, b); \
|
||||
}
|
||||
|
||||
OVERFLOW_CHECKED_INT_OPERATION(add,+)
|
||||
@ -333,12 +333,12 @@ OVERFLOW_CHECKED_INT_OPERATION(mul,*)
|
||||
|
||||
#define BASIC_BIN_OP(name,operator) \
|
||||
KRK_Method(int,__ ## name ## __) { \
|
||||
if (likely(IS_INTEGER(argv[1]))) return krk_int_op_ ## name(self, AS_INTEGER(argv[1])); \
|
||||
if (likely(IS_INTEGER(argv[1]))) return krk_int_op_ ## name(_thread, self, AS_INTEGER(argv[1])); \
|
||||
else if (likely(IS_FLOATING(argv[1]))) return FLOATING_VAL((double)self operator AS_FLOATING(argv[1])); \
|
||||
return NOTIMPL_VAL(); \
|
||||
} \
|
||||
KRK_Method(int,__r ## name ## __) { \
|
||||
if (likely(IS_INTEGER(argv[1]))) return krk_int_op_ ## name(AS_INTEGER(argv[1]), self); \
|
||||
if (likely(IS_INTEGER(argv[1]))) return krk_int_op_ ## name(_thread, AS_INTEGER(argv[1]), self); \
|
||||
else if (likely(IS_FLOATING(argv[1]))) return FLOATING_VAL(AS_FLOATING(argv[1]) operator (double)self); \
|
||||
return NOTIMPL_VAL(); \
|
||||
}
|
||||
@ -368,13 +368,13 @@ INT_ONLY_BIN_OP(xor,^)
|
||||
INT_ONLY_BIN_OP(and,&)
|
||||
|
||||
#define DEFER_TO_LONG(name) \
|
||||
extern KrkValue krk_long_coerced_ ## name (krk_integer_type a, krk_integer_type b); \
|
||||
extern KrkValue krk_long_coerced_ ## name (KrkThreadState *, krk_integer_type a, krk_integer_type b); \
|
||||
KRK_Method(int,__ ## name ## __) { \
|
||||
if (likely(IS_INTEGER(argv[1]))) return krk_long_coerced_ ## name (self, AS_INTEGER(argv[1])); \
|
||||
if (likely(IS_INTEGER(argv[1]))) return krk_long_coerced_ ## name (_thread,self, AS_INTEGER(argv[1])); \
|
||||
return NOTIMPL_VAL(); \
|
||||
} \
|
||||
KRK_Method(int,__r ## name ## __) { \
|
||||
if (likely(IS_INTEGER(argv[1]))) return krk_long_coerced_ ## name (AS_INTEGER(argv[1]), self); \
|
||||
if (likely(IS_INTEGER(argv[1]))) return krk_long_coerced_ ## name (_thread,AS_INTEGER(argv[1]), self); \
|
||||
return NOTIMPL_VAL(); \
|
||||
}
|
||||
|
||||
@ -423,7 +423,7 @@ KRK_Method(int,__rtruediv__) {
|
||||
* that Python produces, for compatibility, and also because that's
|
||||
* what our 'long' type does...
|
||||
*/
|
||||
static KrkValue _krk_int_div(krk_integer_type a, krk_integer_type b) {
|
||||
static KrkValue _krk_int_div(KrkThreadState * _thread, krk_integer_type a, krk_integer_type b) {
|
||||
if (unlikely(b == 0)) return krk_runtimeError(vm.exceptions->zeroDivisionError, "integer division or modulo by zero");
|
||||
if (a == 0) return INTEGER_VAL(0);
|
||||
int64_t abs_a = a < 0 ? -a : a;
|
||||
@ -436,7 +436,7 @@ static KrkValue _krk_int_div(krk_integer_type a, krk_integer_type b) {
|
||||
return INTEGER_VAL((abs_a / abs_b));
|
||||
}
|
||||
|
||||
static KrkValue _krk_int_mod(krk_integer_type a, krk_integer_type b) {
|
||||
static KrkValue _krk_int_mod(KrkThreadState * _thread, krk_integer_type a, krk_integer_type b) {
|
||||
if (unlikely(b == 0)) return krk_runtimeError(vm.exceptions->zeroDivisionError, "integer division or modulo by zero");
|
||||
if (a == 0) return INTEGER_VAL(0);
|
||||
int64_t abs_a = a < 0 ? -a : a;
|
||||
@ -455,13 +455,13 @@ static KrkValue _krk_int_mod(krk_integer_type a, krk_integer_type b) {
|
||||
|
||||
KRK_Method(int,__mod__) {
|
||||
METHOD_TAKES_EXACTLY(1);
|
||||
if (likely(IS_INTEGER(argv[1]))) return _krk_int_mod(self, AS_INTEGER(argv[1]));
|
||||
if (likely(IS_INTEGER(argv[1]))) return _krk_int_mod(_thread, self, AS_INTEGER(argv[1]));
|
||||
return NOTIMPL_VAL();
|
||||
}
|
||||
|
||||
KRK_Method(int,__rmod__) {
|
||||
METHOD_TAKES_EXACTLY(1);
|
||||
if (likely(IS_INTEGER(argv[1]))) return _krk_int_mod(AS_INTEGER(argv[1]), self);
|
||||
if (likely(IS_INTEGER(argv[1]))) return _krk_int_mod(_thread, AS_INTEGER(argv[1]), self);
|
||||
return NOTIMPL_VAL();
|
||||
}
|
||||
|
||||
@ -469,7 +469,7 @@ KRK_Method(int,__rmod__) {
|
||||
KRK_Method(int,__floordiv__) {
|
||||
METHOD_TAKES_EXACTLY(1);
|
||||
if (likely(IS_INTEGER(argv[1]))) {
|
||||
return _krk_int_div(self,AS_INTEGER(argv[1]));
|
||||
return _krk_int_div(_thread, self,AS_INTEGER(argv[1]));
|
||||
} else if (likely(IS_FLOATING(argv[1]))) {
|
||||
double b = AS_FLOATING(argv[1]);
|
||||
if (unlikely(b == 0.0)) return krk_runtimeError(vm.exceptions->zeroDivisionError, "float division by zero");
|
||||
@ -481,7 +481,7 @@ KRK_Method(int,__floordiv__) {
|
||||
KRK_Method(int,__rfloordiv__) {
|
||||
METHOD_TAKES_EXACTLY(1);
|
||||
if (unlikely(self == 0)) return krk_runtimeError(vm.exceptions->zeroDivisionError, "integer division by zero");
|
||||
else if (likely(IS_INTEGER(argv[1]))) return _krk_int_div(AS_INTEGER(argv[1]), self);
|
||||
else if (likely(IS_INTEGER(argv[1]))) return _krk_int_div(_thread, AS_INTEGER(argv[1]), self);
|
||||
else if (likely(IS_FLOATING(argv[1]))) return FLOATING_VAL(__builtin_floor(AS_FLOATING(argv[1]) / (double)self));
|
||||
return NOTIMPL_VAL();
|
||||
}
|
||||
@ -757,7 +757,7 @@ KRK_Method(NotImplementedType,__eq__) {
|
||||
BIND_METHOD(klass,__r ## name ## __); \
|
||||
krk_defineNative(&_ ## klass->methods,"__i" #name "__",_ ## klass ## ___ ## name ## __);
|
||||
_noexport
|
||||
void _createAndBind_numericClasses(void) {
|
||||
void _createAndBind_numericClasses(KrkThreadState *_thread) {
|
||||
KrkClass * _int = ADD_BASE_CLASS(vm.baseClasses->intClass, "int", vm.baseClasses->objectClass);
|
||||
_int->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
|
||||
BIND_METHOD(int,__init__);
|
||||
|
@ -80,7 +80,7 @@ KRK_Method(range,__iter__) {
|
||||
krk_integer_type step = self->step;
|
||||
|
||||
krk_push(OBJECT_VAL(output));
|
||||
FUNC_NAME(rangeiterator,__init__)(4, (KrkValue[]){krk_peek(0), INTEGER_VAL(min), INTEGER_VAL(max), INTEGER_VAL(step)},0);
|
||||
FUNC_NAME(rangeiterator,__init__)(_thread, 4, (KrkValue[]){krk_peek(0), INTEGER_VAL(min), INTEGER_VAL(max), INTEGER_VAL(step)},0);
|
||||
krk_pop();
|
||||
|
||||
return OBJECT_VAL(output);
|
||||
@ -112,7 +112,7 @@ KRK_Method(rangeiterator,__call__) {
|
||||
}
|
||||
|
||||
_noexport
|
||||
void _createAndBind_rangeClass(void) {
|
||||
void _createAndBind_rangeClass(KrkThreadState * _thread) {
|
||||
KrkClass * range = ADD_BASE_CLASS(vm.baseClasses->rangeClass, "range", vm.baseClasses->objectClass);
|
||||
range->allocSize = sizeof(struct Range);
|
||||
range->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
|
||||
|
@ -16,11 +16,11 @@ struct Set {
|
||||
#define IS_set(o) krk_isInstanceOf(o,KRK_BASE_CLASS(set))
|
||||
#define AS_set(o) ((struct Set*)AS_OBJECT(o))
|
||||
|
||||
static void _set_gcscan(KrkInstance * self) {
|
||||
static void _set_gcscan(KrkThreadState * _thread, KrkInstance * self) {
|
||||
krk_markTable(&((struct Set*)self)->entries);
|
||||
}
|
||||
|
||||
static void _set_gcsweep(KrkInstance * self) {
|
||||
static void _set_gcsweep(KrkThreadState * _thread, KrkInstance * self) {
|
||||
krk_freeTable(&((struct Set*)self)->entries);
|
||||
}
|
||||
|
||||
@ -36,14 +36,14 @@ struct SetIterator {
|
||||
#define IS_setiterator(o) krk_isInstanceOf(o,KRK_BASE_CLASS(setiterator))
|
||||
#define AS_setiterator(o) ((struct SetIterator*)AS_OBJECT(o))
|
||||
|
||||
static void _setiterator_gcscan(KrkInstance * self) {
|
||||
static void _setiterator_gcscan(KrkThreadState * _thread, KrkInstance * self) {
|
||||
krk_markValue(((struct SetIterator*)self)->set);
|
||||
}
|
||||
|
||||
#define CURRENT_CTYPE struct Set *
|
||||
#define CURRENT_NAME self
|
||||
|
||||
static int _set_init_callback(void * context, const KrkValue * values, size_t count) {
|
||||
static int _set_init_callback(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) {
|
||||
struct Set * self = context;
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
krk_tableSet(&self->entries, values[i], BOOLEAN_VAL(1));
|
||||
@ -104,7 +104,7 @@ KRK_Method(set,__and__) {
|
||||
|
||||
KrkValue outSet = OBJECT_VAL(krk_newInstance(KRK_BASE_CLASS(set)));
|
||||
krk_push(outSet);
|
||||
FUNC_NAME(set,__init__)(1,&outSet,0);
|
||||
FUNC_NAME(set,__init__)(_thread, 1,&outSet,0);
|
||||
|
||||
KrkClass * type = krk_getType(argv[1]);
|
||||
if (!type->_contains)
|
||||
@ -132,7 +132,7 @@ KRK_Method(set,__xor__) {
|
||||
|
||||
KrkValue outSet = OBJECT_VAL(krk_newInstance(KRK_BASE_CLASS(set)));
|
||||
krk_push(outSet);
|
||||
FUNC_NAME(set,__init__)(1,&outSet,0);
|
||||
FUNC_NAME(set,__init__)(_thread, 1,&outSet,0);
|
||||
|
||||
KrkClass * type = krk_getType(argv[1]);
|
||||
if (!type->_contains)
|
||||
@ -177,7 +177,7 @@ KRK_Method(set,__or__) {
|
||||
|
||||
KrkValue outSet = OBJECT_VAL(krk_newInstance(KRK_BASE_CLASS(set)));
|
||||
krk_push(outSet);
|
||||
FUNC_NAME(set,__init__)(1,&outSet,0);
|
||||
FUNC_NAME(set,__init__)(_thread, 1,&outSet,0);
|
||||
|
||||
krk_tableAddAll(&self->entries, &AS_set(outSet)->entries);
|
||||
krk_tableAddAll(&them->entries, &AS_set(outSet)->entries);
|
||||
@ -300,7 +300,7 @@ KRK_Method(set,__iter__) {
|
||||
METHOD_TAKES_NONE();
|
||||
KrkInstance * output = krk_newInstance(KRK_BASE_CLASS(setiterator));
|
||||
krk_push(OBJECT_VAL(output));
|
||||
FUNC_NAME(setiterator,__init__)(2,(KrkValue[]){krk_peek(0), argv[0]}, 0);
|
||||
FUNC_NAME(setiterator,__init__)(_thread, 2,(KrkValue[]){krk_peek(0), argv[0]}, 0);
|
||||
return krk_pop();
|
||||
}
|
||||
|
||||
@ -331,7 +331,7 @@ KRK_Method(setiterator,__call__) {
|
||||
} while (1);
|
||||
}
|
||||
|
||||
KrkValue krk_set_of(int argc, const KrkValue argv[], int hasKw) {
|
||||
KrkValue krk_set_of_r(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) {
|
||||
KrkValue outSet = OBJECT_VAL(krk_newInstance(KRK_BASE_CLASS(set)));
|
||||
krk_push(outSet);
|
||||
krk_initTable(&AS_set(outSet)->entries);
|
||||
@ -345,7 +345,7 @@ KrkValue krk_set_of(int argc, const KrkValue argv[], int hasKw) {
|
||||
}
|
||||
|
||||
_noexport
|
||||
void _createAndBind_setClass(void) {
|
||||
void _createAndBind_setClass(KrkThreadState * _thread) {
|
||||
KrkClass * set = krk_makeClass(vm.builtins, &KRK_BASE_CLASS(set), "set", vm.baseClasses->objectClass);
|
||||
set->allocSize = sizeof(struct Set);
|
||||
set->_ongcscan = _set_gcscan;
|
||||
|
@ -5,13 +5,13 @@
|
||||
#include <kuroko/memory.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)->end);
|
||||
krk_markValue(((struct KrkSlice*)self)->step);
|
||||
}
|
||||
|
||||
KrkValue krk_slice_of(int argc, const KrkValue argv[], int hasKw) {
|
||||
KrkValue krk_slice_of_r(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) {
|
||||
KrkValue outSlice = OBJECT_VAL(krk_newInstance(vm.baseClasses->sliceClass));
|
||||
krk_push(outSlice);
|
||||
|
||||
@ -36,7 +36,7 @@ static inline krk_integer_type _wrapn(krk_integer_type count, krk_integer_type v
|
||||
return val;
|
||||
}
|
||||
|
||||
int krk_extractSlicer(const char * _method_name, KrkValue slicerVal, krk_integer_type count, krk_integer_type *start, krk_integer_type *end, krk_integer_type *step) {
|
||||
int krk_extractSlicer(KrkThreadState * _thread, const char * _method_name, KrkValue slicerVal, krk_integer_type count, krk_integer_type *start, krk_integer_type *end, krk_integer_type *step) {
|
||||
if (!(IS_slice(slicerVal))) {
|
||||
TYPE_ERROR(slice, slicerVal);
|
||||
return 1;
|
||||
@ -166,7 +166,7 @@ KRK_Method(slice,step) {
|
||||
}
|
||||
|
||||
_noexport
|
||||
void _createAndBind_sliceClass(void) {
|
||||
void _createAndBind_sliceClass(KrkThreadState * _thread) {
|
||||
KrkClass * slice = ADD_BASE_CLASS(vm.baseClasses->sliceClass, "slice", vm.baseClasses->objectClass);
|
||||
slice->allocSize = sizeof(struct KrkSlice);
|
||||
slice->_ongcscan = _slice_gcscan;
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "private.h"
|
||||
|
||||
static KrkValue FUNC_NAME(striterator,__init__)(int,const KrkValue[],int);
|
||||
static KrkValue FUNC_NAME(striterator,__init__)(KrkThreadState*,int,const KrkValue[],int);
|
||||
|
||||
#define CURRENT_CTYPE KrkString *
|
||||
#define CURRENT_NAME self
|
||||
@ -169,14 +169,14 @@ KRK_Method(str,__getitem__) {
|
||||
}
|
||||
}
|
||||
|
||||
const char * krk_parseCommonFormatSpec(struct ParsedFormatSpec *result, const char * spec, size_t length);
|
||||
const char * krk_parseCommonFormatSpec(KrkThreadState * _thread, struct ParsedFormatSpec *result, const char * spec, size_t length);
|
||||
|
||||
KRK_Method(str,__format__) {
|
||||
METHOD_TAKES_EXACTLY(1);
|
||||
CHECK_ARG(1,str,KrkString*,format_spec);
|
||||
|
||||
struct ParsedFormatSpec opts = {0};
|
||||
const char * spec = krk_parseCommonFormatSpec(&opts, format_spec->chars, format_spec->length);
|
||||
const char * spec = krk_parseCommonFormatSpec(_thread, &opts, format_spec->chars, format_spec->length);
|
||||
if (!spec) return NONE_VAL();
|
||||
|
||||
switch (*spec) {
|
||||
@ -408,7 +408,7 @@ KRK_Method(str,__mul__) {
|
||||
|
||||
KRK_Method(str,__rmul__) {
|
||||
METHOD_TAKES_EXACTLY(1);
|
||||
if (IS_INTEGER(argv[1])) return FUNC_NAME(str,__mul__)(argc,argv,hasKw);
|
||||
if (IS_INTEGER(argv[1])) return FUNC_NAME(str,__mul__)(_thread, argc,argv,hasKw);
|
||||
return NOTIMPL_VAL();
|
||||
}
|
||||
|
||||
@ -418,7 +418,7 @@ struct _str_join_context {
|
||||
int isFirst;
|
||||
};
|
||||
|
||||
static int _str_join_callback(void * context, const KrkValue * values, size_t count) {
|
||||
static int _str_join_callback(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) {
|
||||
struct _str_join_context * _context = context;
|
||||
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
@ -490,7 +490,7 @@ static int charIn(uint32_t c, KrkString * str) {
|
||||
* Implements all three of strip, lstrip, rstrip.
|
||||
* Set which = 0, 1, 2 respectively
|
||||
*/
|
||||
static KrkValue _string_strip_shared(int argc, const KrkValue argv[], int which) {
|
||||
static KrkValue _string_strip_shared(KrkThreadState *_thread, int argc, const KrkValue argv[], int which) {
|
||||
KrkString * subset = AS_STRING(vm.specialMethodNames[METHOD_STRSTRIP]);
|
||||
if (argc > 1) {
|
||||
if (IS_STRING(argv[1])) {
|
||||
@ -519,15 +519,15 @@ static KrkValue _string_strip_shared(int argc, const KrkValue argv[], int which)
|
||||
|
||||
KRK_Method(str,strip) {
|
||||
METHOD_TAKES_AT_MOST(1); /* TODO */
|
||||
return _string_strip_shared(argc,argv,0);
|
||||
return _string_strip_shared(_thread, argc,argv,0);
|
||||
}
|
||||
KRK_Method(str,lstrip) {
|
||||
METHOD_TAKES_AT_MOST(1); /* TODO */
|
||||
return _string_strip_shared(argc,argv,1);
|
||||
return _string_strip_shared(_thread, argc,argv,1);
|
||||
}
|
||||
KRK_Method(str,rstrip) {
|
||||
METHOD_TAKES_AT_MOST(1); /* TODO */
|
||||
return _string_strip_shared(argc,argv,2);
|
||||
return _string_strip_shared(_thread, argc,argv,2);
|
||||
}
|
||||
|
||||
#define strCompare(name,lop,iop,rop) \
|
||||
@ -831,7 +831,7 @@ KRK_Method(str,find) {
|
||||
}
|
||||
|
||||
KRK_Method(str,index) {
|
||||
KrkValue result = FUNC_NAME(str,find)(argc,argv,hasKw);
|
||||
KrkValue result = FUNC_NAME(str,find)(_thread, argc,argv,hasKw);
|
||||
if (IS_INTEGER(result) && AS_INTEGER(result) == -1) {
|
||||
return krk_runtimeError(vm.exceptions->valueError, "substring not found");
|
||||
}
|
||||
@ -924,8 +924,8 @@ KRK_Method(str,__str__) {
|
||||
return argv[0];
|
||||
}
|
||||
|
||||
void krk_addObjects(void) {
|
||||
KrkValue tmp = FUNC_NAME(str,__add__)(2, (KrkValue[]){krk_peek(1), krk_peek(0)},0);
|
||||
void krk_addObjects_r(KrkThreadState * _thread) {
|
||||
KrkValue tmp = FUNC_NAME(str,__add__)(_thread, 2, (KrkValue[]){krk_peek(1), krk_peek(0)},0);
|
||||
krk_pop(); krk_pop();
|
||||
krk_push(tmp);
|
||||
}
|
||||
@ -935,7 +935,7 @@ KRK_Method(str,__iter__) {
|
||||
KrkInstance * output = krk_newInstance(vm.baseClasses->striteratorClass);
|
||||
|
||||
krk_push(OBJECT_VAL(output));
|
||||
FUNC_NAME(striterator,__init__)(2, (KrkValue[]){krk_peek(0), argv[0]},0);
|
||||
FUNC_NAME(striterator,__init__)(_thread, 2, (KrkValue[]){krk_peek(0), argv[0]},0);
|
||||
krk_pop();
|
||||
|
||||
return OBJECT_VAL(output);
|
||||
@ -1057,14 +1057,14 @@ KRK_Method(striterator,__call__) {
|
||||
return argv[0];
|
||||
} else {
|
||||
krk_attachNamedValue(&self->fields, "i", INTEGER_VAL(AS_INTEGER(_counter)+1));
|
||||
return FUNC_NAME(str,__getitem__)(2,(KrkValue[]){_str,_counter},3);
|
||||
return FUNC_NAME(str,__getitem__)(_thread, 2,(KrkValue[]){_str,_counter},3);
|
||||
}
|
||||
_corrupt:
|
||||
return krk_runtimeError(vm.exceptions->typeError, "Corrupt str iterator: %s", errorStr);
|
||||
}
|
||||
|
||||
_noexport
|
||||
void _createAndBind_strClass(void) {
|
||||
void _createAndBind_strClass(KrkThreadState * _thread) {
|
||||
KrkClass * str = ADD_BASE_CLASS(vm.baseClasses->strClass, "str", vm.baseClasses->objectClass);
|
||||
str->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
|
||||
BIND_METHOD(str,__init__);
|
||||
|
@ -9,7 +9,7 @@
|
||||
if (index < 0) index += self->values.count; \
|
||||
if (index < 0 || index >= (krk_integer_type)self->values.count) return krk_runtimeError(vm.exceptions->indexError, "tuple index out of range: " PRIkrk_int, index)
|
||||
|
||||
static int _tuple_init_callback(void * context, const KrkValue * values, size_t count) {
|
||||
static int _tuple_init_callback(KrkThreadState * _thread, void * context, const KrkValue * values, size_t count) {
|
||||
KrkValueArray * positionals = context;
|
||||
if (positionals->count + count > positionals->capacity) {
|
||||
size_t old = positionals->capacity;
|
||||
@ -24,7 +24,7 @@ static int _tuple_init_callback(void * context, const KrkValue * values, size_t
|
||||
return 0;
|
||||
}
|
||||
|
||||
static KrkValue _tuple_init(int argc, const KrkValue argv[], int hasKw) {
|
||||
static KrkValue _tuple_init(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) {
|
||||
if (argc == 1) {
|
||||
return OBJECT_VAL(krk_newTuple(0));
|
||||
} else if (argc == 2) {
|
||||
@ -42,7 +42,7 @@ static KrkValue _tuple_init(int argc, const KrkValue argv[], int hasKw) {
|
||||
}
|
||||
|
||||
/* tuple creator */
|
||||
KrkValue krk_tuple_of(int argc, const KrkValue argv[], int hasKw) {
|
||||
KrkValue krk_tuple_of_r(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) {
|
||||
KrkTuple * self = krk_newTuple(argc);
|
||||
krk_push(OBJECT_VAL(self));
|
||||
for (size_t i = 0; i < (size_t)argc; ++i) {
|
||||
@ -99,7 +99,7 @@ KRK_Method(tuple,__getitem__) {
|
||||
}
|
||||
|
||||
/* make into a list */
|
||||
KrkValue result = krk_callNativeOnStack(len, &krk_currentThread.stackTop[-len], 0, krk_tuple_of);
|
||||
KrkValue result = krk_callNativeOnStack(len, &krk_currentThread.stackTop[-len], 0, krk_tuple_of_r);
|
||||
krk_currentThread.stackTop[-len-1] = result;
|
||||
while (len) {
|
||||
krk_pop();
|
||||
@ -201,18 +201,18 @@ struct TupleIter {
|
||||
int i;
|
||||
};
|
||||
|
||||
static KrkValue _tuple_iter_init(int argc, const KrkValue argv[], int hasKw) {
|
||||
static KrkValue _tuple_iter_init(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) {
|
||||
struct TupleIter * self = (struct TupleIter *)AS_OBJECT(argv[0]);
|
||||
self->myTuple = argv[1];
|
||||
self->i = 0;
|
||||
return argv[0];
|
||||
}
|
||||
|
||||
static void _tuple_iter_gcscan(KrkInstance * self) {
|
||||
static void _tuple_iter_gcscan(KrkThreadState * _thread, KrkInstance * self) {
|
||||
krk_markValue(((struct TupleIter*)self)->myTuple);
|
||||
}
|
||||
|
||||
static KrkValue _tuple_iter_call(int argc, const KrkValue argv[], int hasKw) {
|
||||
static KrkValue _tuple_iter_call(KrkThreadState * _thread, int argc, const KrkValue argv[], int hasKw) {
|
||||
struct TupleIter * self = (struct TupleIter *)AS_OBJECT(argv[0]);
|
||||
KrkValue t = self->myTuple; /* Tuple to iterate */
|
||||
int i = self->i;
|
||||
@ -227,7 +227,7 @@ static KrkValue _tuple_iter_call(int argc, const KrkValue argv[], int hasKw) {
|
||||
KRK_Method(tuple,__iter__) {
|
||||
KrkInstance * output = krk_newInstance(vm.baseClasses->tupleiteratorClass);
|
||||
krk_push(OBJECT_VAL(output));
|
||||
_tuple_iter_init(2, (KrkValue[]){krk_peek(0), argv[0]}, 0);
|
||||
_tuple_iter_init(_thread, 2, (KrkValue[]){krk_peek(0), argv[0]}, 0);
|
||||
krk_pop();
|
||||
return OBJECT_VAL(output);
|
||||
}
|
||||
@ -270,7 +270,7 @@ KRK_Method(tuple,__mul__) {
|
||||
}
|
||||
|
||||
_noexport
|
||||
void _createAndBind_tupleClass(void) {
|
||||
void _createAndBind_tupleClass(KrkThreadState *_thread) {
|
||||
KrkClass * tuple = ADD_BASE_CLASS(vm.baseClasses->tupleClass, "tuple", vm.baseClasses->objectClass);
|
||||
tuple->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
|
||||
BIND_METHOD(tuple,__repr__);
|
||||
|
@ -20,7 +20,7 @@
|
||||
* So if you specify list[int], you'll get 'list[int]'.
|
||||
*/
|
||||
|
||||
static KrkValue typeToString(KrkValue val) {
|
||||
static KrkValue typeToString(KrkThreadState * _thread, KrkValue val) {
|
||||
if (IS_CLASS(val)) {
|
||||
return OBJECT_VAL(AS_CLASS(val)->name);
|
||||
} else if (IS_STRING(val)) {
|
||||
@ -30,7 +30,7 @@ static KrkValue typeToString(KrkValue val) {
|
||||
struct StringBuilder sb = {0};
|
||||
|
||||
for (size_t i = 0; i < AS_TUPLE(val)->values.count; ++i) {
|
||||
krk_push(typeToString(AS_TUPLE(val)->values.values[i]));
|
||||
krk_push(typeToString(_thread, AS_TUPLE(val)->values.values[i]));
|
||||
pushStringBuilderStr(&sb, AS_CSTRING(krk_peek(0)), AS_STRING(krk_peek(0))->length);
|
||||
krk_pop();
|
||||
if (i < AS_TUPLE(val)->values.count - 1) {
|
||||
@ -57,7 +57,7 @@ KRK_Function(__class_getitem__) {
|
||||
pushStringBuilderStr(&sb, AS_CLASS(argv[0])->name->chars, AS_CLASS(argv[0])->name->length);
|
||||
pushStringBuilder(&sb,'[');
|
||||
|
||||
krk_push(typeToString(argv[1]));
|
||||
krk_push(typeToString(_thread, argv[1]));
|
||||
pushStringBuilderStr(&sb, AS_CSTRING(krk_peek(0)), AS_STRING(krk_peek(0))->length);
|
||||
krk_pop();
|
||||
pushStringBuilder(&sb,']');
|
||||
|
52
src/object.c
52
src/object.c
@ -9,14 +9,14 @@
|
||||
#include <kuroko/table.h>
|
||||
|
||||
#define ALLOCATE_OBJECT(type, objectType) \
|
||||
(type*)allocateObject(sizeof(type), objectType)
|
||||
(type*)allocateObject(_thread,sizeof(type), objectType)
|
||||
|
||||
#ifndef KRK_DISABLE_THREADS
|
||||
static volatile int _stringLock = 0;
|
||||
static volatile int _objectLock = 0;
|
||||
#endif
|
||||
|
||||
static KrkObj * allocateObject(size_t size, KrkObjType type) {
|
||||
static KrkObj * allocateObject(KrkThreadState *_thread, size_t size, KrkObjType type) {
|
||||
KrkObj * object = (KrkObj*)krk_reallocate(NULL, 0, size);
|
||||
memset(object,0,size);
|
||||
object->type = type;
|
||||
@ -32,7 +32,7 @@ static KrkObj * allocateObject(size_t size, KrkObjType type) {
|
||||
return object;
|
||||
}
|
||||
|
||||
size_t krk_codepointToBytes(krk_integer_type value, unsigned char * out) {
|
||||
size_t krk_codepointToBytes_r(KrkThreadState * _thread, krk_integer_type value, unsigned char * out) {
|
||||
if (value > 0xFFFF) {
|
||||
out[0] = (0xF0 | (value >> 18));
|
||||
out[1] = (0x80 | ((value >> 12) & 0x3F));
|
||||
@ -100,7 +100,7 @@ _reject:
|
||||
return *state;
|
||||
}
|
||||
|
||||
static int checkString(const char * chars, size_t length, size_t *codepointCount) {
|
||||
static int checkString(KrkThreadState * _thread, const char * chars, size_t length, size_t *codepointCount) {
|
||||
uint32_t state = 0;
|
||||
uint32_t codepoint = 0;
|
||||
unsigned char * end = (unsigned char *)chars + length;
|
||||
@ -147,7 +147,7 @@ GENREADY(2,uint16_t)
|
||||
GENREADY(4,uint32_t)
|
||||
#undef GENREADY
|
||||
|
||||
void * krk_unicodeString(KrkString * string) {
|
||||
void * krk_unicodeString_r(KrkThreadState * _thread, KrkString * string) {
|
||||
if (string->codes) return string->codes;
|
||||
else if ((string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) == KRK_OBJ_FLAGS_STRING_UCS1) _readyUCS1(string);
|
||||
else if ((string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) == KRK_OBJ_FLAGS_STRING_UCS2) _readyUCS2(string);
|
||||
@ -156,7 +156,7 @@ void * krk_unicodeString(KrkString * string) {
|
||||
return string->codes;
|
||||
}
|
||||
|
||||
uint32_t krk_unicodeCodepoint(KrkString * string, size_t index) {
|
||||
uint32_t krk_unicodeCodepoint_r(KrkThreadState * _thread, KrkString * string, size_t index) {
|
||||
krk_unicodeString(string);
|
||||
switch (string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) {
|
||||
case KRK_OBJ_FLAGS_STRING_ASCII:
|
||||
@ -169,9 +169,9 @@ uint32_t krk_unicodeCodepoint(KrkString * string, size_t index) {
|
||||
}
|
||||
}
|
||||
|
||||
static KrkString * allocateString(char * chars, size_t length, uint32_t hash) {
|
||||
static KrkString * allocateString(KrkThreadState * _thread, char * chars, size_t length, uint32_t hash) {
|
||||
size_t codesLength = 0;
|
||||
int type = checkString(chars,length,&codesLength);
|
||||
int type = checkString(_thread, chars,length,&codesLength);
|
||||
if (type == -1) {
|
||||
return krk_copyString("",0);
|
||||
}
|
||||
@ -190,7 +190,7 @@ static KrkString * allocateString(char * chars, size_t length, uint32_t hash) {
|
||||
return string;
|
||||
}
|
||||
|
||||
static uint32_t hashString(const char * key, size_t length) {
|
||||
static uint32_t hashString(KrkThreadState * _thread, const char * key, size_t length) {
|
||||
uint32_t hash = 0;
|
||||
/* This is the so-called "sdbm" hash. It comes from a piece of
|
||||
* public domain code from a clone of ndbm. */
|
||||
@ -200,8 +200,8 @@ static uint32_t hashString(const char * key, size_t length) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
KrkString * krk_takeString(char * chars, size_t length) {
|
||||
uint32_t hash = hashString(chars, length);
|
||||
KrkString * krk_takeString_r(KrkThreadState * _thread, char * chars, size_t length) {
|
||||
uint32_t hash = hashString(_thread, chars, length);
|
||||
_obtain_lock(_stringLock);
|
||||
KrkString * interned = krk_tableFindString(&vm.strings, chars, length, hash);
|
||||
if (interned != NULL) {
|
||||
@ -212,12 +212,12 @@ KrkString * krk_takeString(char * chars, size_t length) {
|
||||
|
||||
/* Part of taking ownership of this string is that we track its memory usage */
|
||||
krk_gcTakeBytes(chars, length + 1);
|
||||
KrkString * result = allocateString(chars, length, hash);
|
||||
KrkString * result = allocateString(_thread, chars, length, hash);
|
||||
return result;
|
||||
}
|
||||
|
||||
KrkString * krk_copyString(const char * chars, size_t length) {
|
||||
uint32_t hash = hashString(chars, length);
|
||||
KrkString * krk_copyString_r(KrkThreadState * _thread, const char * chars, size_t length) {
|
||||
uint32_t hash = hashString(_thread, chars, length);
|
||||
_obtain_lock(_stringLock);
|
||||
KrkString * interned = krk_tableFindString(&vm.strings, chars ? chars : "", length, hash);
|
||||
if (interned) {
|
||||
@ -227,13 +227,13 @@ KrkString * krk_copyString(const char * chars, size_t length) {
|
||||
char * heapChars = ALLOCATE(char, length + 1);
|
||||
memcpy(heapChars, chars ? chars : "", length);
|
||||
heapChars[length] = '\0';
|
||||
KrkString * result = allocateString(heapChars, length, hash);
|
||||
KrkString * result = allocateString(_thread, heapChars, length, hash);
|
||||
if (result->chars != heapChars) free(heapChars);
|
||||
_release_lock(_stringLock);
|
||||
return result;
|
||||
}
|
||||
|
||||
KrkString * krk_takeStringVetted(char * chars, size_t length, size_t codesLength, KrkStringType type, uint32_t hash) {
|
||||
KrkString * krk_takeStringVetted_r(KrkThreadState * _thread, char * chars, size_t length, size_t codesLength, KrkStringType type, uint32_t hash) {
|
||||
_obtain_lock(_stringLock);
|
||||
KrkString * interned = krk_tableFindString(&vm.strings, chars, length, hash);
|
||||
if (interned != NULL) {
|
||||
@ -256,7 +256,7 @@ KrkString * krk_takeStringVetted(char * chars, size_t length, size_t codesLength
|
||||
return string;
|
||||
}
|
||||
|
||||
KrkCodeObject * krk_newCodeObject(void) {
|
||||
KrkCodeObject * krk_newCodeObject_r(KrkThreadState * _thread) {
|
||||
KrkCodeObject * codeobject = ALLOCATE_OBJECT(KrkCodeObject, KRK_OBJ_CODEOBJECT);
|
||||
codeobject->requiredArgs = 0;
|
||||
codeobject->keywordArgs = 0;
|
||||
@ -271,7 +271,7 @@ KrkCodeObject * krk_newCodeObject(void) {
|
||||
return codeobject;
|
||||
}
|
||||
|
||||
KrkNative * krk_newNative(NativeFn function, const char * name, int type) {
|
||||
KrkNative * krk_newNative_r(KrkThreadState * _thread, NativeFn function, const char * name, int type) {
|
||||
KrkNative * native = ALLOCATE_OBJECT(KrkNative, KRK_OBJ_NATIVE);
|
||||
native->function = function;
|
||||
native->obj.flags = type;
|
||||
@ -280,7 +280,7 @@ KrkNative * krk_newNative(NativeFn function, const char * name, int type) {
|
||||
return native;
|
||||
}
|
||||
|
||||
KrkClosure * krk_newClosure(KrkCodeObject * function, KrkValue globals) {
|
||||
KrkClosure * krk_newClosure_r(KrkThreadState * _thread, KrkCodeObject * function, KrkValue globals) {
|
||||
KrkUpvalue ** upvalues = ALLOCATE(KrkUpvalue*, function->upvalueCount);
|
||||
for (size_t i = 0; i < function->upvalueCount; ++i) {
|
||||
upvalues[i] = NULL;
|
||||
@ -305,7 +305,7 @@ KrkClosure * krk_newClosure(KrkCodeObject * function, KrkValue globals) {
|
||||
return closure;
|
||||
}
|
||||
|
||||
KrkUpvalue * krk_newUpvalue(int slot) {
|
||||
KrkUpvalue * krk_newUpvalue_r(KrkThreadState * _thread, int slot) {
|
||||
KrkUpvalue * upvalue = ALLOCATE_OBJECT(KrkUpvalue, KRK_OBJ_UPVALUE);
|
||||
upvalue->location = slot;
|
||||
upvalue->next = NULL;
|
||||
@ -314,7 +314,7 @@ KrkUpvalue * krk_newUpvalue(int slot) {
|
||||
return upvalue;
|
||||
}
|
||||
|
||||
KrkClass * krk_newClass(KrkString * name, KrkClass * baseClass) {
|
||||
KrkClass * krk_newClass_r(KrkThreadState * _thread, KrkString * name, KrkClass * baseClass) {
|
||||
KrkClass * _class = ALLOCATE_OBJECT(KrkClass, KRK_OBJ_CLASS);
|
||||
_class->name = name;
|
||||
_class->allocSize = sizeof(KrkInstance);
|
||||
@ -333,21 +333,21 @@ KrkClass * krk_newClass(KrkString * name, KrkClass * baseClass) {
|
||||
return _class;
|
||||
}
|
||||
|
||||
KrkInstance * krk_newInstance(KrkClass * _class) {
|
||||
KrkInstance * instance = (KrkInstance*)allocateObject(_class->allocSize, KRK_OBJ_INSTANCE);
|
||||
KrkInstance * krk_newInstance_r(KrkThreadState * _thread, KrkClass * _class) {
|
||||
KrkInstance * instance = (KrkInstance*)allocateObject(_thread, _class->allocSize, KRK_OBJ_INSTANCE);
|
||||
instance->_class = _class;
|
||||
krk_initTable(&instance->fields);
|
||||
return instance;
|
||||
}
|
||||
|
||||
KrkBoundMethod * krk_newBoundMethod(KrkValue receiver, KrkObj * method) {
|
||||
KrkBoundMethod * krk_newBoundMethod_r(KrkThreadState * _thread, KrkValue receiver, KrkObj * method) {
|
||||
KrkBoundMethod * bound = ALLOCATE_OBJECT(KrkBoundMethod, KRK_OBJ_BOUND_METHOD);
|
||||
bound->receiver = receiver;
|
||||
bound->method = method;
|
||||
return bound;
|
||||
}
|
||||
|
||||
KrkTuple * krk_newTuple(size_t length) {
|
||||
KrkTuple * krk_newTuple_r(KrkThreadState * _thread, size_t length) {
|
||||
KrkTuple * tuple = ALLOCATE_OBJECT(KrkTuple, KRK_OBJ_TUPLE);
|
||||
krk_initValueArray(&tuple->values);
|
||||
krk_push(OBJECT_VAL(tuple));
|
||||
@ -357,7 +357,7 @@ KrkTuple * krk_newTuple(size_t length) {
|
||||
return tuple;
|
||||
}
|
||||
|
||||
KrkBytes * krk_newBytes(size_t length, uint8_t * source) {
|
||||
KrkBytes * krk_newBytes_r(KrkThreadState * _thread, size_t length, uint8_t * source) {
|
||||
KrkBytes * bytes = ALLOCATE_OBJECT(KrkBytes, KRK_OBJ_BYTES);
|
||||
bytes->length = length;
|
||||
bytes->bytes = NULL;
|
||||
|
9
src/os.c
9
src/os.c
@ -139,7 +139,7 @@ KRK_Method(Environ,__delitem__) {
|
||||
return krk_callDirect(vm.baseClasses->dictClass->_delitem, 2);
|
||||
}
|
||||
|
||||
static void _loadEnviron(KrkInstance * module) {
|
||||
static void _loadEnviron(KrkThreadState * _thread, KrkInstance * module) {
|
||||
/* Create a new class to subclass `dict` */
|
||||
KrkClass * Environ = krk_makeClass(module, &KRK_BASE_CLASS(Environ), "_Environ", vm.baseClasses->dictClass);
|
||||
krk_attachNamedObject(&module->fields, "_Environ", (KrkObj*)Environ);
|
||||
@ -463,7 +463,7 @@ KRK_Function(get_terminal_size) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static int makeArgs(int count, const KrkValue * values, char *** argsOut, const char * _method_name) {
|
||||
static int makeArgs_r(KrkThreadState * _thread, int count, const KrkValue * values, char *** argsOut, const char * _method_name) {
|
||||
char ** out = malloc(sizeof(char*)*(count+1));
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (!IS_STRING(values[i])) {
|
||||
@ -477,6 +477,7 @@ static int makeArgs(int count, const KrkValue * values, char *** argsOut, const
|
||||
*argsOut = out;
|
||||
return 0;
|
||||
}
|
||||
#define makeArgs(c,v,a,m) makeArgs_r(_thread,c,v,a,m)
|
||||
|
||||
KRK_Function(execl) {
|
||||
FUNCTION_TAKES_AT_LEAST(1);
|
||||
@ -661,7 +662,7 @@ KRK_Function(S_ISSOCK) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void krk_module_init_os(void) {
|
||||
void krk_module_init_os(KrkThreadState * _thread) {
|
||||
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
|
||||
krk_attachNamedObject(&vm.modules, "os", (KrkObj*)module);
|
||||
krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("os"));
|
||||
@ -881,7 +882,7 @@ void krk_module_init_os(void) {
|
||||
"Obtain the size of the host terminal as a tuple of columns and lines.");
|
||||
#endif
|
||||
|
||||
_loadEnviron(module);
|
||||
_loadEnviron(_thread, module);
|
||||
|
||||
/* Nothing special */
|
||||
KrkClass * stat_result = krk_makeClass(module, &KRK_BASE_CLASS(stat_result), "stat_result", vm.baseClasses->objectClass);
|
||||
|
@ -7,21 +7,21 @@
|
||||
*/
|
||||
#include "kuroko/kuroko.h"
|
||||
|
||||
extern void _createAndBind_numericClasses(void);
|
||||
extern void _createAndBind_strClass(void);
|
||||
extern void _createAndBind_listClass(void);
|
||||
extern void _createAndBind_tupleClass(void);
|
||||
extern void _createAndBind_bytesClass(void);
|
||||
extern void _createAndBind_dictClass(void);
|
||||
extern void _createAndBind_functionClass(void);
|
||||
extern void _createAndBind_rangeClass(void);
|
||||
extern void _createAndBind_setClass(void);
|
||||
extern void _createAndBind_generatorClass(void);
|
||||
extern void _createAndBind_sliceClass(void);
|
||||
extern void _createAndBind_builtins(void);
|
||||
extern void _createAndBind_type(void);
|
||||
extern void _createAndBind_exceptions(void);
|
||||
extern void _createAndBind_longClass(void);
|
||||
extern void _createAndBind_numericClasses(KrkThreadState*);
|
||||
extern void _createAndBind_strClass(KrkThreadState*);
|
||||
extern void _createAndBind_listClass(KrkThreadState*);
|
||||
extern void _createAndBind_tupleClass(KrkThreadState*);
|
||||
extern void _createAndBind_bytesClass(KrkThreadState*);
|
||||
extern void _createAndBind_dictClass(KrkThreadState*);
|
||||
extern void _createAndBind_functionClass(KrkThreadState*);
|
||||
extern void _createAndBind_rangeClass(KrkThreadState*);
|
||||
extern void _createAndBind_setClass(KrkThreadState*);
|
||||
extern void _createAndBind_generatorClass(KrkThreadState*);
|
||||
extern void _createAndBind_sliceClass(KrkThreadState*);
|
||||
extern void _createAndBind_builtins(KrkThreadState*);
|
||||
extern void _createAndBind_type(KrkThreadState*);
|
||||
extern void _createAndBind_exceptions(KrkThreadState*);
|
||||
extern void _createAndBind_longClass(KrkThreadState*);
|
||||
|
||||
/**
|
||||
* @brief Index numbers for always-available interned strings representing important method and member names.
|
||||
|
@ -177,7 +177,7 @@ KRK_Function(inspect_value) {
|
||||
return OBJECT_VAL(krk_newBytes(sizeof(KrkValue),(uint8_t*)&argv[0]));
|
||||
}
|
||||
|
||||
void krk_module_init_kuroko(void) {
|
||||
void krk_module_init_kuroko(KrkThreadState * _thread) {
|
||||
/**
|
||||
* kuroko = module()
|
||||
*
|
||||
|
30
src/table.c
30
src/table.c
@ -11,18 +11,18 @@
|
||||
|
||||
#define TABLE_MAX_LOAD 0.75
|
||||
|
||||
void krk_initTable(KrkTable * table) {
|
||||
void krk_initTable_r(struct KrkThreadState * _thread, KrkTable * table) {
|
||||
table->count = 0;
|
||||
table->capacity = 0;
|
||||
table->entries = NULL;
|
||||
}
|
||||
|
||||
void krk_freeTable(KrkTable * table) {
|
||||
void krk_freeTable_r(struct KrkThreadState * _thread, KrkTable * table) {
|
||||
FREE_ARRAY(KrkTableEntry, table->entries, table->capacity);
|
||||
krk_initTable(table);
|
||||
}
|
||||
|
||||
inline int krk_hashValue(KrkValue value, uint32_t *hashOut) {
|
||||
inline int krk_hashValue_r(struct KrkThreadState * _thread, KrkValue value, uint32_t *hashOut) {
|
||||
switch (KRK_VAL_TYPE(value)) {
|
||||
case KRK_VAL_BOOLEAN:
|
||||
case KRK_VAL_INTEGER:
|
||||
@ -59,7 +59,7 @@ _unhashable:
|
||||
return 1;
|
||||
}
|
||||
|
||||
KrkTableEntry * krk_findEntry(KrkTableEntry * entries, size_t capacity, KrkValue key) {
|
||||
KrkTableEntry * krk_findEntry_r(struct KrkThreadState * _thread, KrkTableEntry * entries, size_t capacity, KrkValue key) {
|
||||
uint32_t index;
|
||||
if (krk_hashValue(key, &index)) {
|
||||
return NULL;
|
||||
@ -82,7 +82,7 @@ KrkTableEntry * krk_findEntry(KrkTableEntry * entries, size_t capacity, KrkValue
|
||||
}
|
||||
}
|
||||
|
||||
KrkTableEntry * krk_findEntryExact(KrkTableEntry * entries, size_t capacity, KrkValue key) {
|
||||
KrkTableEntry * krk_findEntryExact_r(struct KrkThreadState * _thread, KrkTableEntry * entries, size_t capacity, KrkValue key) {
|
||||
uint32_t index;
|
||||
if (krk_hashValue(key, &index)) {
|
||||
return NULL;
|
||||
@ -113,7 +113,7 @@ int __builtin_clz(unsigned int x) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void krk_tableAdjustCapacity(KrkTable * table, size_t capacity) {
|
||||
void krk_tableAdjustCapacity_r(struct KrkThreadState * _thread, KrkTable * table, size_t capacity) {
|
||||
if (capacity) {
|
||||
/* Fast power-of-two calculation */
|
||||
size_t powerOfTwoCapacity = __builtin_clz(1) - __builtin_clz(capacity);
|
||||
@ -142,7 +142,7 @@ void krk_tableAdjustCapacity(KrkTable * table, size_t capacity) {
|
||||
table->capacity = capacity;
|
||||
}
|
||||
|
||||
int krk_tableSet(KrkTable * table, KrkValue key, KrkValue value) {
|
||||
int krk_tableSet_r(struct KrkThreadState * _thread, KrkTable * table, KrkValue key, KrkValue value) {
|
||||
if (table->count + 1 > table->capacity * TABLE_MAX_LOAD) {
|
||||
size_t capacity = GROW_CAPACITY(table->capacity);
|
||||
krk_tableAdjustCapacity(table, capacity);
|
||||
@ -156,7 +156,7 @@ int krk_tableSet(KrkTable * table, KrkValue key, KrkValue value) {
|
||||
return isNewKey;
|
||||
}
|
||||
|
||||
int krk_tableSetIfExists(KrkTable * table, KrkValue key, KrkValue value) {
|
||||
int krk_tableSetIfExists_r(struct KrkThreadState * _thread, KrkTable * table, KrkValue key, KrkValue value) {
|
||||
if (table->count == 0) return 0;
|
||||
KrkTableEntry * entry = krk_findEntry(table->entries, table->capacity, key);
|
||||
if (!entry) return 0;
|
||||
@ -166,7 +166,7 @@ int krk_tableSetIfExists(KrkTable * table, KrkValue key, KrkValue value) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void krk_tableAddAll(KrkTable * from, KrkTable * to) {
|
||||
void krk_tableAddAll_r(struct KrkThreadState * _thread, KrkTable * from, KrkTable * to) {
|
||||
for (size_t i = 0; i < from->capacity; ++i) {
|
||||
KrkTableEntry * entry = &from->entries[i];
|
||||
if (!IS_KWARGS(entry->key)) {
|
||||
@ -175,7 +175,7 @@ void krk_tableAddAll(KrkTable * from, KrkTable * to) {
|
||||
}
|
||||
}
|
||||
|
||||
int krk_tableGet(KrkTable * table, KrkValue key, KrkValue * value) {
|
||||
int krk_tableGet_r(struct KrkThreadState * _thread, KrkTable * table, KrkValue key, KrkValue * value) {
|
||||
if (table->count == 0) return 0;
|
||||
KrkTableEntry * entry = krk_findEntry(table->entries, table->capacity, key);
|
||||
if (!entry || IS_KWARGS(entry->key)) {
|
||||
@ -186,7 +186,7 @@ int krk_tableGet(KrkTable * table, KrkValue key, KrkValue * value) {
|
||||
}
|
||||
}
|
||||
|
||||
int krk_tableGet_fast(KrkTable * table, KrkString * str, KrkValue * value) {
|
||||
int krk_tableGet_fast_r(struct KrkThreadState * _thread, KrkTable * table, KrkString * str, KrkValue * value) {
|
||||
if (unlikely(table->count == 0)) return 0;
|
||||
uint32_t index = str->obj.hash & (table->capacity-1);
|
||||
for (;;) {
|
||||
@ -200,7 +200,7 @@ int krk_tableGet_fast(KrkTable * table, KrkString * str, KrkValue * value) {
|
||||
}
|
||||
}
|
||||
|
||||
int krk_tableDelete(KrkTable * table, KrkValue key) {
|
||||
int krk_tableDelete_r(struct KrkThreadState * _thread, KrkTable * table, KrkValue key) {
|
||||
if (table->count == 0) return 0;
|
||||
KrkTableEntry * entry = krk_findEntry(table->entries, table->capacity, key);
|
||||
if (!entry || IS_KWARGS(entry->key)) {
|
||||
@ -212,9 +212,9 @@ int krk_tableDelete(KrkTable * table, KrkValue key) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int krk_tableDeleteExact(KrkTable * table, KrkValue key) {
|
||||
int krk_tableDeleteExact_r(struct KrkThreadState * _thread, KrkTable * table, KrkValue key) {
|
||||
if (table->count == 0) return 0;
|
||||
KrkTableEntry * entry = krk_findEntryExact(table->entries, table->capacity, key);
|
||||
KrkTableEntry * entry = krk_findEntryExact_r(_thread, table->entries, table->capacity, key);
|
||||
if (!entry || IS_KWARGS(entry->key)) {
|
||||
return 0;
|
||||
}
|
||||
@ -224,7 +224,7 @@ int krk_tableDeleteExact(KrkTable * table, KrkValue key) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
KrkString * krk_tableFindString(KrkTable * table, const char * chars, size_t length, uint32_t hash) {
|
||||
KrkString * krk_tableFindString_r(struct KrkThreadState * _thread, KrkTable * table, const char * chars, size_t length, uint32_t hash) {
|
||||
if (table->count == 0) return NULL;
|
||||
|
||||
uint32_t index = hash & (table->capacity-1);
|
||||
|
@ -32,6 +32,7 @@
|
||||
struct Thread {
|
||||
KrkInstance inst;
|
||||
KrkThreadState * threadState;
|
||||
KrkVM * owner;
|
||||
pthread_t nativeRef;
|
||||
pid_t tid;
|
||||
unsigned int started:1;
|
||||
@ -61,10 +62,11 @@ KRK_Function(current_thread) {
|
||||
|
||||
static volatile int _threadLock = 0;
|
||||
static void * _startthread(void * _threadObj) {
|
||||
#if defined(__APPLE__) && defined(__aarch64__)
|
||||
krk_forceThreadData();
|
||||
#endif
|
||||
memset(&krk_currentThread, 0, sizeof(KrkThreadState));
|
||||
struct Thread * self = _threadObj;
|
||||
self->threadState = calloc(1,sizeof(KrkThreadState));
|
||||
KrkThreadState * _thread = self->threadState;
|
||||
_thread->owner = self->owner;
|
||||
|
||||
krk_currentThread.frames = calloc(vm.maximumCallDepth,sizeof(KrkCallFrame));
|
||||
vm.globalFlags |= KRK_GLOBAL_THREADS;
|
||||
_obtain_lock(_threadLock);
|
||||
@ -75,8 +77,6 @@ static void * _startthread(void * _threadObj) {
|
||||
_release_lock(_threadLock);
|
||||
|
||||
/* Get our run function */
|
||||
struct Thread * self = _threadObj;
|
||||
self->threadState = &krk_currentThread;
|
||||
self->tid = gettid();
|
||||
|
||||
KrkValue runMethod = NONE_VAL();
|
||||
@ -93,7 +93,7 @@ static void * _startthread(void * _threadObj) {
|
||||
|
||||
/* Remove this thread from the thread pool, its stack is garbage anyway */
|
||||
_obtain_lock(_threadLock);
|
||||
krk_resetStack();
|
||||
krk_resetStack(_thread);
|
||||
KrkThreadState * previous = vm.threads;
|
||||
while (previous) {
|
||||
if (previous->next == &krk_currentThread) {
|
||||
@ -133,6 +133,7 @@ KRK_Method(Thread,start) {
|
||||
|
||||
self->started = 1;
|
||||
self->alive = 1;
|
||||
self->owner = _thread->owner;
|
||||
pthread_create(&self->nativeRef, NULL, _startthread, (void*)self);
|
||||
|
||||
return argv[0];
|
||||
@ -155,7 +156,7 @@ KRK_Method(Lock,__init__) {
|
||||
return argv[0];
|
||||
}
|
||||
|
||||
static inline void _pushLockStatus(struct Lock * self, struct StringBuilder * sb) {
|
||||
static inline void _pushLockStatus(KrkThreadState * _thread, struct Lock * self, struct StringBuilder * sb) {
|
||||
#ifdef __GLIBC__
|
||||
{
|
||||
if (self->mutex.__data.__owner) {
|
||||
@ -182,7 +183,7 @@ KRK_Method(Lock,__repr__) {
|
||||
pushStringBuilderStr(&sb, tmp, len);
|
||||
}
|
||||
|
||||
_pushLockStatus(self,&sb);
|
||||
_pushLockStatus(_thread, self,&sb);
|
||||
|
||||
pushStringBuilder(&sb,'>');
|
||||
return finishStringBuilder(&sb);
|
||||
@ -199,7 +200,7 @@ KRK_Method(Lock,__exit__) {
|
||||
return NONE_VAL();
|
||||
}
|
||||
|
||||
void krk_module_init_threading(void) {
|
||||
void krk_module_init_threading(KrkThreadState * _thread) {
|
||||
/**
|
||||
* threads = module()
|
||||
*
|
||||
|
@ -38,7 +38,7 @@ KRK_Function(time) {
|
||||
return FLOATING_VAL(out);
|
||||
}
|
||||
|
||||
void krk_module_init_time(void) {
|
||||
void krk_module_init_time(KrkThreadState * _thread) {
|
||||
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
|
||||
krk_attachNamedObject(&vm.modules, "time", (KrkObj*)module);
|
||||
krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("time"));
|
||||
|
38
src/value.c
38
src/value.c
@ -8,13 +8,13 @@
|
||||
|
||||
#include "opcode_enum.h"
|
||||
|
||||
void krk_initValueArray(KrkValueArray * array) {
|
||||
void krk_initValueArray_r(KrkThreadState * _thread, KrkValueArray * array) {
|
||||
array->values = NULL;
|
||||
array->capacity = 0;
|
||||
array->count = 0;
|
||||
}
|
||||
|
||||
void krk_writeValueArray(KrkValueArray * array, KrkValue value) {
|
||||
void krk_writeValueArray_r(KrkThreadState * _thread, KrkValueArray * array, KrkValue value) {
|
||||
if (array->capacity < array->count + 1) {
|
||||
int old = array->capacity;
|
||||
array->capacity = GROW_CAPACITY(old);
|
||||
@ -25,12 +25,12 @@ void krk_writeValueArray(KrkValueArray * array, KrkValue value) {
|
||||
array->count++;
|
||||
}
|
||||
|
||||
void krk_freeValueArray(KrkValueArray * array) {
|
||||
void krk_freeValueArray_r(KrkThreadState * _thread, KrkValueArray * array) {
|
||||
FREE_ARRAY(KrkValue, array->values, array->capacity);
|
||||
krk_initValueArray(array);
|
||||
}
|
||||
|
||||
void krk_printValue(FILE * f, KrkValue printable) {
|
||||
void krk_printValue_r(KrkThreadState * _thread, FILE * f, KrkValue printable) {
|
||||
KrkClass * type = krk_getType(printable);
|
||||
if (type->_tostr) {
|
||||
krk_push(printable);
|
||||
@ -49,7 +49,7 @@ void krk_printValue(FILE * f, KrkValue printable) {
|
||||
|
||||
#define STRING_DEBUG_TRUNCATE 50
|
||||
|
||||
void krk_printValueSafe(FILE * f, KrkValue printable) {
|
||||
void krk_printValueSafe_r(KrkThreadState * _thread, FILE * f, KrkValue printable) {
|
||||
if (!IS_OBJECT(printable)) {
|
||||
switch (KRK_VAL_TYPE(printable)) {
|
||||
case KRK_VAL_INTEGER: fprintf(f, PRIkrk_int, AS_INTEGER(printable)); break;
|
||||
@ -145,11 +145,11 @@ void krk_printValueSafe(FILE * f, KrkValue printable) {
|
||||
/**
|
||||
* Identity really should be the simple...
|
||||
*/
|
||||
int krk_valuesSame(KrkValue a, KrkValue b) {
|
||||
int krk_valuesSame_r(KrkThreadState * _thread, KrkValue a, KrkValue b) {
|
||||
return a == b;
|
||||
}
|
||||
|
||||
static inline int _krk_method_equivalence(KrkValue a, KrkValue b) {
|
||||
static inline int _krk_method_equivalence(KrkThreadState * _thread, KrkValue a, KrkValue b) {
|
||||
KrkClass * type = krk_getType(a);
|
||||
if (likely(type && type->_eq)) {
|
||||
krk_push(a);
|
||||
@ -173,7 +173,7 @@ static inline int _krk_method_equivalence(KrkValue a, KrkValue b) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int _krk_same_type_equivalence(uint16_t valtype, KrkValue a, KrkValue b) {
|
||||
static inline int _krk_same_type_equivalence(KrkThreadState * _thread, uint16_t valtype, KrkValue a, KrkValue b) {
|
||||
switch (valtype) {
|
||||
case KRK_VAL_BOOLEAN:
|
||||
case KRK_VAL_INTEGER:
|
||||
@ -184,11 +184,11 @@ static inline int _krk_same_type_equivalence(uint16_t valtype, KrkValue a, KrkVa
|
||||
return a == b;
|
||||
case KRK_VAL_OBJECT:
|
||||
default:
|
||||
return _krk_method_equivalence(a,b);
|
||||
return _krk_method_equivalence(_thread,a,b);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int _krk_same_type_equivalence_b(uint16_t valtype, KrkValue a, KrkValue b) {
|
||||
static inline int _krk_same_type_equivalence_b(KrkThreadState * _thread, uint16_t valtype, KrkValue a, KrkValue b) {
|
||||
switch (valtype) {
|
||||
case KRK_VAL_BOOLEAN:
|
||||
case KRK_VAL_INTEGER:
|
||||
@ -199,33 +199,33 @@ static inline int _krk_same_type_equivalence_b(uint16_t valtype, KrkValue a, Krk
|
||||
return 0;
|
||||
case KRK_VAL_OBJECT:
|
||||
default:
|
||||
return _krk_method_equivalence(a,b);
|
||||
return _krk_method_equivalence(_thread,a,b);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int _krk_diff_type_equivalence(uint16_t val_a, uint16_t val_b, KrkValue a, KrkValue b) {
|
||||
static inline int _krk_diff_type_equivalence(KrkThreadState * _thread, uint16_t val_a, uint16_t val_b, KrkValue a, KrkValue b) {
|
||||
/* We do not want to let KWARGS leak to anything needs to, eg., examine types. */
|
||||
if (val_b == KRK_VAL_KWARGS || val_a == KRK_VAL_KWARGS) return 0;
|
||||
|
||||
/* Fall back to methods */
|
||||
return _krk_method_equivalence(a,b);
|
||||
return _krk_method_equivalence(_thread,a,b);
|
||||
}
|
||||
|
||||
__attribute__((hot))
|
||||
int krk_valuesSameOrEqual(KrkValue a, KrkValue b) {
|
||||
int krk_valuesSameOrEqual_r(KrkThreadState * _thread, KrkValue a, KrkValue b) {
|
||||
if (a == b) return 1;
|
||||
uint16_t val_a = KRK_VAL_TYPE(a);
|
||||
uint16_t val_b = KRK_VAL_TYPE(b);
|
||||
return (val_a == val_b)
|
||||
? _krk_same_type_equivalence_b(val_a, a, b)
|
||||
: _krk_diff_type_equivalence(val_a, val_b, a, b);
|
||||
? _krk_same_type_equivalence_b(_thread, val_a, a, b)
|
||||
: _krk_diff_type_equivalence(_thread, val_a, val_b, a, b);
|
||||
}
|
||||
|
||||
__attribute__((hot))
|
||||
int krk_valuesEqual(KrkValue a, KrkValue b) {
|
||||
int krk_valuesEqual_r(KrkThreadState * _thread, KrkValue a, KrkValue b) {
|
||||
uint16_t val_a = KRK_VAL_TYPE(a);
|
||||
uint16_t val_b = KRK_VAL_TYPE(b);
|
||||
return (val_a == val_b)
|
||||
? _krk_same_type_equivalence(val_a,a,b)
|
||||
: _krk_diff_type_equivalence(val_a,val_b,a,b);
|
||||
? _krk_same_type_equivalence(_thread,val_a,a,b)
|
||||
: _krk_diff_type_equivalence(_thread,val_a,val_b,a,b);
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ KrkValue SeenFunctions;
|
||||
KrkValue UnseenFunctions;
|
||||
KrkValue StringTable;
|
||||
|
||||
static void _initListFunctions(void) {
|
||||
static void _initListFunctions(KrkThreadState * _thread) {
|
||||
KrkValue _list_pop;
|
||||
KrkValue _list_append;
|
||||
KrkValue _list_contains;
|
||||
@ -70,24 +70,30 @@ static void _initListFunctions(void) {
|
||||
ListIndex = AS_NATIVE(_list_index)->function;
|
||||
}
|
||||
|
||||
static void findInterpreter(char * argv[]) {
|
||||
static char * findInterpreter(char * argv[]) {
|
||||
#ifdef _WIN32
|
||||
vm.binpath = strdup(_pgmptr);
|
||||
return strdup(_pgmptr);
|
||||
#else
|
||||
/* Try asking /proc */
|
||||
char tmp[4096];
|
||||
char * binpath = realpath("/proc/self/exe", NULL);
|
||||
if (!binpath || (access(binpath, X_OK) != 0)) {
|
||||
if (binpath) {
|
||||
free(binpath);
|
||||
binpath = NULL;
|
||||
}
|
||||
if (strchr(argv[0], '/')) {
|
||||
binpath = realpath(argv[0], NULL);
|
||||
} else {
|
||||
/* Search PATH for argv[0] */
|
||||
char * _path = strdup(getenv("PATH"));
|
||||
char * p = getenv("PATH");
|
||||
if (!p) return NULL;
|
||||
char * _path = strdup(p);
|
||||
char * path = _path;
|
||||
while (path) {
|
||||
char * next = strchr(path,':');
|
||||
if (next) *next++ = '\0';
|
||||
|
||||
char tmp[4096];
|
||||
snprintf(tmp, 4096, "%s/%s", path, argv[0]);
|
||||
if (access(tmp, X_OK) == 0) {
|
||||
binpath = strdup(tmp);
|
||||
@ -98,9 +104,7 @@ static void findInterpreter(char * argv[]) {
|
||||
free(_path);
|
||||
}
|
||||
}
|
||||
if (binpath) {
|
||||
vm.binpath = binpath;
|
||||
} /* Else, give up at this point and just don't attach it at all. */
|
||||
return binpath;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -121,7 +125,7 @@ static size_t internString(KrkString * str) {
|
||||
return count++;
|
||||
}
|
||||
|
||||
static int doStringTable(FILE * out) {
|
||||
static int doStringTable(KrkThreadState * _thread, FILE * out) {
|
||||
uint32_t stringCount = count;
|
||||
fwrite(&stringCount, 1, sizeof(uint32_t), out);
|
||||
|
||||
@ -134,8 +138,8 @@ static int doStringTable(FILE * out) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define WRITE_INTEGER(i) _writeInteger(out, i)
|
||||
static void _writeInteger(FILE* out, krk_integer_type i) {
|
||||
#define WRITE_INTEGER(i) _writeInteger(_thread, out, i)
|
||||
static void _writeInteger(KrkThreadState * _thread, FILE* out, krk_integer_type i) {
|
||||
if (i >= 0 && i < 256) { \
|
||||
fwrite((uint8_t[]){'i',i}, 1, 2, out);
|
||||
} else {
|
||||
@ -147,8 +151,8 @@ static void _writeInteger(FILE* out, krk_integer_type i) {
|
||||
}
|
||||
}
|
||||
|
||||
#define WRITE_FLOATING(f) _writeFloating(out, f)
|
||||
static void _writeFloating(FILE * out, double f) {
|
||||
#define WRITE_FLOATING(f) _writeFloating(_thread, out, f)
|
||||
static void _writeFloating(KrkThreadState * _thread, FILE * out, double f) {
|
||||
uint64_t doubleOut;
|
||||
memcpy(&doubleOut, &f, sizeof(double));
|
||||
fwrite("d", 1, 1, out);
|
||||
@ -157,8 +161,8 @@ static void _writeFloating(FILE * out, double f) {
|
||||
|
||||
#define WRITE_KWARGS(k) fwrite("k",1,1,out);
|
||||
|
||||
#define WRITE_STRING(s) _writeString(out, s)
|
||||
static void _writeString(FILE * out, KrkString * s) {
|
||||
#define WRITE_STRING(s) _writeString(_thread, out, s)
|
||||
static void _writeString(KrkThreadState * _thread, FILE * out, KrkString * s) {
|
||||
uint32_t ind = internString(s);
|
||||
if (ind < 256) {
|
||||
fwrite((uint8_t[]){'s',(uint8_t)ind}, 1, 2, out);
|
||||
@ -168,8 +172,8 @@ static void _writeString(FILE * out, KrkString * s) {
|
||||
}
|
||||
}
|
||||
|
||||
#define WRITE_BYTES(b) _writeBytes(out,b)
|
||||
static void _writeBytes(FILE * out, KrkBytes * b) {
|
||||
#define WRITE_BYTES(b) _writeBytes(_thread, out,b)
|
||||
static void _writeBytes(KrkThreadState * _thread, FILE * out, KrkBytes * b) {
|
||||
if (b->length < 256) {
|
||||
fwrite((uint8_t[]){'b', (uint8_t)b->length}, 1, 2, out);
|
||||
fwrite(b->bytes, 1, b->length, out);
|
||||
@ -181,11 +185,11 @@ static void _writeBytes(FILE * out, KrkBytes * b) {
|
||||
}
|
||||
}
|
||||
|
||||
#define WRITE_FUNCTION(f) _writeFunction(out,f)
|
||||
static void _writeFunction(FILE * out, KrkCodeObject * f) {
|
||||
#define WRITE_FUNCTION(f) _writeFunction(_thread,out,f)
|
||||
static void _writeFunction(KrkThreadState * _thread, FILE * out, KrkCodeObject * f) {
|
||||
/* Find this function in the function table. */
|
||||
KrkValue this = OBJECT_VAL(f);
|
||||
KrkValue index = ListIndex(2,(KrkValue[]){SeenFunctions,this},0);
|
||||
KrkValue index = ListIndex(_thread,2,(KrkValue[]){SeenFunctions,this},0);
|
||||
if (!IS_INTEGER(index)) {
|
||||
fprintf(stderr, "Internal error: Expected int from list.index, got '%s'\n", krk_typeName(index));
|
||||
exit(1);
|
||||
@ -204,13 +208,13 @@ static void _writeFunction(FILE * out, KrkCodeObject * f) {
|
||||
}
|
||||
}
|
||||
|
||||
static int doFirstPass(FILE * out) {
|
||||
static int doFirstPass(KrkThreadState * _thread, FILE * out) {
|
||||
/* Go through all functions and build string tables and function index */
|
||||
|
||||
while (AS_LIST(UnseenFunctions)->count) {
|
||||
KrkValue nextFunc = ListPop(2,(KrkValue[]){UnseenFunctions,INTEGER_VAL(0)},0);
|
||||
KrkValue nextFunc = ListPop(_thread, 2,(KrkValue[]){UnseenFunctions,INTEGER_VAL(0)},0);
|
||||
krk_push(nextFunc);
|
||||
ListAppend(2,(KrkValue[]){SeenFunctions,nextFunc},0);
|
||||
ListAppend(_thread,2,(KrkValue[]){SeenFunctions,nextFunc},0);
|
||||
|
||||
/* Examine */
|
||||
KrkCodeObject * func = AS_codeobject(nextFunc);
|
||||
@ -235,9 +239,9 @@ static int doFirstPass(FILE * out) {
|
||||
} else if (IS_codeobject(value)) {
|
||||
/* If we haven't seen this function yet, append it to the list */
|
||||
krk_push(value);
|
||||
KrkValue boolResult = ListContains(2,(KrkValue[]){SeenFunctions,value},0);
|
||||
KrkValue boolResult = ListContains(_thread,2,(KrkValue[]){SeenFunctions,value},0);
|
||||
if (IS_BOOLEAN(boolResult) && AS_BOOLEAN(boolResult) == 0) {
|
||||
ListAppend(2,(KrkValue[]){UnseenFunctions,value},0);
|
||||
ListAppend(_thread,2,(KrkValue[]){UnseenFunctions,value},0);
|
||||
}
|
||||
krk_pop();
|
||||
}
|
||||
@ -250,7 +254,7 @@ static int doFirstPass(FILE * out) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int doSecondPass(FILE * out) {
|
||||
static int doSecondPass(KrkThreadState * _thread, FILE * out) {
|
||||
|
||||
/* Write the function count */
|
||||
uint32_t functionCount = AS_LIST(SeenFunctions)->count;
|
||||
@ -343,7 +347,7 @@ static int doSecondPass(FILE * out) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int compileFile(char * fileName) {
|
||||
static int compileFile(KrkThreadState * _thread, char * fileName) {
|
||||
/* Compile source file */
|
||||
FILE * f = fopen(fileName, "r");
|
||||
if (!f) {
|
||||
@ -366,7 +370,7 @@ static int compileFile(char * fileName) {
|
||||
|
||||
|
||||
krk_startModule("__main__");
|
||||
KrkCodeObject * func = krk_compile(buf, fileName);
|
||||
KrkCodeObject * func = krk_compile(_thread, buf, fileName);
|
||||
|
||||
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) {
|
||||
fprintf(stderr, "%s: exception during compilation:\n", fileName);
|
||||
@ -382,15 +386,15 @@ static int compileFile(char * fileName) {
|
||||
|
||||
fwrite(&header, 1, sizeof(header), out);
|
||||
|
||||
SeenFunctions = krk_list_of(0,NULL,0);
|
||||
SeenFunctions = krk_list_of_r(_thread, 0,NULL,0);
|
||||
krk_push(SeenFunctions);
|
||||
|
||||
UnseenFunctions = krk_list_of(1,(KrkValue[]){OBJECT_VAL(func)},0);
|
||||
UnseenFunctions = krk_list_of_r(_thread,1,(KrkValue[]){OBJECT_VAL(func)},0);
|
||||
krk_push(UnseenFunctions);
|
||||
|
||||
if (doFirstPass(out)) return 1;
|
||||
if (doStringTable(out)) return 1;
|
||||
if (doSecondPass(out)) return 1;
|
||||
if (doFirstPass(_thread, out)) return 1;
|
||||
if (doStringTable(_thread, out)) return 1;
|
||||
if (doSecondPass(_thread, out)) return 1;
|
||||
|
||||
krk_pop(); /* UnseenFunctions */
|
||||
krk_pop(); /* SeenFunctions */
|
||||
@ -398,7 +402,7 @@ static int compileFile(char * fileName) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static KrkValue valueFromConstant(int i, FILE * inFile) {
|
||||
static KrkValue valueFromConstant(KrkThreadState * _thread, int i, FILE * inFile) {
|
||||
uint8_t c = fgetc(inFile);
|
||||
DEBUGOUT(" %4lu: ", (unsigned long)i);
|
||||
switch (c) {
|
||||
@ -444,7 +448,7 @@ static KrkValue valueFromConstant(int i, FILE * inFile) {
|
||||
}
|
||||
}
|
||||
|
||||
static int readFile(char * fileName) {
|
||||
static int readFile(KrkThreadState * _thread, char * fileName) {
|
||||
|
||||
FILE * inFile = fopen(fileName, "r");
|
||||
if (!inFile) {
|
||||
@ -484,7 +488,7 @@ static int readFile(char * fileName) {
|
||||
|
||||
/* Create a string */
|
||||
krk_push(OBJECT_VAL(krk_takeString(strVal,strLen)));
|
||||
ListAppend(2,(KrkValue[]){StringTable, krk_peek(0)},0);
|
||||
ListAppend(_thread,2,(KrkValue[]){StringTable, krk_peek(0)},0);
|
||||
#ifdef ISDEBUG
|
||||
fprintf(stderr, "%04lu: ", (unsigned long)i);
|
||||
krk_printValueSafe(stderr, krk_peek(0));
|
||||
@ -500,7 +504,7 @@ static int readFile(char * fileName) {
|
||||
|
||||
for (size_t i = 0; i < (size_t)functionCount; ++i) {
|
||||
krk_push(OBJECT_VAL(krk_newCodeObject()));
|
||||
ListAppend(2,(KrkValue[]){SeenFunctions, krk_peek(0)}, 0);
|
||||
ListAppend(_thread,2,(KrkValue[]){SeenFunctions, krk_peek(0)}, 0);
|
||||
krk_pop();
|
||||
}
|
||||
|
||||
@ -551,12 +555,12 @@ static int readFile(char * fileName) {
|
||||
/* Read argument names */
|
||||
DEBUGOUT(" [Required Arguments]\n");
|
||||
for (size_t i = 0; i < (size_t)function.reqArgs + !!(self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS); i++) {
|
||||
krk_writeValueArray(&self->requiredArgNames, valueFromConstant(i,inFile));
|
||||
krk_writeValueArray(&self->requiredArgNames, valueFromConstant(_thread, i,inFile));
|
||||
}
|
||||
|
||||
DEBUGOUT(" [Keyword Arguments]\n");
|
||||
for (size_t i = 0; i < (size_t)function.kwArgs + !!(self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS); i++) {
|
||||
krk_writeValueArray(&self->keywordArgNames, valueFromConstant(i,inFile));
|
||||
krk_writeValueArray(&self->keywordArgNames, valueFromConstant(_thread, i,inFile));
|
||||
}
|
||||
|
||||
/* Skip bytecode for now, we'll look at it later */
|
||||
@ -584,7 +588,7 @@ static int readFile(char * fileName) {
|
||||
/* Read constants */
|
||||
DEBUGOUT(" [Constants Table]\n");
|
||||
for (size_t i = 0; i < function.ctSize; i++) {
|
||||
krk_writeValueArray(&self->chunk.constants, valueFromConstant(i, inFile));
|
||||
krk_writeValueArray(&self->chunk.constants, valueFromConstant(_thread, i, inFile));
|
||||
}
|
||||
}
|
||||
|
||||
@ -603,10 +607,11 @@ static int readFile(char * fileName) {
|
||||
KrkValue result = krk_runNext();
|
||||
if (IS_INTEGER(result)) return AS_INTEGER(result);
|
||||
else {
|
||||
return runSimpleRepl();
|
||||
return runSimpleRepl(_thread);
|
||||
}
|
||||
}
|
||||
|
||||
extern KrkThreadState * krk_initVM_withBinpath(int flags, char * binpath);
|
||||
int main(int argc, char * argv[]) {
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "usage: %s path-to-file.krk\n"
|
||||
@ -616,14 +621,14 @@ int main(int argc, char * argv[]) {
|
||||
}
|
||||
|
||||
/* Initialize a VM */
|
||||
findInterpreter(argv);
|
||||
krk_initVM(0);
|
||||
_initListFunctions();
|
||||
char * path = findInterpreter(argv);
|
||||
KrkThreadState * _thread = krk_initVM_withBinpath(0,path);
|
||||
_initListFunctions(_thread);
|
||||
|
||||
if (argc < 3) {
|
||||
return compileFile(argv[1]);
|
||||
return compileFile(_thread, argv[1]);
|
||||
} else if (argc == 3 && !strcmp(argv[1],"-r")) {
|
||||
return readFile(argv[2]);
|
||||
return readFile(_thread, argv[2]);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -3,10 +3,10 @@
|
||||
#include <kuroko/vm.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
krk_initVM(0);
|
||||
KrkThreadState * _thread = krk_initVM(0);
|
||||
krk_startModule("__main__");
|
||||
krk_interpret("import kuroko\nprint('Kuroko',kuroko.version)\n", "<stdin>");
|
||||
krk_freeVM();
|
||||
krk_interpret(_thread, "import kuroko\nprint('Kuroko',kuroko.version)\n", "<stdin>");
|
||||
krk_freeVM(_thread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -8,14 +8,14 @@
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
/* Disable automatic traceback printing, default modules */
|
||||
krk_initVM(KRK_GLOBAL_CLEAN_OUTPUT|KRK_GLOBAL_NO_DEFAULT_MODULES);
|
||||
KrkThreadState * _thread = krk_initVM(KRK_GLOBAL_CLEAN_OUTPUT|KRK_GLOBAL_NO_DEFAULT_MODULES);
|
||||
|
||||
/* Set up our module context. */
|
||||
krk_startModule("__main__");
|
||||
|
||||
int retval = 0;
|
||||
if (argc > 1) {
|
||||
KrkValue result = krk_interpret(argv[1], "<stdin>");
|
||||
KrkValue result = krk_interpret(_thread, argv[1], "<stdin>");
|
||||
if (!IS_NONE(result)) {
|
||||
if (IS_INTEGER(result)) {
|
||||
retval = AS_INTEGER(result);
|
||||
@ -33,10 +33,10 @@ int main(int argc, char * argv[]) {
|
||||
retval = 1;
|
||||
}
|
||||
} else {
|
||||
runSimpleRepl();
|
||||
runSimpleRepl(_thread);
|
||||
}
|
||||
|
||||
krk_freeVM();
|
||||
krk_freeVM(_thread);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
#define PROMPT_MAIN ">>> "
|
||||
#define PROMPT_BLOCK " > "
|
||||
static int runSimpleRepl(void) {
|
||||
static int runSimpleRepl(KrkThreadState * _thread) {
|
||||
int exitRepl = 0;
|
||||
while (!exitRepl) {
|
||||
size_t lineCapacity = 8;
|
||||
@ -99,7 +99,7 @@ static int runSimpleRepl(void) {
|
||||
}
|
||||
FREE_ARRAY(char *, lines, lineCapacity);
|
||||
if (valid) {
|
||||
KrkValue result = krk_interpret(allData, "<stdin>");
|
||||
KrkValue result = krk_interpret(_thread, allData, "<stdin>");
|
||||
if (!IS_NONE(result)) {
|
||||
KrkClass * type = krk_getType(result);
|
||||
const char * formatStr = " \033[1;30m=> %s\033[0m\n";
|
||||
@ -118,7 +118,7 @@ static int runSimpleRepl(void) {
|
||||
} else if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) {
|
||||
krk_dumpTraceback();
|
||||
}
|
||||
krk_resetStack();
|
||||
krk_resetStack(_thread);
|
||||
free(allData);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user