6 #define KRK_VERSION_MAJOR 1
7 #define KRK_VERSION_MINOR 5
8 #define KRK_VERSION_PATCH 0
9 #define KRK_VERSION_LEVEL 0xa
10 #define KRK_VERSION_SERIAL 0x1
12 #define KRK_VERSION_EXTRA_BASE "a1"
14 #ifndef KRK_STATIC_ONLY
15 #define KRK_VERSION_EXTRA KRK_VERSION_EXTRA_BASE
17 #define KRK_VERSION_EXTRA KRK_VERSION_EXTRA_BASE "-static"
20 #define KRK_BUILD_DATE __DATE__ " at " __TIME__
22 #if (defined(__GNUC__) || defined(__GNUG__)) && !(defined(__clang__) || defined(__INTEL_COMPILER))
23 # define KRK_BUILD_COMPILER "GCC " __VERSION__
24 #elif (defined(__clang__))
25 # define KRK_BUILD_COMPILER "clang " __clang_version__
26 #elif (defined(_MSC_VER) && !defined(__clang__))
27 # define KRK_ARG_STR(str) #str
28 # define KRK_ARG_LOL(s) KRK_ARG_STR(s)
29 # define KRK_BUILD_COMPILER "msvc " KRK_ARG_LOL(_MSC_FULL_VER)
31 # define KRK_BUILD_COMPILER ""
35 #ifndef KRK_DISABLE_DEBUG
36 KRK_Function(set_tracing) {
41 "|$pp", (
const char *[]){
"tracing",
"disassembly"},
42 &tracing, &disassembly)) {
46 #define SET_THREAD(arg,flag) do { if (arg != -1) { if (arg) krk_currentThread.flags |= KRK_THREAD_ENABLE_ ## flag; else krk_currentThread.flags &= ~KRK_THREAD_ENABLE_ ## flag; } } while (0)
47 SET_THREAD(tracing,TRACING);
48 SET_THREAD(disassembly,DISASSEMBLY);
51 return BOOLEAN_VAL(1);
54 KRK_Function(set_tracing) {
55 return krk_runtimeError(
vm.exceptions->typeError,
"Debugging is not enabled in this build.");
59 KRK_Function(getsizeof) {
60 if (argc < 1 || !IS_OBJECT(argv[0]))
return INTEGER_VAL(0);
62 switch (AS_OBJECT(argv[0])->type) {
63 case KRK_OBJ_STRING: {
65 mySize +=
sizeof(
KrkString) + self->length + 1;
66 if (self->codes && self->chars != self->codes) {
67 if ((self->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) <= KRK_OBJ_FLAGS_STRING_UCS1) mySize += self->codesLength;
68 else if ((self->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) == KRK_OBJ_FLAGS_STRING_UCS2) mySize += 2 * self->codesLength;
69 else if ((self->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) == KRK_OBJ_FLAGS_STRING_UCS4) mySize += 4 * self->codesLength;
73 case KRK_OBJ_CODEOBJECT: {
77 mySize +=
sizeof(uint8_t) * self->chunk.capacity;
78 mySize +=
sizeof(
KrkLineMap) *
self->chunk.linesCapacity;
79 mySize +=
sizeof(
KrkValue) * self->chunk.constants.capacity;
82 mySize +=
sizeof(
KrkValue) * self->positionalArgNames.capacity;
84 mySize +=
sizeof(
KrkValue) *
self->keywordArgNames.capacity;
91 case KRK_OBJ_NATIVE: {
93 mySize +=
sizeof(
KrkNative) + strlen(self->name) + 1;
96 case KRK_OBJ_CLOSURE: {
101 case KRK_OBJ_UPVALUE: {
107 case KRK_OBJ_CLASS: {
108 KrkClass *
self = AS_CLASS(argv[0]);
110 mySize += (
sizeof(
KrkTableEntry) +
sizeof(ssize_t)) * self->methods.capacity;
111 mySize += (
sizeof(
KrkTableEntry) +
sizeof(ssize_t)) *
self->subclasses.capacity;
114 case KRK_OBJ_INSTANCE: {
116 mySize += (
sizeof(
KrkTableEntry) +
sizeof(ssize_t)) * self->fields.capacity;
122 mySize +=
sizeof(
KrkValue) * AS_LIST(argv[0])->capacity;
124 mySize += (
sizeof(
KrkTableEntry) +
sizeof(ssize_t)) * AS_DICT(argv[0])->capacity;
128 case KRK_OBJ_BOUND_METHOD: {
132 case KRK_OBJ_TUPLE: {
133 KrkTuple *
self = AS_TUPLE(argv[0]);
137 case KRK_OBJ_BYTES: {
138 KrkBytes *
self = AS_BYTES(argv[0]);
139 mySize +=
sizeof(
KrkBytes) + self->length;
144 return INTEGER_VAL(mySize);
147 KRK_Function(set_clean_output) {
148 if (!argc || (IS_BOOLEAN(argv[0]) && AS_BOOLEAN(argv[0]))) {
149 vm.globalFlags |= KRK_GLOBAL_CLEAN_OUTPUT;
151 vm.globalFlags &= ~KRK_GLOBAL_CLEAN_OUTPUT;
156 KRK_Function(importmodule) {
157 FUNCTION_TAKES_EXACTLY(1);
158 if (!IS_STRING(argv[0]))
return TYPE_ERROR(str,argv[0]);
163 KRK_Function(modules) {
164 FUNCTION_TAKES_NONE();
167 for (
size_t i = 0; i <
vm.modules.capacity; ++i) {
169 if (IS_KWARGS(entry->key))
continue;
175 KRK_Function(unload) {
176 FUNCTION_TAKES_EXACTLY(1);
177 if (!IS_STRING(argv[0]))
return TYPE_ERROR(str,argv[0]);
184 KRK_Function(inspect_value) {
185 FUNCTION_TAKES_EXACTLY(1);
189 KRK_Function(members) {
191 if (!
krk_parseArgs(
"V", (
const char*[]){
"obj"}, &val))
return NONE_VAL();
198 if (IS_INSTANCE(val) || IS_CLASS(val)) {
199 src = &AS_INSTANCE(val)->fields;
200 }
else if (IS_CLOSURE(val)) {
201 src = &AS_CLOSURE(val)->fields;
211 KRK_Function(set_recursion_depth) {
212 unsigned int maxdepth;
214 if (!
krk_parseArgs(
"I|p",(
const char*[]){
"maxdepth",
"quiet"},&maxdepth,&quiet))
return NONE_VAL();
216 if (quiet)
return BOOLEAN_VAL(0);
217 return krk_runtimeError(
vm.exceptions->valueError,
"Can not change recursion depth in this context.");
220 return BOOLEAN_VAL(1);
223 KRK_Function(get_recursion_depth) {
239 KRK_DOC(
vm.system,
"@brief System module.");
241 #define STR(x) STR_(x)
243 (
KrkObj*)S(STR(KRK_VERSION_MAJOR)
"." STR(KRK_VERSION_MINOR)
"." STR(KRK_VERSION_PATCH) KRK_VERSION_EXTRA));
247 INTEGER_VAL((KRK_VERSION_MAJOR << 24) | (KRK_VERSION_MINOR << 16) | (KRK_VERSION_PATCH << 8) | (KRK_VERSION_LEVEL << 4) | (KRK_VERSION_SERIAL)));
250 "@brief Calculate the approximate size of an object in bytes.\n"
251 "@arguments value\n\n"
252 "@param value Value to examine.");
253 KRK_DOC(BIND_FUNC(
vm.system,set_clean_output),
254 "@brief Disables terminal escapes in some output from the VM.\n"
255 "@arguments clean=True\n\n"
256 "@param clean Whether to remove escapes.");
257 KRK_DOC(BIND_FUNC(
vm.system,set_tracing),
258 "@brief Toggle debugging modes.\n"
259 "@arguments tracing=None,disassembly=None\n\n"
260 "Enables or disables tracing options for the current thread.\n\n"
261 "@param tracing Enables instruction tracing.\n"
262 "@param disassembly Prints bytecode disassembly after compilation.");
263 KRK_DOC(BIND_FUNC(
vm.system,importmodule),
264 "@brief Import a module by string name\n"
265 "@arguments module\n\n"
266 "Imports the dot-separated module @p module as if it were imported by the @c import statement and returns the resulting module object.\n\n"
267 "@param module A string with a dot-separated package or module name");
269 "Get the list of valid names from the module table");
271 "Removes a module from the module table. It is not necessarily garbage collected if other references to it exist.");
272 KRK_DOC(BIND_FUNC(
vm.system,inspect_value),
273 "Obtain the memory representation of a stack value.");
275 "Obtain a copy of a dict of the direct members of an object.");
276 KRK_DOC(BIND_FUNC(
vm.system,set_recursion_depth),
277 "Change the maximum recursion depth of the current thread if possible.");
278 KRK_DOC(BIND_FUNC(
vm.system,get_recursion_depth),
279 "Examine the maximum recursion depth of the current thread.");
285 #ifndef KRK_NO_FILESYSTEM
288 char * dir = strdup(
vm.binpath);
290 char * slash = strrchr(dir,
'/');
291 if (slash) *slash =
'\0';
292 if (strstr(dir,
"/bin") == (dir + strlen(dir) - 4)) {
293 slash = strrchr(dir,
'/');
294 if (slash) *slash =
'\0';
300 char * backslash = strrchr(dir,
'\\');
301 if (backslash) *backslash =
'\0';
KrkValue krk_runtimeError(KrkClass *type, const char *fmt,...)
Produce and raise an exception with a formatted message.
Struct definitions for core object types.
struct KrkClass KrkClass
Type object.
struct KrkString KrkString
Immutable sequence of Unicode codepoints.
struct KrkUpvalue KrkUpvalue
Storage for values referenced from nested functions.
A function that has been attached to an object to serve as a method.
Immutable sequence of bytes.
KrkBytes * krk_newBytes(size_t length, uint8_t *source)
Create a new byte array.
size_t allocSize
Size to allocate when creating instances of this class.
KrkValue krk_dict_of(int argc, const KrkValue argv[], int hasKw)
Create a dict object.
Map entry of opcode offsets to expressions spans.
KrkInstance * krk_newInstance(KrkClass *_class)
Create a new instance of the given class.
Map entry of instruction offsets to line numbers.
KrkValue krk_list_of(int argc, const KrkValue argv[], int hasKw)
Create a list object.
Metadata on a local variable name in a function.
Managed binding to a C function.
The most basic object type.
Immutable sequence of Unicode codepoints.
KrkString * krk_copyString(const char *chars, size_t length)
Obtain a string object representation of the given C string.
One (key,value) pair in a table.
Simple hash table of arbitrary keys to values.
int krk_tableDelete(KrkTable *table, KrkValue key)
Remove a key from a hash table.
void krk_attachNamedObject(KrkTable *table, const char name[], KrkObj *obj)
Attach an object to an attribute table.
void krk_attachNamedValue(KrkTable *table, const char name[], KrkValue obj)
Attach a value to an attribute table.
void krk_tableAddAll(KrkTable *from, KrkTable *to)
Add all key-value pairs from 'from' into 'to'.
unsigned int maximumCallDepth
Immutable sequence of arbitrary values.
Storage for values referenced from nested functions.
void krk_writeValueArray(KrkValueArray *array, KrkValue value)
Add a value to a value array.
Stack reference or primative value.
int krk_isInstanceOf(KrkValue obj, const KrkClass *type)
Determine if a class is an instance or subclass of a given type.
KrkClass * krk_getType(KrkValue value)
Get the class representing a value.
Utilities for creating native bindings.
#define krk_parseArgs(f, n,...)
Parse arguments to a function while accepting keyword arguments.
#define KRK_DOC(thing, text)
Attach documentation to a thing of various types.
Definitions for primitive stack references.
Core API for the bytecode virtual machine.
krk_threadLocal KrkThreadState krk_currentThread
Thread-local VM state.
#define vm
Convenience macro for namespacing.
int krk_doRecursiveModuleLoad(KrkString *name)
Load a module by a dotted name.
KrkValue krk_pop(void)
Pop the top of the stack.
void krk_setMaximumRecursionDepth(size_t maxDepth)
Set the maximum recursion call depth.
void krk_module_init_kuroko(void)
Initialize the built-in 'kuroko' module.
void krk_push(KrkValue value)
Push a stack value.