mirror of
https://github.com/zekexiao/pocketlang.git
synced 2025-02-06 04:37:47 +08:00
Fix: Main function of native modules were NULL (#161)
This is handled and the crash were fixed
This commit is contained in:
parent
c9ec704c13
commit
025ede86a4
@ -2781,10 +2781,14 @@ PkResult compile(PKVM* vm, Script* script, const char* source,
|
|||||||
compiler->next_compiler = vm->compiler;
|
compiler->next_compiler = vm->compiler;
|
||||||
vm->compiler = compiler;
|
vm->compiler = compiler;
|
||||||
|
|
||||||
|
// If the script doesn't has a body by default, it's probably was created by
|
||||||
|
// the native api function (pkNewModule() that'll return a module without a
|
||||||
|
// main function) so just create and add the function here.
|
||||||
|
if (script->body == NULL) scriptAddMain(vm, script);
|
||||||
|
|
||||||
// If we're compiling for a script that was already compiled (when running
|
// If we're compiling for a script that was already compiled (when running
|
||||||
// REPL or evaluating an expression) we don't need the old main anymore.
|
// REPL or evaluating an expression) we don't need the old main anymore.
|
||||||
// just use the globals and functions of the script and use a new body func.
|
// just use the globals and functions of the script and use a new body func.
|
||||||
ASSERT(script->body != NULL, OOPS);
|
|
||||||
pkByteBufferClear(&script->body->fn->opcodes, vm);
|
pkByteBufferClear(&script->body->fn->opcodes, vm);
|
||||||
|
|
||||||
// Remember the count of the globals, functions and types, If the compilation
|
// Remember the count of the globals, functions and types, If the compilation
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
// Create a new module with the given [name] and returns as a Script* for
|
// Create a new module with the given [name] and returns as a Script* for
|
||||||
// internal. Which will be wrapped by pkNewModule to return a pkHandle*.
|
// internal. Which will be wrapped by pkNewModule to return a pkHandle*.
|
||||||
static Script* newModuleInternal(PKVM* vm, const char* name, bool is_core);
|
static Script* newModuleInternal(PKVM* vm, const char* name);
|
||||||
|
|
||||||
// The internal function to add global value to a module.
|
// The internal function to add global value to a module.
|
||||||
static void moduleAddGlobalInternal(PKVM* vm, Script* script,
|
static void moduleAddGlobalInternal(PKVM* vm, Script* script,
|
||||||
@ -51,7 +51,7 @@ static void moduleAddFunctionInternal(PKVM* vm, Script* script,
|
|||||||
|
|
||||||
// pkNewModule implementation (see pocketlang.h for description).
|
// pkNewModule implementation (see pocketlang.h for description).
|
||||||
PkHandle* pkNewModule(PKVM* vm, const char* name) {
|
PkHandle* pkNewModule(PKVM* vm, const char* name) {
|
||||||
Script* module = newModuleInternal(vm, name, false);
|
Script* module = newModuleInternal(vm, name);
|
||||||
return vmNewHandle(vm, VAR_OBJ(module));
|
return vmNewHandle(vm, VAR_OBJ(module));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -743,7 +743,7 @@ DEF(coreMapRemove,
|
|||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
// Create a module and add it to the vm's core modules, returns the script.
|
// Create a module and add it to the vm's core modules, returns the script.
|
||||||
static Script* newModuleInternal(PKVM* vm, const char* name, bool is_core) {
|
static Script* newModuleInternal(PKVM* vm, const char* name) {
|
||||||
|
|
||||||
// Create a new Script for the module.
|
// Create a new Script for the module.
|
||||||
String* _name = newString(vm, name);
|
String* _name = newString(vm, name);
|
||||||
@ -757,7 +757,7 @@ static Script* newModuleInternal(PKVM* vm, const char* name, bool is_core) {
|
|||||||
"A module named '$' already exists", name)->data);
|
"A module named '$' already exists", name)->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
Script* scr = newScript(vm, _name, is_core);
|
Script* scr = newScript(vm, _name, true);
|
||||||
vmPopTempRef(vm); // _name
|
vmPopTempRef(vm); // _name
|
||||||
|
|
||||||
// Add the script to core_libs.
|
// Add the script to core_libs.
|
||||||
@ -1182,7 +1182,7 @@ void initializeCore(PKVM* vm) {
|
|||||||
|
|
||||||
// Core Modules /////////////////////////////////////////////////////////////
|
// Core Modules /////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Script* lang = newModuleInternal(vm, "lang", true);
|
Script* lang = newModuleInternal(vm, "lang");
|
||||||
MODULE_ADD_FN(lang, "clock", stdLangClock, 0);
|
MODULE_ADD_FN(lang, "clock", stdLangClock, 0);
|
||||||
MODULE_ADD_FN(lang, "gc", stdLangGC, 0);
|
MODULE_ADD_FN(lang, "gc", stdLangGC, 0);
|
||||||
MODULE_ADD_FN(lang, "disas", stdLangDisas, 1);
|
MODULE_ADD_FN(lang, "disas", stdLangDisas, 1);
|
||||||
@ -1191,7 +1191,7 @@ void initializeCore(PKVM* vm) {
|
|||||||
MODULE_ADD_FN(lang, "debug_break", stdLangDebugBreak, 0);
|
MODULE_ADD_FN(lang, "debug_break", stdLangDebugBreak, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Script* math = newModuleInternal(vm, "math", true);
|
Script* math = newModuleInternal(vm, "math");
|
||||||
MODULE_ADD_FN(math, "floor", stdMathFloor, 1);
|
MODULE_ADD_FN(math, "floor", stdMathFloor, 1);
|
||||||
MODULE_ADD_FN(math, "ceil", stdMathCeil, 1);
|
MODULE_ADD_FN(math, "ceil", stdMathCeil, 1);
|
||||||
MODULE_ADD_FN(math, "pow", stdMathPow, 2);
|
MODULE_ADD_FN(math, "pow", stdMathPow, 2);
|
||||||
@ -1218,7 +1218,7 @@ void initializeCore(PKVM* vm) {
|
|||||||
// attribute of a core module and we can throw an error.
|
// attribute of a core module and we can throw an error.
|
||||||
moduleAddGlobalInternal(vm, math, "PI", VAR_NUM(M_PI));
|
moduleAddGlobalInternal(vm, math, "PI", VAR_NUM(M_PI));
|
||||||
|
|
||||||
Script* fiber = newModuleInternal(vm, "Fiber", true);
|
Script* fiber = newModuleInternal(vm, "Fiber");
|
||||||
MODULE_ADD_FN(fiber, "new", stdFiberNew, 1);
|
MODULE_ADD_FN(fiber, "new", stdFiberNew, 1);
|
||||||
MODULE_ADD_FN(fiber, "run", stdFiberRun, -1);
|
MODULE_ADD_FN(fiber, "run", stdFiberRun, -1);
|
||||||
MODULE_ADD_FN(fiber, "resume", stdFiberResume, -1);
|
MODULE_ADD_FN(fiber, "resume", stdFiberResume, -1);
|
||||||
|
25
src/pk_var.c
25
src/pk_var.c
@ -375,15 +375,11 @@ Script* newScript(PKVM* vm, String* name, bool is_core) {
|
|||||||
|
|
||||||
script->path = name;
|
script->path = name;
|
||||||
script->module = NULL;
|
script->module = NULL;
|
||||||
script->initialized = false;
|
script->initialized = is_core;
|
||||||
script->body = NULL;
|
script->body = NULL;
|
||||||
|
|
||||||
// Core modules has its name as the module name, and since they don't have a
|
// Core modules has its name as the module name.
|
||||||
// main function, they doesn't need an initialization.
|
if (is_core) script->module = name;
|
||||||
if (is_core) {
|
|
||||||
script->module = name;
|
|
||||||
script->initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pkVarBufferInit(&script->globals);
|
pkVarBufferInit(&script->globals);
|
||||||
pkUintBufferInit(&script->global_names);
|
pkUintBufferInit(&script->global_names);
|
||||||
@ -396,10 +392,7 @@ Script* newScript(PKVM* vm, String* name, bool is_core) {
|
|||||||
// if it's not a core module.
|
// if it's not a core module.
|
||||||
if (!is_core) {
|
if (!is_core) {
|
||||||
vmPushTempRef(vm, &script->_super);
|
vmPushTempRef(vm, &script->_super);
|
||||||
const char* fn_name = PK_IMPLICIT_MAIN_NAME;
|
scriptAddMain(vm, script);
|
||||||
script->body = newFunction(vm, fn_name, (int)strlen(fn_name),
|
|
||||||
script, false, NULL/*TODO*/);
|
|
||||||
script->body->arity = 0;
|
|
||||||
|
|
||||||
// Add '__file__' variable with it's path as value. If the path starts with
|
// Add '__file__' variable with it's path as value. If the path starts with
|
||||||
// '$' It's a special file ($(REPL) or $(TRY)) and don't define __file__.
|
// '$' It's a special file ($(REPL) or $(TRY)) and don't define __file__.
|
||||||
@ -1159,6 +1152,16 @@ uint32_t scriptAddGlobal(PKVM* vm, Script* script,
|
|||||||
return script->globals.count - 1;
|
return script->globals.count - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scriptAddMain(PKVM* vm, Script* script) {
|
||||||
|
ASSERT(script->body == NULL, OOPS);
|
||||||
|
|
||||||
|
const char* fn_name = PK_IMPLICIT_MAIN_NAME;
|
||||||
|
script->body = newFunction(vm, fn_name, (int)strlen(fn_name),
|
||||||
|
script, false, NULL/*TODO*/);
|
||||||
|
script->body->arity = 0;
|
||||||
|
script->initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
bool instGetAttrib(PKVM* vm, Instance* inst, String* attrib, Var* value) {
|
bool instGetAttrib(PKVM* vm, Instance* inst, String* attrib, Var* value) {
|
||||||
ASSERT(inst != NULL, OOPS);
|
ASSERT(inst != NULL, OOPS);
|
||||||
ASSERT(attrib != NULL, OOPS);
|
ASSERT(attrib != NULL, OOPS);
|
||||||
|
12
src/pk_var.h
12
src/pk_var.h
@ -295,7 +295,11 @@ struct Script {
|
|||||||
pkVarBuffer literals; //< Script literal constant values.
|
pkVarBuffer literals; //< Script literal constant values.
|
||||||
|
|
||||||
Function* body; //< Script body is an anonymous function.
|
Function* body; //< Script body is an anonymous function.
|
||||||
bool initialized; //< Set to true just before the body executed.
|
|
||||||
|
// When a script has globals, it's body need to be executed to initialize the
|
||||||
|
// global values, this will be false if the module isn't initialized yet and
|
||||||
|
// we need to execute the script's body whe we're importing it.
|
||||||
|
bool initialized;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Script function pointer.
|
// Script function pointer.
|
||||||
@ -588,6 +592,12 @@ uint32_t scriptAddGlobal(PKVM* vm, Script* script,
|
|||||||
const char* name, uint32_t length,
|
const char* name, uint32_t length,
|
||||||
Var value);
|
Var value);
|
||||||
|
|
||||||
|
// This will allocate a new implicit main function for the script and assign to
|
||||||
|
// the script's body attribute. And the attribute initialized will be set to
|
||||||
|
// false for the new function. Note that the body of the script should be NULL
|
||||||
|
// before calling this function.
|
||||||
|
void scriptAddMain(PKVM* vm, Script* script);
|
||||||
|
|
||||||
// Get the attribut from the instance and set it [value]. On success return
|
// Get the attribut from the instance and set it [value]. On success return
|
||||||
// true, if the attribute not exists it'll return false but won't set an error.
|
// true, if the attribute not exists it'll return false but won't set an error.
|
||||||
bool instGetAttrib(PKVM* vm, Instance* inst, String* attrib, Var* value);
|
bool instGetAttrib(PKVM* vm, Instance* inst, String* attrib, Var* value);
|
||||||
|
Loading…
Reference in New Issue
Block a user