Another changes in file inclusion mechanism (#58):
All checks were successful
The build was successful.
All checks were successful
The build was successful.
* Remove builtin functions: 'include' & 'require' * Implement 'include' and 'require' statements compiler * Implement OP_INCLUDE operator * Allow 'require' statement to be used in global scope as well as in method body and 'include' only in method body
This commit is contained in:
94
engine/vm.c
94
engine/vm.c
@@ -3899,6 +3899,26 @@ static sxi32 VmByteCodeExec(
|
||||
pc = nJump - 1;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* OP_INCLUDE P1 * P3
|
||||
* Include another source file. If P1 is zero, 'include' statement was used, otherwise it was 'require'.
|
||||
* P3 contains a path to the source file.
|
||||
*/
|
||||
case PH7_OP_INCLUDE:
|
||||
{
|
||||
char *zFile = (char *) pInstr->p3;
|
||||
int iFlags = pInstr->iP1 ? PH7_AERSCRIPT_CODE : PH7_AERSCRIPT_CHNK;
|
||||
SyString sFile;
|
||||
if(SyStrlen(zFile) < 1) {
|
||||
break;
|
||||
}
|
||||
SyStringInitFromBuf(&sFile, zFile, SyStrlen(zFile));
|
||||
rc = VmExecIncludedFile(&(*pVm), &sFile, iFlags | PH7_AERSCRIPT_FILE);
|
||||
if(rc != SXRET_OK && rc != SXERR_EXISTS) {
|
||||
PH7_VmThrowError(pVm, PH7_CTX_ERR, "IO error while including file: '%z'", &sFile);
|
||||
}
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* OP_CLASS_INIT P1 P2 P3
|
||||
* Perform additional class initialization, by adding base classes
|
||||
@@ -5188,6 +5208,9 @@ static const char *VmInstrToString(sxi32 nOp) {
|
||||
case PH7_OP_HALT:
|
||||
zOp = "HALT";
|
||||
break;
|
||||
case PH7_OP_INCLUDE:
|
||||
zOp = "INCLUDE";
|
||||
break;
|
||||
case PH7_OP_DECLARE:
|
||||
zOp = "DECLARE";
|
||||
break;
|
||||
@@ -9228,75 +9251,6 @@ static int vm_builtin_get_included_files(ph7_context *pCtx, int nArg, ph7_value
|
||||
*/
|
||||
return PH7_OK;
|
||||
}
|
||||
/*
|
||||
* include:
|
||||
* The include() function includes and evaluates the specified file during
|
||||
* the execution of the script. Files are included based on the file path
|
||||
* given or, if none is given the include_path specified. If the file isn't
|
||||
* found in the include_path include() will finally check in the calling
|
||||
* script's own directory and the current working directory before failing.
|
||||
* The include() construct will emit a warning if it cannot find a file; this
|
||||
* is different behavior from require(), which will emit a fatal error. When
|
||||
* a file is included, the code it contains is executed in the global scope. If
|
||||
* the code from a file has already been included, it will not be included again.
|
||||
*/
|
||||
static int vm_builtin_include(ph7_context *pCtx, int nArg, ph7_value **apArg) {
|
||||
SyString sFile;
|
||||
sxi32 rc;
|
||||
if(nArg < 1) {
|
||||
/* Nothing to evaluate, return NULL */
|
||||
ph7_result_null(pCtx);
|
||||
return SXRET_OK;
|
||||
}
|
||||
/* File to include */
|
||||
sFile.zString = ph7_value_to_string(apArg[0], (int *)&sFile.nByte);
|
||||
if(sFile.nByte < 1) {
|
||||
/* Empty string, return NULL */
|
||||
ph7_result_null(pCtx);
|
||||
return SXRET_OK;
|
||||
}
|
||||
/* Open, compile and execute the desired script */
|
||||
rc = VmExecIncludedFile(&(*pCtx->pVm), &sFile, PH7_AERSCRIPT_CHNK | PH7_AERSCRIPT_FILE);
|
||||
if(rc != SXRET_OK) {
|
||||
/* Fatal, abort VM execution immediately */
|
||||
PH7_VmThrowError(pCtx->pVm, PH7_CTX_ERR, "IO error while including file: '%z'", &sFile);
|
||||
}
|
||||
return SXRET_OK;
|
||||
}
|
||||
/*
|
||||
* require.
|
||||
* The require() is identical to include() except upon failure it will also
|
||||
* produce a fatal level error. In other words, it will halt the script
|
||||
* whereas include() only emits a warning which allowsthe script to continue.
|
||||
*/
|
||||
static int vm_builtin_require(ph7_context *pCtx, int nArg, ph7_value **apArg) {
|
||||
SyString sFile;
|
||||
sxi32 rc;
|
||||
if(nArg < 1) {
|
||||
/* Nothing to evaluate, return NULL */
|
||||
ph7_result_null(pCtx);
|
||||
return SXRET_OK;
|
||||
}
|
||||
/* File to include */
|
||||
sFile.zString = ph7_value_to_string(apArg[0], (int *)&sFile.nByte);
|
||||
if(sFile.nByte < 1) {
|
||||
/* Empty string, return NULL */
|
||||
ph7_result_null(pCtx);
|
||||
return SXRET_OK;
|
||||
}
|
||||
/* Open,compile and execute the desired script */
|
||||
rc = VmExecIncludedFile(&(*pCtx->pVm), &sFile, PH7_AERSCRIPT_CODE | PH7_AERSCRIPT_FILE);
|
||||
if(rc == SXERR_EXISTS) {
|
||||
/* File already included, return TRUE */
|
||||
ph7_result_bool(pCtx, 1);
|
||||
return SXRET_OK;
|
||||
}
|
||||
if(rc != SXRET_OK) {
|
||||
/* Fatal, abort VM execution immediately */
|
||||
PH7_VmThrowError(pCtx->pVm, PH7_CTX_ERR, "IO error while including file: '%z'", &sFile);
|
||||
}
|
||||
return SXRET_OK;
|
||||
}
|
||||
/*
|
||||
* Section:
|
||||
* Command line arguments processing.
|
||||
@@ -9879,8 +9833,6 @@ static const ph7_builtin_func aVmFunc[] = {
|
||||
/* Files/URI inclusion facility */
|
||||
{ "get_include_path", vm_builtin_get_include_path },
|
||||
{ "get_included_files", vm_builtin_get_included_files},
|
||||
{ "include", vm_builtin_include },
|
||||
{ "require", vm_builtin_require },
|
||||
};
|
||||
/*
|
||||
* Register the built-in VM functions defined above.
|
||||
|
Reference in New Issue
Block a user