Library Reference - WheretIB/nullc GitHub Wiki
NULLC library reference
-
Interface
-
Interoperability with C code
1. Interface
1.1 Library compilation options
Various library configuration options are available in "nullcdef.h" file.
#define NULLC_MAX_VARIABLE_NAME_LENGTH 2048
This define controls the maximum variable, function or class name that NULLC will attempt to handle.
#define NULLC_MAX_TYPE_NAME_LENGTH 8192
This define controls the maximum type name that NULLC will attempt to handle.
#define NULLC_DEFAULT_GLOBAL_MEMORY_LIMIT 1024 * 1024 * 1024
This define controls the default maximum global memory limit (1Gb by default).
You can change this constant or use the nullcSetGlobalMemoryLimit function.
#define NULLC_ERROR_BUFFER_SIZE 64 * 1024
This define controls the maximum error message length.
#define NULLC_MAX_GENERIC_INSTANCE_DEPTH 64
This define controls the limit on generic function and type instantiation depth.
#define NULLC_MAX_EXPRESSION_DEPTH 2048
This define controls the limit on the complexity of a single expression.
#define NULLC_MAX_TYPE_SIZE 256 * 1024 * 1024
This define controls the max type size in memory. This limit should not be increased because of the limits in the bytecode fields (but can be reduced).
#define NULLC_REG_VM_PROFILE_INSTRUCTIONS
Enable instruction counters for profiling and debugging (slows down execution). This define is disabled by default.
#define NULLC_TIME_TRACE
Enabled support for compiler execution time tracking. This define is enabled by default in Debug configuration.
#define NULLC_NO_RAW_EXTERNAL_CALL
Disable support for direct external function code using automatic generation of assembly glue code between nullc and C++. Direct calls might perform faster but support for different platforms is limited and 'wrapped' external function calls are preferred.
#define NULLC_BUILD_X86_JIT
This define enables x86 JiT executor.
This define is enabled by default on platforms and compilers that support it.
#define NULLC_OPTIMIZE_X86
This define enables x86 JiT executor code optimization.
Code compilation speed is reduced greatly when JiT is in use and this flag is enabled.
This define is enabled by default on platforms and compilers that support it.
#define NULLC_NO_EXECUTOR
This define will build a compiler-only version of NULLC library.
This define is disabled by default.
#define NULLC_AUTOBINDING
This define will enable an automatic function binding on Windows and Linux. More information in a topic Binding functions to NULLC
This define is enabled by default on supported platforms, unless direct function call support is disabled or not available.
1.2 Initialization and termination
nullres nullcInit();
Function initializes NULLC library with default allocation and deallocation functions.
nullres nullcInitCustomAlloc(void* (*allocFunc)(int), void (*deallocFunc)(void*));
Function initializes NULLC library with specified allocation and deallocation functions.
- allocFunc parameter sets the allocation function. It must be _cdecl function accepting one argument (allocation size) and returning pointer to allocated memory block.
- deallocFunc parameter sets the deallocation function. It must be _cdecl function
void nullcClearImportPaths();
This function clears the list of registered module import search paths.
void nullcAddImportPath(const char* importPath);
This function adds a module search import path to the list.
- importPath parameter sets is the path where modules are searched.
void nullcRemoveImportPath(const char* importPath);
This function removes a module import search path from the list.
- importPath is the path to remove
nullres nullcHasImportPath(const char* importPath);
Check if the module import path is registered.
- importPath is the path to search for
Return value is 1 if the path is found and 0 otherwise.
void nullcSetFileReadHandler(const char* (*fileLoadFunc)(const char* name, unsigned* size), void (*fileFreeFunc)(const char* data));
Function allows to set a handler for module file read operation. By default, fopen/ftell/fread/fclose function are used.
- fileLoadFunc parameter sets the handler function. It must be _cdecl function accepting two arguments and returning pointer to a memory, where file contents are placed.
name argument contains the path to a module.
size argument is a pointer to a variable that should receive file size.
- fileFreeFunc parameter sets the function that will be called to free file data returned by fileLoadFunc
void nullcSetGlobalMemoryLimit(unsigned limit);
Function sets the global memory limit and overrides the one set by NULLC_DEFAULT_GLOBAL_MEMORY_LIMIT define.
- limit parameter is the new global memory limit.
void nullcSetEnableLogFiles(int enable, void* (*openStream)(const char* name), void (*writeStream)(void *stream, const char *data, unsigned size), void (*closeStream)(void* stream));
TODO
void nullcSetOptimizationLevel(int level);
Select code generation optimization level.
- level parameter selects the optimization level:
- 0 - no optimization
- 1 - perform lightweight optimizations
- 2 - perform all available optimizations
void nullcSetEnableTimeTrace(int enable);
Control compiler time tracing report. - enable parameter can be 1 or 0 to enable or disable the option
void nullcSetModuleAnalyzeMemoryLimit(unsigned bytes);
Set a limit on the memory that a single module compilation can take. - bytes parameter controls the limit in bytes
void nullcSetEnableExternalDebugger(int enable);
Control if additional debug information should be generated for an external debugger extension.
void nullcTerminate();
This function performs NULLC library deinitialization.
1.3 Execution settings and environment
void nullcSetExecutor(unsigned id);
Change current executor.
- id is executor ID. Can be either NULLC_VM or NULLC_X86 (JiT).
nullres nullcSetExecutorStackSize(unsigned bytes);
Control the max amount of memory used for the stack. - bytes parameter controls the limit in bytes
nullres nullcBindModuleFunction(const char* module, void (*ptr)(), const char* name, int index);
This function is used to bind unresolved module functions to external C functions directly.
Read more abount C function binding in interoperability section.
- module parameter is the module name (as in NULLC import expression), where the function will be searched.
- ptr parameter is the pointer to C function (use a cast operation to bind functions with different types).
- name parameter is the function name.
- index parameter is the number of a function overload in order of definition in the source code.
nullres nullcBindModuleFunctionWrapper(const char* module, void *func, void (*ptr)(void *func, char* retBuf, char* argBuf), const char* name, int index);
This function is used to bind unresolved module functions to external C functions through a wrapper.
nullbind.h C++ header is provided with a nullcBindModuleFunctionHelper
function that takes function pointers directly.
nullres nullcLoadModuleBySource(const char* module, const char* code);
Builds module and saves its binary into binary cache.
- module parameter is the module name as in NULLC import expression.
- code parameter is the module source code.
nullres nullcLoadModuleByBinary(const char* module, const char* binary);
Loads module into binary cache.
- module parameter is the module name as in NULLC import expression.
- binary parameter is the module binary code.
void nullcRemoveModule(const char* module);
Remove module bytecode from binary cache.
1.4 Basic functions
nullres nullcBuild(const char* code);
Compiles and links code.
- code parameter is the module name as in NULLC import expression.
nullres nullcBuildWithModuleName(const char* code, const char* moduleName);
Compiles and links code with an additional module name info.
- code parameter is the module name as in NULLC import expression.
- moduleName parameter is the root module name.
1.5 Execution functions
nullres nullcRun();
Run global code.
This function should be called at least once, before nullcRunFunction can be safely called, since it calculates global variable values.
nullres nullcRunFunction(const char* funcName, ...);
Run function code.
- funcName parameter is the name of the function to run. If it's NULL, the result is the same as calling nullcRun.
- ... arguments that will be passed into a function.
unsigned nullcGetResultType();
Get type of the global/function execution result.
NULLCRef nullcGetResultObject();
Get nullc object reference holding the result.
const char* nullcGetResult();
Retrieve result as a string for a limited number of types.
int nullcGetResultInt();
double nullcGetResultDouble();
long long nullcGetResultLong();
Functions that retrieve last execution result of global code or function.
const char* nullcGetLastError();
Function returns last error description.
NULLCRef nullcGetLastErrorObject();
Get null object reference holding the error object.
1.6 Interaction functions
void* nullcAllocate(unsigned size);
Function allocates memory block that is managed by GC.
- size parameter is an allocation size.
void* nullcAllocateTyped(unsigned typeID);
Function allocates memory block holding an object of the specified type.
NULLCRef nullcAllocateObjectTyped(unsigned typeID);
Function allocates null object reference of the specified type.
NULLCArray nullcAllocateArrayTyped(unsigned typeID, unsigned count);
Function allocates an array of nullc objects of the specified type.
void nullcThrowError(const char* error, ...);
Function aborts NULLC execution with a specified error (formatting as in printf function is supported).
- error parameter is a format string.
- ... extra arguments.
void nullcThrowErrorObject(NULLCRef error);
Function aborts NULLC execution with a specified error object.
void nullcClearError();
Continue execution after it was stopped with an error without doing a full reset.
nullres nullcCallFunction(NULLCFuncPtr ptr, ...);
Call function using NULLC function pointer with optional arguments.
- ptr parameter is a pointer to NULLC function.
- ... arguments that will be passed into a function.
nullres nullcSetGlobal(const char* name, void* data);
Set global variable value.
- name parameter is a global variable name.
- data parameter is a pointer to new variable data.
void* nullcGetGlobal(const char* name);
Get global variable value (can be modified).
- name parameter is a global variable name.
nullres nullcGetFunction(const char* name, NULLCFuncPtr* func);
Get function pointer to use it in nullcCallFunction or to redirect it to some other function using nullcSetFunction.
- name parameter is the function name.
- func parameter is the pointer to NULLCFuncPtr struct that will receive pointer to function.
nullres nullcSetFunction(const char* name, NULLCFuncPtr func);
Set function using function pointer to redirect function to another one.
- name parameter is a global variable name.
- func parameter is the NULLCFuncPtr struct that contains pointer to source function.
nullres nullcRedirectFunction(unsigned sourceId, unsigned targetId);
Change one function to target another.
nullres nullcIsStackPointer(void* ptr);
Function returns 1 if passed pointer points to NULLC stack; otherwise, the return value is 0.
- ptr parameter is a pointer to check.
nullres nullcIsManagedPointer(void* ptr);
Function returns 1 if passed pointer points to a memory managed by NULLC GC; otherwise, the return value is 0.
- ptr parameter is a pointer to check.
1.7 Special modules
Some modules heavily rely on internal NULLC structure, and because of that, they are initialized through NULLC interface.
int nullcInitTypeinfoModule();
Function initializes std.typeinfo module.
int nullcInitDynamicModule();
Function initializes std.dynamic module.
1.8 Extended functions
nullres nullcAnalyze(const char* code);
Analyzes the code and returns 1 on success. Pointer to code string must be available until nullcClean is called. - code parameter is a pointer to a string with source code.
nullres nullcCompile(const char* code);
Compiles the code and returns 1 on success. Pointer to code string must be available until nullcClean is called.
- code parameter is a pointer to a string with source code.
unsigned nullcGetBytecode(char** bytecode);
Function is used to get bytecode for compiled source code.
Bytecode can be later linked with nullcLinkCode and executed.
- bytecode parameter is a pointer to pointer that will receive the bytecode. Memory must be freed by user.
Function returns the size of the bytecode.
unsigned nullcGetBytecodeNoCache(char** bytecode);
This function is similar to nullcGetBytecode, with one exception:
After bytecode is retrieved by nullcGetBytecode, it is put into bytecode cache as "__last" module that can be imported later to implement advanced features like dynamic code evaluation (see std.dynamic).
If you wish that "__last" module bytecode is not changed, you should use this function.
nullres nullcSaveListing(const char* fileName);
This function saves disassembly of last compiled code into file.
nullres nullcTranslateToC(const char* fileName, const char* mainName, void (*addDependency)(const char *fileName));
This function saved analog of C++ code of last compiled code into file.
void nullcClean();
Clean all accumulated bytecode from linker.
nullres nullcLinkCode(const char* bytecode);
Link new chunk of bytecode.
Type or function redefinition generates an error.
Global variables with the same name are handled silently.
nullres nullcLinkCodeWithModuleName(const char *bytecode, const char *moduleName);
Link new chunk of code with an additional module name info.
1.9 Debug functions
void* nullcGetVariableData(unsigned int *count);
unsigned int nullcGetCurrentExecutor(void **exec);
const void* nullcGetModule(const char* path);
ExternTypeInfo* nullcDebugTypeInfo(unsigned int *count);
ExternMemberInfo* nullcDebugTypeExtraInfo(unsigned int *count);
ExternConstantInfo* nullcDebugTypeConstantInfo(unsigned int *count);
ExternVarInfo* nullcDebugVariableInfo(unsigned int *count);
ExternFuncInfo* nullcDebugFunctionInfo(unsigned int *count);
ExternLocalInfo* nullcDebugLocalInfo(unsigned int *count);
char* nullcDebugSymbols(unsigned int *count);
char* nullcDebugSource();
ExternSourceInfo* nullcDebugSourceInfo(unsigned int *count);
ExternModuleInfo* nullcDebugModuleInfo(unsigned int *count);
void nullcDebugBeginCallStack();
unsigned int nullcDebugGetStackFrame();
unsigned int nullcDebugEnumStackFrame(unsigned frame);
unsigned int nullcDebugGetStackFrameCount();
nullres nullcDebugSetBreakFunction(void *context, unsigned (*callback)(void*, unsigned));
A function that is called when breakpoint is hit. Function accepts instruction number and returns how the break should be handled (constant above).
nullres nullcDebugClearBreakpoints();
You can remove all breakpoints explicitly. nullcClean clears all breakpoints automatically.
nullres nullcDebugAddBreakpoint(unsigned int instruction);
Line number can be translated into instruction number by using nullcDebugCodeInfo and nullcDebugModuleInfo.
nullres nullcDebugAddOneHitBreakpoint(unsigned int instruction);
Line number can be translated into instruction number by using nullcDebugCodeInfo and nullcDebugModuleInfo.
nullres nullcDebugRemoveBreakpoint(unsigned int instruction);
Line number can be translated into instruction number by using nullcDebugCodeInfo and nullcDebugModuleInfo.
ExternFuncInfo* nullcDebugConvertAddressToFunction(int instruction, ExternFuncInfo* codeFunctions, unsigned functionCount);
const char* nullcDebugGetInstructionSourceLocation(unsigned instruction);
unsigned nullcDebugGetSourceLocationModuleIndex(const char *sourceLocation);
unsigned nullcDebugGetSourceLocationLineAndColumn(const char *sourceLocation, unsigned moduleIndex, unsigned &column);
unsigned nullcDebugConvertNativeAddressToInstruction(void *address);
unsigned nullcDebugGetReversedStackDataBase(unsigned framePos);
Get call stack frame data location offset from base. Positions are counted from top, starting with 1. If 0 is passed, returns data location offset from the active call stack frame that doesn't have an entry in a call stack.
const char* nullcDebugGetVmAddressLocation(unsigned instruction, unsigned full);
const char* nullcDebugGetNativeAddressLocation(void *address, unsigned full);
2. Interoperability with C code
2.1 Binding functions to NULLC
Only functions with cdecl calling convention can be binded to NULLC.
All basic numeric types are equal in representation to C++ types, except for "long" type which corresponds to 64bit "long long" type in C++.
NULLC reference types are simple pointers.
NULLC array with implicit size corresponds to NULLCArray struct.
NULLC "auto ref" type corresponds to NULLCRef struct.
NULLC function pointers correspond to NULLCFuncPtr struct.
NULLC "auto[]" type corresponds to NULLCAutoArray struct.
It is not recommended to pass NULLC classes and explicitly-sized arrays by value.
If you want to bind class member function, it must accept pointer to class type as the last parameter.
NULLC classes can be transformed into C structures by applying the same transformations used for function arguments.
A care must be taken for class member alignment: members are aligned to their default align values, but no more than 4 bytes (see Basic types topic in language reference).
So it is recommended to wrap C struct definition into a "#pragma pack(push, 4) ... #pragma pack(pop)".
When binding a class member function, add "class::" before the function name (that's two ':' instead of one you see in externally defined member function).
If NULLC_AUTOBINDING define is enabled, you can write NULLC_BIND before your functions and NULLC linker will bind them automatically.
This works only for plain functions and not for class member functions.
Under gcc, you must build NULLC with "-ldl" flag and build your application with "-rdynamic" and "-ldl" flags, in order for auto binding to work.
nullbind.h C++ header is provided with a nullcBindModuleFunctionHelper
function that takes function pointers directly.