mirror of
https://github.com/zekexiao/pocketlang.git
synced 2025-03-04 13:15:55 +08:00
Garbage collection bugs fixed
- Objects that weren't pushed to PKVM's temp reference were fixed - vm->bytes_allocated was modified after the re-calculation of garbage collection fixed.
This commit is contained in:
parent
0cfdfa7415
commit
82919a690e
@ -2734,9 +2734,12 @@ static void compileFunction(Compiler* compiler, FuncType fn_type) {
|
|||||||
|
|
||||||
if (compiler->parser.has_syntax_error) return;
|
if (compiler->parser.has_syntax_error) return;
|
||||||
|
|
||||||
|
// The function will register itself in the owner's constant pool and it's
|
||||||
|
// GC root so we don't need to push it to temp references.
|
||||||
int fn_index;
|
int fn_index;
|
||||||
Function* func = newFunction(compiler->parser.vm, name, name_length,
|
Function* func = newFunction(compiler->parser.vm, name, name_length,
|
||||||
compiler->module, false, NULL, &fn_index);
|
compiler->module, false, NULL, &fn_index);
|
||||||
|
|
||||||
func->is_method = (fn_type == FUNC_METHOD || fn_type == FUNC_CONSTRUCTOR);
|
func->is_method = (fn_type == FUNC_METHOD || fn_type == FUNC_CONSTRUCTOR);
|
||||||
|
|
||||||
checkMaxConstantsReached(compiler, fn_index);
|
checkMaxConstantsReached(compiler, fn_index);
|
||||||
|
@ -124,6 +124,7 @@ PKVM* pkNewVM(PkConfiguration* config) {
|
|||||||
vm->working_set = (Object**)vm->config.realloc_fn(
|
vm->working_set = (Object**)vm->config.realloc_fn(
|
||||||
NULL, sizeof(Object*) * vm->working_set_capacity, NULL);
|
NULL, sizeof(Object*) * vm->working_set_capacity, NULL);
|
||||||
vm->next_gc = INITIAL_GC_SIZE;
|
vm->next_gc = INITIAL_GC_SIZE;
|
||||||
|
vm->collecting_garbage = false;
|
||||||
vm->min_heap_size = MIN_HEAP_SIZE;
|
vm->min_heap_size = MIN_HEAP_SIZE;
|
||||||
vm->heap_fill_percent = HEAP_FILL_PERCENT;
|
vm->heap_fill_percent = HEAP_FILL_PERCENT;
|
||||||
|
|
||||||
@ -179,7 +180,12 @@ void pkSetUserData(PKVM* vm, void* user_data) {
|
|||||||
PkHandle* pkNewModule(PKVM* vm, const char* name) {
|
PkHandle* pkNewModule(PKVM* vm, const char* name) {
|
||||||
CHECK_ARG_NULL(name);
|
CHECK_ARG_NULL(name);
|
||||||
Module* module = newModuleInternal(vm, name);
|
Module* module = newModuleInternal(vm, name);
|
||||||
return vmNewHandle(vm, VAR_OBJ(module));
|
|
||||||
|
vmPushTempRef(vm, &module->_super); // module.
|
||||||
|
PkHandle* handle = vmNewHandle(vm, VAR_OBJ(module));
|
||||||
|
vmPopTempRef(vm); // module.
|
||||||
|
|
||||||
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pkRegisterModule(PKVM* vm, PkHandle* module) {
|
void pkRegisterModule(PKVM* vm, PkHandle* module) {
|
||||||
@ -219,7 +225,10 @@ PkHandle* pkNewClass(PKVM* vm, const char* name,
|
|||||||
class_->new_fn = new_fn;
|
class_->new_fn = new_fn;
|
||||||
class_->delete_fn = delete_fn;
|
class_->delete_fn = delete_fn;
|
||||||
|
|
||||||
return vmNewHandle(vm, VAR_OBJ(class_));
|
vmPushTempRef(vm, &class_->_super); // class_.
|
||||||
|
PkHandle* handle = vmNewHandle(vm, VAR_OBJ(class_));
|
||||||
|
vmPopTempRef(vm); // class_.
|
||||||
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pkClassAddMethod(PKVM* vm, PkHandle* cls,
|
void pkClassAddMethod(PKVM* vm, PkHandle* cls,
|
||||||
@ -237,6 +246,8 @@ void pkClassAddMethod(PKVM* vm, PkHandle* cls,
|
|||||||
|
|
||||||
Function* fn = newFunction(vm, name, (int)strlen(name),
|
Function* fn = newFunction(vm, name, (int)strlen(name),
|
||||||
class_->owner, true, NULL, NULL);
|
class_->owner, true, NULL, NULL);
|
||||||
|
vmPushTempRef(vm, &fn->_super); // fn.
|
||||||
|
|
||||||
fn->arity = arity;
|
fn->arity = arity;
|
||||||
fn->is_method = true;
|
fn->is_method = true;
|
||||||
fn->native = fptr;
|
fn->native = fptr;
|
||||||
@ -246,7 +257,9 @@ void pkClassAddMethod(PKVM* vm, PkHandle* cls,
|
|||||||
// won't be garbage collected (class handle has reference to the module).
|
// won't be garbage collected (class handle has reference to the module).
|
||||||
|
|
||||||
Closure* method = newClosure(vm, fn);
|
Closure* method = newClosure(vm, fn);
|
||||||
|
vmPopTempRef(vm); // fn.
|
||||||
|
vmPushTempRef(vm, &method->_super); // method.
|
||||||
|
{
|
||||||
if (strcmp(name, CTOR_NAME) == 0) {
|
if (strcmp(name, CTOR_NAME) == 0) {
|
||||||
class_->ctor = method;
|
class_->ctor = method;
|
||||||
|
|
||||||
@ -256,6 +269,8 @@ void pkClassAddMethod(PKVM* vm, PkHandle* cls,
|
|||||||
vmPopTempRef(vm); // method.
|
vmPopTempRef(vm); // method.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
vmPopTempRef(vm); // method.
|
||||||
|
}
|
||||||
|
|
||||||
void pkReleaseHandle(PKVM* vm, PkHandle* handle) {
|
void pkReleaseHandle(PKVM* vm, PkHandle* handle) {
|
||||||
ASSERT(handle != NULL, "Given handle was NULL.");
|
ASSERT(handle != NULL, "Given handle was NULL.");
|
||||||
@ -766,7 +781,11 @@ bool pkSetAttribute(PKVM* vm, int instance, const char* name, int value) {
|
|||||||
VALIDATE_SLOT_INDEX(instance);
|
VALIDATE_SLOT_INDEX(instance);
|
||||||
VALIDATE_SLOT_INDEX(value);
|
VALIDATE_SLOT_INDEX(value);
|
||||||
|
|
||||||
varSetAttrib(vm, SLOT(instance), newString(vm, name), SLOT(value));
|
String* sname = newString(vm, name);
|
||||||
|
vmPushTempRef(vm, &sname->_super); // sname.
|
||||||
|
varSetAttrib(vm, SLOT(instance), sname, SLOT(value));
|
||||||
|
vmPopTempRef(vm); // sname.
|
||||||
|
|
||||||
return !VM_HAS_ERROR(vm);
|
return !VM_HAS_ERROR(vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -777,12 +796,19 @@ bool pkGetAttribute(PKVM* vm, int instance, const char* name,
|
|||||||
VALIDATE_SLOT_INDEX(instance);
|
VALIDATE_SLOT_INDEX(instance);
|
||||||
VALIDATE_SLOT_INDEX(index);
|
VALIDATE_SLOT_INDEX(index);
|
||||||
|
|
||||||
SET_SLOT(index, varGetAttrib(vm, SLOT(instance), newString(vm, name)));
|
String* sname = newString(vm, name);
|
||||||
|
vmPushTempRef(vm, &sname->_super); // sname.
|
||||||
|
SET_SLOT(index, varGetAttrib(vm, SLOT(instance), sname));
|
||||||
|
vmPopTempRef(vm); // sname.
|
||||||
|
|
||||||
return !VM_HAS_ERROR(vm);
|
return !VM_HAS_ERROR(vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Var _newInstance(PKVM* vm, Class* cls, int argc, Var* argv) {
|
static Var _newInstance(PKVM* vm, Class* cls, int argc, Var* argv) {
|
||||||
Var instance = preConstructSelf(vm, cls);
|
Var instance = preConstructSelf(vm, cls);
|
||||||
|
if (VM_HAS_ERROR(vm)) return VAR_NULL;
|
||||||
|
|
||||||
|
if (IS_OBJ(instance)) vmPushTempRef(vm, AS_OBJ(instance)); // instance.
|
||||||
|
|
||||||
Closure* ctor = cls->ctor;
|
Closure* ctor = cls->ctor;
|
||||||
while (ctor == NULL) {
|
while (ctor == NULL) {
|
||||||
@ -792,6 +818,7 @@ static Var _newInstance(PKVM* vm, Class* cls, int argc, Var* argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ctor != NULL) vmCallMethod(vm, instance, ctor, argc, argv, NULL);
|
if (ctor != NULL) vmCallMethod(vm, instance, ctor, argc, argv, NULL);
|
||||||
|
if (IS_OBJ(instance)) vmPopTempRef(vm); // instance.
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
@ -861,8 +888,12 @@ bool pkCallMethod(PKVM* vm, int instance, const char* method,
|
|||||||
if (ret >= 0) VALIDATE_SLOT_INDEX(ret);
|
if (ret >= 0) VALIDATE_SLOT_INDEX(ret);
|
||||||
|
|
||||||
bool is_method = false;
|
bool is_method = false;
|
||||||
Var callable = getMethod(vm, SLOT(instance), newString(vm, method),
|
String* smethod = newString(vm, method);
|
||||||
|
vmPushTempRef(vm, &smethod->_super); // smethod.
|
||||||
|
Var callable = getMethod(vm, SLOT(instance), smethod,
|
||||||
&is_method);
|
&is_method);
|
||||||
|
vmPopTempRef(vm); // smethod.
|
||||||
|
|
||||||
if (VM_HAS_ERROR(vm)) return false;
|
if (VM_HAS_ERROR(vm)) return false;
|
||||||
|
|
||||||
// Calls a class == construct.
|
// Calls a class == construct.
|
||||||
|
@ -149,7 +149,9 @@ static void popMarkedObjectsInternal(Object* obj, PKVM* vm) {
|
|||||||
|
|
||||||
markObject(vm, &func->owner->_super);
|
markObject(vm, &func->owner->_super);
|
||||||
|
|
||||||
if (!func->is_native) {
|
// If a garbage collection is triggered when allocating a name string
|
||||||
|
// for this function, it's [fn] property will be NULL.
|
||||||
|
if (!func->is_native && func->fn != NULL) {
|
||||||
Fn* fn = func->fn;
|
Fn* fn = func->fn;
|
||||||
vm->bytes_allocated += sizeof(Fn);
|
vm->bytes_allocated += sizeof(Fn);
|
||||||
|
|
||||||
@ -293,14 +295,14 @@ String* newStringVaArgs(PKVM* vm, const char* fmt, va_list args) {
|
|||||||
|
|
||||||
List* newList(PKVM* vm, uint32_t size) {
|
List* newList(PKVM* vm, uint32_t size) {
|
||||||
List* list = ALLOCATE(vm, List);
|
List* list = ALLOCATE(vm, List);
|
||||||
vmPushTempRef(vm, &list->_super);
|
vmPushTempRef(vm, &list->_super); // list.
|
||||||
varInitObject(&list->_super, vm, OBJ_LIST);
|
varInitObject(&list->_super, vm, OBJ_LIST);
|
||||||
pkVarBufferInit(&list->elements);
|
pkVarBufferInit(&list->elements);
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
pkVarBufferFill(&list->elements, vm, VAR_NULL, size);
|
pkVarBufferFill(&list->elements, vm, VAR_NULL, size);
|
||||||
list->elements.count = 0;
|
list->elements.count = 0;
|
||||||
}
|
}
|
||||||
vmPopTempRef(vm);
|
vmPopTempRef(vm); // list.
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,13 +325,9 @@ Range* newRange(PKVM* vm, double from, double to) {
|
|||||||
|
|
||||||
Module* newModule(PKVM* vm) {
|
Module* newModule(PKVM* vm) {
|
||||||
Module* module = ALLOCATE(vm, Module);
|
Module* module = ALLOCATE(vm, Module);
|
||||||
|
memset(module, 0, sizeof(Module));
|
||||||
varInitObject(&module->_super, vm, OBJ_MODULE);
|
varInitObject(&module->_super, vm, OBJ_MODULE);
|
||||||
|
|
||||||
module->path = NULL;
|
|
||||||
module->name = NULL;
|
|
||||||
module->initialized = false;
|
|
||||||
module->body = NULL;
|
|
||||||
|
|
||||||
pkVarBufferInit(&module->globals);
|
pkVarBufferInit(&module->globals);
|
||||||
pkUintBufferInit(&module->global_names);
|
pkUintBufferInit(&module->global_names);
|
||||||
pkVarBufferInit(&module->constants);
|
pkVarBufferInit(&module->constants);
|
||||||
@ -343,6 +341,7 @@ Function* newFunction(PKVM* vm, const char* name, int length,
|
|||||||
int* fn_index) {
|
int* fn_index) {
|
||||||
|
|
||||||
Function* func = ALLOCATE(vm, Function);
|
Function* func = ALLOCATE(vm, Function);
|
||||||
|
memset(func, 0, sizeof(Function));
|
||||||
varInitObject(&func->_super, vm, OBJ_FUNC);
|
varInitObject(&func->_super, vm, OBJ_FUNC);
|
||||||
|
|
||||||
vmPushTempRef(vm, &func->_super); // func
|
vmPushTempRef(vm, &func->_super); // func
|
||||||
@ -388,10 +387,7 @@ Closure* newClosure(PKVM* vm, Function* fn) {
|
|||||||
varInitObject(&closure->_super, vm, OBJ_CLOSURE);
|
varInitObject(&closure->_super, vm, OBJ_CLOSURE);
|
||||||
|
|
||||||
closure->fn = fn;
|
closure->fn = fn;
|
||||||
|
memset(closure->upvalues, 0, sizeof(Upvalue*) * fn->upvalue_count);
|
||||||
for (int i = 0; i < fn->upvalue_count; i++) {
|
|
||||||
closure->upvalues[i] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return closure;
|
return closure;
|
||||||
}
|
}
|
||||||
@ -410,9 +406,10 @@ Fiber* newFiber(PKVM* vm, Closure* closure) {
|
|||||||
ASSERT(closure == NULL || closure->fn->arity >= -1, OOPS);
|
ASSERT(closure == NULL || closure->fn->arity >= -1, OOPS);
|
||||||
|
|
||||||
Fiber* fiber = ALLOCATE(vm, Fiber);
|
Fiber* fiber = ALLOCATE(vm, Fiber);
|
||||||
ASSERT(fiber != NULL, "Out of memory");
|
|
||||||
|
|
||||||
// Not sure why this memset is needed here. If it doesn't then remove it.
|
// If a garbage collection is triggered here, and the fiber isn't fully
|
||||||
|
// constructed -> it's fields are not intialized yet, would cause a crash
|
||||||
|
// so we need to memset here.
|
||||||
memset(fiber, 0, sizeof(Fiber));
|
memset(fiber, 0, sizeof(Fiber));
|
||||||
|
|
||||||
varInitObject(&fiber->_super, vm, OBJ_FIBER);
|
varInitObject(&fiber->_super, vm, OBJ_FIBER);
|
||||||
@ -476,6 +473,12 @@ Class* newClass(PKVM* vm, const char* name, int length,
|
|||||||
const char* docstring, int* cls_index) {
|
const char* docstring, int* cls_index) {
|
||||||
|
|
||||||
Class* cls = ALLOCATE(vm, Class);
|
Class* cls = ALLOCATE(vm, Class);
|
||||||
|
|
||||||
|
// If the garbage collection trigged bellow while allocating for
|
||||||
|
// [cls->name] or other properties, the calss is in the root (temp ref)
|
||||||
|
// and it's property [cls->name] is un initialized, which cause a crash.
|
||||||
|
memset(cls, 0, sizeof(Class));
|
||||||
|
|
||||||
varInitObject(&cls->_super, vm, OBJ_CLASS);
|
varInitObject(&cls->_super, vm, OBJ_CLASS);
|
||||||
|
|
||||||
vmPushTempRef(vm, &cls->_super); // class.
|
vmPushTempRef(vm, &cls->_super); // class.
|
||||||
@ -483,12 +486,7 @@ Class* newClass(PKVM* vm, const char* name, int length,
|
|||||||
pkClosureBufferInit(&cls->methods);
|
pkClosureBufferInit(&cls->methods);
|
||||||
|
|
||||||
cls->class_of = PK_INSTANCE;
|
cls->class_of = PK_INSTANCE;
|
||||||
cls->owner = NULL;
|
|
||||||
cls->super_class = super;
|
cls->super_class = super;
|
||||||
cls->docstring = NULL;
|
|
||||||
cls->ctor = NULL;
|
|
||||||
cls->new_fn = NULL;
|
|
||||||
cls->delete_fn = NULL;
|
|
||||||
|
|
||||||
// Builtin types doesn't belongs to a module.
|
// Builtin types doesn't belongs to a module.
|
||||||
if (module != NULL) {
|
if (module != NULL) {
|
||||||
@ -510,36 +508,38 @@ Instance* newInstance(PKVM* vm, Class* cls) {
|
|||||||
"class with newInstance() function.");
|
"class with newInstance() function.");
|
||||||
|
|
||||||
Instance* inst = ALLOCATE(vm, Instance);
|
Instance* inst = ALLOCATE(vm, Instance);
|
||||||
|
memset(inst, 0, sizeof(Instance));
|
||||||
varInitObject(&inst->_super, vm, OBJ_INST);
|
varInitObject(&inst->_super, vm, OBJ_INST);
|
||||||
|
|
||||||
vmPushTempRef(vm, &inst->_super); // inst.
|
vmPushTempRef(vm, &inst->_super); // inst.
|
||||||
|
|
||||||
inst->cls = cls;
|
inst->cls = cls;
|
||||||
inst->attribs = newMap(vm);
|
|
||||||
|
|
||||||
if (cls->new_fn != NULL) {
|
if (cls->new_fn != NULL) {
|
||||||
inst->native = cls->new_fn(vm);
|
inst->native = cls->new_fn(vm);
|
||||||
} else {
|
} else {
|
||||||
inst->native = NULL;
|
inst->native = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inst->attribs = newMap(vm);
|
||||||
|
|
||||||
vmPopTempRef(vm); // inst.
|
vmPopTempRef(vm); // inst.
|
||||||
return inst;
|
return inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
List* rangeAsList(PKVM* vm, Range* self) {
|
List* rangeAsList(PKVM* vm, Range* self) {
|
||||||
List* list;
|
|
||||||
if (self->from < self->to) {
|
if (self->from < self->to) {
|
||||||
list = newList(vm, (uint32_t)(self->to - self->from));
|
List* list = newList(vm, (uint32_t)(self->to - self->from));
|
||||||
|
vmPushTempRef(vm, &list->_super); // list.
|
||||||
for (double i = self->from; i < self->to; i++) {
|
for (double i = self->from; i < self->to; i++) {
|
||||||
pkVarBufferWrite(&list->elements, vm, VAR_NUM(i));
|
pkVarBufferWrite(&list->elements, vm, VAR_NUM(i));
|
||||||
}
|
}
|
||||||
return list;
|
vmPopTempRef(vm); // list.
|
||||||
|
|
||||||
} else {
|
return list;
|
||||||
list = newList(vm, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return newList(vm, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
String* stringLower(PKVM* vm, String* self) {
|
String* stringLower(PKVM* vm, String* self) {
|
||||||
|
@ -27,10 +27,24 @@ void* vmRealloc(PKVM* vm, void* memory, size_t old_size, size_t new_size) {
|
|||||||
// Track the total allocated memory of the VM to trigger the GC.
|
// Track the total allocated memory of the VM to trigger the GC.
|
||||||
// if vmRealloc is called for freeing, the old_size would be 0 since
|
// if vmRealloc is called for freeing, the old_size would be 0 since
|
||||||
// deallocated bytes are traced by garbage collector.
|
// deallocated bytes are traced by garbage collector.
|
||||||
|
//
|
||||||
|
// If we're running a garbage collection, VM's byte allocated will be
|
||||||
|
// re-calculated at vmCollectGarbage() which is equal to the remaining
|
||||||
|
// objects after clening the garbage. And clearing a garbage will
|
||||||
|
// recursively invoke this function so we shouldn't modify it.
|
||||||
|
if (!vm->collecting_garbage) {
|
||||||
vm->bytes_allocated += new_size - old_size;
|
vm->bytes_allocated += new_size - old_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're garbage collecting no new allocation is allowed.
|
||||||
|
ASSERT(!vm->collecting_garbage || new_size == 0,
|
||||||
|
"No new allocation is allowed while garbage collection is running.");
|
||||||
|
|
||||||
if (new_size > 0 && vm->bytes_allocated > vm->next_gc) {
|
if (new_size > 0 && vm->bytes_allocated > vm->next_gc) {
|
||||||
|
ASSERT(vm->collecting_garbage == false, OOPS);
|
||||||
|
vm->collecting_garbage = true;
|
||||||
vmCollectGarbage(vm);
|
vmCollectGarbage(vm);
|
||||||
|
vm->collecting_garbage = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TRACE_MEMORY
|
#if TRACE_MEMORY
|
||||||
@ -99,10 +113,6 @@ Module* vmGetModule(PKVM* vm, String* key) {
|
|||||||
|
|
||||||
void vmCollectGarbage(PKVM* vm) {
|
void vmCollectGarbage(PKVM* vm) {
|
||||||
|
|
||||||
// Reset VM's bytes_allocated value and count it again so that we don't
|
|
||||||
// required to know the size of each object that'll be freeing.
|
|
||||||
vm->bytes_allocated = 0;
|
|
||||||
|
|
||||||
// Mark builtin functions.
|
// Mark builtin functions.
|
||||||
for (int i = 0; i < vm->builtins_count; i++) {
|
for (int i = 0; i < vm->builtins_count; i++) {
|
||||||
markObject(vm, &vm->builtins_funcs[i]->_super);
|
markObject(vm, &vm->builtins_funcs[i]->_super);
|
||||||
@ -139,11 +149,23 @@ void vmCollectGarbage(PKVM* vm) {
|
|||||||
markObject(vm, &vm->fiber->_super);
|
markObject(vm, &vm->fiber->_super);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset VM's bytes_allocated value and count it again so that we don't
|
||||||
|
// required to know the size of each object that'll be freeing.
|
||||||
|
vm->bytes_allocated = 0;
|
||||||
|
|
||||||
// Pop the marked objects from the working set and push all of it's
|
// Pop the marked objects from the working set and push all of it's
|
||||||
// referenced objects. This will repeat till no more objects left in the
|
// referenced objects. This will repeat till no more objects left in the
|
||||||
// working set.
|
// working set.
|
||||||
popMarkedObjects(vm);
|
popMarkedObjects(vm);
|
||||||
|
|
||||||
|
// Now [vm->bytes_allocated] is equal to the number of bytes allocated for
|
||||||
|
// the root objects which are marked above. Since we're garbage collecting
|
||||||
|
// freeObject() shouldn't modify vm->bytes_allocated. We ensure this by
|
||||||
|
// copying the value to [bytes_allocated] and check after freeing.
|
||||||
|
#ifdef DEBUG
|
||||||
|
size_t bytes_allocated = vm->bytes_allocated;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Now sweep all the un-marked objects in then link list and remove them
|
// Now sweep all the un-marked objects in then link list and remove them
|
||||||
// from the chain.
|
// from the chain.
|
||||||
|
|
||||||
@ -166,6 +188,10 @@ void vmCollectGarbage(PKVM* vm) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
ASSERT(bytes_allocated = vm->bytes_allocated, OOPS);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Next GC heap size will be change depends on the byte we've left with now,
|
// Next GC heap size will be change depends on the byte we've left with now,
|
||||||
// and the [heap_fill_percent].
|
// and the [heap_fill_percent].
|
||||||
vm->next_gc = vm->bytes_allocated + (
|
vm->next_gc = vm->bytes_allocated + (
|
||||||
@ -937,7 +963,9 @@ L_vm_main_loop:
|
|||||||
ASSERT_INDEX(index, module->constants.count);
|
ASSERT_INDEX(index, module->constants.count);
|
||||||
ASSERT(IS_OBJ_TYPE(module->constants.data[index], OBJ_FUNC), OOPS);
|
ASSERT(IS_OBJ_TYPE(module->constants.data[index], OBJ_FUNC), OOPS);
|
||||||
Function* fn = (Function*)AS_OBJ(module->constants.data[index]);
|
Function* fn = (Function*)AS_OBJ(module->constants.data[index]);
|
||||||
|
|
||||||
Closure* closure = newClosure(vm, fn);
|
Closure* closure = newClosure(vm, fn);
|
||||||
|
vmPushTempRef(vm, &closure->_super); // closure.
|
||||||
|
|
||||||
// Capture the vaupes.
|
// Capture the vaupes.
|
||||||
for (int i = 0; i < fn->upvalue_count; i++) {
|
for (int i = 0; i < fn->upvalue_count; i++) {
|
||||||
@ -954,6 +982,8 @@ L_vm_main_loop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
PUSH(VAR_OBJ(closure));
|
PUSH(VAR_OBJ(closure));
|
||||||
|
vmPopTempRef(vm); // closure.
|
||||||
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +69,10 @@ struct PKVM {
|
|||||||
// The number of bytes that'll trigger the next GC.
|
// The number of bytes that'll trigger the next GC.
|
||||||
size_t next_gc;
|
size_t next_gc;
|
||||||
|
|
||||||
|
// True if PKVM is running a garbage collection, and no new allocation is
|
||||||
|
// allowed in this phase.
|
||||||
|
bool collecting_garbage;
|
||||||
|
|
||||||
// Minimum size the heap could get.
|
// Minimum size the heap could get.
|
||||||
size_t min_heap_size;
|
size_t min_heap_size;
|
||||||
|
|
||||||
|
@ -1,259 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020-2022 Thakee Nathees
|
|
||||||
* Copyright (c) 2021-2022 Pocketlang Contributors
|
|
||||||
* Distributed Under The MIT License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PK_AMALGAMATED
|
|
||||||
#include "libs.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define TERM_IMPLEMENT
|
|
||||||
#include "thirdparty/term/term.h" //<< AMALG_INLINE >>
|
|
||||||
#undef TERM_IMPLEMENT
|
|
||||||
|
|
||||||
// A reference to the event class, to check is instance of.
|
|
||||||
static PkHandle* _cls_term_event = NULL;
|
|
||||||
|
|
||||||
static void _setSlotVector(PKVM* vm, int slot, int tmp, double x, double y) {
|
|
||||||
|
|
||||||
if (!pkImportModule(vm, "types", slot)) return;
|
|
||||||
if (!pkGetAttribute(vm, slot, "Vector", slot)) return;
|
|
||||||
if (!pkNewInstance(vm, slot, slot, 0, 0)) return;
|
|
||||||
|
|
||||||
pkSetSlotNumber(vm, tmp, x);
|
|
||||||
if (!pkSetAttribute(vm, slot, "x", tmp)) return;
|
|
||||||
pkSetSlotNumber(vm, tmp, y);
|
|
||||||
if (!pkSetAttribute(vm, slot, "y", tmp)) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* _termEventNew(PKVM* vm) {
|
|
||||||
term_Event* event = pkRealloc(vm, NULL, sizeof(term_Event));
|
|
||||||
event->type = TERM_ET_UNKNOWN;
|
|
||||||
return event;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _termEventDelete(PKVM* vm, void* event) {
|
|
||||||
pkRealloc(vm, event, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _termEventGetter(PKVM* vm) {
|
|
||||||
const char* name;
|
|
||||||
if (!pkValidateSlotString(vm, 1, &name, NULL)) return;
|
|
||||||
|
|
||||||
term_Event* event = pkGetSelf(vm);
|
|
||||||
|
|
||||||
if (strcmp(name, "type") == 0) {
|
|
||||||
pkSetSlotNumber(vm, 0, (double)event->type);
|
|
||||||
|
|
||||||
} else if (strcmp(name, "keycode") == 0) {
|
|
||||||
pkSetSlotNumber(vm, 0, (double)event->key.code);
|
|
||||||
|
|
||||||
} else if (strcmp(name, "ascii") == 0) {
|
|
||||||
pkSetSlotNumber(vm, 0, (double)event->key.ascii);
|
|
||||||
|
|
||||||
} else if (strcmp(name, "modifiers") == 0) {
|
|
||||||
if (event->type == TERM_ET_KEY_DOWN) {
|
|
||||||
pkSetSlotNumber(vm, 0, (double)event->key.modifiers);
|
|
||||||
} else {
|
|
||||||
pkSetSlotNumber(vm, 0, (double)event->mouse.modifiers);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (strcmp(name, "button") == 0) {
|
|
||||||
pkSetSlotNumber(vm, 0, (double)event->mouse.button);
|
|
||||||
|
|
||||||
} else if (strcmp(name, "pos") == 0) {
|
|
||||||
pkReserveSlots(vm, 2);
|
|
||||||
_setSlotVector(vm, 0, 1, event->mouse.pos.x, event->mouse.pos.y);
|
|
||||||
|
|
||||||
} else if (strcmp(name, "scroll") == 0) {
|
|
||||||
pkSetSlotBool(vm, 0, event->mouse.scroll);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void _registerEnums(PKVM* vm, PkHandle* term) {
|
|
||||||
pkReserveSlots(vm, 1);
|
|
||||||
pkSetSlotHandle(vm, 0, term);
|
|
||||||
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_UNKNOWN); pkSetAttribute(vm, 0, "KEY_UNKNOWN", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_0); pkSetAttribute(vm, 0, "KEY_0", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_1); pkSetAttribute(vm, 0, "KEY_1", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_2); pkSetAttribute(vm, 0, "KEY_2", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_3); pkSetAttribute(vm, 0, "KEY_3", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_4); pkSetAttribute(vm, 0, "KEY_4", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_5); pkSetAttribute(vm, 0, "KEY_5", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_6); pkSetAttribute(vm, 0, "KEY_6", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_7); pkSetAttribute(vm, 0, "KEY_7", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_8); pkSetAttribute(vm, 0, "KEY_8", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_9); pkSetAttribute(vm, 0, "KEY_9", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_A); pkSetAttribute(vm, 0, "KEY_A", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_B); pkSetAttribute(vm, 0, "KEY_B", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_C); pkSetAttribute(vm, 0, "KEY_C", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_D); pkSetAttribute(vm, 0, "KEY_D", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_E); pkSetAttribute(vm, 0, "KEY_E", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_F); pkSetAttribute(vm, 0, "KEY_F", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_G); pkSetAttribute(vm, 0, "KEY_G", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_H); pkSetAttribute(vm, 0, "KEY_H", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_I); pkSetAttribute(vm, 0, "KEY_I", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_J); pkSetAttribute(vm, 0, "KEY_J", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_K); pkSetAttribute(vm, 0, "KEY_K", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_L); pkSetAttribute(vm, 0, "KEY_L", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_M); pkSetAttribute(vm, 0, "KEY_M", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_N); pkSetAttribute(vm, 0, "KEY_N", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_O); pkSetAttribute(vm, 0, "KEY_O", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_P); pkSetAttribute(vm, 0, "KEY_P", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_Q); pkSetAttribute(vm, 0, "KEY_Q", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_R); pkSetAttribute(vm, 0, "KEY_R", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_S); pkSetAttribute(vm, 0, "KEY_S", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_T); pkSetAttribute(vm, 0, "KEY_T", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_U); pkSetAttribute(vm, 0, "KEY_U", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_V); pkSetAttribute(vm, 0, "KEY_V", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_W); pkSetAttribute(vm, 0, "KEY_W", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_X); pkSetAttribute(vm, 0, "KEY_X", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_Y); pkSetAttribute(vm, 0, "KEY_Y", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_Z); pkSetAttribute(vm, 0, "KEY_Z", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_ESC); pkSetAttribute(vm, 0, "KEY_ESC", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_ENTER); pkSetAttribute(vm, 0, "KEY_ENTER", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_SPACE); pkSetAttribute(vm, 0, "KEY_SPACE", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_HOME); pkSetAttribute(vm, 0, "KEY_HOME", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_END); pkSetAttribute(vm, 0, "KEY_END", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_PAGEUP); pkSetAttribute(vm, 0, "KEY_PAGEUP", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_PAGEDOWN); pkSetAttribute(vm, 0, "KEY_PAGEDOWN", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_LEFT); pkSetAttribute(vm, 0, "KEY_LEFT", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_UP); pkSetAttribute(vm, 0, "KEY_UP", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_RIGHT); pkSetAttribute(vm, 0, "KEY_RIGHT", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_DOWN); pkSetAttribute(vm, 0, "KEY_DOWN", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_INSERT); pkSetAttribute(vm, 0, "KEY_INSERT", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_DELETE); pkSetAttribute(vm, 0, "KEY_DELETE", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_BACKSPACE); pkSetAttribute(vm, 0, "KEY_BACKSPACE", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_TAB); pkSetAttribute(vm, 0, "KEY_TAB", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_F1); pkSetAttribute(vm, 0, "KEY_F1", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_F2); pkSetAttribute(vm, 0, "KEY_F2", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_F3); pkSetAttribute(vm, 0, "KEY_F3", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_F4); pkSetAttribute(vm, 0, "KEY_F4", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_F5); pkSetAttribute(vm, 0, "KEY_F5", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_F6); pkSetAttribute(vm, 0, "KEY_F6", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_F7); pkSetAttribute(vm, 0, "KEY_F7", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_F8); pkSetAttribute(vm, 0, "KEY_F8", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_F9); pkSetAttribute(vm, 0, "KEY_F9", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_F10); pkSetAttribute(vm, 0, "KEY_F10", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_F11); pkSetAttribute(vm, 0, "KEY_F11", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_KEY_F12); pkSetAttribute(vm, 0, "KEY_F12", 1);
|
|
||||||
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_MB_UNKNOWN); pkSetAttribute(vm, 0, "BUTTON_UNKNOWN", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_MB_LEFT); pkSetAttribute(vm, 0, "BUTTON_LEFT", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_MB_MIDDLE); pkSetAttribute(vm, 0, "BUTTON_MIDDLE", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_MB_RIGHT); pkSetAttribute(vm, 0, "BUTTON_RIGHT", 1);
|
|
||||||
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_MD_NONE); pkSetAttribute(vm, 0, "MD_NONE", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_MD_CTRL); pkSetAttribute(vm, 0, "MD_CTRL", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_MD_ALT); pkSetAttribute(vm, 0, "MD_ALT", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_MD_SHIFT); pkSetAttribute(vm, 0, "MD_SHIFT", 1);
|
|
||||||
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_ET_UNKNOWN); pkSetAttribute(vm, 0, "EVENT_UNKNOWN", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_ET_KEY_DOWN); pkSetAttribute(vm, 0, "EVENT_KEY_DOWN", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_ET_RESIZE); pkSetAttribute(vm, 0, "EVENT_RESIZE", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_ET_DOUBLE_CLICK); pkSetAttribute(vm, 0, "EVENT_DOUBLE_CLICK", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_ET_MOUSE_DOWN); pkSetAttribute(vm, 0, "EVENT_MOUSE_DOWN", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_ET_MOUSE_UP); pkSetAttribute(vm, 0, "EVENT_MOUSE_UP", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_ET_MOUSE_MOVE); pkSetAttribute(vm, 0, "EVENT_MOUSE_MOVE", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_ET_MOUSE_DRAG); pkSetAttribute(vm, 0, "EVENT_MOUSE_DRAG", 1);
|
|
||||||
pkSetSlotNumber(vm, 1, TERM_ET_MOUSE_SCROLL); pkSetAttribute(vm, 0, "EVENT_MOUSE_SCROLL", 1);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void _termInit(PKVM* vm) {
|
|
||||||
bool capture_events;
|
|
||||||
if (!pkValidateSlotBool(vm, 1, &capture_events)) return;
|
|
||||||
term_init(capture_events);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _termCleanup(PKVM* vm) {
|
|
||||||
term_cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _termIsatty(PKVM* vm) {
|
|
||||||
pkSetSlotBool(vm, 0, term_isatty());
|
|
||||||
}
|
|
||||||
|
|
||||||
void _termNewScreenBuffer(PKVM* vm) {
|
|
||||||
term_new_screen_buffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _termRestoreScreenBuffer(PKVM* vm) {
|
|
||||||
term_restore_screen_buffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _termGetSize(PKVM* vm) {
|
|
||||||
pkReserveSlots(vm, 2);
|
|
||||||
term_Vec size = term_getsize();
|
|
||||||
_setSlotVector(vm, 0, 1, size.x, size.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _termGetPosition(PKVM* vm) {
|
|
||||||
pkReserveSlots(vm, 2);
|
|
||||||
term_Vec pos = term_getposition();
|
|
||||||
_setSlotVector(vm, 0, 1, pos.x, pos.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _termSetPosition(PKVM* vm) {
|
|
||||||
double x, y;
|
|
||||||
|
|
||||||
int argc = pkGetArgc(vm);
|
|
||||||
if (!pkCheckArgcRange(vm, argc, 1, 2)) return;
|
|
||||||
|
|
||||||
if (argc == 1) {
|
|
||||||
pkReserveSlots(vm, 3);
|
|
||||||
if (!pkGetAttribute(vm, 1, "x", 2)) return;
|
|
||||||
if (!pkValidateSlotNumber(vm, 2, &x)) return;
|
|
||||||
|
|
||||||
if (!pkGetAttribute(vm, 1, "y", 2)) return;
|
|
||||||
if (!pkValidateSlotNumber(vm, 2, &y)) return;
|
|
||||||
} else {
|
|
||||||
if (!pkValidateSlotNumber(vm, 1, &x)) return;
|
|
||||||
if (!pkValidateSlotNumber(vm, 2, &y)) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
term_Vec pos = term_vec((int)x, (int)y);
|
|
||||||
term_setposition(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _termReadEvent(PKVM* vm) {
|
|
||||||
pkReserveSlots(vm, 3);
|
|
||||||
pkSetSlotHandle(vm, 2, _cls_term_event);
|
|
||||||
if (!pkValidateSlotInstanceOf(vm, 1, 2)) return;
|
|
||||||
|
|
||||||
term_Event* event = pkGetSlotNativeInstance(vm, 1);
|
|
||||||
pkSetSlotBool(vm, 0, term_read_event(event));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/* MODULE REGISTER */
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
void registerModuleTerm(PKVM* vm) {
|
|
||||||
PkHandle* term = pkNewModule(vm, "term");
|
|
||||||
|
|
||||||
_registerEnums(vm, term);
|
|
||||||
pkModuleAddFunction(vm, term, "init", _termInit, 1);
|
|
||||||
pkModuleAddFunction(vm, term, "cleanup", _termCleanup, 0);
|
|
||||||
pkModuleAddFunction(vm, term, "isatty", _termIsatty, 0);
|
|
||||||
pkModuleAddFunction(vm, term, "new_screen_buffer", _termNewScreenBuffer, 0);
|
|
||||||
pkModuleAddFunction(vm, term, "restore_screen_buffer", _termRestoreScreenBuffer, 0);
|
|
||||||
pkModuleAddFunction(vm, term, "getsize", _termGetSize, 0);
|
|
||||||
pkModuleAddFunction(vm, term, "getposition", _termGetPosition, 0);
|
|
||||||
pkModuleAddFunction(vm, term, "setposition", _termSetPosition, -1);
|
|
||||||
pkModuleAddFunction(vm, term, "read_event", _termReadEvent, 1);
|
|
||||||
|
|
||||||
_cls_term_event = pkNewClass(vm, "Event", NULL, term, _termEventNew, _termEventDelete);
|
|
||||||
pkClassAddMethod(vm, _cls_term_event, "@getter", _termEventGetter, 1);
|
|
||||||
|
|
||||||
pkRegisterModule(vm, term);
|
|
||||||
pkReleaseHandle(vm, term);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cleanupModuleTerm(PKVM* vm) {
|
|
||||||
if (_cls_term_event) pkReleaseHandle(vm, _cls_term_event);
|
|
||||||
}
|
|
@ -17,11 +17,6 @@ void registerModuleIO(PKVM* vm);
|
|||||||
void registerModulePath(PKVM* vm);
|
void registerModulePath(PKVM* vm);
|
||||||
void registerModuleDummy(PKVM* vm);
|
void registerModuleDummy(PKVM* vm);
|
||||||
|
|
||||||
// Additional libraries.
|
|
||||||
|
|
||||||
void registerModuleTerm(PKVM* vm);
|
|
||||||
void cleanupModuleTerm(PKVM* vm);
|
|
||||||
|
|
||||||
// Registers the modules.
|
// Registers the modules.
|
||||||
void registerLibs(PKVM* vm) {
|
void registerLibs(PKVM* vm) {
|
||||||
registerModuleMath(vm);
|
registerModuleMath(vm);
|
||||||
@ -30,11 +25,8 @@ void registerLibs(PKVM* vm) {
|
|||||||
registerModuleIO(vm);
|
registerModuleIO(vm);
|
||||||
registerModulePath(vm);
|
registerModulePath(vm);
|
||||||
registerModuleDummy(vm);
|
registerModuleDummy(vm);
|
||||||
|
|
||||||
registerModuleTerm(vm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup the modules.
|
// Cleanup the modules.
|
||||||
void cleanupLibs(PKVM* vm) {
|
void cleanupLibs(PKVM* vm) {
|
||||||
cleanupModuleTerm(vm);
|
|
||||||
}
|
}
|
||||||
|
21
src/libs/thirdparty/term/LICENSE
vendored
21
src/libs/thirdparty/term/LICENSE
vendored
@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2022 Thakee Nathees
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to
|
|
||||||
deal in the Software without restriction, including without limitation the
|
|
||||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
IN THE SOFTWARE.
|
|
1027
src/libs/thirdparty/term/term.h
vendored
1027
src/libs/thirdparty/term/term.h
vendored
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user