Fix: Main function of native modules were NULL (#161)

This is handled and the crash were fixed
This commit is contained in:
Thakee Nathees 2021-07-03 21:54:36 +05:30 committed by GitHub
parent c9ec704c13
commit 025ede86a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 21 deletions

View File

@ -2766,7 +2766,7 @@ static void compileTopLevelStatement(Compiler* compiler) {
} }
PkResult compile(PKVM* vm, Script* script, const char* source, PkResult compile(PKVM* vm, Script* script, const char* source,
const PkCompileOptions* options) { const PkCompileOptions* options) {
// Skip utf8 BOM if there is any. // Skip utf8 BOM if there is any.
if (strncmp(source, "\xEF\xBB\xBF", 3) == 0) source += 3; 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; 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

View File

@ -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);

View File

@ -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);

View File

@ -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);