Reimplement import() builtin function as a global-scope statement. This fixes #58.
All checks were successful
The build was successful.
All checks were successful
The build was successful.
This commit is contained in:
123
engine/vm.c
123
engine/vm.c
@@ -3899,6 +3899,55 @@ static sxi32 VmByteCodeExec(
|
||||
pc = nJump - 1;
|
||||
break;
|
||||
}
|
||||
case PH7_OP_IMPORT:
|
||||
{
|
||||
VmModule pModule, *pSearch;
|
||||
char *zModule = (char *) pInstr->p3;
|
||||
int nLen = SyStrlen(zModule);
|
||||
if(nLen < 1) {
|
||||
break;
|
||||
}
|
||||
while(SySetGetNextEntry(&pVm->aModules, (void **)&pSearch) == SXRET_OK) {
|
||||
if(SyStrncmp(pSearch->sName.zString, zModule, (sxu32)(SXMAX((int) pSearch->sName.nByte, nLen))) == 0) {
|
||||
SySetResetCursor(&pVm->aModules);
|
||||
break;
|
||||
}
|
||||
}
|
||||
SySetResetCursor(&pVm->aModules);
|
||||
|
||||
/* Zero the module entry */
|
||||
SyZero(&pModule, sizeof(VmModule));
|
||||
SyStringInitFromBuf(&pModule.sName, zModule, nLen);
|
||||
char bfile[255] = {0};
|
||||
char *file;
|
||||
snprintf(bfile, sizeof(bfile) - 1, "./binary/%s%s", zModule, PH7_LIBRARY_SUFFIX);
|
||||
file = bfile;
|
||||
SyStringInitFromBuf(&pModule.sFile, file, nLen);
|
||||
#ifdef __WINNT__
|
||||
pModule.pHandle = LoadLibrary(file);
|
||||
#else
|
||||
pModule.pHandle = dlopen(pModule.sFile.zString, RTLD_LAZY);
|
||||
#endif
|
||||
if(!pModule.pHandle) {
|
||||
/* Could not load the module library file */
|
||||
PH7_VmThrowError(pVm, PH7_CTX_ERR, "ImportError: No module named '%z' found", &pModule.sName);
|
||||
}
|
||||
void (*init)(ph7_vm *, ph7_real *, SyString *);
|
||||
#ifdef __WINNT__
|
||||
*(void**)(&init) = GetProcAddress(pModule.pHandle, "initializeModule");
|
||||
#else
|
||||
*(void**)(&init) = dlsym(pModule.pHandle, "initializeModule");
|
||||
#endif
|
||||
if(!init) {
|
||||
PH7_VmThrowError(pVm, PH7_CTX_ERR, "ImportError: Method '%z::initializeModule()' not found", &pModule.sName);
|
||||
/* Could not find the module entry point */
|
||||
}
|
||||
/* Initialize the module */
|
||||
init(pVm, &pModule.fVer, &pModule.sDesc);
|
||||
/* Put information about module on top of the modules stack */
|
||||
SySetPut(&pVm->aModules, (const void *)&pModule);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* OP_INCLUDE P1 * P3
|
||||
* Include another source file. If P1 is zero, 'include' statement was used, otherwise it was 'require'.
|
||||
@@ -5208,6 +5257,9 @@ static const char *VmInstrToString(sxi32 nOp) {
|
||||
case PH7_OP_HALT:
|
||||
zOp = "HALT";
|
||||
break;
|
||||
case PH7_OP_IMPORT:
|
||||
zOp = "IMPORT";
|
||||
break;
|
||||
case PH7_OP_INCLUDE:
|
||||
zOp = "INCLUDE";
|
||||
break;
|
||||
@@ -9108,75 +9160,6 @@ static sxi32 VmExecIncludedFile(
|
||||
SyBlobRelease(&sContents);
|
||||
return rc;
|
||||
}
|
||||
/*
|
||||
* bool import(string $library)
|
||||
* Loads an AerScript module library at runtime
|
||||
* Parameters
|
||||
* $library
|
||||
* This parameter is only the module library name that should be loaded.
|
||||
* Return
|
||||
* Returns TRUE on success or FALSE on failure
|
||||
*/
|
||||
static int vm_builtin_import(ph7_context *pCtx, int nArg, ph7_value **apArg) {
|
||||
const char *zStr;
|
||||
VmModule pModule, *pSearch;
|
||||
int nLen;
|
||||
if(nArg != 1 || !ph7_value_is_string(apArg[0])) {
|
||||
/* Missing/Invalid arguments, return FALSE */
|
||||
ph7_result_bool(pCtx, 0);
|
||||
return PH7_OK;
|
||||
}
|
||||
/* Extract the given module name */
|
||||
zStr = ph7_value_to_string(apArg[0], &nLen);
|
||||
if(nLen < 1) {
|
||||
/* Nothing to process, return FALSE */
|
||||
ph7_result_bool(pCtx, 0);
|
||||
return PH7_OK;
|
||||
}
|
||||
while(SySetGetNextEntry(&pCtx->pVm->aModules, (void **)&pSearch) == SXRET_OK) {
|
||||
if(SyStrncmp(pSearch->sName.zString, zStr, (sxu32)(SXMAX((int) pSearch->sName.nByte, nLen))) == 0) {
|
||||
SySetResetCursor(&pCtx->pVm->aModules);
|
||||
ph7_result_bool(pCtx, 1);
|
||||
return PH7_OK;
|
||||
}
|
||||
}
|
||||
SySetResetCursor(&pCtx->pVm->aModules);
|
||||
/* Zero the module entry */
|
||||
SyZero(&pModule, sizeof(VmModule));
|
||||
SyStringInitFromBuf(&pModule.sName, zStr, nLen);
|
||||
char bfile[255] = {0};
|
||||
char *file;
|
||||
snprintf(bfile, sizeof(bfile) - 1, "./binary/%s%s", zStr, PH7_LIBRARY_SUFFIX);
|
||||
file = bfile;
|
||||
SyStringInitFromBuf(&pModule.sFile, file, nLen);
|
||||
#ifdef __WINNT__
|
||||
pModule.pHandle = LoadLibrary(file);
|
||||
#else
|
||||
pModule.pHandle = dlopen(pModule.sFile.zString, RTLD_LAZY);
|
||||
#endif
|
||||
if(!pModule.pHandle) {
|
||||
/* Could not load the module library file */
|
||||
ph7_result_bool(pCtx, 0);
|
||||
return PH7_OK;
|
||||
}
|
||||
void (*init)(ph7_vm *, ph7_real *, SyString *);
|
||||
#ifdef __WINNT__
|
||||
*(void**)(&init) = GetProcAddress(pModule.pHandle, "initializeModule");
|
||||
#else
|
||||
*(void**)(&init) = dlsym(pModule.pHandle, "initializeModule");
|
||||
#endif
|
||||
if(!init) {
|
||||
/* Could not find the module entry point */
|
||||
ph7_result_bool(pCtx, 0);
|
||||
return PH7_OK;
|
||||
}
|
||||
/* Initialize the module */
|
||||
init(pCtx->pVm, &pModule.fVer, &pModule.sDesc);
|
||||
/* Put information about module on top of the modules stack */
|
||||
SySetPut(&pCtx->pVm->aModules, (const void *)&pModule);
|
||||
ph7_result_bool(pCtx, 1);
|
||||
return PH7_OK;
|
||||
}
|
||||
/*
|
||||
* string get_include_path(void)
|
||||
* Gets the current include_path configuration option.
|
||||
@@ -9828,8 +9811,6 @@ static const ph7_builtin_func aVmFunc[] = {
|
||||
{"utf8_decode", vm_builtin_utf8_decode},
|
||||
/* Command line processing */
|
||||
{"getopt", vm_builtin_getopt },
|
||||
/* Module loading facility */
|
||||
{ "import", vm_builtin_import },
|
||||
/* Files/URI inclusion facility */
|
||||
{ "get_include_path", vm_builtin_get_include_path },
|
||||
{ "get_included_files", vm_builtin_get_included_files},
|
||||
|
Reference in New Issue
Block a user