More header cleanup, rename some stuff

This commit is contained in:
K. Lange 2021-02-19 12:30:39 +09:00
parent 6f1eefe68d
commit 79cc3bdac1
20 changed files with 226 additions and 167 deletions

View File

@ -1,5 +1,8 @@
#pragma once
/**
* @file chunk.h
* @brief Structures and enums for bytecode chunks.
*/
#include "kuroko.h"
#include "value.h"

View File

@ -231,7 +231,7 @@ static void advance() {
(parser.current.type == TOKEN_INDENTATION || parser.current.type == TOKEN_EOL)) continue;
#ifdef ENABLE_SCAN_TRACING
if (krk_currentThread.flags & KRK_ENABLE_SCAN_TRACING) {
if (krk_currentThread.flags & KRK_THREAD_ENABLE_SCAN_TRACING) {
fprintf(stderr, "[%s<%d> %d:%d '%.*s'] ",
getRule(parser.current.type)->name,
(int)parser.current.type,
@ -358,7 +358,7 @@ static KrkFunction * endCompiler() {
}
#ifdef ENABLE_DISASSEMBLY
if ((krk_currentThread.flags & KRK_ENABLE_DISASSEMBLY) && !parser.hadError) {
if ((krk_currentThread.flags & KRK_THREAD_ENABLE_DISASSEMBLY) && !parser.hadError) {
krk_disassembleChunk(stderr, function, function->name ? function->name->chars : "(module)");
}
#endif
@ -837,7 +837,7 @@ static void block(size_t indentation, const char * blockName) {
}
};
#ifdef ENABLE_SCAN_TRACING
if (krk_currentThread.flags & KRK_ENABLE_SCAN_TRACING) {
if (krk_currentThread.flags & KRK_THREAD_ENABLE_SCAN_TRACING) {
fprintf(stderr, "\n\nfinished with block %s (ind=%d) on line %d, sitting on a %s (len=%d)\n\n",
blockName, (int)indentation, (int)parser.current.line,
getRule(parser.current.type)->name, (int)parser.current.length);
@ -1080,7 +1080,7 @@ static KrkToken classDeclaration() {
method(currentIndentation);
}
#ifdef ENABLE_SCAN_TRACING
if (krk_currentThread.flags & KRK_ENABLE_SCAN_TRACING) fprintf(stderr, "Exiting from class definition on %s\n", getRule(parser.current.type)->name);
if (krk_currentThread.flags & KRK_THREAD_ENABLE_SCAN_TRACING) fprintf(stderr, "Exiting from class definition on %s\n", getRule(parser.current.type)->name);
#endif
/* Exit from block */
}

View File

@ -1,5 +1,8 @@
#pragma once
/**
* @file compiler.h
* @brief Exported methods for the source compiler.
*/
#include "object.h"
/**

View File

@ -1,5 +1,8 @@
#pragma once
/**
* @file debug.h
* @brief Functions for disassembling bytecode.
*/
#include <stdio.h>
#include "chunk.h"
#include "object.h"

View File

@ -1,3 +1,7 @@
/**
* @file exceptions.c
* @brief Definitions and native method bindings for error types.
*/
#include <string.h>
#include "vm.h"
#include "value.h"
@ -5,11 +9,11 @@
#include "util.h"
/**
* @def ADD_EXCEPTION_CLASS(obj, name, baseClass)
* @def ADD_EXCEPTION_CLASS(obj,name,baseClass)
*
* Convenience macro for creating exception types.
*/
#define ADD_EXCEPTION_CLASS(obj, name, baseClass) do { \
#define ADD_EXCEPTION_CLASS(obj,name,baseClass) do { \
obj = krk_newClass(S(name), baseClass); \
krk_attachNamedObject(&vm.builtins->fields, name, (KrkObj*)obj); \
krk_finalizeClass(obj); \
@ -31,9 +35,9 @@ static KrkValue krk_initException(int argc, KrkValue argv[], int hasKw) {
/**
* @brief Create a string representation of an Exception.
*
* Native binding for Exception.__repr__
* Native binding for @c Exception.__repr__
*
* Generates a string representation of the form "Exception(arg)".
* Generates a string representation of the form @c "Exception(arg)" .
*/
static KrkValue _exception_repr(int argc, KrkValue argv[], int hasKw) {
KrkInstance * self = AS_INSTANCE(argv[0]);
@ -58,7 +62,7 @@ static KrkValue _exception_repr(int argc, KrkValue argv[], int hasKw) {
/**
* @brief Obtain a descriptive string from an exception.
*
* Native binding for Exception.__str__
* Native binding for @c Exception.__str__
*
* For most exceptions, this is the 'arg' value attached at initialization
* and is printed during a traceback after the name of the exception type.
@ -79,7 +83,7 @@ static KrkValue _exception_str(int argc, KrkValue argv[], int hasKw) {
/**
* @brief Generate printable text for a syntax error.
*
* Native binding for SyntaxError.__str__
* Native binding for @c SyntaxError.__str__
*
* Syntax errors are handled specially by the traceback generator so that they
* can print the original source line containing the erroneous input, so instead

View File

@ -355,7 +355,7 @@ static int compileFile(char * argv[], int flags, char * fileName) {
KrkFunction * func = krk_compile(buf, 0, fileName);
/* See if there was an exception. */
if (krk_currentThread.flags & KRK_HAS_EXCEPTION) {
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) {
krk_dumpTraceback();
}
@ -388,19 +388,19 @@ int main(int argc, char * argv[]) {
return runString(argv, flags, optarg);
case 'd':
/* Disassemble code blocks after compilation. */
flags |= KRK_ENABLE_DISASSEMBLY;
flags |= KRK_THREAD_ENABLE_DISASSEMBLY;
break;
case 'g':
/* Always garbage collect during an allocation. */
flags |= KRK_ENABLE_STRESS_GC;
flags |= KRK_GLOBAL_ENABLE_STRESS_GC;
break;
case 's':
/* Print debug information during compilation. */
flags |= KRK_ENABLE_SCAN_TRACING;
flags |= KRK_THREAD_ENABLE_SCAN_TRACING;
break;
case 't':
/* Disassemble instructions as they are executed. */
flags |= KRK_ENABLE_TRACING;
flags |= KRK_THREAD_ENABLE_TRACING;
break;
case 'm':
moduleAsMain = 1;
@ -482,7 +482,7 @@ _finishArgs:
AS_STRING(AS_LIST(argList)->values[0]),
&module,
AS_STRING(krk_peek(0)));
if (krk_currentThread.flags & KRK_HAS_EXCEPTION) {
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) {
krk_dumpTraceback();
krk_resetStack();
}

View File

@ -1,5 +1,8 @@
#pragma once
/**
* @file kuroko.h
* @brief Top-level header with configuration macros.
*/
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>

View File

@ -8,9 +8,9 @@
void * krk_reallocate(void * ptr, size_t old, size_t new) {
vm.bytesAllocated += new - old;
if (new > old && ptr != krk_currentThread.stack && &krk_currentThread == vm.threads && !(vm.globalFlags & KRK_GC_PAUSED)) {
if (new > old && ptr != krk_currentThread.stack && &krk_currentThread == vm.threads && !(vm.globalFlags & KRK_GLOBAL_GC_PAUSED)) {
#ifdef ENABLE_STRESS_GC
if (vm.globalFlags & KRK_ENABLE_STRESS_GC) {
if (vm.globalFlags & KRK_GLOBAL_ENABLE_STRESS_GC) {
krk_collectGarbage();
}
#endif
@ -259,7 +259,7 @@ static void markThreadRoots(KrkThreadState * thread) {
if (thread->module) krk_markObject((KrkObj*)thread->module);
for (int i = 0; i < THREAD_SCRATCH_SIZE; ++i) {
for (int i = 0; i < KRK_THREAD_SCRATCH_SIZE; ++i) {
krk_markValue(thread->scratchSpace[i]);
}
}
@ -318,12 +318,12 @@ static KrkValue krk_generations(int argc, KrkValue argv[], int hasKw) {
}
static KrkValue _gc_pause(int argc, KrkValue argv[], int hasKw) {
vm.globalFlags |= (KRK_GC_PAUSED);
vm.globalFlags |= (KRK_GLOBAL_GC_PAUSED);
return NONE_VAL();
}
static KrkValue _gc_resume(int argc, KrkValue argv[], int hasKw) {
vm.globalFlags &= ~(KRK_GC_PAUSED);
vm.globalFlags &= ~(KRK_GLOBAL_GC_PAUSED);
return NONE_VAL();
}

View File

@ -1,5 +1,8 @@
#pragma once
/**
* @file memory.h
* @brief Functions for dealing with garbage collection and memory allocation.
*/
#include "kuroko.h"
#include "object.h"
#include "table.h"

View File

@ -1,7 +1,9 @@
#pragma once
/**
* @file object.h
* @brief Struct definitions for core object types.
*/
#include <stdio.h>
#include "kuroko.h"
#include "value.h"
#include "chunk.h"
@ -11,31 +13,6 @@
#include <pthread.h>
#endif
#define isObjType(v,t) (IS_OBJECT(v) && (AS_OBJECT(v)->type == (t)))
#define OBJECT_TYPE(value) (AS_OBJECT(value)->type)
#define IS_STRING(value) isObjType(value, OBJ_STRING)
#define AS_STRING(value) ((KrkString *)AS_OBJECT(value))
#define AS_CSTRING(value) (((KrkString *)AS_OBJECT(value))->chars)
#define IS_BYTES(value) isObjType(value, OBJ_BYTES)
#define AS_BYTES(value) ((KrkBytes*)AS_OBJECT(value))
#define IS_FUNCTION(value) isObjType(value, OBJ_FUNCTION)
#define AS_FUNCTION(value) ((KrkFunction *)AS_OBJECT(value))
#define IS_NATIVE(value) isObjType(value, OBJ_NATIVE)
#define AS_NATIVE(value) ((KrkNative *)AS_OBJECT(value))
#define IS_CLOSURE(value) isObjType(value, OBJ_CLOSURE)
#define AS_CLOSURE(value) ((KrkClosure *)AS_OBJECT(value))
#define IS_CLASS(value) isObjType(value, OBJ_CLASS)
#define AS_CLASS(value) ((KrkClass *)AS_OBJECT(value))
#define IS_INSTANCE(value) isObjType(value, OBJ_INSTANCE)
#define AS_INSTANCE(value) ((KrkInstance *)AS_OBJECT(value))
#define IS_BOUND_METHOD(value) isObjType(value, OBJ_BOUND_METHOD)
#define AS_BOUND_METHOD(value) ((KrkBoundMethod*)AS_OBJECT(value))
#define IS_TUPLE(value) isObjType(value, OBJ_TUPLE)
#define AS_TUPLE(value) ((KrkTuple *)AS_OBJECT(value))
#define IS_PROPERTY(value) isObjType(value, OBJ_PROPERTY)
#define AS_PROPERTY(value) ((KrkProperty *)AS_OBJECT(value))
typedef enum {
OBJ_FUNCTION,
OBJ_NATIVE,
@ -58,7 +35,7 @@ struct Obj {
unsigned char isImmortal:1;
uint32_t hash;
struct Obj * next;
};
} /* KrkObj */;
typedef enum {
KRK_STRING_ASCII = 0,
@ -75,7 +52,7 @@ struct ObjString {
size_t codesLength;
char * chars;
void * codes;
};
} /* KrkString */;
typedef struct {
KrkObj obj;
@ -215,9 +192,6 @@ struct DictKeys {
size_t i;
};
#define AS_LIST(value) (&((KrkList *)AS_OBJECT(value))->values)
#define AS_DICT(value) (&((KrkDict *)AS_OBJECT(value))->entries)
/**
* @brief Yield ownership of a C string to the GC and obtain a string object.
*
@ -296,14 +270,17 @@ extern size_t krk_codepointToBytes(krk_integer_type value, unsigned char * out);
/* Internal stuff. */
extern KrkFunction * krk_newFunction(void);
extern KrkNative * krk_newNative(NativeFn function, const char * name, int type);
extern KrkNative * krk_newNative(NativeFn function, const char * name, int type);
extern KrkClosure * krk_newClosure(KrkFunction * function);
extern KrkUpvalue * krk_newUpvalue(int slot);
extern KrkClass * krk_newClass(KrkString * name, KrkClass * base);
extern KrkInstance * krk_newInstance(KrkClass * _class);
extern KrkBoundMethod * krk_newBoundMethod(KrkValue receiver, KrkObj * method);
extern KrkTuple * krk_newTuple(size_t length);
extern KrkProperty * krk_newProperty(KrkValue method);
extern KrkProperty * krk_newProperty(KrkValue method);
extern KrkBytes * krk_newBytes(size_t length, uint8_t * source);
extern void krk_bytesUpdateHash(KrkBytes * bytes);
extern void krk_tupleUpdateHash(KrkTuple * self);
#define KRK_STRING_FAST(string,offset) (uint32_t)\
(string->type <= 1 ? ((uint8_t*)string->codes)[offset] : \
@ -312,7 +289,29 @@ extern KrkProperty * krk_newProperty(KrkValue method);
#define CODEPOINT_BYTES(cp) (cp < 0x80 ? 1 : (cp < 0x800 ? 2 : (cp < 0x10000 ? 3 : 4)))
extern KrkBytes * krk_newBytes(size_t length, uint8_t * source);
extern void krk_bytesUpdateHash(KrkBytes * bytes);
#define isObjType(v,t) (IS_OBJECT(v) && (AS_OBJECT(v)->type == (t)))
#define OBJECT_TYPE(value) (AS_OBJECT(value)->type)
#define IS_STRING(value) isObjType(value, OBJ_STRING)
#define AS_STRING(value) ((KrkString *)AS_OBJECT(value))
#define AS_CSTRING(value) (((KrkString *)AS_OBJECT(value))->chars)
#define IS_BYTES(value) isObjType(value, OBJ_BYTES)
#define AS_BYTES(value) ((KrkBytes*)AS_OBJECT(value))
#define IS_FUNCTION(value) isObjType(value, OBJ_FUNCTION)
#define AS_FUNCTION(value) ((KrkFunction *)AS_OBJECT(value))
#define IS_NATIVE(value) isObjType(value, OBJ_NATIVE)
#define AS_NATIVE(value) ((KrkNative *)AS_OBJECT(value))
#define IS_CLOSURE(value) isObjType(value, OBJ_CLOSURE)
#define AS_CLOSURE(value) ((KrkClosure *)AS_OBJECT(value))
#define IS_CLASS(value) isObjType(value, OBJ_CLASS)
#define AS_CLASS(value) ((KrkClass *)AS_OBJECT(value))
#define IS_INSTANCE(value) isObjType(value, OBJ_INSTANCE)
#define AS_INSTANCE(value) ((KrkInstance *)AS_OBJECT(value))
#define IS_BOUND_METHOD(value) isObjType(value, OBJ_BOUND_METHOD)
#define AS_BOUND_METHOD(value) ((KrkBoundMethod*)AS_OBJECT(value))
#define IS_TUPLE(value) isObjType(value, OBJ_TUPLE)
#define AS_TUPLE(value) ((KrkTuple *)AS_OBJECT(value))
#define IS_PROPERTY(value) isObjType(value, OBJ_PROPERTY)
#define AS_PROPERTY(value) ((KrkProperty *)AS_OBJECT(value))
#define AS_LIST(value) (&((KrkList *)AS_OBJECT(value))->values)
#define AS_DICT(value) (&((KrkDict *)AS_OBJECT(value))->entries)
extern void krk_tupleUpdateHash(KrkTuple * self);

View File

@ -1,4 +1,8 @@
#pragma once
/**
* @file scanner.h
* @brief Definitions used by the token scanner.
*/
typedef enum {
TOKEN_LEFT_PAREN, TOKEN_RIGHT_PAREN,

View File

@ -1,6 +1,8 @@
#pragma once
/*
/**
* @file table.h
* @brief Implementation of a generic hash table.
*
* I was going to just use the ToaruOS hashmap library, but to make following
* the book easier, let's just start from their Table implementation; it has
* an advantage of using stored entries and fixed arrays, so it has some nice

View File

@ -1,4 +1,8 @@
#pragma once
/**
* @file threads.h
* @brief Convience header for providing atomic operations to threads.
*/
#ifdef ENABLE_THREADING
#include <pthread.h>

View File

@ -1,12 +1,12 @@
#pragma once
/**
* Utilities for creating native bindings.
* @file util.h
* @brief Utilities for creating native bindings.
*
* This is intended for use in C extensions to provide a uniform interface
* for defining extension methods and ensuring they have consistent argument
* and keyword argument usage.
*/
#pragma once
#include "object.h"
#include "vm.h"
#include "memory.h"

View File

@ -1,5 +1,8 @@
#pragma once
/**
* @file value.h
* @brief Definitions for primitive stack references.
*/
#include <stdio.h>
#include "kuroko.h"

View File

@ -100,7 +100,7 @@ void krk_resetStack() {
krk_currentThread.stackTop = krk_currentThread.stack;
krk_currentThread.frameCount = 0;
krk_currentThread.openUpvalues = NULL;
krk_currentThread.flags &= ~KRK_HAS_EXCEPTION;
krk_currentThread.flags &= ~KRK_THREAD_HAS_EXCEPTION;
krk_currentThread.currentException = NONE_VAL();
}
@ -234,7 +234,7 @@ void krk_dumpTraceback() {
return;
}
/* Clear the exception state while printing the exception. */
krk_currentThread.flags &= ~(KRK_HAS_EXCEPTION);
krk_currentThread.flags &= ~(KRK_THREAD_HAS_EXCEPTION);
fprintf(stderr, "%s", krk_typeName(krk_currentThread.currentException));
KrkValue result = krk_callSimple(OBJECT_VAL(krk_getType(krk_currentThread.currentException)->_tostr), 1, 0);
if (!IS_STRING(result)) {
@ -243,7 +243,7 @@ void krk_dumpTraceback() {
fprintf(stderr, ": %s\n", AS_CSTRING(result));
}
/* Turn the exception flag back on */
krk_currentThread.flags |= KRK_HAS_EXCEPTION;
krk_currentThread.flags |= KRK_THREAD_HAS_EXCEPTION;
}
}
@ -289,7 +289,7 @@ KrkValue krk_runtimeError(KrkClass * type, const char * fmt, ...) {
va_start(args, fmt);
size_t len = vsnprintf(buf, 1024, fmt, args);
va_end(args);
krk_currentThread.flags |= KRK_HAS_EXCEPTION;
krk_currentThread.flags |= KRK_THREAD_HAS_EXCEPTION;
/* Allocate an exception object of the requested type. */
KrkInstance * exceptionObject = krk_newInstance(type);
@ -478,14 +478,14 @@ static KrkValue krk_set_tracing(int argc, KrkValue argv[], int hasKw) {
if (hasKw) {
KrkValue test;
if (krk_tableGet(AS_DICT(argv[argc]), OBJECT_VAL(S("tracing")), &test) && IS_INTEGER(test)) {
if (AS_INTEGER(test) == 1) krk_currentThread.flags |= KRK_ENABLE_TRACING; else krk_currentThread.flags &= ~KRK_ENABLE_TRACING; }
if (AS_INTEGER(test) == 1) krk_currentThread.flags |= KRK_THREAD_ENABLE_TRACING; else krk_currentThread.flags &= ~KRK_THREAD_ENABLE_TRACING; }
if (krk_tableGet(AS_DICT(argv[argc]), OBJECT_VAL(S("disassembly")), &test) && IS_INTEGER(test)) {
if (AS_INTEGER(test) == 1) krk_currentThread.flags |= KRK_ENABLE_DISASSEMBLY; else krk_currentThread.flags &= ~KRK_ENABLE_DISASSEMBLY; }
if (AS_INTEGER(test) == 1) krk_currentThread.flags |= KRK_THREAD_ENABLE_DISASSEMBLY; else krk_currentThread.flags &= ~KRK_THREAD_ENABLE_DISASSEMBLY; }
if (krk_tableGet(AS_DICT(argv[argc]), OBJECT_VAL(S("scantracing")), &test) && IS_INTEGER(test)) {
if (AS_INTEGER(test) == 1) krk_currentThread.flags |= KRK_ENABLE_SCAN_TRACING; else krk_currentThread.flags &= ~KRK_ENABLE_SCAN_TRACING; }
if (AS_INTEGER(test) == 1) krk_currentThread.flags |= KRK_THREAD_ENABLE_SCAN_TRACING; else krk_currentThread.flags &= ~KRK_THREAD_ENABLE_SCAN_TRACING; }
if (krk_tableGet(AS_DICT(argv[argc]), OBJECT_VAL(S("stressgc")), &test) && IS_INTEGER(test)) {
if (AS_INTEGER(test) == 1) vm.globalFlags |= KRK_ENABLE_STRESS_GC; else krk_currentThread.flags &= ~KRK_ENABLE_STRESS_GC; }
if (AS_INTEGER(test) == 1) vm.globalFlags |= KRK_GLOBAL_ENABLE_STRESS_GC; else krk_currentThread.flags &= ~KRK_GLOBAL_ENABLE_STRESS_GC; }
}
return BOOLEAN_VAL(1);
#else
@ -1106,9 +1106,9 @@ static KrkValue krk_getsize(int argc, KrkValue argv[], int hasKw) {
static KrkValue krk_setclean(int argc, KrkValue argv[], int hasKw) {
if (!argc || (IS_BOOLEAN(argv[0]) && AS_BOOLEAN(argv[0]))) {
vm.globalFlags |= KRK_CLEAN_OUTPUT;
vm.globalFlags |= KRK_GLOBAL_CLEAN_OUTPUT;
} else {
vm.globalFlags &= ~KRK_CLEAN_OUTPUT;
vm.globalFlags &= ~KRK_GLOBAL_CLEAN_OUTPUT;
}
return NONE_VAL();
}
@ -1406,7 +1406,7 @@ static int handleException() {
krk_currentThread.frameCount = frameOffset + 1;
/* Clear the exception flag so we can continue executing from the handler. */
krk_currentThread.flags &= ~KRK_HAS_EXCEPTION;
krk_currentThread.flags &= ~KRK_THREAD_HAS_EXCEPTION;
return 0;
}
@ -1487,7 +1487,7 @@ int krk_loadModule(KrkString * path, KrkValue * moduleOut, KrkString * runAs) {
*moduleOut = krk_callfile(fileName,runAs->chars,fileName);
krk_currentThread.module = enclosing;
if (!IS_OBJECT(*moduleOut)) {
if (!(krk_currentThread.flags & KRK_HAS_EXCEPTION)) {
if (!(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) {
krk_runtimeError(vm.exceptions->importError,
"Failed to load module '%s' from '%s'", runAs->chars, fileName);
}
@ -1771,7 +1771,7 @@ static KrkValue run() {
while (1) {
#ifdef ENABLE_TRACING
if (krk_currentThread.flags & KRK_ENABLE_TRACING) {
if (krk_currentThread.flags & KRK_THREAD_ENABLE_TRACING) {
dumpStack(frame);
krk_disassembleInstruction(stderr, frame->closure->function,
(size_t)(frame->ip - frame->closure->function->chunk.code));
@ -1886,7 +1886,7 @@ static KrkValue run() {
case OP_RAISE: {
krk_currentThread.currentException = krk_pop();
attachTraceback();
krk_currentThread.flags |= KRK_HAS_EXCEPTION;
krk_currentThread.flags |= KRK_THREAD_HAS_EXCEPTION;
goto _finishException;
}
/* This version of the call instruction takes its arity from the
@ -2015,7 +2015,7 @@ static KrkValue run() {
if (!isMatch) {
/* Restore and re-raise the exception if it didn't match. */
krk_currentThread.currentException = krk_peek(1);
krk_currentThread.flags |= KRK_HAS_EXCEPTION;
krk_currentThread.flags |= KRK_THREAD_HAS_EXCEPTION;
goto _finishException;
}
/* Else pop the filter value */
@ -2365,7 +2365,7 @@ static KrkValue run() {
break;
}
}
if (likely(!(krk_currentThread.flags & KRK_HAS_EXCEPTION))) continue;
if (likely(!(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION))) continue;
_finishException:
if (!handleException()) {
frame = &krk_currentThread.frames[krk_currentThread.frameCount - 1];

186
src/vm.h
View File

@ -1,5 +1,11 @@
#pragma once
/**
* @file vm.h
* @brief Core API for the bytecode virtual machine.
*
* Functions and structures declared here make up the bulk of the public C API
* for Kuroko, including initializing the VM and passing code to be interpreted.
*/
#include <stdarg.h>
#include <sys/types.h>
#include "kuroko.h"
@ -7,8 +13,22 @@
#include "table.h"
#include "object.h"
/**
* @def KRK_CALL_FRAMES_MAX
* @brief Maximum depth of the call stack in managed-code function calls.
*/
#define KRK_CALL_FRAMES_MAX 64
/**
* @def KRK_THREAD_SCRATCH_SIZE
* @brief Extra space for each thread to store a set of working values safe from the GC.
*
* Various operations require threads to remove values from the stack but ensure
* they are not lost to garbage collection. This space allows each thread to keep
* a few things around during those operations.
*/
#define KRK_THREAD_SCRATCH_SIZE 3
/**
* @brief Represents a managed call state in a VM thread.
*
@ -34,11 +54,11 @@ typedef struct {
*
* The VM must look up many methods and members by fixed names. To avoid
* continuously having to box and unbox these from C strings to the appropriate
* interned KrkString, we keep an array of the KrkString pointers in the global VM state.
* interned @c KrkString, we keep an array of the @c KrkString pointers in the global VM state.
*
* These values are the offsets into that index for each of the relevant
* function names (generally with extra underscores removed). For example
* METHOD_INIT is the offset for the string value for "__init__".
* @c METHOD_INIT is the offset for the string value for @c "__init__".
*/
typedef enum {
METHOD_INIT,
@ -163,8 +183,7 @@ typedef struct ThreadState {
int flags; /**< Thread-local VM flags; each thread inherits the low byte of the global VM flags. */
long watchdog; /**< Decrementing watchdog timer for embedding. */
#define THREAD_SCRATCH_SIZE 3
KrkValue scratchSpace[THREAD_SCRATCH_SIZE]; /**< A place to store a few values to keep them from being prematurely GC'd. */
KrkValue scratchSpace[KRK_THREAD_SCRATCH_SIZE]; /**< A place to store a few values to keep them from being prematurely GC'd. */
} KrkThreadState;
/**
@ -198,28 +217,37 @@ typedef struct {
} KrkVM;
/* Thread-specific flags */
/* TODO Should these be in an enum instead? */
#define KRK_ENABLE_TRACING (1 << 0)
#define KRK_ENABLE_DISASSEMBLY (1 << 1)
#define KRK_ENABLE_SCAN_TRACING (1 << 2)
#define KRK_HAS_EXCEPTION (1 << 3)
#define KRK_THREAD_ENABLE_TRACING (1 << 0)
#define KRK_THREAD_ENABLE_DISASSEMBLY (1 << 1)
#define KRK_THREAD_ENABLE_SCAN_TRACING (1 << 2)
#define KRK_THREAD_HAS_EXCEPTION (1 << 3)
/* Global flags */
#define KRK_ENABLE_STRESS_GC (1 << 8)
#define KRK_GC_PAUSED (1 << 9)
#define KRK_CLEAN_OUTPUT (1 << 10)
#define KRK_GLOBAL_ENABLE_STRESS_GC (1 << 8)
#define KRK_GLOBAL_GC_PAUSED (1 << 9)
#define KRK_GLOBAL_CLEAN_OUTPUT (1 << 10)
#ifdef ENABLE_THREADING
extern void _createAndBind_threadsMod(void);
extern __thread KrkThreadState krk_currentThread;
# define threadLocal __thread
#else
extern KrkThreadState krk_currentThread;
# define threadLocal
#endif
/**
* Singleton instance of the shared VM state.
* @brief Thread-local VM state.
*
* See @c KrkThreadState for more information.
*/
extern threadLocal KrkThreadState krk_currentThread;
/**
* @brief Singleton instance of the shared VM state.
*/
extern KrkVM krk_vm;
/**
* @def vm Convience macro for namespacing.
*/
#define vm krk_vm
/**
@ -252,7 +280,7 @@ extern void krk_freeVM(void);
* In a repl, this can be called before or after each iteration to clean up any
* remnant stack entries from an uncaught exception. It should not be called
* during normal execution by C extensions. Values on the stack may be lost
* to garbage collection after a call to krk_resetStack .
* to garbage collection after a call to @c krk_resetStack .
*/
extern void krk_resetStack(void);
@ -268,9 +296,9 @@ extern void krk_resetStack(void);
* @param fromFile Path to the source file, or a representative string like "<stdin>".
* @return When newScope is non-zero, an object representing the globals of the new scope;
* otherwise, the returned result of the execution of this code. If an uncaught
* exception occurred, this will be None, krk_currentThread.flags should indicate
* KRK_HAS_EXCEPTION, and krk_currentThread.currentException should contain the raised
* exception value.
* exception occurred, this will be @c None and @c krk_currentThread.flags should
* indicate @c KRK_THREAD_HAS_EXCEPTION and @c krk_currentThread.currentException
* should contain the raised exception value.
*/
extern KrkValue krk_interpret(const char * src, int newScope, char *, char *);
@ -283,9 +311,9 @@ extern KrkValue krk_interpret(const char * src, int newScope, char *, char *);
*
* @param fileName Path to the source file to read and execute.
* @param newScope Whether this file should be run in the context of a new module.
* @param fromName Value to assign to __name__
* @param fromFile Value to assign to __file__
* @return As with krk_interpret, an object representing the newly created module,
* @param fromName Value to assign to @c __name__
* @param fromFile Value to assign to @c __file__
* @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, int newScope, char *, char *);
@ -293,13 +321,13 @@ extern KrkValue krk_runfile(const char * fileName, int newScope, char *, char *)
/**
* @brief Load and run a file as a module.
*
* Similar to krk_runfile, but ensures that execution of the VM returns to the caller
* after the file is run. This should be run after calling krk_startModule to initialize
* Similar to @c krk_runfile but ensures that execution of the VM returns to the caller
* after the file is run. This should be run after calling @c krk_startModule to initialize
* a new module context and is used internally by the import mechanism.
*
* @param fileName Path to the source file to read and execute.
* @param fromName Value to assign to __name__
* @param fromFile Value to assign to __file__
* @param fromName Value to assign to @c __name__
* @param fromFile Value to assign to @c __file__
* @return The object representing the module, or None if execution of the file failed.
*/
extern KrkValue krk_callfile(const char * fileName, char * fromName, char * fromFile);
@ -344,7 +372,7 @@ extern KrkValue krk_peek(int distance);
* exception messages, such as those describing TypeErrors.
*
* @param value Value to examine
* @return Nul-terminated C string of the type of 'value'.
* @return Nul-terminated C string of the type of @p value
*/
extern const char * krk_typeName(KrkValue value);
@ -353,11 +381,11 @@ extern const char * krk_typeName(KrkValue value);
*
* Attaches the given native function pointer to an attribute table
* while managing the stack shuffling and boxing of both the name and
* the function object. If 'name' begins with a '.', the native function
* is marked as a method. If 'name' begins with a ':', the native function
* the function object. If @p name begins with a '.', the native function
* is marked as a method. If @p name begins with a ':', the native function
* is marked as a dynamic property.
*
* @param table Attribute table to attach to, such as &someInstance->fields
* @param table Attribute table to attach to, such as @c &someInstance->fields
* @param name Nil-terminated C string with the name to assign
* @param function Native function pointer to attach
* @return A pointer to the object representing the attached function.
@ -367,11 +395,11 @@ extern KrkNative * krk_defineNative(KrkTable * table, const char * name, NativeF
/**
* @brief Attach a native dynamic property to an attribute table.
*
* Mostly the same as defineNative, but ensures the creation of a dynamic property.
* Mostly the same as @c krk_defineNative, but ensures the creation of a dynamic property.
* The intention of this function is to replace uses of defineNative with ":" names,
* and replace specialized methods with KrkProperty* objects.
* and replace specialized methods with @c KrkProperty* objects.
*
* @param table Attribute table to attach to, such as &someInstance->fields
* @param table Attribute table to attach to, such as @c &someInstance->fields
* @param name Nil-terminated C string with the name to assign
* @param function Native function pointer to attach
* @return A pointer to the property object created.
@ -382,10 +410,10 @@ extern KrkProperty * krk_defineNativeProperty(KrkTable * table, const char * nam
* @brief Attach a value to an attribute table.
*
* Manages the stack shuffling and boxing of the name string when attaching
* a value to an attribute table. Rather than using krk_tableSet, this is
* a value to an attribute table. Rather than using @c krk_tableSet, this is
* the preferred method of supplying fields to objects from C code.
*
* @param table Attribute table to attach to, such as &someInstance->fields
* @param table Attribute table to attach to, such as @c &someInstance->fields
* @param name Nil-terminated C string with the name to assign
* @param obj Value to attach.
*/
@ -395,12 +423,12 @@ extern void krk_attachNamedValue(KrkTable * table, const char name[], KrkValue o
* @brief Attach an object to an attribute table.
*
* Manages the stack shuffling and boxing of the name string when attaching
* an object to an attribute table. Rather than using krk_tableSet, this is
* an object to an attribute table. Rather than using @c krk_tableSet, this is
* the preferred method of supplying fields to objects from C code.
*
* This is a convenience wrapper around krk_attachNamedValue.
* This is a convenience wrapper around @c krk_attachNamedValue.
*
* @param table Attribute table to attach to, such as &someInstance->fields
* @param table Attribute table to attach to, such as @c &someInstance->fields
* @param name Nil-terminated C string with the name to assign
* @param obj Object to attach.
*/
@ -415,18 +443,18 @@ extern void krk_attachNamedObject(KrkTable * table, const char name[], KrkObj *
* may have different initializer signatures and need separate initialization.
*
* The created exception object is attached to the current thread state and
* the HAS_EXCEPTION flag is set.
* the @c KRK_THREAD_HAS_EXCEPTION flag is set.
*
* @param type Class pointer for the exception type, eg. vm.exceptions->valueError
* @param type Class pointer for the exception type, eg. @c vm.exceptions->valueError
* @param fmt Format string.
* @return As a convenience to C extension authors, returns None.
* @return As a convenience to C extension authors, returns @c None
*/
extern KrkValue krk_runtimeError(KrkClass * type, const char * fmt, ...);
/**
* @brief Get a pointer to the current thread state.
*
* Generally equivalent to &krk_currentThread, though krk_currentThread
* Generally equivalent to @c &krk_currentThread, though @c krk_currentThread
* itself may be implemented as a macro that calls this function depending
* on the platform's thread support.
*
@ -440,7 +468,7 @@ extern KrkThreadState * krk_getCurrentThread(void);
* Resumes the VM dispatch loop, returning to the caller when
* the next exit trigger event happens. Generally, callers will
* want to set the current thread's exitOnFrame before calling
* krk_runNext. Alternatively, see krk_callValue which manages
* @c krk_runNext. Alternatively, see @c krk_callValue which manages
* exit triggers automatically when calling function objects.
*
* @return Value returned by the exit trigger, generally the value
@ -465,28 +493,28 @@ extern KrkClass * krk_getType(KrkValue value);
* @brief Determine if a class is an instance or subclass of a given type.
*
* Searches the class hierarchy of the given value to determine if it is
* a subtype of 'type'. As this chains through the inheritence tree, the
* more deeply subclassed 'obj' is, the longer it may take to determine
* if it is a subtype of 'type'. All types should eventually be subtypes
* of the 'object' type, so this condition should not be checked. For
* a subtype of @p type. As this chains through the inheritence tree, the
* more deeply subclassed @p obj is, the longer it may take to determine
* if it is a subtype of @p type. All types should eventually be subtypes
* of the @c object type, so this condition should not be checked. For
* some types, convenience macros are available. If you need to check if
* 'obj' is a specific type, exclusive of subtypes, compare krk_getType
* @p obj is a specific type, exclusive of subtypes, compare @c krk_getType
* instead of using this function.
*
* @param obj Value to examine.
* @param type Class object to test for membership of.
* @return 1 if obj is an instance of type or of a subclass of type
* @return 1 if @p obj is an instance of @p type or of a subclass of @p type
*/
extern int krk_isInstanceOf(KrkValue obj, KrkClass * type);
/**
* @brief Perform method binding on the stack.
*
* Performs attribute lookup from the class '_class' for 'name'.
* If 'name' is not a valid method, the binding fails.
* If 'name' is a valid method, the method will be retrieved and
* Performs attribute lookup from the class @p _class for @p name.
* If @p name is not a valid method, the binding fails.
* If @p name is a valid method, the method will be retrieved and
* bound to the instance on the top of the stack, replacing it
* with a BoundMethod object.
* with a @c BoundMethod object.
*
* @param _class Class object to resolve methods from.
* @param name String object with the name of the method to resolve.
@ -498,7 +526,7 @@ extern int krk_bindMethod(KrkClass * _class, KrkString * name);
* @brief Call a callable value in the current stack context.
*
* Executes the given callable object (function, bound method, object
* with a __call__() method, etc.) using 'argCount' arguments from the stack.
* with a @c __call__() method, etc.) using @p argCount arguments from the stack.
*
* @param callee Value referencing a callable object.
* @param argCount Arguments to retreive from stack.
@ -519,21 +547,21 @@ extern int krk_callValue(KrkValue callee, int argCount, int extra);
/**
* @brief Create a list object.
*
* This is the native function bound to 'listOf'.
* This is the native function bound to @c listOf
*/
extern KrkValue krk_list_of(int argc, KrkValue argv[], int hasKw);
/**
* @brief Create a dict object.
*
* This is the native function bound to 'dictOf'
* This is the native function bound to @c dictOf
*/
extern KrkValue krk_dict_of(int argc, KrkValue argv[], int hasKw);
/**
* @brief Create a tuple object.
*
* This is the native function bound to 'tupleOf'.
* This is the native function bound to @c tupleOf
*/
extern KrkValue krk_tuple_of(int argc, KrkValue argv[], int hasKw);
@ -543,7 +571,7 @@ extern KrkValue krk_tuple_of(int argc, KrkValue argv[], int hasKw);
* This is a wrapper around various mechanisms including krk_callValue
* intended for use by C extensions to call arbitrary functions without
* knowledge of their implementation details. See the notes for
* krk_callValue's 'extra' paramater for details on how 'isMethod' is used.
* @c krk_callValue 's @c extra paramater for details on how @p isMethod is used.
*
* @param value Callable object reference.
* @param argCount Arguments to collect from the stack.
@ -555,14 +583,14 @@ extern KrkValue krk_callSimple(KrkValue value, int argCount, int isMethod);
/**
* @brief Convenience function for creating new types.
*
* Creates a class object, output to *_class, setting its name to 'name', inheriting
* from 'base', and attaching it with its name to the fields table of the given 'module'.
* Creates a class object, output to @p _class, setting its name to @p name, inheriting
* from @p base, and attaching it with its name to the fields table of the given @p module.
*
* @param module Pointer to an instance for a module to attach to, or NULL to skip attaching.
* @param module Pointer to an instance for a module to attach to, or @c NULL to skip attaching.
* @param _class Output pointer to assign the new class object to.
* @param name Name of the new class.
* @param base Pointer to class object to inherit from.
* @return A pointer to the class object, equivalent to the value assigned to *_class.
* @return A pointer to the class object, equivalent to the value assigned to @p _class.
*/
extern KrkClass * krk_makeClass(KrkInstance * module, KrkClass ** _class, const char * name, KrkClass * base);
@ -578,26 +606,26 @@ extern KrkClass * krk_makeClass(KrkInstance * module, KrkClass ** _class, const
extern void krk_finalizeClass(KrkClass * _class);
/**
* @brief If there is an active exception, print a traceback to stderr.
* @brief If there is an active exception, print a traceback to @c stderr
*
* This function is exposed as a convenience for repl developers. Normally,
* the VM will call dumpTraceback itself if an exception is unhandled and no
* the VM will call @c krk_dumpTraceback itself if an exception is unhandled and no
* exit trigger is current set. The traceback is obtained from the exception
* object. If the exception object does not have a traceback, only the
* exception itself will be printed. The traceback printer will attempt to
* open source files to print faulting lines and may call into the VM if the
* exception object has a managed implementation of __str__.
* exception object has a managed implementation of @c __str__.
*/
extern void krk_dumpTraceback();
/**
* @brief Set up a new module object in the current thread.
*
* Creates a new instance of the module type and attaches a __builtins__
* Creates a new instance of the module type and attaches a @c __builtins__
* reference to its fields. The module becomes the current thread's
* main module, but is not directly attached to the module table.
*
* @param name Name of the module, which is assigned to __name__
* @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);
@ -605,7 +633,7 @@ extern KrkInstance * krk_startModule(const char * name);
/**
* @brief Obtain a list of properties for an object.
*
* This is the native function bound to 'object.__dir__'
* This is the native function bound to @c object.__dir__
*/
extern KrkValue krk_dirObject(int argc, KrkValue argv[], int hasKw);
@ -616,8 +644,8 @@ extern KrkValue krk_dirObject(int argc, KrkValue argv[], int hasKw);
*
* @param name Name of the module, used for file lookup.
* @param moduleOut Receives a value with the module object.
* @param runAs Name to attach to __name__ for this module, different from 'name'.
* @return 1 if the module was loaded, 0 if an ImportError occurred.
* @param runAs Name to attach to @c __name__ for this module, different from @p name
* @return 1 if the module was loaded, 0 if an @c ImportError occurred.
*/
extern int krk_loadModule(KrkString * name, KrkValue * moduleOut, KrkString * runAs);
@ -628,7 +656,7 @@ extern int krk_loadModule(KrkString * name, KrkValue * moduleOut, KrkString * ru
* into the module table.
*
* @param name String object of the dot-separated package path to import.
* @return 1 if the module was loaded, 0 if an ImportError occurred.
* @return 1 if the module was loaded, 0 if an @c ImportError occurred.
*/
extern int krk_doRecursiveModuleLoad(KrkString * name);
@ -647,12 +675,12 @@ extern int krk_isFalsey(KrkValue value);
/**
* @brief Concatenate two strings.
*
* This is a convenience function which calls 'str.__add__' on the top stack
* values. Generally, this should be avoided - use StringBuilder instead.
* 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);
/**
/*
* All of the remaining stuff is internal and shouldn't be used by library users or embedders.
* FIXME This stuff needs to be moved to another header! FIXME
*/
@ -668,10 +696,8 @@ extern KrkValue _str_split(int argc, KrkValue argv[], int hasKw);
extern KrkValue _str_format(int argc, KrkValue argv[], int hasKw);
#define krk_string_format _str_format
/* obj_dict.h */
extern KrkValue krk_dict_nth_key_fast(size_t capacity, KrkTableEntry * entries, size_t index);
extern void _createAndBind_numericClasses(void);
extern void _createAndBind_strClass(void);
extern void _createAndBind_listClass(void);
@ -688,7 +714,9 @@ extern void _createAndBind_gcMod(void);
extern void _createAndBind_timeMod(void);
extern void _createAndBind_osMod(void);
extern void _createAndBind_fileioMod(void);
#ifdef ENABLE_THREADING
extern void _createAndBind_threadsMod(void);
#endif
extern KrkValue krk_operator_lt(KrkValue,KrkValue);
extern KrkValue krk_operator_gt(KrkValue,KrkValue);

View File

@ -370,7 +370,7 @@ static int compileFile(char * fileName) {
krk_startModule("__main__");
KrkFunction * func = krk_compile(buf, 0, fileName);
if (krk_currentThread.flags & KRK_HAS_EXCEPTION) {
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) {
fprintf(stderr, "%s: exception during compilation:\n", fileName);
krk_dumpTraceback();
return 3;

View File

@ -37,7 +37,7 @@ int main(int argc, char * argv[]) {
if (IS_STRING(result)) {
fprintf(stdout, "%s\n", AS_CSTRING(result));
}
} else if (krk_currentThread.flags & KRK_HAS_EXCEPTION) {
} else if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) {
krk_dumpTraceback();
retval = 1;
}

View File

@ -116,7 +116,7 @@ static int runSimpleRepl(void) {
fprintf(stdout, formatStr, AS_CSTRING(result));
}
krk_resetStack();
} else if (krk_currentThread.flags & KRK_HAS_EXCEPTION) {
} else if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) {
krk_dumpTraceback();
}
free(allData);