vm.h File Reference

Core API for the bytecode virtual machine. More...

#include <stdarg.h>
#include <sys/types.h>
#include "kuroko.h"
#include "value.h"
#include "table.h"
#include "object.h"
Include dependency graph for vm.h:

Go to the source code of this file.

Data Structures

struct  KrkCallFrame
 Represents a managed call state in a VM thread. More...
 
struct  Exceptions
 Table of basic exception types. More...
 
struct  BaseClasses
 Table of classes for built-in object types. More...
 
struct  KrkThreadState
 Execution state of a VM thread. More...
 
struct  KrkVM
 Global VM state. More...
 

Macros

#define KRK_CALL_FRAMES_MAX   1000
 Maximum depth of the call stack in managed-code function calls.
 
#define KRK_THREAD_SCRATCH_SIZE   3
 Extra space for each thread to store a set of working values safe from the GC. More...
 
#define KRK_THREAD_ENABLE_TRACING   (1 << 0)
 
#define KRK_THREAD_ENABLE_DISASSEMBLY   (1 << 1)
 
#define KRK_THREAD_HAS_EXCEPTION   (1 << 3)
 
#define KRK_THREAD_SINGLE_STEP   (1 << 4)
 
#define KRK_THREAD_SIGNALLED   (1 << 5)
 
#define KRK_THREAD_DEFER_STACK_FREE   (1 << 6)
 
#define KRK_GLOBAL_ENABLE_STRESS_GC   (1 << 8)
 
#define KRK_GLOBAL_GC_PAUSED   (1 << 9)
 
#define KRK_GLOBAL_CLEAN_OUTPUT   (1 << 10)
 
#define KRK_GLOBAL_REPORT_GC_COLLECTS   (1 << 12)
 
#define KRK_GLOBAL_THREADS   (1 << 13)
 
#define KRK_GLOBAL_NO_DEFAULT_MODULES   (1 << 14)
 
#define krk_threadLocal   __thread
 
#define vm   krk_vm
 Convenience macro for namespacing.
 

Typedefs

typedef struct KrkThreadState KrkThreadState
 Execution state of a VM thread. More...
 
typedef struct KrkVM KrkVM
 Global VM state. More...
 

Functions

void krk_resetStack (void)
 Reset the current thread's stack state to the top level. More...
 
KrkValue krk_interpret (const char *src, const char *fromFile)
 Compile and execute a source code input. More...
 
KrkValue krk_runfile (const char *fileName, const char *fromFile)
 Load and run a source file and return when execution completes. More...
 
void krk_push (KrkValue value)
 Push a stack value. More...
 
KrkValue krk_pop (void)
 Pop the top of the stack. More...
 
KrkValue krk_peek (int distance)
 Peek down from the top of the stack. More...
 
void krk_swap (int distance)
 Swap the top of the stack of the value distance slots down. More...
 
KrkValue krk_runtimeError (KrkClass *type, const char *fmt,...)
 Produce and raise an exception with a formatted message. More...
 
void krk_raiseException (KrkValue base, KrkValue cause)
 Raise an exception value. More...
 
void krk_attachInnerException (KrkValue innerException)
 Attach an inner exception to the current exception object. More...
 
KrkThreadStatekrk_getCurrentThread (void)
 Get a pointer to the current thread state. More...
 
KrkValue krk_runNext (void)
 Continue VM execution until the next exit trigger. More...
 
KrkValue krk_callStack (int argCount)
 Call a callable on the stack with argCount arguments. More...
 
KrkValue krk_callDirect (KrkObj *callable, int argCount)
 Call a closure or native function with argCount arguments. More...
 
void krk_dumpTraceback (void)
 If there is an active exception, print a traceback to stderr. More...
 
KrkInstancekrk_startModule (const char *name)
 Set up a new module object in the current thread. More...
 
KrkValue krk_dirObject (int argc, const KrkValue argv[], int hasKw)
 Obtain a list of properties for an object. More...
 
int krk_loadModule (KrkString *path, KrkValue *moduleOut, KrkString *runAs, KrkValue parent)
 Load a module from a file with a specified name. More...
 
int krk_doRecursiveModuleLoad (KrkString *name)
 Load a module by a dotted name. More...
 
int krk_importModule (KrkString *name, KrkString *runAs)
 Load the dotted name name with the final element as runAs. More...
 
KrkValue krk_valueGetAttribute_default (KrkValue value, char *name, KrkValue defaultVal)
 See krk_valueGetAttribute.
 
void krk_addObjects (void)
 Concatenate two strings. More...
 
KrkValue krk_operator_lt (KrkValue, KrkValue)
 Compare two values, returning True if the left is less than the right. More...
 
KrkValue krk_operator_gt (KrkValue, KrkValue)
 Compare to values, returning True if the left is greater than the right. More...
 
KrkValue krk_operator_le (KrkValue, KrkValue)
 Compare two values, returning True if the left is less than or equal to the right. More...
 
KrkValue krk_operator_ge (KrkValue, KrkValue)
 Compare to values, returning True if the left is greater than or equal to the right. More...
 
void krk_setMaximumRecursionDepth (size_t maxDepth)
 Set the maximum recursion call depth. More...
 
KrkValue krk_callNativeOnStack (size_t argCount, const KrkValue *stackArgs, int hasKw, NativeFn native)
 Call a native function using a reference to stack arguments safely. More...
 
KrkValue krk_instanceSetAttribute_wrapper (KrkValue owner, KrkString *name, KrkValue to)
 Set an attribute of an instance object, bypassing __setattr__. More...
 
int krk_getAttribute (KrkString *name)
 Implementation of the GET_PROPERTY instruction. More...
 
int krk_setAttribute (KrkString *name)
 Implementation of the SET_PROPERTY instruction. More...
 
int krk_delAttribute (KrkString *name)
 Implementation of the DEL_PROPERTY instruction. More...
 
void krk_module_init_kuroko (void)
 Initialize the built-in 'kuroko' module. More...
 
void krk_module_init_threading (void)
 Initialize the built-in 'threading' module. More...
 

Variables

krk_threadLocal KrkThreadState krk_currentThread
 Thread-local VM state. More...
 
KrkVM krk_vm
 Singleton instance of the shared VM state.
 

Detailed Description

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.

Definition in file vm.h.

Macro Definition Documentation

◆ KRK_THREAD_SCRATCH_SIZE

#define KRK_THREAD_SCRATCH_SIZE   3

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.

Definition at line 30 of file vm.h.

Typedef Documentation

◆ KrkThreadState

Execution state of a VM thread.

Each thread in the VM has its own local thread state, which contains the thread's stack, stack pointer, call frame stack, a thread-specific VM flags bitarray, and an exception state.

See also
krk_currentThread

◆ KrkVM

typedef struct KrkVM KrkVM

Global VM state.

This state is shared by all VM threads and stores the path to the VM binary, global execution flags, the string and module tables, tables of builtin types, and the state of the (shared) garbage collector.

Function Documentation

◆ krk_addObjects()

void krk_addObjects ( void  )

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.

Definition at line 941 of file obj_str.c.

◆ krk_attachInnerException()

void krk_attachInnerException ( KrkValue  innerException)

Attach an inner exception to the current exception object.

Sets the __context__ of the current exception object.

There must be a current exception, and it must be an instance object.

Parameters
innerException__context__ to set.

Definition at line 423 of file exceptions.c.

◆ krk_callDirect()

KrkValue krk_callDirect ( KrkObj callable,
int  argCount 
)

Call a closure or native function with argCount arguments.

Calls the closure or native callable with arguments from the top of the stack. argCount arguments are popped from the stack and the return value of the call is returned.

Parameters
callableClosure or native function.
argCountArguments to collect from the stack.
Returns
The return value of the function.

Definition at line 740 of file vm.c.

◆ krk_callNativeOnStack()

KrkValue krk_callNativeOnStack ( size_t  argCount,
const KrkValue stackArgs,
int  hasKw,
NativeFn  native 
)
inline

Call a native function using a reference to stack arguments safely.

Passing the address of the stack to a native function directly would be unsafe: the stack can be reallocated at any time through pushes. To allow for native functions to be called with arguments from the stack safely, this wrapper holds on to a reference to the stack at the call time, unless one was already held by an outer call; if a held stack is reallocated, it will be freed when execution returns to the call to krk_callNativeOnStack that holds it.

Make a call to a native function using values on the stack without moving them. If the stack is reallocated within this call, the old stack will not be freed until all such nested calls through krk_callNativeOnStack have returned.

If someone is already preserving this stack, we can just call directly.

Definition at line 601 of file vm.c.

◆ krk_callStack()

KrkValue krk_callStack ( int  argCount)

Call a callable on the stack with argCount arguments.

Calls the callable argCount stack entries down from the top of the stack, passing argCount arguments. Resumes execution of the VM for managed calls until they are completed. Pops all arguments and the callable from the stack and returns the return value of the call.

Parameters
argCountArguments to collect from the stack.
Returns
The return value of the function.

Takes care of runnext/pop

Definition at line 732 of file vm.c.

◆ krk_delAttribute()

int krk_delAttribute ( KrkString name)

Implementation of the DEL_PROPERTY instruction.

Attempts to delete the attribute specified by name from the value at the top of the stack, returning 1 and reducing the stack by one on success. If the attribute is not found or attribute deletion is not meaningful, 0 is returned and the stack remains unmodified, but no exception is raised.

Warning
Currently, no __delattr__ mechanism is available.
Parameters
nameName of the attribute to delete.
Returns
1 if the attribute was found and can be deleted, 0 otherwise.

Definition at line 1825 of file vm.c.

◆ krk_dirObject()

KrkValue krk_dirObject ( int  argc,
const KrkValue  argv[],
int  hasKw 
)

Obtain a list of properties for an object.

This is the native function bound to object.__dir__

Definition at line 13 of file builtins.c.

◆ krk_doRecursiveModuleLoad()

int krk_doRecursiveModuleLoad ( KrkString name)

Load a module by a dotted name.

Given a package identifier, attempt to the load module into the module table. This is a thin wrapper around krk_importModule().

Parameters
nameString object of the dot-separated package path to import.
Returns
1 if the module was loaded, 0 if an ImportError occurred.

Definition at line 1572 of file vm.c.

◆ krk_dumpTraceback()

void krk_dumpTraceback ( void  )

If there is an active exception, print a traceback to stderr.

This function is exposed as a convenience for repl developers. Normally, the VM will call 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__.

Display a traceback by scanning up the stack / call frames. The format of the output here is modeled after the output given by CPython, so we display the outermost call first and then move inwards; on each call frame we try to open the source file and print the corresponding line.

Definition at line 366 of file exceptions.c.

◆ krk_getAttribute()

int krk_getAttribute ( KrkString name)

Implementation of the GET_PROPERTY instruction.

Retrieves the attribute specifed by name from the value at the top of the stack. The top of the stack will be replaced with the resulting attribute value, if one is found, and 1 will be returned. Otherwise, 0 is returned and the stack remains unchanged. No exception is raised if the property is not found, allowing this function to be used in context where a default value is desired, but note that exceptions may be raised __getattr__ methods or by descriptor __get__ methods.

Parameters
nameName of the attribute to look up.
Returns
1 if the attribute was found, 0 otherwise.

Definition at line 1765 of file vm.c.

◆ krk_getCurrentThread()

KrkThreadState* krk_getCurrentThread ( void  )

Get a pointer to the current thread state.

Generally equivalent to &krk_currentThread, though krk_currentThread itself may be implemented as a macro that calls this function depending on the platform's thread support.

Returns
Pointer to current thread's thread state.

◆ krk_importModule()

int krk_importModule ( KrkString name,
KrkString runAs 
)

Load the dotted name name with the final element as runAs.

If name was imported previously with a name different from runAs, it will be imported again with the new name; this may result in unexpected behaviour. Generally, runAs is used to specify that the module should be run as __main__.

Parameters
nameDotted path name of a module.
runAsAlternative name to attach to __name__ for the module.
Returns
1 on success, 0 on failure.

For relative imports, we canonicalize the import name based on the current package, and then trying importModule again with the fully qualified name.

from .. import ... or from ..something import ...

If there n dots, there are n-1 components to pop from the end of the package name, as '..' is "go up one" and '...' is "go up two".

To import foo.bar.baz

  • import foo as foo
  • import foo/bar as foo.bar
  • import foo/bar/baz as foo.bar.baz

Definition at line 1378 of file vm.c.

◆ krk_instanceSetAttribute_wrapper()

KrkValue krk_instanceSetAttribute_wrapper ( KrkValue  owner,
KrkString name,
KrkValue  to 
)

Set an attribute of an instance object, bypassing __setattr__.

This can be used to emulate the behavior of super(object).__setattr__ for types that derive from KrkInstance and have a fields table, and is the internal mechanism by which object.__setattr__() performs this task.

Does not bypass descriptors.

Parameters
ownerInstance object to set an attribute on.
nameName of the attribute
toNew value for the attribute
Returns
The value set, which is likely to but may be the returned value of a descriptor __set__ method.

Definition at line 1862 of file vm.c.

◆ krk_interpret()

KrkValue krk_interpret ( const char *  src,
const char *  fromFile 
)

Compile and execute a source code input.

Compiles and executes the source code in src and returns the result of execution - generally the return value of a function body or the last value on the stack in a REPL expression. This is the lowest level call for most usecases, including execution of commands from a REPL or when executing a file.

The string provided in fromFile is used in exception tracebacks.

Parameters
srcSource code to compile and run.
fromFilePath to the source file, or a representative string like "<stdin>".
Returns
The value of the executed code, which is either the value of an explicit 'return' statement, or the last expression value from an executed statement. If an uncaught exception occurred, this will be None and krk_currentThread.flags should indicate KRK_THREAD_HAS_EXCEPTION and krk_currentThread.currentException should contain the raised exception value.

Definition at line 3219 of file vm.c.

◆ krk_loadModule()

int krk_loadModule ( KrkString path,
KrkValue moduleOut,
KrkString runAs,
KrkValue  parent 
)

Load a module from a file with a specified name.

This is generally called by the import mechanisms to load a single module and will establish a module context internally to load the new module into, return a KrkValue representing that module context through the moduleOut parameter.

Parameters
pathDotted path of the module, used for file lookup.
moduleOutReceives a value with the module object.
runAsName to attach to __name__ for this module, different from path
parentParent module object, if loaded from a package.
Returns
1 if the module was loaded, 0 if an ImportError occurred.

Load a module.

The module search path is stored in builtins.module_paths and should be a list of directories (with trailing forward-slash) to look at, in order, to resolve module names. krk source files will always take priority, so if a later search path has a krk source and an earlier search path has a shared object module, the later search path will still win.

Definition at line 1146 of file vm.c.

◆ krk_module_init_kuroko()

void krk_module_init_kuroko ( void  )

Initialize the built-in 'kuroko' module.

kuroko = module()

This is equivalent to Python's "sys" module, but we do not use that name in consideration of future compatibility, where a "sys" module may be added to emulate Python version numbers, etc.

Definition at line 227 of file sys.c.

◆ krk_module_init_threading()

void krk_module_init_threading ( void  )

Initialize the built-in 'threading' module.

Not available if KRK_DISABLE_THREADS is set.

threads = module()

Methods for dealing with threads.

Definition at line 207 of file threads.c.

◆ krk_operator_ge()

KrkValue krk_operator_ge ( KrkValue  ,
KrkValue   
)

Compare to values, returning True if the left is greater than or equal to the right.

This is equivalent to the opcode instruction OP_GREATER_EQUAL.

◆ krk_operator_gt()

KrkValue krk_operator_gt ( KrkValue  ,
KrkValue   
)

Compare to values, returning True if the left is greater than the right.

This is equivalent to the opcode instruction OP_GREATER.

◆ krk_operator_le()

KrkValue krk_operator_le ( KrkValue  ,
KrkValue   
)

Compare two values, returning True if the left is less than or equal to the right.

This is equivalent to the opcode instruction OP_LESS_EQUAL.

◆ krk_operator_lt()

KrkValue krk_operator_lt ( KrkValue  ,
KrkValue   
)

Compare two values, returning True if the left is less than the right.

This is equivalent to the opcode instruction OP_LESS.

◆ krk_peek()

KrkValue krk_peek ( int  distance)
inline

Peek down from the top of the stack.

Obtains a value from the current thread's stack without modifying the stack.

Parameters
distanceHow far down from the top of the stack to peek (0 = the top)
Returns
The value from the stack.

Definition at line 139 of file vm.c.

◆ krk_pop()

KrkValue krk_pop ( void  )
inline

Pop the top of the stack.

Removes and returns the value at the top of current thread's stack. Generally, it is preferably to leave values on the stack and use krk_peek if the value is desired, as removing a value from the stack may result in it being garbage collected.

Returns
The value previously at the top of the stack.

Pop the top of the stack. We never reclaim space used by the stack, so anything that is popped can be safely pushed back on without the stack moving, and you an also generally rely on a popped item still being where it was if you don't allocate anything in between; the repl relies on this it expects to be able to get the last pushed value and display it (if it's not None).

Definition at line 131 of file vm.c.

◆ krk_push()

void krk_push ( KrkValue  value)
inline

Push a stack value.

Pushes a value onto the current thread's stack, triggering a stack resize if there is not enough space to hold the new value.

Parameters
valueValue to push.

Push a value onto the stack, and grow the stack if necessary. Note that growing the stack can involve the stack moving, so do not rely on the memory offset of a stack value if you expect the stack to grow - eg. if you are calling into managed code to do anything, or if you are pushing anything.

Definition at line 118 of file vm.c.

◆ krk_raiseException()

void krk_raiseException ( KrkValue  base,
KrkValue  cause 
)

Raise an exception value.

Implementation of the OP_RAISE and OP_RAISE_FROM instructions.

If either of base or cause is a class, the class will be called to produce an instance, so exception classes may be used directly if desired.

If cause is not None it will be attached as __cause__ to the resulting exception object.

A traceback is automatically attached.

Parameters
baseException object or class to raise.
causeException cause object or class to attach.

Definition at line 435 of file exceptions.c.

◆ krk_resetStack()

void krk_resetStack ( void  )

Reset the current thread's stack state to the top level.

In a repl, this should 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 .

Reset the stack pointers, frame, upvalue list, clear the exception flag and current exception; happens on startup (twice) and after an exception.

Definition at line 85 of file vm.c.

◆ krk_runfile()

KrkValue krk_runfile ( const char *  fileName,
const char *  fromFile 
)

Load and run a source file and return when execution completes.

Loads and runs a source file. Can be used by interpreters to run scripts, either in the context of a new a module or as if they were continuations of the current module state (eg. as if they were lines entered on a repl)

Parameters
fileNamePath to the source file to read and execute.
fromFileValue to assign to __file__
Returns
As with krk_interpret, an object representing the newly created module, or the final return value of the VM execution.

Definition at line 3236 of file vm.c.

◆ krk_runNext()

KrkValue krk_runNext ( void  )

Continue VM execution until the next exit trigger.

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 exit triggers automatically when calling function objects.

Returns
Value returned by the exit trigger, generally the value returned by the inner function before the VM returned to the exit frame.

Run the VM until it returns from the current call frame; used by native methods to call into managed methods. Returns the value returned by the RETURN instruction that exited the call frame. Should be nestable so a managed method can call a native method can call a managed can call a native and so on (hopefully).

Definition at line 3201 of file vm.c.

◆ krk_runtimeError()

KrkValue krk_runtimeError ( KrkClass type,
const char *  fmt,
  ... 
)

Produce and raise an exception with a formatted message.

Creates an instance of the given exception type, passing a formatted string to the initializer. All of the core exception types take an option string value to attach to the exception, but third-party exception types may have different initializer signatures and need separate initialization.

The created exception object is attached to the current thread state and the KRK_THREAD_HAS_EXCEPTION flag is set.

If the format string is exactly "%V", the first format argument will be attached the exception as the 'msg' attribute.

No field width or precisions are supported on any conversion specifiers.

Standard conversion specifiers 'c', 's', 'd', 'u' are available, and the 'd' and 'u' specifiers may have length modifiers of l, L, or z.

Additional format specifiers are as follows:

S - Accepts one KrkString* to be printed in its entirety. R - Accepts one KrkValue and calls repr on it. T - Accepts one KrkValue and emits the name of its type.

Parameters
typeClass pointer for the exception type, eg. vm.exceptions->valueError
fmtFormat string.
Returns
As a convenience to C extension authors, returns None

Raise an exception. Creates an exception object of the requested type and formats a message string to attach to it. Exception classes are found in vm.exceptions and are initialized on startup.

Definition at line 460 of file exceptions.c.

◆ krk_setAttribute()

int krk_setAttribute ( KrkString name)

Implementation of the SET_PROPERTY instruction.

Sets the attribute specifed by name on the value second from top of the stack to the value at the top of the stack. Upon successful completion, 1 is returned the stack is reduced by one slot, and the top of the stack is the value set, which may be the result of a descriptor __set__ method. If the owner object does not allow for attributes to be set, and no descriptor object is present, 0 will be returned and the stack remains unmodified. No exception is raised in this case, though exceptions may still be raised by __setattr__ methods or descriptor __set__ methods.

Parameters
nameName of the attribute to set.
Returns
1 if the attribute could be set, 0 otherwise.

Definition at line 1903 of file vm.c.

◆ krk_setMaximumRecursionDepth()

void krk_setMaximumRecursionDepth ( size_t  maxDepth)

Set the maximum recursion call depth.

Must not be called while execution is in progress.

Definition at line 863 of file vm.c.

◆ krk_startModule()

KrkInstance* krk_startModule ( const char *  name)

Set up a new module object in the current thread.

Creates a new instance of the module type and attaches a __builtins__ reference to its fields. The module becomes the current thread's main module, but is not directly attached to the module table.

Parameters
nameName of the module, which is assigned to __name__
Returns
The instance object representing the module.

Definition at line 3209 of file vm.c.

◆ krk_swap()

void krk_swap ( int  distance)
inline

Swap the top of the stack of the value distance slots down.

Exchanges the values at the top of the stack and distance slots from the top without removing or shuffling anything in between.

Parameters
distanceHow from down from the top of the stack to swap (0 = the top)

Definition at line 145 of file vm.c.

Variable Documentation

◆ krk_currentThread

krk_threadLocal KrkThreadState krk_currentThread
extern

Thread-local VM state.

See KrkThreadState for more information.