mirror of
https://github.com/zekexiao/pocketlang.git
synced 2025-02-05 20:26:53 +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
@ -2766,7 +2766,7 @@ static void compileTopLevelStatement(Compiler* compiler) {
|
||||
}
|
||||
|
||||
PkResult compile(PKVM* vm, Script* script, const char* source,
|
||||
const PkCompileOptions* options) {
|
||||
const PkCompileOptions* options) {
|
||||
|
||||
// Skip utf8 BOM if there is any.
|
||||
if (strncmp(source, "\xEF\xBB\xBF", 3) == 0) source += 3;
|
||||
@ -2781,10 +2781,14 @@ PkResult compile(PKVM* vm, Script* script, const char* source,
|
||||
compiler->next_compiler = vm->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
|
||||
// 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.
|
||||
ASSERT(script->body != NULL, OOPS);
|
||||
pkByteBufferClear(&script->body->fn->opcodes, vm);
|
||||
|
||||
// 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
|
||||
// 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.
|
||||
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).
|
||||
PkHandle* pkNewModule(PKVM* vm, const char* name) {
|
||||
Script* module = newModuleInternal(vm, name, false);
|
||||
Script* module = newModuleInternal(vm, name);
|
||||
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.
|
||||
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.
|
||||
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);
|
||||
}
|
||||
|
||||
Script* scr = newScript(vm, _name, is_core);
|
||||
Script* scr = newScript(vm, _name, true);
|
||||
vmPopTempRef(vm); // _name
|
||||
|
||||
// Add the script to core_libs.
|
||||
@ -1182,7 +1182,7 @@ void initializeCore(PKVM* vm) {
|
||||
|
||||
// Core Modules /////////////////////////////////////////////////////////////
|
||||
|
||||
Script* lang = newModuleInternal(vm, "lang", true);
|
||||
Script* lang = newModuleInternal(vm, "lang");
|
||||
MODULE_ADD_FN(lang, "clock", stdLangClock, 0);
|
||||
MODULE_ADD_FN(lang, "gc", stdLangGC, 0);
|
||||
MODULE_ADD_FN(lang, "disas", stdLangDisas, 1);
|
||||
@ -1191,7 +1191,7 @@ void initializeCore(PKVM* vm) {
|
||||
MODULE_ADD_FN(lang, "debug_break", stdLangDebugBreak, 0);
|
||||
#endif
|
||||
|
||||
Script* math = newModuleInternal(vm, "math", true);
|
||||
Script* math = newModuleInternal(vm, "math");
|
||||
MODULE_ADD_FN(math, "floor", stdMathFloor, 1);
|
||||
MODULE_ADD_FN(math, "ceil", stdMathCeil, 1);
|
||||
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.
|
||||
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, "run", stdFiberRun, -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->module = NULL;
|
||||
script->initialized = false;
|
||||
script->initialized = is_core;
|
||||
script->body = NULL;
|
||||
|
||||
// Core modules has its name as the module name, and since they don't have a
|
||||
// main function, they doesn't need an initialization.
|
||||
if (is_core) {
|
||||
script->module = name;
|
||||
script->initialized = true;
|
||||
}
|
||||
// Core modules has its name as the module name.
|
||||
if (is_core) script->module = name;
|
||||
|
||||
pkVarBufferInit(&script->globals);
|
||||
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 (!is_core) {
|
||||
vmPushTempRef(vm, &script->_super);
|
||||
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;
|
||||
scriptAddMain(vm, script);
|
||||
|
||||
// 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__.
|
||||
@ -1159,6 +1152,16 @@ uint32_t scriptAddGlobal(PKVM* vm, Script* script,
|
||||
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) {
|
||||
ASSERT(inst != 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.
|
||||
|
||||
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.
|
||||
@ -588,6 +592,12 @@ uint32_t scriptAddGlobal(PKVM* vm, Script* script,
|
||||
const char* name, uint32_t length,
|
||||
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
|
||||
// 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);
|
||||
|
Loading…
Reference in New Issue
Block a user