Merge branch 'compiler_rework' into master
The build was successful. Details

This commit is contained in:
Rafal Kupiec 2018-08-16 21:28:49 +02:00 committed by Gitea
commit 03a5b7e397
21 changed files with 1248 additions and 1311 deletions

View File

@ -456,13 +456,6 @@ const char *ph7_lib_version(void) {
const char *ph7_lib_signature(void) {
return PH7_SIG;
}
/*
* [CAPIREF: ph7_lib_ident()]
* Please refer to the official documentation for function purpose and expected parameters.
*/
const char *ph7_lib_ident(void) {
return PH7_IDENT;
}
/*
* [CAPIREF: ph7_lib_copyright()]
* Please refer to the official documentation for function purpose and expected parameters.
@ -652,21 +645,16 @@ int ph7_vm_init(
* This API does not actually evaluate the PHP code. It merely compile and prepares the PHP script
* for evaluation.
*/
static sxi32 ProcessScript(
static sxi32 ProcessSourceFile(
ph7 *pEngine, /* Running PH7 engine */
ph7_vm **ppVm, /* OUT: A pointer to the virtual machine */
SyString *pScript, /* Raw PHP script to compile */
sxi32 iFlags, /* Compile-time flags */
const char *zFilePath /* File path if script come from a file. NULL otherwise */
) {
ph7_vm *pVm = *ppVm;
int iFileDir, rc;
char *pFileDir, *fFilePath[PATH_MAX + 1];
char *pFilePath[PATH_MAX + 1];
if(iFlags < 0) {
/* Default compile-time flags */
iFlags = 0;
}
/* Install local import path which is the current directory */
ph7_vm_config(pVm, PH7_VM_CONFIG_IMPORT_PATH, "./");
if(zFilePath && SyRealPath(zFilePath, fFilePath) == PH7_OK) {
@ -680,7 +668,7 @@ static sxi32 ProcessScript(
PH7_VmPushFilePath(pVm, pFilePath, -1, TRUE, 0);
}
/* Compile the script */
PH7_CompileScript(pVm, &(*pScript), iFlags);
PH7_CompileAerScript(pVm, &(*pScript), PH7_AERSCRIPT_CODE);
if(pVm->sCodeGen.nErr > 0 || pVm == 0) {
sxu32 nErr = pVm->sCodeGen.nErr;
/* Compilation error or null ppVm pointer,release this VM */
@ -720,7 +708,7 @@ Release:
* [CAPIREF: ph7_compile()]
* Please refer to the official documentation for function purpose and expected parameters.
*/
int ph7_compile(ph7 *pEngine, const char *zSource, int nLen, ph7_vm **ppOutVm) {
int ph7_compile_code(ph7 *pEngine, const char *zSource, int nLen, ph7_vm **ppOutVm) {
SyString sScript;
int rc;
if(PH7_ENGINE_MISUSE(pEngine) || zSource == 0) {
@ -740,39 +728,7 @@ int ph7_compile(ph7 *pEngine, const char *zSource, int nLen, ph7_vm **ppOutVm) {
}
#endif
/* Compile the script */
rc = ProcessScript(&(*pEngine), ppOutVm, &sScript, 0, 0);
#if defined(PH7_ENABLE_THREADS)
/* Leave engine mutex */
SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */
#endif
/* Compilation result */
return rc;
}
/*
* [CAPIREF: ph7_compile_v2()]
* Please refer to the official documentation for function purpose and expected parameters.
*/
int ph7_compile_v2(ph7 *pEngine, const char *zSource, int nLen, ph7_vm **ppOutVm, int iFlags) {
SyString sScript;
int rc;
if(PH7_ENGINE_MISUSE(pEngine) || zSource == 0) {
return PH7_CORRUPT;
}
if(nLen < 0) {
/* Compute input length automatically */
nLen = (int)SyStrlen(zSource);
}
SyStringInitFromBuf(&sScript, zSource, nLen);
#if defined(PH7_ENABLE_THREADS)
/* Acquire engine mutex */
SyMutexEnter(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */
if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE &&
PH7_THRD_ENGINE_RELEASE(pEngine)) {
return PH7_ABORT; /* Another thread have released this instance */
}
#endif
/* Compile the script */
rc = ProcessScript(&(*pEngine), ppOutVm, &sScript, iFlags, 0);
rc = ProcessSourceFile(&(*pEngine), ppOutVm, &sScript, 0);
#if defined(PH7_ENABLE_THREADS)
/* Leave engine mutex */
SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */
@ -784,7 +740,7 @@ int ph7_compile_v2(ph7 *pEngine, const char *zSource, int nLen, ph7_vm **ppOutVm
* [CAPIREF: ph7_compile_file()]
* Please refer to the official documentation for function purpose and expected parameters.
*/
int ph7_compile_file(ph7 *pEngine, const char *zFilePath, ph7_vm **ppOutVm, int iFlags) {
int ph7_compile_file(ph7 *pEngine, const char *zFilePath, ph7_vm **ppOutVm) {
const ph7_vfs *pVfs;
int rc;
rc = PH7_OK; /* cc warning */
@ -819,7 +775,7 @@ int ph7_compile_file(ph7 *pEngine, const char *zFilePath, ph7_vm **ppOutVm, int
} else {
/* Compile the file */
SyStringInitFromBuf(&sScript, pMapView, nSize);
rc = ProcessScript(&(*pEngine), ppOutVm, &sScript, iFlags, zFilePath);
rc = ProcessSourceFile(&(*pEngine), ppOutVm, &sScript, zFilePath);
/* Release the memory view of the whole file */
if(pVfs->xUnmap) {
pVfs->xUnmap(pMapView, nSize);

File diff suppressed because it is too large Load Diff

View File

@ -83,7 +83,7 @@ static sxi32 TokenizePHP(SyStream *pStream, SyToken *pToken, void *pUserData, vo
nKeyword = KeywordCode(pStr->zString, (int)pStr->nByte);
if(nKeyword != PH7_TK_ID) {
if(nKeyword &
(PH7_TKWRD_NEW | PH7_TKWRD_CLONE | PH7_TKWRD_INSTANCEOF)) {
(PH7_KEYWORD_NEW | PH7_KEYWORD_CLONE | PH7_KEYWORD_INSTANCEOF)) {
/* Alpha stream operators [i.e: new,clone,instanceof],save the operator instance for later processing */
pToken->pUserData = (void *)PH7_ExprExtractOperator(pStr, 0);
/* Mark as an operator */
@ -225,22 +225,22 @@ static sxi32 TokenizePHP(SyStream *pStream, SyToken *pToken, void *pUserData, vo
pTmp = (SyToken *)SySetPeek(pTokSet);
if(pTmp->nType & PH7_TK_KEYWORD) {
sxi32 nID = SX_PTR_TO_INT(pTmp->pUserData);
if((sxu32)nID & (PH7_TKWRD_ARRAY | PH7_TKWRD_INT | PH7_TKWRD_FLOAT | PH7_TKWRD_STRING | PH7_TKWRD_OBJECT | PH7_TKWRD_BOOL | PH7_TKWRD_UNSET)) {
if((sxu32)nID & (PH7_KEYWORD_ARRAY | PH7_KEYWORD_INT | PH7_KEYWORD_FLOAT | PH7_KEYWORD_STRING | PH7_KEYWORD_OBJECT | PH7_KEYWORD_BOOL | PH7_KEYWORD_UNSET)) {
pTmp = (SyToken *)SySetAt(pTokSet, pTokSet->nUsed - 2);
if(pTmp->nType & PH7_TK_LPAREN) {
/* Merge the three tokens '(' 'TYPE' ')' into a single one */
const char *zTypeCast = "(int)";
if(nID & PH7_TKWRD_FLOAT) {
if(nID & PH7_KEYWORD_FLOAT) {
zTypeCast = "(float)";
} else if(nID & PH7_TKWRD_BOOL) {
} else if(nID & PH7_KEYWORD_BOOL) {
zTypeCast = "(bool)";
} else if(nID & PH7_TKWRD_STRING) {
} else if(nID & PH7_KEYWORD_STRING) {
zTypeCast = "(string)";
} else if(nID & PH7_TKWRD_ARRAY) {
} else if(nID & PH7_KEYWORD_ARRAY) {
zTypeCast = "(array)";
} else if(nID & PH7_TKWRD_OBJECT) {
} else if(nID & PH7_KEYWORD_OBJECT) {
zTypeCast = "(object)";
} else if(nID & PH7_TKWRD_UNSET) {
} else if(nID & PH7_KEYWORD_UNSET) {
zTypeCast = "(unset)";
}
/* Reflect the change */
@ -573,59 +573,59 @@ static sxu32 KeywordCode(const char *z, int n) {
int value;
} ph7_token;
static ph7_token pTokenLookup[] = {
{"extends", PH7_TKWRD_EXTENDS},
{"switch", PH7_TKWRD_SWITCH},
{"int", PH7_TKWRD_INT},
{"require_once", PH7_TKWRD_REQONCE},
{"require", PH7_TKWRD_REQUIRE},
{"return", PH7_TKWRD_RETURN},
{"namespace", PH7_TKWRD_NAMESPACE},
{"object", PH7_TKWRD_OBJECT},
{"throw", PH7_TKWRD_THROW},
{"bool", PH7_TKWRD_BOOL},
{"default", PH7_TKWRD_DEFAULT},
{"try", PH7_TKWRD_TRY},
{"case", PH7_TKWRD_CASE},
{"self", PH7_TKWRD_SELF},
{"final", PH7_TKWRD_FINAL},
{"list", PH7_TKWRD_LIST},
{"static", PH7_TKWRD_STATIC},
{"clone", PH7_TKWRD_CLONE},
{"new", PH7_TKWRD_NEW},
{"const", PH7_TKWRD_CONST},
{"string", PH7_TKWRD_STRING},
{"using", PH7_TKWRD_USING},
{"elseif", PH7_TKWRD_ELIF},
{"else", PH7_TKWRD_ELSE},
{"if", PH7_TKWRD_IF},
{"float", PH7_TKWRD_FLOAT},
{"var", PH7_TKWRD_VAR},
{"array", PH7_TKWRD_ARRAY},
{"virtual", PH7_TKWRD_VIRTUAL},
{"class", PH7_TKWRD_CLASS},
{"as", PH7_TKWRD_AS},
{"continue", PH7_TKWRD_CONTINUE},
{"function", PH7_TKWRD_FUNCTION},
{"while", PH7_TKWRD_WHILE},
{"eval", PH7_TKWRD_EVAL},
{"do", PH7_TKWRD_DO},
{"exit", PH7_TKWRD_EXIT},
{"implements", PH7_TKWRD_IMPLEMENTS},
{"include_once", PH7_TKWRD_INCONCE},
{"include", PH7_TKWRD_INCLUDE},
{"empty", PH7_TKWRD_EMPTY},
{"instanceof", PH7_TKWRD_INSTANCEOF},
{"interface", PH7_TKWRD_INTERFACE},
{"for", PH7_TKWRD_FOR},
{"foreach", PH7_TKWRD_FOREACH},
{"isset", PH7_TKWRD_ISSET},
{"parent", PH7_TKWRD_PARENT},
{"private", PH7_TKWRD_PRIVATE},
{"protected", PH7_TKWRD_PROTECTED},
{"public", PH7_TKWRD_PUBLIC},
{"catch", PH7_TKWRD_CATCH},
{"unset", PH7_TKWRD_UNSET},
{"break", PH7_TKWRD_BREAK}
{"extends", PH7_KEYWORD_EXTENDS},
{"switch", PH7_KEYWORD_SWITCH},
{"int", PH7_KEYWORD_INT},
{"require", PH7_KEYWORD_REQUIRE},
{"return", PH7_KEYWORD_RETURN},
{"namespace", PH7_KEYWORD_NAMESPACE},
{"object", PH7_KEYWORD_OBJECT},
{"throw", PH7_KEYWORD_THROW},
{"bool", PH7_KEYWORD_BOOL},
{"default", PH7_KEYWORD_DEFAULT},
{"try", PH7_KEYWORD_TRY},
{"case", PH7_KEYWORD_CASE},
{"self", PH7_KEYWORD_SELF},
{"final", PH7_KEYWORD_FINAL},
{"finally", PH7_KEYWORD_FINALLY},
{"list", PH7_KEYWORD_LIST},
{"static", PH7_KEYWORD_STATIC},
{"clone", PH7_KEYWORD_CLONE},
{"new", PH7_KEYWORD_NEW},
{"const", PH7_KEYWORD_CONST},
{"string", PH7_KEYWORD_STRING},
{"using", PH7_KEYWORD_USING},
{"elseif", PH7_KEYWORD_ELIF},
{"else", PH7_KEYWORD_ELSE},
{"if", PH7_KEYWORD_IF},
{"float", PH7_KEYWORD_FLOAT},
{"var", PH7_KEYWORD_VAR},
{"array", PH7_KEYWORD_ARRAY},
{"virtual", PH7_KEYWORD_VIRTUAL},
{"class", PH7_KEYWORD_CLASS},
{"as", PH7_KEYWORD_AS},
{"continue", PH7_KEYWORD_CONTINUE},
{"function", PH7_KEYWORD_FUNCTION},
{"while", PH7_KEYWORD_WHILE},
{"eval", PH7_KEYWORD_EVAL},
{"do", PH7_KEYWORD_DO},
{"exit", PH7_KEYWORD_EXIT},
{"import", PH7_KEYWORD_IMPORT},
{"implements", PH7_KEYWORD_IMPLEMENTS},
{"include", PH7_KEYWORD_INCLUDE},
{"empty", PH7_KEYWORD_EMPTY},
{"instanceof", PH7_KEYWORD_INSTANCEOF},
{"interface", PH7_KEYWORD_INTERFACE},
{"for", PH7_KEYWORD_FOR},
{"foreach", PH7_KEYWORD_FOREACH},
{"isset", PH7_KEYWORD_ISSET},
{"parent", PH7_KEYWORD_PARENT},
{"private", PH7_KEYWORD_PRIVATE},
{"protected", PH7_KEYWORD_PROTECTED},
{"public", PH7_KEYWORD_PUBLIC},
{"catch", PH7_KEYWORD_CATCH},
{"unset", PH7_KEYWORD_UNSET},
{"break", PH7_KEYWORD_BREAK}
};
if(n < 2) {
return PH7_TK_ID;
@ -642,7 +642,7 @@ static sxu32 KeywordCode(const char *z, int n) {
* Tokenize a raw PHP input.
* This is the public tokenizer called by most code generator routines.
*/
PH7_PRIVATE sxi32 PH7_TokenizePHP(const char *zInput, sxu32 nLen, sxu32 nLineStart, SySet *pOut) {
PH7_PRIVATE sxi32 PH7_TokenizeAerScript(const char *zInput, sxu32 nLen, sxu32 nLineStart, SySet *pOut) {
SyLex sLexer;
sxi32 rc;
/* Initialize the lexer */

View File

@ -317,31 +317,6 @@ PH7_PRIVATE void PH7_DelimitNestedTokens(SyToken *pIn, SyToken *pEnd, sxu32 nTok
/* Point to the end of the chunk */
*ppEnd = pCur;
}
/*
* Return TRUE if the given ID represent a language construct [i.e: print,echo..]. FALSE otherwise.
* Note on reserved keywords.
* According to the PHP language reference manual:
* These words have special meaning in PHP. Some of them represent things which look like
* functions, some look like constants, and so on--but they're not, really: they are language
* constructs. You cannot use any of the following words as constants, class names, function
* or method names. Using them as variable names is generally OK, but could lead to confusion.
*/
PH7_PRIVATE int PH7_IsLangConstruct(sxu32 nKeyID, sxu8 bCheckFunc) {
if(nKeyID == PH7_TKWRD_INCLUDE || nKeyID == PH7_TKWRD_INCONCE
|| nKeyID == PH7_TKWRD_REQUIRE || nKeyID == PH7_TKWRD_REQONCE
) {
return TRUE;
}
if(bCheckFunc) {
if(nKeyID == PH7_TKWRD_ISSET || nKeyID == PH7_TKWRD_UNSET || nKeyID == PH7_TKWRD_EVAL
|| nKeyID == PH7_TKWRD_EMPTY || nKeyID == PH7_TKWRD_ARRAY || nKeyID == PH7_TKWRD_LIST
|| /* TICKET 1433-012 */ nKeyID == PH7_TKWRD_NEW || nKeyID == PH7_TKWRD_CLONE) {
return TRUE;
}
}
/* Not a language construct */
return FALSE;
}
/*
* Make sure we are dealing with a valid expression tree.
* This function check for balanced parenthesis,braces,brackets and so on.
@ -515,18 +490,16 @@ static void ExprAssembleLiteral(SyToken **ppCur, SyToken *pEnd) {
*ppCur = pIn;
}
/*
* Collect and assemble tokens holding anonymous functions/closure body.
* Collect and assemble tokens holding closure body.
* When errors,PH7 take care of generating the appropriate error message.
* Note on anonymous functions.
* According to the PHP language reference manual:
* Anonymous functions, also known as closures, allow the creation of functions
* which have no specified name. They are most useful as the value of callback
* parameters, but they have many other uses.
* Closures may also inherit variables from the parent scope. Any such variables
* must be declared in the function header. Inheriting variables from the parent
* scope is not the same as using global variables. Global variables exist in the global scope
* which is the same no matter what function is executing. The parent scope of a closure is the
* function in which the closure was declared (not necessarily the function it was called from).
* Anonymous functions, also known as closures, allow the creation of functions
* which have no specified name. They are most useful as the value of callback
* parameters, but they have many other uses.
* Closures may also inherit variables from the parent scope. Any such variables
* must be declared in the function header. Inheriting variables from the parent
* scope is not the same as using global variables. Global variables exist in the global scope
* which is the same no matter what function is executing. The parent scope of a closure is the
* function in which the closure was declared (not necessarily the function it was called from).
*
* Some example:
* $greet = function($name)
@ -534,7 +507,7 @@ static void ExprAssembleLiteral(SyToken **ppCur, SyToken *pEnd) {
* printf("Hello %s\r\n", $name);
* };
* $greet('World');
* $greet('PHP');
* $greet('AerScript');
*
* $double = function($a) {
* return $a * 2;
@ -545,9 +518,9 @@ static void ExprAssembleLiteral(SyToken **ppCur, SyToken *pEnd) {
* // double the size of each element in our
* // range
* $new_numbers = array_map($double, $numbers);
* print implode(' ', $new_numbers);
* print(implode(' ', $new_numbers));
*/
static sxi32 ExprAssembleAnnon(ph7_gen_state *pGen, SyToken **ppCur, SyToken *pEnd) {
static sxi32 ExprAssembleClosure(ph7_gen_state *pGen, SyToken **ppCur, SyToken *pEnd) {
SyToken *pIn = *ppCur;
sxu32 nLine;
sxi32 rc;
@ -579,7 +552,7 @@ static sxi32 ExprAssembleAnnon(ph7_gen_state *pGen, SyToken **ppCur, SyToken *pE
if(pIn->nType & PH7_TK_KEYWORD) {
sxu32 nKey = SX_PTR_TO_INT(pIn->pUserData);
/* Check if we are dealing with a closure */
if(nKey == PH7_TKWRD_USING) {
if(nKey == PH7_KEYWORD_USING) {
pIn++; /* Jump the 'using' keyword */
if(pIn >= pEnd || (pIn->nType & PH7_TK_LPAREN) == 0) {
/* Syntax error */
@ -688,7 +661,7 @@ static sxi32 ExprExtractNode(ph7_gen_state *pGen, ph7_expr_node **ppNode) {
pNode->xCode = PH7_CompileVariable;
} else if(pCur->nType & PH7_TK_KEYWORD) {
sxu32 nKeyword = (sxu32)SX_PTR_TO_INT(pCur->pUserData);
if(nKeyword == PH7_TKWRD_ARRAY || nKeyword == PH7_TKWRD_LIST) {
if(nKeyword == PH7_KEYWORD_ARRAY || nKeyword == PH7_KEYWORD_LIST) {
/* List/Array node */
if(&pCur[1] >= pGen->pEnd || (pCur[1].nType & PH7_TK_LPAREN) == 0) {
/* Assume a literal */
@ -703,14 +676,14 @@ static sxi32 ExprExtractNode(ph7_gen_state *pGen, ph7_expr_node **ppNode) {
} else {
/* Syntax error */
rc = PH7_GenCompileError(pGen, E_ERROR, pNode->pStart->nLine,
"%s: Missing closing parenthesis ')'", nKeyword == PH7_TKWRD_LIST ? "list" : "array");
"%s: Missing closing parenthesis ')'", nKeyword == PH7_KEYWORD_LIST ? "list" : "array");
if(rc != SXERR_ABORT) {
rc = SXERR_SYNTAX;
}
SyMemBackendPoolFree(&pGen->pVm->sAllocator, pNode);
return rc;
}
pNode->xCode = (nKeyword == PH7_TKWRD_LIST) ? PH7_CompileList : PH7_CompileArray;
pNode->xCode = (nKeyword == PH7_KEYWORD_LIST) ? PH7_CompileList : PH7_CompileArray;
if(pNode->xCode == PH7_CompileList) {
ph7_expr_op *pOp = (pCur < pGen->pEnd) ? (ph7_expr_op *)pCur->pUserData : 0;
if(pCur >= pGen->pEnd || (pCur->nType & PH7_TK_OP) == 0 || pOp == 0 || pOp->iVmOp != PH7_OP_STORE /*'='*/) {
@ -724,7 +697,7 @@ static sxi32 ExprExtractNode(ph7_gen_state *pGen, ph7_expr_node **ppNode) {
}
}
}
} else if(nKeyword == PH7_TKWRD_FUNCTION) {
} else if(nKeyword == PH7_KEYWORD_FUNCTION) {
/* Anonymous function */
if(&pCur[1] >= pGen->pEnd) {
/* Assume a literal */
@ -732,17 +705,13 @@ static sxi32 ExprExtractNode(ph7_gen_state *pGen, ph7_expr_node **ppNode) {
pNode->xCode = PH7_CompileLiteral;
} else {
/* Assemble anonymous functions body */
rc = ExprAssembleAnnon(&(*pGen), &pCur, pGen->pEnd);
rc = ExprAssembleClosure(&(*pGen), &pCur, pGen->pEnd);
if(rc != SXRET_OK) {
SyMemBackendPoolFree(&pGen->pVm->sAllocator, pNode);
return rc;
}
pNode->xCode = PH7_CompileAnnonFunc;
pNode->xCode = PH7_CompileClosure;
}
} else if(PH7_IsLangConstruct(nKeyword, FALSE) == TRUE && &pCur[1] < pGen->pEnd) {
/* Language constructs [i.e: print,echo,die...] require special handling */
PH7_DelimitNestedTokens(pCur, pGen->pEnd, PH7_TK_LPAREN | PH7_TK_OCB | PH7_TK_OSB, PH7_TK_RPAREN | PH7_TK_CCB | PH7_TK_CSB, &pCur);
pNode->xCode = PH7_CompileLangConstruct;
} else {
/* Assume a literal */
ExprAssembleLiteral(&pCur, pGen->pEnd);

View File

@ -78,7 +78,7 @@ static int PH7_vfs_chdir(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xChdir == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -115,7 +115,7 @@ static int PH7_vfs_chroot(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xChroot == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -147,7 +147,7 @@ static int PH7_vfs_getcwd(ph7_context *pCtx, int nArg, ph7_value **apArg) {
SXUNUSED(apArg);
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -185,7 +185,7 @@ static int PH7_vfs_rmdir(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xRmdir == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -222,7 +222,7 @@ static int PH7_vfs_is_dir(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xIsdir == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -270,7 +270,7 @@ static int PH7_vfs_mkdir(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xMkdir == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -321,7 +321,7 @@ static int PH7_vfs_rename(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xRename == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -358,7 +358,7 @@ static int PH7_vfs_realpath(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xRealpath == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -396,7 +396,7 @@ static int PH7_vfs_sleep(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xSleep == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -479,7 +479,7 @@ static int PH7_vfs_unlink(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xUnlink == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -519,7 +519,7 @@ static int PH7_vfs_chmod(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xChmod == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -560,7 +560,7 @@ static int PH7_vfs_chown(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xChown == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -601,7 +601,7 @@ static int PH7_vfs_chgrp(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xChgrp == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -640,7 +640,7 @@ static int PH7_vfs_disk_free_space(ph7_context *pCtx, int nArg, ph7_value **apAr
if(pVfs == 0 || pVfs->xFreeSpace == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -677,7 +677,7 @@ static int PH7_vfs_disk_total_space(ph7_context *pCtx, int nArg, ph7_value **apA
if(pVfs == 0 || pVfs->xTotalSpace == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -714,7 +714,7 @@ static int PH7_vfs_file_exists(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xFileExists == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -751,7 +751,7 @@ static int PH7_vfs_file_size(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xFileSize == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -788,7 +788,7 @@ static int PH7_vfs_file_atime(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xFileAtime == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -825,7 +825,7 @@ static int PH7_vfs_file_mtime(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xFileMtime == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -862,7 +862,7 @@ static int PH7_vfs_file_ctime(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xFileCtime == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -876,6 +876,117 @@ static int PH7_vfs_file_ctime(ph7_context *pCtx, int nArg, ph7_value **apArg) {
ph7_result_int64(pCtx, iTime);
return PH7_OK;
}
/*
* int64 filegroup(string $filename)
* Gets the file group.
* Parameters
* $filename
* Path to the file.
* Return
* The group ID of the file or FALSE on failure.
*/
static int PH7_vfs_file_group(ph7_context *pCtx, int nArg, ph7_value **apArg) {
const char *zPath;
ph7_int64 iGroup;
ph7_vfs *pVfs;
if(nArg < 1 || !ph7_value_is_string(apArg[0])) {
/* Missing/Invalid argument,return FALSE */
ph7_result_bool(pCtx, 0);
return PH7_OK;
}
/* Point to the underlying vfs */
pVfs = (ph7_vfs *)ph7_context_user_data(pCtx);
if(pVfs == 0 || pVfs->xFileCtime == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
return PH7_OK;
}
/* Point to the desired directory */
zPath = ph7_value_to_string(apArg[0], 0);
/* Perform the requested operation */
iGroup = pVfs->xFileGroup(zPath);
/* IO return value */
ph7_result_int64(pCtx, iGroup);
return PH7_OK;
}
/*
* int64 fileinode(string $filename)
* Gets the file inode.
* Parameters
* $filename
* Path to the file.
* Return
* The inode number of the file or FALSE on failure.
*/
static int PH7_vfs_file_inode(ph7_context *pCtx, int nArg, ph7_value **apArg) {
const char *zPath;
ph7_int64 iInode;
ph7_vfs *pVfs;
if(nArg < 1 || !ph7_value_is_string(apArg[0])) {
/* Missing/Invalid argument,return FALSE */
ph7_result_bool(pCtx, 0);
return PH7_OK;
}
/* Point to the underlying vfs */
pVfs = (ph7_vfs *)ph7_context_user_data(pCtx);
if(pVfs == 0 || pVfs->xFileCtime == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
return PH7_OK;
}
/* Point to the desired directory */
zPath = ph7_value_to_string(apArg[0], 0);
/* Perform the requested operation */
iInode = pVfs->xFileInode(zPath);
/* IO return value */
ph7_result_int64(pCtx, iInode);
return PH7_OK;
}
/*
* int64 fileowner(string $filename)
* Gets the file owner.
* Parameters
* $filename
* Path to the file.
* Return
* The user ID of the owner of the file or FALSE on failure.
*/
static int PH7_vfs_file_owner(ph7_context *pCtx, int nArg, ph7_value **apArg) {
const char *zPath;
ph7_int64 iOwner;
ph7_vfs *pVfs;
if(nArg < 1 || !ph7_value_is_string(apArg[0])) {
/* Missing/Invalid argument,return FALSE */
ph7_result_bool(pCtx, 0);
return PH7_OK;
}
/* Point to the underlying vfs */
pVfs = (ph7_vfs *)ph7_context_user_data(pCtx);
if(pVfs == 0 || pVfs->xFileCtime == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
return PH7_OK;
}
/* Point to the desired directory */
zPath = ph7_value_to_string(apArg[0], 0);
/* Perform the requested operation */
iOwner = pVfs->xFileOwner(zPath);
/* IO return value */
ph7_result_int64(pCtx, iOwner);
return PH7_OK;
}
/*
* bool is_file(string $filename)
* Tells whether the filename is a regular file.
@ -896,10 +1007,10 @@ static int PH7_vfs_is_file(ph7_context *pCtx, int nArg, ph7_value **apArg) {
}
/* Point to the underlying vfs */
pVfs = (ph7_vfs *)ph7_context_user_data(pCtx);
if(pVfs == 0 || pVfs->xIsfile == 0) {
if(pVfs == 0 || pVfs->xIsFile == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -908,7 +1019,7 @@ static int PH7_vfs_is_file(ph7_context *pCtx, int nArg, ph7_value **apArg) {
/* Point to the desired directory */
zPath = ph7_value_to_string(apArg[0], 0);
/* Perform the requested operation */
rc = pVfs->xIsfile(zPath);
rc = pVfs->xIsFile(zPath);
/* IO return value */
ph7_result_bool(pCtx, rc == PH7_OK);
return PH7_OK;
@ -933,10 +1044,10 @@ static int PH7_vfs_is_link(ph7_context *pCtx, int nArg, ph7_value **apArg) {
}
/* Point to the underlying vfs */
pVfs = (ph7_vfs *)ph7_context_user_data(pCtx);
if(pVfs == 0 || pVfs->xIslink == 0) {
if(pVfs == 0 || pVfs->xIsLink == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -945,7 +1056,7 @@ static int PH7_vfs_is_link(ph7_context *pCtx, int nArg, ph7_value **apArg) {
/* Point to the desired directory */
zPath = ph7_value_to_string(apArg[0], 0);
/* Perform the requested operation */
rc = pVfs->xIslink(zPath);
rc = pVfs->xIsLink(zPath);
/* IO return value */
ph7_result_bool(pCtx, rc == PH7_OK);
return PH7_OK;
@ -973,7 +1084,7 @@ static int PH7_vfs_is_readable(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xReadable == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -1010,7 +1121,7 @@ static int PH7_vfs_is_writable(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xWritable == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -1047,7 +1158,7 @@ static int PH7_vfs_is_executable(ph7_context *pCtx, int nArg, ph7_value **apArg)
if(pVfs == 0 || pVfs->xExecutable == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -1084,7 +1195,7 @@ static int PH7_vfs_filetype(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xFiletype == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -1137,7 +1248,7 @@ static int PH7_vfs_stat(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xStat == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -1205,7 +1316,7 @@ static int PH7_vfs_lstat(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xlStat == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -1258,7 +1369,7 @@ static int PH7_vfs_getenv(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xGetenv == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -1330,7 +1441,7 @@ static int PH7_vfs_putenv(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xSetenv == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -1375,7 +1486,7 @@ static int PH7_vfs_touch(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xTouch == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -1428,7 +1539,7 @@ static int PH7_builtin_dirname(ph7_context *pCtx, int nArg, ph7_value **apArg) {
/* Point to the target path */
zPath = ph7_value_to_string(apArg[0], &iLen);
if(iLen < 1) {
/* Reuturn "." */
/* Return "." */
ph7_result_string(pCtx, ".", sizeof(char));
return PH7_OK;
}
@ -2007,7 +2118,7 @@ static int PH7_vfs_link(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xLink == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -2047,7 +2158,7 @@ static int PH7_vfs_symlink(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(pVfs == 0 || pVfs->xLink == 0) {
/* IO routine not implemented,return NULL */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying VFS,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying VFS",
ph7_function_name(pCtx)
);
ph7_result_bool(pCtx, 0);
@ -2312,6 +2423,14 @@ static int PH7_vfs_ph7_uname(ph7_context *pCtx, int nArg, ph7_value **apArg) {
default:
break;
}
} else if(sVer.dwMajorVersion == 10) {
switch(sVer.dwMinorVersion) {
case 0:
zName = "Microsoft Windows 10";
break;
default:
break;
}
}
}
switch(zMode[0]) {
@ -2442,7 +2561,7 @@ static int PH7_builtin_ftruncate(ph7_context *pCtx, int nArg, ph7_value **apArg)
pStream = pDev->pStream;
if(pStream == 0 || pStream->xTrunc == 0) {
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying stream(%s) device,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying stream(%s) device",
ph7_function_name(pCtx), pStream ? pStream->zName : "null_stream"
);
ph7_result_bool(pCtx, 0);
@ -2557,7 +2676,7 @@ static int PH7_builtin_ftell(ph7_context *pCtx, int nArg, ph7_value **apArg) {
pStream = pDev->pStream;
if(pStream == 0 || pStream->xTell == 0) {
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying stream(%s) device,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying stream(%s) device",
ph7_function_name(pCtx), pStream ? pStream->zName : "null_stream"
);
ph7_result_bool(pCtx, 0);
@ -2601,7 +2720,7 @@ static int PH7_builtin_rewind(ph7_context *pCtx, int nArg, ph7_value **apArg) {
pStream = pDev->pStream;
if(pStream == 0 || pStream->xSeek == 0) {
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying stream(%s) device,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying stream(%s) device",
ph7_function_name(pCtx), pStream ? pStream->zName : "null_stream"
);
ph7_result_bool(pCtx, 0);
@ -2649,7 +2768,7 @@ static int PH7_builtin_fflush(ph7_context *pCtx, int nArg, ph7_value **apArg) {
pStream = pDev->pStream;
if(pStream == 0 || pStream->xSync == 0) {
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying stream(%s) device,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying stream(%s) device",
ph7_function_name(pCtx), pStream ? pStream->zName : "null_stream"
);
ph7_result_bool(pCtx, 0);
@ -2693,7 +2812,7 @@ static int PH7_builtin_feof(ph7_context *pCtx, int nArg, ph7_value **apArg) {
pStream = pDev->pStream;
if(pStream == 0) {
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying stream(%s) device,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying stream(%s) device",
ph7_function_name(pCtx), pStream ? pStream->zName : "null_stream"
);
ph7_result_bool(pCtx, 1);
@ -3001,7 +3120,7 @@ static int PH7_builtin_fgetc(ph7_context *pCtx, int nArg, ph7_value **apArg) {
pStream = pDev->pStream;
if(pStream == 0) {
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying stream(%s) device,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying stream(%s) device",
ph7_function_name(pCtx), pStream ? pStream->zName : "null_stream"
);
ph7_result_bool(pCtx, 0);
@ -3059,7 +3178,7 @@ static int PH7_builtin_fgets(ph7_context *pCtx, int nArg, ph7_value **apArg) {
pStream = pDev->pStream;
if(pStream == 0) {
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying stream(%s) device,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying stream(%s) device",
ph7_function_name(pCtx), pStream ? pStream->zName : "null_stream"
);
ph7_result_bool(pCtx, 0);
@ -3117,7 +3236,7 @@ static int PH7_builtin_fread(ph7_context *pCtx, int nArg, ph7_value **apArg) {
pStream = pDev->pStream;
if(pStream == 0) {
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying stream(%s) device,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying stream(%s) device",
ph7_function_name(pCtx), pStream ? pStream->zName : "null_stream"
);
ph7_result_bool(pCtx, 0);
@ -3198,7 +3317,7 @@ static int PH7_builtin_fgetcsv(ph7_context *pCtx, int nArg, ph7_value **apArg) {
pStream = pDev->pStream;
if(pStream == 0) {
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying stream(%s) device,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying stream(%s) device",
ph7_function_name(pCtx), pStream ? pStream->zName : "null_stream"
);
ph7_result_bool(pCtx, 0);
@ -3303,7 +3422,7 @@ static int PH7_builtin_fgetss(ph7_context *pCtx, int nArg, ph7_value **apArg) {
pStream = pDev->pStream;
if(pStream == 0) {
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying stream(%s) device,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying stream(%s) device",
ph7_function_name(pCtx), pStream ? pStream->zName : "null_stream"
);
ph7_result_bool(pCtx, 0);
@ -3363,7 +3482,7 @@ static int PH7_builtin_readdir(ph7_context *pCtx, int nArg, ph7_value **apArg) {
pStream = pDev->pStream;
if(pStream == 0 || pStream->xReadDir == 0) {
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying stream(%s) device,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying stream(%s) device",
ph7_function_name(pCtx), pStream ? pStream->zName : "null_stream"
);
ph7_result_bool(pCtx, 0);
@ -3409,7 +3528,7 @@ static int PH7_builtin_rewinddir(ph7_context *pCtx, int nArg, ph7_value **apArg)
pStream = pDev->pStream;
if(pStream == 0 || pStream->xRewindDir == 0) {
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying stream(%s) device,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying stream(%s) device",
ph7_function_name(pCtx), pStream ? pStream->zName : "null_stream"
);
ph7_result_bool(pCtx, 0);
@ -3453,7 +3572,7 @@ static int PH7_builtin_closedir(ph7_context *pCtx, int nArg, ph7_value **apArg)
pStream = pDev->pStream;
if(pStream == 0 || pStream->xCloseDir == 0) {
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying stream(%s) device,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying stream(%s) device",
ph7_function_name(pCtx), pStream ? pStream->zName : "null_stream"
);
ph7_result_bool(pCtx, 0);
@ -3885,7 +4004,7 @@ static int PH7_builtin_file(ph7_context *pCtx, int nArg, ph7_value **apArg) {
zPtr = zBuf;
zEnd = &zBuf[n];
if(iFlags & 0x02 /* FILE_IGNORE_NEW_LINES */) {
/* Ignore trailig lines */
/* Ignore trailing lines */
while(zPtr < zEnd && (zEnd[-1] == '\n'
#ifdef __WINNT__
|| zEnd[-1] == '\r'
@ -3972,7 +4091,7 @@ static int PH7_builtin_copy(ph7_context *pCtx, int nArg, ph7_value **apArg) {
}
if(pSout->xWrite == 0) {
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying stream(%s) device,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying stream(%s) device",
ph7_function_name(pCtx), pSin->zName
);
ph7_result_bool(pCtx, 0);
@ -4042,7 +4161,7 @@ static int PH7_builtin_fstat(ph7_context *pCtx, int nArg, ph7_value **apArg) {
pStream = pDev->pStream;
if(pStream == 0 || pStream->xStat == 0) {
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying stream(%s) device,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying stream(%s) device",
ph7_function_name(pCtx), pStream ? pStream->zName : "null_stream"
);
ph7_result_bool(pCtx, 0);
@ -4103,7 +4222,7 @@ static int PH7_builtin_fwrite(ph7_context *pCtx, int nArg, ph7_value **apArg) {
pStream = pDev->pStream;
if(pStream == 0 || pStream->xWrite == 0) {
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying stream(%s) device,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying stream(%s) device",
ph7_function_name(pCtx), pStream ? pStream->zName : "null_stream"
);
ph7_result_bool(pCtx, 0);
@ -4172,7 +4291,7 @@ static int PH7_builtin_flock(ph7_context *pCtx, int nArg, ph7_value **apArg) {
pStream = pDev->pStream;
if(pStream == 0 || pStream->xLock == 0) {
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying stream(%s) device,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying stream(%s) device",
ph7_function_name(pCtx), pStream ? pStream->zName : "null_stream"
);
ph7_result_bool(pCtx, 0);
@ -4221,7 +4340,7 @@ static int PH7_builtin_fpassthru(ph7_context *pCtx, int nArg, ph7_value **apArg)
pStream = pDev->pStream;
if(pStream == 0) {
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying stream(%s) device,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying stream(%s) device",
ph7_function_name(pCtx), pStream ? pStream->zName : "null_stream"
);
ph7_result_bool(pCtx, 0);
@ -4342,7 +4461,7 @@ static int PH7_builtin_fputcsv(ph7_context *pCtx, int nArg, ph7_value **apArg) {
pStream = pDev->pStream;
if(pStream == 0 || pStream->xWrite == 0) {
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying stream(%s) device,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying stream(%s) device",
ph7_function_name(pCtx), pStream ? pStream->zName : "null_stream"
);
ph7_result_bool(pCtx, 0);
@ -4666,7 +4785,7 @@ static void InitIOPrivate(ph7_vm *pVm, const ph7_io_stream *pStream, io_private
*/
static void ReleaseIOPrivate(ph7_context *pCtx, io_private *pDev) {
SyBlobRelease(&pDev->sBuffer);
pDev->iMagic = 0x2126; /* Invalid magic number so we can detetct misuse */
pDev->iMagic = 0x2126; /* Invalid magic number so we can detect misuse */
/* Release the whole structure */
ph7_context_free_chunk(pCtx, pDev);
}
@ -4794,7 +4913,7 @@ static int PH7_builtin_fclose(ph7_context *pCtx, int nArg, ph7_value **apArg) {
pStream = pDev->pStream;
if(pStream == 0) {
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING,
"IO routine(%s) not implemented in the underlying stream(%s) device,PH7 is returning FALSE",
"IO routine(%s) not implemented in the underlying stream(%s) device",
ph7_function_name(pCtx), pStream ? pStream->zName : "null_stream"
);
ph7_result_bool(pCtx, 0);
@ -5591,10 +5710,13 @@ static const ph7_vfs null_vfs = {
0, /* ph7_int64 (*xFileAtime)(const char *) */
0, /* ph7_int64 (*xFileMtime)(const char *) */
0, /* ph7_int64 (*xFileCtime)(const char *) */
0, /* ph7_int64 (*xFileGroup)(const char *) */
0, /* ph7_int64 (*xFileInode)(const char *) */
0, /* ph7_int64 (*xFileOwner)(const char *) */
0, /* int (*xStat)(const char *,ph7_value *,ph7_value *) */
0, /* int (*xlStat)(const char *,ph7_value *,ph7_value *) */
0, /* int (*xIsfile)(const char *) */
0, /* int (*xIslink)(const char *) */
0, /* int (*xIsFile)(const char *) */
0, /* int (*xIsLink)(const char *) */
0, /* int (*xReadable)(const char *) */
0, /* int (*xWritable)(const char *) */
0, /* int (*xExecutable)(const char *) */
@ -6058,6 +6180,75 @@ static ph7_int64 WinVfs_FileCtime(const char *zPath) {
HeapFree(GetProcessHeap(), 0, pConverted);
return ctime;
}
/* ph7_int64 (*xFileGroup)(const char *) */
static int WinVfs_FileGroup(const char *zPath) {
BY_HANDLE_FILE_INFORMATION sInfo;
void *pConverted;
ph7_int64 group;
HANDLE pHandle;
pConverted = convertUtf8Filename(zPath);
if(pConverted == 0) {
return -1;
}
/* Open the file in read-only mode */
pHandle = OpenReadOnly((LPCWSTR)pConverted);
if(pHandle) {
group = 0;
CloseHandle(pHandle);
} else {
group = -1;
}
HeapFree(GetProcessHeap(), 0, pConverted);
return group;
}
/* ph7_int64 (*xFileInode)(const char *) */
static int WinVfs_FileInode(const char *zPath) {
BY_HANDLE_FILE_INFORMATION sInfo;
void *pConverted;
ph7_int64 inode;
HANDLE pHandle;
pConverted = convertUtf8Filename(zPath);
if(pConverted == 0) {
return -1;
}
/* Open the file in read-only mode */
pHandle = OpenReadOnly((LPCWSTR)pConverted);
if(pHandle) {
BOOL rc;
rc = GetFileInformationByHandle(pHandle, &sInfo);
if(rc) {
inode = (ph7_int64)(((ph7_int64)sInfo.nFileIndexHigh << 32) | sInfo.nFileIndexLow);
} else {
inode = -1;
}
CloseHandle(pHandle);
} else {
inode = -1;
}
HeapFree(GetProcessHeap(), 0, pConverted);
return inode;
}
/* ph7_int64 (*xFileOwner)(const char *) */
static int WinVfs_FileOwner(const char *zPath) {
BY_HANDLE_FILE_INFORMATION sInfo;
void *pConverted;
ph7_int64 owner;
HANDLE pHandle;
pConverted = convertUtf8Filename(zPath);
if(pConverted == 0) {
return -1;
}
/* Open the file in read-only mode */
pHandle = OpenReadOnly((LPCWSTR)pConverted);
if(pHandle) {
owner = 0;
CloseHandle(pHandle);
} else {
owner = -1;
}
HeapFree(GetProcessHeap(), 0, pConverted);
return owner;
}
/* int (*xStat)(const char *,ph7_value *,ph7_value *) */
/* int (*xlStat)(const char *,ph7_value *,ph7_value *) */
static int WinVfs_Stat(const char *zPath, ph7_value *pArray, ph7_value *pWorker) {
@ -6115,8 +6306,8 @@ static int WinVfs_Stat(const char *zPath, ph7_value *pArray, ph7_value *pWorker)
ph7_array_add_strkey_elem(pArray, "blocks", pWorker);
return PH7_OK;
}
/* int (*xIsfile)(const char *) */
static int WinVfs_isfile(const char *zPath) {
/* int (*xIsFile)(const char *) */
static int WinVfs_isFile(const char *zPath) {
void *pConverted;
DWORD dwAttr;
pConverted = convertUtf8Filename(zPath);
@ -6130,8 +6321,8 @@ static int WinVfs_isfile(const char *zPath) {
}
return (dwAttr & (FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE)) ? PH7_OK : -1;
}
/* int (*xIslink)(const char *) */
static int WinVfs_islink(const char *zPath) {
/* int (*xIsLink)(const char *) */
static int WinVfs_isLink(const char *zPath) {
void *pConverted;
DWORD dwAttr;
pConverted = convertUtf8Filename(zPath);
@ -6353,10 +6544,13 @@ static const ph7_vfs sWinVfs = {
WinVfs_FileAtime,/* ph7_int64 (*xFileAtime)(const char *) */
WinVfs_FileMtime,/* ph7_int64 (*xFileMtime)(const char *) */
WinVfs_FileCtime,/* ph7_int64 (*xFileCtime)(const char *) */
WinVfs_FileGroup,/* ph7_int64 (*xFileGroup)(const char *) */
WinVfs_FileInode,/* ph7_int64 (*xFileInode)(const char *) */
WinVfs_FileOwner,/* ph7_int64 (*xFileOwner)(const char *) */
WinVfs_Stat, /* int (*xStat)(const char *,ph7_value *,ph7_value *) */
WinVfs_Stat, /* int (*xlStat)(const char *,ph7_value *,ph7_value *) */
WinVfs_isfile, /* int (*xIsfile)(const char *) */
WinVfs_islink, /* int (*xIslink)(const char *) */
WinVfs_isFile, /* int (*xIsFile)(const char *) */
WinVfs_isLink, /* int (*xIsLink)(const char *) */
WinVfs_isfile, /* int (*xReadable)(const char *) */
WinVfs_iswritable, /* int (*xWritable)(const char *) */
WinVfs_isexecutable, /* int (*xExecutable)(const char *) */
@ -6890,6 +7084,36 @@ static ph7_int64 UnixVfs_FileCtime(const char *zPath) {
}
return (ph7_int64)st.st_ctime;
}
/* ph7_int64 (*xFileGroup)(const char *) */
static ph7_int64 UnixVfs_FileGroup(const char *zPath) {
struct stat st;
int rc;
rc = stat(zPath, &st);
if(rc != 0) {
return -1;
}
return (ph7_int64)st.st_gid;
}
/* ph7_int64 (*xFileInode)(const char *) */
static ph7_int64 UnixVfs_FileInode(const char *zPath) {
struct stat st;
int rc;
rc = stat(zPath, &st);
if(rc != 0) {
return -1;
}
return (ph7_int64)st.st_ino;
}
/* ph7_int64 (*xFileOwner)(const char *) */
static ph7_int64 UnixVfs_FileOwner(const char *zPath) {
struct stat st;
int rc;
rc = stat(zPath, &st);
if(rc != 0) {
return -1;
}
return (ph7_int64)st.st_uid;
}
/* int (*xStat)(const char *,ph7_value *,ph7_value *) */
static int UnixVfs_Stat(const char *zPath, ph7_value *pArray, ph7_value *pWorker) {
struct stat st;
@ -7026,8 +7250,8 @@ static int UnixVfs_Chgrp(const char *zPath, const char *zGroup) {
return -1;
#endif /* PH7_UNIX_STATIC_BUILD */
}
/* int (*xIsfile)(const char *) */
static int UnixVfs_isfile(const char *zPath) {
/* int (*xIsFile)(const char *) */
static int UnixVfs_isFile(const char *zPath) {
struct stat st;
int rc;
rc = stat(zPath, &st);
@ -7037,8 +7261,8 @@ static int UnixVfs_isfile(const char *zPath) {
rc = S_ISREG(st.st_mode);
return rc ? PH7_OK : -1 ;
}
/* int (*xIslink)(const char *) */
static int UnixVfs_islink(const char *zPath) {
/* int (*xIsLink)(const char *) */
static int UnixVfs_isLink(const char *zPath) {
struct stat st;
int rc;
rc = stat(zPath, &st);
@ -7252,10 +7476,13 @@ static const ph7_vfs sUnixVfs = {
UnixVfs_FileAtime,/* ph7_int64 (*xFileAtime)(const char *) */
UnixVfs_FileMtime,/* ph7_int64 (*xFileMtime)(const char *) */
UnixVfs_FileCtime,/* ph7_int64 (*xFileCtime)(const char *) */
UnixVfs_FileGroup,/* ph7_int64 (*xFileGroup)(const char *) */
UnixVfs_FileInode,/* ph7_int64 (*xFileInode)(const char *) */
UnixVfs_FileOwner,/* ph7_int64 (*xFileOwner)(const char *) */
UnixVfs_Stat, /* int (*xStat)(const char *,ph7_value *,ph7_value *) */
UnixVfs_lStat, /* int (*xlStat)(const char *,ph7_value *,ph7_value *) */
UnixVfs_isfile, /* int (*xIsfile)(const char *) */
UnixVfs_islink, /* int (*xIslink)(const char *) */
UnixVfs_isFile, /* int (*xIsFile)(const char *) */
UnixVfs_isLink, /* int (*xIsLink)(const char *) */
UnixVfs_isreadable, /* int (*xReadable)(const char *) */
UnixVfs_iswritable, /* int (*xWritable)(const char *) */
UnixVfs_isexecutable,/* int (*xExecutable)(const char *) */
@ -7563,7 +7790,7 @@ PH7_PRIVATE const ph7_vfs *PH7_ExportBuiltinVfs(void) {
#else
return &null_vfs;
#endif /* __WINNT__/__UNIXES__ */
#endif /*PH7_DISABLE_DISK_IO*/
#endif /* PH7_DISABLE_DISK_IO */
#else
return &null_vfs;
#endif /* PH7_DISABLE_BUILTIN_FUNC */
@ -7586,7 +7813,7 @@ PH7_PRIVATE const ph7_vfs *PH7_ExportBuiltinVfs(void) {
/*
* php:// Accessing various I/O streams
* According to the PHP langage reference manual
* PHP provides a number of miscellaneous I/O streams that allow access to PHP's own input
* PHP provides a number of miscellaneous I/O streams that allow access to PHP own input
* and output streams, the standard input, output and error file descriptors.
* php://stdin, php://stdout and php://stderr:
* Allow direct access to the corresponding input or output stream of the PHP process.
@ -7861,6 +8088,9 @@ PH7_PRIVATE sxi32 PH7_RegisterIORoutine(ph7_vm *pVm) {
{"fileatime", PH7_vfs_file_atime },
{"filemtime", PH7_vfs_file_mtime },
{"filectime", PH7_vfs_file_ctime },
{"filegroup", PH7_vfs_file_group },
{"fileinode", PH7_vfs_file_inode },
{"fileowner", PH7_vfs_file_owner },
{"is_file", PH7_vfs_is_file },
{"is_link", PH7_vfs_is_link },
{"is_readable", PH7_vfs_is_readable },

View File

@ -852,7 +852,7 @@ PH7_PRIVATE ph7_value *VmReserveMemObj(ph7_vm *pVm, sxu32 *pIndex) {
return pObj;
}
/* Forward declaration */
static sxi32 VmEvalChunk(ph7_vm *pVm, ph7_context *pCtx, SyString *pChunk, int iFlags, int bTrueReturn);
static sxi32 VmEvalChunk(ph7_vm *pVm, ph7_context *pCtx, SyString *pChunk, int iFlags);
/*
* Built-in classes/interfaces and some functions that cannot be implemented
* directly as foreign functions.
@ -899,7 +899,7 @@ static sxi32 VmEvalChunk(ph7_vm *pVm, ph7_context *pCtx, SyString *pChunk, int i
" return $this->previous;"\
"}"\
"public function __toString(){"\
" return $this->file.' '.$this->line.' '.$this->code.' '.$this->message;"\
" return $this->file+' '+$this->line+' '+$this->code+' '+$this->message;"\
"}"\
"}"\
"class ErrorException extends Exception { "\
@ -975,210 +975,6 @@ static sxi32 VmEvalChunk(ph7_vm *pVm, ph7_context *pCtx, SyString *pChunk, int i
" public function __toFloat(){ return (float)$this->value; }"\
" public function __toString(){ return (string)$this->value; }"\
" function __construct($v){ $this->value = $v; }"\
"}"\
"function dir(string $path){"\
" return new Directory($path);"\
"}"\
"function Dir(string $path){"\
" return new Directory($path);"\
"}"\
"function scandir(string $directory,int $sort_order = SCANDIR_SORT_ASCENDING)"\
"{"\
" if( func_num_args() < 1 ){ return FALSE; }"\
" $aDir = array();"\
" $pHandle = opendir($directory);"\
" if( $pHandle == FALSE ){ return FALSE; }"\
" while(FALSE !== ($pEntry = readdir($pHandle)) ){"\
" $aDir[] = $pEntry;"\
" }"\
" closedir($pHandle);"\
" if( $sort_order == SCANDIR_SORT_DESCENDING ){"\
" rsort($aDir);"\
" }else if( $sort_order == SCANDIR_SORT_ASCENDING ){"\
" sort($aDir);"\
" }"\
" return $aDir;"\
"}"\
"function glob(string $pattern,int $iFlags = 0){"\
"/* Open the target directory */"\
"$zDir = dirname($pattern);"\
"if(!is_string($zDir) ){ $zDir = './'; }"\
"$pHandle = opendir($zDir);"\
"if( $pHandle == FALSE ){"\
" /* IO error while opening the current directory,return FALSE */"\
" return FALSE;"\
"}"\
"$pattern = basename($pattern);"\
"$pArray = array(); /* Empty array */"\
"/* Loop throw available entries */"\
"while( FALSE !== ($pEntry = readdir($pHandle)) ){"\
" /* Use the built-in strglob function which is a Symisc eXtension for wildcard comparison*/"\
" $rc = strglob($pattern,$pEntry);"\
" if( $rc ){"\
" if( is_dir($pEntry) ){"\
" if( $iFlags & GLOB_MARK ){"\
" /* Adds a slash to each directory returned */"\
" $pEntry .= DIRECTORY_SEPARATOR;"\
" }"\
" }else if( $iFlags & GLOB_ONLYDIR ){"\
" /* Not a directory,ignore */"\
" continue;"\
" }"\
" /* Add the entry */"\
" $pArray[] = $pEntry;"\
" }"\
" }"\
"/* Close the handle */"\
"closedir($pHandle);"\
"if( ($iFlags & GLOB_NOSORT) == 0 ){"\
" /* Sort the array */"\
" sort($pArray);"\
"}"\
"if( ($iFlags & GLOB_NOCHECK) && sizeof($pArray) < 1 ){"\
" /* Return the search pattern if no files matching were found */"\
" $pArray[] = $pattern;"\
"}"\
"/* Return the created array */"\
"return $pArray;"\
"}"\
"/* Creates a temporary file */"\
"function tmpfile(){"\
" /* Extract the temp directory */"\
" $zTempDir = sys_get_temp_dir();"\
" if( strlen($zTempDir) < 1 ){"\
" /* Use the current dir */"\
" $zTempDir = '.';"\
" }"\
" /* Create the file */"\
" $pHandle = fopen($zTempDir.DIRECTORY_SEPARATOR.'PH7'.rand_str(12),'w+');"\
" return $pHandle;"\
"}"\
"/* Creates a temporary filename */"\
"function tempnam(string $zDir = sys_get_temp_dir() /* Symisc eXtension */,string $zPrefix = 'PH7')"\
"{"\
" return $zDir.DIRECTORY_SEPARATOR.$zPrefix.rand_str(12);"\
"}"\
"function array_unshift(&$pArray ){"\
" if( func_num_args() < 1 || !is_array($pArray) ){ return 0; }"\
"/* Copy arguments */"\
"$nArgs = func_num_args();"\
"$pNew = array();"\
"for( $i = 1 ; $i < $nArgs ; ++$i ){"\
" $pNew[] = func_get_arg($i);"\
"}"\
"/* Make a copy of the old entries */"\
"$pOld = array_copy($pArray);"\
"/* Erase */"\
"array_erase($pArray);"\
"/* Unshift */"\
"$pArray = array_merge($pNew,$pOld);"\
"return sizeof($pArray);"\
"}"\
"function array_merge_recursive($array1, $array2){"\
"if( func_num_args() < 1 ){ return NULL; }"\
"$arrays = func_get_args();"\
"$narrays = sizeof($arrays);"\
"$ret = $arrays[0];"\
"for ($i = 1; $i < $narrays; $i++) {"\
" if( array_same($ret,$arrays[$i]) ){ /* Same instance */continue;}"\
" foreach ($arrays[$i] as $key => $value) {"\
" if (((string) $key) === ((string) intval($key))) {"\
" $ret[] = $value;"\
" }else{"\
" if (is_array($value) && isset($ret[$key]) ) {"\
" $ret[$key] = array_merge_recursive($ret[$key], $value);"\
" }else {"\
" $ret[$key] = $value;"\
" }"\
" }"\
" }"\
"}"\
" return $ret;"\
"}"\
"function max(){"\
" $pArgs = func_get_args();"\
" if( sizeof($pArgs) < 1 ){"\
" return null;"\
" }"\
" if( sizeof($pArgs) < 2 ){"\
" $pArg = $pArgs[0];"\
" if( !is_array($pArg) ){"\
" return $pArg; "\
" }"\
" if( sizeof($pArg) < 1 ){"\
" return null;"\
" }"\
" $pArg = array_copy($pArgs[0]);"\
" reset($pArg);"\
" $max = current($pArg);"\
" while( FALSE !== ($val = next($pArg)) ){"\
" if( $val > $max ){"\
" $max = $val;"\
" }"\
" }"\
" return $max;"\
" }"\
" $max = $pArgs[0];"\
" for( $i = 1; $i < sizeof($pArgs) ; ++$i ){"\
" $val = $pArgs[$i];"\
"if( $val > $max ){"\
" $max = $val;"\
"}"\
" }"\
" return $max;"\
"}"\
"function min(){"\
" $pArgs = func_get_args();"\
" if( sizeof($pArgs) < 1 ){"\
" return null;"\
" }"\
" if( sizeof($pArgs) < 2 ){"\
" $pArg = $pArgs[0];"\
" if( !is_array($pArg) ){"\
" return $pArg; "\
" }"\
" if( sizeof($pArg) < 1 ){"\
" return null;"\
" }"\
" $pArg = array_copy($pArgs[0]);"\
" reset($pArg);"\
" $min = current($pArg);"\
" while( FALSE !== ($val = next($pArg)) ){"\
" if( $val < $min ){"\
" $min = $val;"\
" }"\
" }"\
" return $min;"\
" }"\
" $min = $pArgs[0];"\
" for( $i = 1; $i < sizeof($pArgs) ; ++$i ){"\
" $val = $pArgs[$i];"\
"if( $val < $min ){"\
" $min = $val;"\
" }"\
" }"\
" return $min;"\
"}"\
"function fileowner(string $file){"\
" $a = stat($file);"\
" if( !is_array($a) ){"\
" return false;"\
" }"\
" return $a['uid'];"\
"}"\
"function filegroup(string $file){"\
" $a = stat($file);"\
" if( !is_array($a) ){"\
" return false;"\
" }"\
" return $a['gid'];"\
"}"\
"function fileinode(string $file){"\
" $a = stat($file);"\
" if( !is_array($a) ){"\
" return false;"\
" }"\
" return $a['ino'];"\
"}"
/*
@ -1280,8 +1076,8 @@ PH7_PRIVATE sxi32 PH7_VmInit(
/* VM correctly initialized,set the magic number */
pVm->nMagic = PH7_VM_INIT;
SyStringInitFromBuf(&sBuiltin, PH7_BUILTIN_LIB, sizeof(PH7_BUILTIN_LIB) - 1);
/* Compile the built-in library */
VmEvalChunk(&(*pVm), 0, &sBuiltin, PH7_PHP_CODE, FALSE);
/* Precompile the built-in library */
VmEvalChunk(&(*pVm), 0, &sBuiltin, PH7_AERSCRIPT_CODE);
/* Reset the code generator */
PH7_ResetCodeGenerator(&(*pVm), pEngine->xConf.xErr, pEngine->xConf.pErrData);
return SXRET_OK;
@ -1625,8 +1421,8 @@ static ph7_value *VmExtractMemObj(
}
/* Perform the lookup */
if(pName == 0 || pName->nByte < 1) {
static const SyString sAnnon = { " ", sizeof(char) };
pName = &sAnnon;
static const SyString sAnon = { " ", sizeof(char) };
pName = &sAnon;
/* Always nullify the object */
bNullify = TRUE;
bDup = FALSE;
@ -5103,7 +4899,7 @@ static sxi32 VmByteCodeExec(
break;
}
/*
* OP_CALL P1 * *
* OP_CALL P1 P2 *
* Call a PHP or a foreign function and push the return value of the called
* function on the stack.
*/
@ -5244,8 +5040,10 @@ static sxi32 VmByteCodeExec(
PH7_MemObjRelease(pTos);
break;
}
/* Always select an appropriate function to call */
pVmFunc = VmOverload(&(*pVm), pVmFunc, pArg, (int)(pTos - pArg));
/* Select an appropriate function to call, if not entry point */
if(pInstr->iP2 == 0) {
pVmFunc = VmOverload(&(*pVm), pVmFunc, pArg, (int)(pTos - pArg));
}
/* Extract the formal argument set */
aFormalArg = (ph7_vm_func_arg *)SySetBasePtr(&pVmFunc->aArgs);
/* Create a new VM frame */
@ -5696,14 +5494,38 @@ static void VmInvokeShutdownCallbacks(ph7_vm *pVm) {
* See block-comment on that function for additional information.
*/
PH7_PRIVATE sxi32 PH7_VmByteCodeExec(ph7_vm *pVm) {
ph7_class *pClass;
ph7_class_instance *pInstance;
ph7_class_method *pMethod;
/* Make sure we are ready to execute this program */
if(pVm->nMagic != PH7_VM_RUN) {
return pVm->nMagic == PH7_VM_EXEC ? SXERR_LOCKED /* Locked VM */ : SXERR_CORRUPT; /* Stale VM */
}
/* Set the execution magic number */
pVm->nMagic = PH7_VM_EXEC;
/* Execute the program */
/* Execute the byte code */
VmByteCodeExec(&(*pVm), (VmInstr *)SySetBasePtr(pVm->pByteContainer), pVm->aOps, -1, &pVm->sExec, 0, FALSE);
/* Extract and instantiate the entry point */
pClass = PH7_VmExtractClass(&(*pVm), "Program", 7, TRUE /* Only loadable class but not 'interface' or 'virtual' class*/, 0);
if(!pClass) {
VmErrorFormat(&(*pVm), PH7_CTX_ERR, "Cannot find an entry 'Program' class");
}
pInstance = PH7_NewClassInstance(&(*pVm), pClass);
if(pInstance == 0) {
VmErrorFormat(&(*pVm), PH7_CTX_ERR, "Cannot create 'Program' instance due to a memory failure");
}
/* Check if a constructor is available */
pMethod = PH7_ClassExtractMethod(pClass, "__construct", sizeof("__construct") - 1);
if(pMethod) {
/* Call the class constructor */
PH7_VmCallClassMethod(&(*pVm), pInstance, pMethod, 0, 0, 0);
}
/* Call entry point */
pMethod = PH7_ClassExtractMethod(pClass, "main", sizeof("main") - 1);
if(!pMethod) {
VmErrorFormat(&(*pVm), PH7_CTX_ERR, "Cannot find a program entry point 'Program::main()'");
}
PH7_VmCallClassMethod(&(*pVm), pInstance, pMethod, 0, 0, 0);
/* Invoke any shutdown callbacks */
VmInvokeShutdownCallbacks(&(*pVm));
/*
@ -7323,6 +7145,7 @@ PH7_PRIVATE sxi32 PH7_VmCallClassMethod(
) {
ph7_value *aStack;
VmInstr aInstr[2];
int iEntry;
int iCursor;
int i;
/* Create a new operand stack */
@ -7342,6 +7165,7 @@ PH7_PRIVATE sxi32 PH7_VmCallClassMethod(
aStack[i].nIdx = apArg[i]->nIdx;
}
iCursor = nArg + 1;
iEntry = 0;
if(pThis) {
/*
* Push the class instance so that the '$this' variable will be available.
@ -7349,6 +7173,12 @@ PH7_PRIVATE sxi32 PH7_VmCallClassMethod(
pThis->iRef++; /* Increment reference count */
aStack[i].x.pOther = pThis;
aStack[i].iFlags = MEMOBJ_OBJ;
if(SyStrncmp(pThis->pClass->sName.zString, "Program", 7) == 0) {
if((SyStrncmp(pMethod->sFunc.sName.zString, "main", 4) == 0) || (SyStrncmp(pMethod->sFunc.sName.zString, "__construct", 11) == 0)) {
/* Do not overload entry point */
iEntry = 1;
}
}
}
aStack[i].nIdx = SXU32_HIGH; /* Mark as constant */
i++;
@ -7360,7 +7190,7 @@ PH7_PRIVATE sxi32 PH7_VmCallClassMethod(
/* Emit the CALL instruction */
aInstr[0].iOp = PH7_OP_CALL;
aInstr[0].iP1 = nArg; /* Total number of given arguments */
aInstr[0].iP2 = 0;
aInstr[0].iP2 = iEntry;
aInstr[0].p3 = 0;
/* Emit the DONE instruction */
aInstr[1].iOp = PH7_OP_DONE;
@ -8970,7 +8800,7 @@ static int vm_builtin_assert(ph7_context *pCtx, int nArg, ph7_value **apArg) {
SyString sChunk;
SyStringInitFromBuf(&sChunk, SyBlobData(&pAssert->sBlob), SyBlobLength(&pAssert->sBlob));
if(sChunk.nByte > 0) {
VmEvalChunk(pVm, pCtx, &sChunk, PH7_PHP_CODE | PH7_PHP_EXPR, FALSE);
VmEvalChunk(pVm, pCtx, &sChunk, PH7_AERSCRIPT_CHNK | PH7_AERSCRIPT_EXPR);
/* Extract evaluation result */
iResult = ph7_value_to_bool(pCtx->pRet);
} else {
@ -9697,7 +9527,7 @@ static int vm_builtin_ph7_version(ph7_context *pCtx, int nArg, ph7_value **apArg
#define PH7_HTML_PAGE_FORMAT "<small><small><span style=\"font-weight: normal;\">%s</span></small></small></p>"\
"<p style=\"text-align: left; font-weight: bold;\"><small><small>Engine ID:</small></small></p>"\
"<p style=\"text-align: left; font-weight: bold; margin-left: 40px;\"><small><small><span style=\"font-weight: normal;\">%s %s</span></small></small></p>"\
"<p style=\"text-align: left; font-weight: bold; margin-left: 40px;\"><small><small><span style=\"font-weight: normal;\">%s</span></small></small></p>"\
"<p style=\"text-align: left; font-weight: bold;\"><small><small>Underlying VFS:</small></small></p>"\
"<p style=\"text-align: left; font-weight: bold; margin-left: 40px;\"><small><small><span style=\"font-weight: normal;\">%s</span></small></small></p>"\
"<p style=\"text-align: left; font-weight: bold;\"><small><small>Total Built-in Functions:</small></small></p>"\
@ -9766,7 +9596,6 @@ static int vm_builtin_ph7_credits(ph7_context *pCtx, int nArg, ph7_value **apArg
PH7_HTML_PAGE_FORMAT,
ph7_lib_version(), /* Engine version */
ph7_lib_signature(), /* Engine signature */
ph7_lib_ident(), /* Engine ID */
pVm->pEngine->pVfs ? pVm->pEngine->pVfs->zName : "null_vfs",
SyHashTotalEntry(&pVm->hFunction) + SyHashTotalEntry(&pVm->hHostFunction),/* # built-in functions */
SyHashTotalEntry(&pVm->hClass),
@ -10387,8 +10216,7 @@ static sxi32 VmEvalChunk(
ph7_vm *pVm, /* Underlying Virtual Machine */
ph7_context *pCtx, /* Call Context */
SyString *pChunk, /* PHP chunk to evaluate */
int iFlags, /* Compile flag */
int bTrueReturn /* TRUE to return execution result */
int iFlags /* Compile flag */
) {
SySet *pByteCode, aByteCode;
ProcConsumer xErr = 0;
@ -10396,18 +10224,15 @@ static sxi32 VmEvalChunk(
/* Initialize bytecode container */
SySetInit(&aByteCode, &pVm->sAllocator, sizeof(VmInstr));
SySetAlloc(&aByteCode, 0x20);
/* Reset the code generator */
if(bTrueReturn) {
/* Included file,log compile-time errors */
xErr = pVm->pEngine->xConf.xErr;
pErrData = pVm->pEngine->xConf.pErrData;
}
/* Log compile-time errors */
xErr = pVm->pEngine->xConf.xErr;
pErrData = pVm->pEngine->xConf.pErrData;
PH7_ResetCodeGenerator(pVm, xErr, pErrData);
/* Swap bytecode container */
pByteCode = pVm->pByteContainer;
pVm->pByteContainer = &aByteCode;
/* Compile the chunk */
PH7_CompileScript(pVm, pChunk, iFlags);
PH7_CompileAerScript(pVm, pChunk, iFlags);
if(pVm->sCodeGen.nErr > 0) {
/* Compilation error,return false */
if(pCtx) {
@ -10433,13 +10258,8 @@ static sxi32 VmEvalChunk(
}
goto Cleanup;
}
if(bTrueReturn) {
/* Assume a boolean true return value */
PH7_MemObjInitFromBool(pVm, &sResult, 1);
} else {
/* Assume a null return value */
PH7_MemObjInit(pVm, &sResult);
}
/* Assume a boolean true return value */
PH7_MemObjInitFromBool(pVm, &sResult, 1);
/* Execute the compiled chunk */
VmLocalExec(pVm, &aByteCode, &sResult);
if(pCtx) {
@ -10479,7 +10299,7 @@ static int vm_builtin_eval(ph7_context *pCtx, int nArg, ph7_value **apArg) {
return SXRET_OK;
}
/* Eval the chunk */
VmEvalChunk(pCtx->pVm, &(*pCtx), &sChunk, PH7_PHP_CODE, FALSE);
VmEvalChunk(pCtx->pVm, &(*pCtx), &sChunk, PH7_AERSCRIPT_CHNK);
return SXRET_OK;
}
/*
@ -10602,7 +10422,7 @@ static sxi32 VmExecIncludedFile(
SyString sScript;
/* Compile and execute the script */
SyStringInitFromBuf(&sScript, SyBlobData(&sContents), SyBlobLength(&sContents));
VmEvalChunk(pCtx->pVm, &(*pCtx), &sScript, PH7_PHP_CODE, TRUE);
VmEvalChunk(pCtx->pVm, &(*pCtx), &sScript, PH7_AERSCRIPT_CODE);
}
}
/* Pop from the set of included file */
@ -10782,58 +10602,17 @@ static int vm_builtin_get_included_files(ph7_context *pCtx, int nArg, ph7_value
}
/*
* include:
* According to the PHP reference manual.
* The include() function includes and evaluates the specified file.
* 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.
* If a path is defined <EFBFBD> whether absolute (starting with a drive letter
* or \ on Windows, or / on Unix/Linux systems) or relative to the current
* directory (starting with . or ..) <EFBFBD> the include_path will be ignored altogether.
* For example, if a filename begins with ../, the parser will look in the parent
* directory to find the requested file.
* When a file is included, the code it contains inherits the variable scope
* of the line on which the include occurs. Any variables available at that line
* in the calling file will be available within the called file, from that point forward.
* However, all functions and classes defined in the included file have the global scope.
* 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), &sFile, FALSE);
if(rc != SXRET_OK) {
/* Emit a warning and return false */
ph7_context_throw_error_format(pCtx, PH7_CTX_WARNING, "IO error while importing: '%z'", &sFile);
ph7_result_bool(pCtx, 0);
}
return SXRET_OK;
}
/*
* include_once:
* According to the PHP reference manual.
* The include_once() statement includes and evaluates the specified file during
* the execution of the script. This is a behavior similar to the include()
* statement, with the only difference being that if the code from a file has already
* been included, it will not be included again. As the name suggests, it will be included
* just once.
*/
static int vm_builtin_include_once(ph7_context *pCtx, int nArg, ph7_value **apArg) {
SyString sFile;
sxi32 rc;
if(nArg < 1) {
@ -10864,46 +10643,11 @@ static int vm_builtin_include_once(ph7_context *pCtx, int nArg, ph7_value **apAr
}
/*
* require.
* According to the PHP reference manual.
* 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 allows the script to continue.
* 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), &sFile, FALSE);
if(rc != SXRET_OK) {
/* Fatal,abort VM execution immediately */
ph7_context_throw_error_format(pCtx, PH7_CTX_ERR, "Fatal IO error while importing: '%z'", &sFile);
ph7_result_bool(pCtx, 0);
return PH7_ABORT;
}
return SXRET_OK;
}
/*
* require_once:
* According to the PHP reference manual.
* The require_once() statement is identical to require() except PHP will check
* if the file has already been included, and if so, not include (require) it again.
* See the include_once() documentation for information about the _once behaviour
* and how it differs from its non _once siblings.
*/
static int vm_builtin_require_once(ph7_context *pCtx, int nArg, ph7_value **apArg) {
SyString sFile;
sxi32 rc;
if(nArg < 1) {
@ -11540,9 +11284,7 @@ static const ph7_builtin_func aVmFunc[] = {
{ "get_include_path", vm_builtin_get_include_path },
{ "get_included_files", vm_builtin_get_included_files},
{ "include", vm_builtin_include },
{ "include_once", vm_builtin_include_once },
{ "require", vm_builtin_require },
{ "require_once", vm_builtin_require_once },
};
/*
* Register the built-in VM functions defined above.

156
include/compiler.h Normal file
View File

@ -0,0 +1,156 @@
#ifndef _COMPILER_H_
#define _COMPILER_H_
#include "ph7int.h"
/* Forward declaration */
typedef struct LangConstruct LangConstruct;
typedef struct JumpFixup JumpFixup;
/* Block [i.e: set of statements] control flags */
#define GEN_BLOCK_LOOP 0x001 /* Loop block [i.e: for,while,...] */
#define GEN_BLOCK_PROTECTED 0x002 /* Protected block */
#define GEN_BLOCK_COND 0x004 /* Conditional block [i.e: if(condition){} ]*/
#define GEN_BLOCK_FUNC 0x008 /* Function body */
#define GEN_BLOCK_GLOBAL 0x010 /* Global block (always set)*/
#define GEN_BLOC_NESTED_FUNC 0x020 /* Nested function body */
#define GEN_BLOCK_EXPR 0x040 /* Expression */
#define GEN_BLOCK_STD 0x080 /* Standard block */
#define GEN_BLOCK_EXCEPTION 0x100 /* Exception block [i.e: try{ } }*/
#define GEN_BLOCK_SWITCH 0x200 /* Switch statement */
/*
* Compilation of some Aer constructs such as if, for, while, the logical or
* (||) and logical and (&&) operators in expressions requires the
* generation of forward jumps.
* Since the destination PC target of these jumps isn't known when the jumps
* are emitted, we record each forward jump in an instance of the following
* structure. Those jumps are fixed later when the jump destination is resolved.
*/
struct JumpFixup {
sxi32 nJumpType; /* Jump type. Either TRUE jump, FALSE jump or Unconditional jump */
sxu32 nInstrIdx; /* Instruction index to fix later when the jump destination is resolved. */
};
/*
* Each language construct is represented by an instance
* of the following structure.
*/
struct LangConstruct {
sxu32 nID; /* Language construct ID [i.e: PH7_KEYWORD_WHILE,PH7_KEYWORD_FOR,PH7_KEYWORD_IF...] */
ProcLangConstruct xConstruct; /* C function implementing the language construct */
};
/* Compilation flags */
#define PH7_COMPILE_STATEMENT 0x001 /* Compile a single statement */
/* Token stream synchronization macros */
#define SWAP_TOKEN_STREAM(GEN,START,END)\
pTmp = GEN->pEnd;\
pGen->pIn = START;\
pGen->pEnd = END
#define UPDATE_TOKEN_STREAM(GEN)\
if( GEN->pIn < pTmp ){\
GEN->pIn++;\
}\
GEN->pEnd = pTmp
#define SWAP_DELIMITER(GEN,START,END)\
pTmpIn = GEN->pIn;\
pTmpEnd = GEN->pEnd;\
GEN->pIn = START;\
GEN->pEnd = END
#define RE_SWAP_DELIMITER(GEN)\
GEN->pIn = pTmpIn;\
GEN->pEnd = pTmpEnd
/* Flags related to expression compilation */
#define EXPR_FLAG_LOAD_IDX_STORE 0x001 /* Set the iP2 flag when dealing with the LOAD_IDX instruction */
#define EXPR_FLAG_RDONLY_LOAD 0x002 /* Read-only load, refer to the 'PH7_OP_LOAD' VM instruction for more information */
#define EXPR_FLAG_COMMA_STATEMENT 0x004 /* Treat comma expression as a single statement (used by class attributes) */
/* Forward declaration */
static sxi32 PH7_CompileExpr(ph7_gen_state *pGen, sxi32 iFlags, sxi32(*xTreeValidator)(ph7_gen_state *, ph7_expr_node *));
static GenBlock *PH7_GenStateFetchBlock(GenBlock *pCurrent, sxi32 iBlockType, sxi32 iCount);
static void PH7_GenStateInitBlock(ph7_gen_state *pGen, GenBlock *pBlock, sxi32 iType, sxu32 nFirstInstr, void *pUserData);
static sxi32 PH7_GenStateEnterBlock(ph7_gen_state *pGen, sxi32 iType, sxu32 nFirstInstr, void *pUserData, GenBlock **ppBlock);
static void PH7_GenStateReleaseBlock(GenBlock *pBlock);
static void PH7_GenStateFreeBlock(GenBlock *pBlock);
static sxi32 PH7_GenStateLeaveBlock(ph7_gen_state *pGen, GenBlock **ppBlock);
static sxi32 PH7_GenStateNewJumpFixup(GenBlock *pBlock, sxi32 nJumpType, sxu32 nInstrIdx);
static sxu32 PH7_GenStateFixJumps(GenBlock *pBlock, sxi32 nJumpType, sxu32 nJumpDest);
static sxi32 PH7_GenStateFindLiteral(ph7_gen_state *pGen, const SyString *pValue, sxu32 *pIdx);
static sxi32 PH7_GenStateInstallLiteral(ph7_gen_state *pGen, ph7_value *pObj, sxu32 nIdx);
static ph7_value *PH7_GenStateInstallNumLiteral(ph7_gen_state *pGen, sxu32 *pIdx);
static sxi32 PH7_CompileNumLiteral(ph7_gen_state *pGen, sxi32 iCompileFlag);
PH7_PRIVATE sxi32 PH7_CompileSimpleString(ph7_gen_state *pGen, sxi32 iCompileFlag);
static sxi32 PH7_GenStateProcessStringExpression(ph7_gen_state *pGen, sxu32 nLine, const char *zIn, const char *zEnd);
static ph7_value *PH7_GenStateNewStrObj(ph7_gen_state *pGen, sxi32 *pCount);
static sxi32 PH7_GenStateCompileString(ph7_gen_state *pGen);
PH7_PRIVATE sxi32 PH7_CompileString(ph7_gen_state *pGen, sxi32 iCompileFlag);
static sxi32 PH7_GenStateCompileArrayEntry(ph7_gen_state *pGen, SyToken *pIn, SyToken *pEnd, sxi32 iFlags, sxi32(*xValidator)(ph7_gen_state *, ph7_expr_node *));
static sxi32 PH7_GenStateArrayNodeValidator(ph7_gen_state *pGen, ph7_expr_node *pRoot);
PH7_PRIVATE sxi32 PH7_CompileArray(ph7_gen_state *pGen, sxi32 iCompileFlag);
static sxi32 PH7_GenStateListNodeValidator(ph7_gen_state *pGen, ph7_expr_node *pRoot);
PH7_PRIVATE sxi32 PH7_CompileList(ph7_gen_state *pGen, sxi32 iCompileFlag);
static sxi32 PH7_GenStateCompileFunc(ph7_gen_state *pGen, SyString *pName, sxi32 iFlags, int bHandleClosure, ph7_vm_func **ppFunc);
PH7_PRIVATE sxi32 PH7_CompileLangConstruct(ph7_gen_state *pGen, sxi32 iCompileFlag);
PH7_PRIVATE sxi32 PH7_CompileVariable(ph7_gen_state *pGen, sxi32 iCompileFlag);
static sxi32 PH7_GenStateLoadLiteral(ph7_gen_state *pGen);
static sxi32 PH7_GenStateResolveNamespaceLiteral(ph7_gen_state *pGen);
PH7_PRIVATE sxi32 PH7_CompileLiteral(ph7_gen_state *pGen, sxi32 iCompileFlag);
static sxi32 PH7_ErrorRecover(ph7_gen_state *pGen);
static int PH7_GenStateIsReservedConstant(SyString *pName);
static sxi32 PH7_CompileConstant(ph7_gen_state *pGen);
static sxi32 PH7_CompileContinue(ph7_gen_state *pGen);
static sxi32 PH7_CompileBreak(ph7_gen_state *pGen);
static sxi32 PH7_GenStateNextChunk(ph7_gen_state *pGen);
static sxi32 PH7_CompileBlock(ph7_gen_state *pGen);
static sxi32 PH7_CompileWhile(ph7_gen_state *pGen);
static sxi32 PH7_CompileDoWhile(ph7_gen_state *pGen);
static sxi32 PH7_CompileFor(ph7_gen_state *pGen);
static sxi32 GenStateForEachNodeValidator(ph7_gen_state *pGen, ph7_expr_node *pRoot);
static sxi32 PH7_CompileForeach(ph7_gen_state *pGen);
static sxi32 PH7_CompileIf(ph7_gen_state *pGen);
static sxi32 PH7_CompileReturn(ph7_gen_state *pGen);
static sxi32 PH7_CompileHalt(ph7_gen_state *pGen);
static sxi32 PH7_CompileStatic(ph7_gen_state *pGen);
static sxi32 PH7_CompileVar(ph7_gen_state *pGen);
static sxi32 PH7_CompileNamespace(ph7_gen_state *pGen);
static sxi32 PH7_CompileUsing(ph7_gen_state *pGen);
static sxi32 PH7_GenStateProcessArgValue(ph7_gen_state *pGen, ph7_vm_func_arg *pArg, SyToken *pIn, SyToken *pEnd);
static sxi32 PH7_GenStateCollectFuncArgs(ph7_vm_func *pFunc, ph7_gen_state *pGen, SyToken *pEnd);
static sxi32 PH7_GenStateCompileFuncBody(ph7_gen_state *pGen, ph7_vm_func *pFunc);
static sxi32 PH7_GenStateCompileFunc(ph7_gen_state *pGen, SyString *pName, sxi32 iFlags, int bHandleClosure, ph7_vm_func **ppFunc);
static sxi32 PH7_CompileFunction(ph7_gen_state *pGen);
static sxi32 PH7_GetProtectionLevel(sxi32 nKeyword);
static sxi32 PH7_GenStateCompileClassConstant(ph7_gen_state *pGen, sxi32 iProtection, sxi32 iFlags, ph7_class *pClass);
static sxi32 PH7_GenStateCompileClassAttr(ph7_gen_state *pGen, sxi32 iProtection, sxi32 iFlags, ph7_class *pClass);
static sxi32 PH7_GenStateCompileClassMethod(ph7_gen_state *pGen, sxi32 iProtection, sxi32 iFlags, int doBody, ph7_class *pClass);
static sxi32 PH7_CompileClassInterface(ph7_gen_state *pGen);
static sxi32 PH7_GenStateCompileClass(ph7_gen_state *pGen, sxi32 iFlags);
static sxi32 PH7_CompileVirtualClass(ph7_gen_state *pGen);
static sxi32 PH7_CompileFinalClass(ph7_gen_state *pGen);
static sxi32 PH7_CompileClass(ph7_gen_state *pGen);
static sxi32 PH7_GenStateThrowNodeValidator(ph7_gen_state *pGen, ph7_expr_node *pRoot);
static sxi32 PH7_CompileThrow(ph7_gen_state *pGen);
static sxi32 PH7_CompileCatch(ph7_gen_state *pGen, ph7_exception *pException);
static sxi32 PH7_CompileTry(ph7_gen_state *pGen);
static sxi32 PH7_GenStateCompileSwitchBlock(ph7_gen_state *pGen, sxu32 *pBlockStart);
static sxi32 PH7_GenStateCompileCaseExpr(ph7_gen_state *pGen, ph7_case_expr *pExpr);
static sxi32 PH7_CompileSwitch(ph7_gen_state *pGen);
static sxi32 PH7_GenStateEmitExprCode(ph7_gen_state *pGen, ph7_expr_node *pNode, sxi32 iFlags);
static sxi32 PH7_CompileExpr(ph7_gen_state *pGen, sxi32 iFlags, sxi32(*xTreeValidator)(ph7_gen_state *, ph7_expr_node *));
PH7_PRIVATE ProcNodeConstruct PH7_GetNodeHandler(sxu32 nNodeType);
static ProcLangConstruct PH7_GenStateGetStatementHandler(sxu32 nKeywordID, SyToken *pLookahead);
static int PH7_IsLangConstruct(sxu32 nKeywordID);
static sxi32 PH7_GenStateCompileChunk(ph7_gen_state *pGen, sxi32 iFlags);
static sxi32 PH7_GenStateCompileGlobalScope(ph7_gen_state *pGen);
static sxi32 PH7_CompileScript(ph7_gen_state *pGen, SySet *pTokenSet, sxi32 iFlags);
PH7_PRIVATE sxi32 PH7_InitCodeGenerator(ph7_vm *pVm, ProcConsumer xErr, void *pErrData);
PH7_PRIVATE sxi32 PH7_ResetCodeGenerator(ph7_vm *pVm, ProcConsumer xErr, void *pErrData);
PH7_PRIVATE sxi32 PH7_GenCompileError(ph7_gen_state *pGen, sxi32 nErrType, sxu32 nLine, const char *zFormat, ...);
#endif /* _COMPILER_H_ */

View File

@ -55,14 +55,6 @@
#ifndef PATH_MAX
#define PATH_MAX MAX_PATH
#endif
/*
* Compile time engine version, signature, identification in the symisc source tree
* and copyright notice.
* Each macro have an equivalent C interface associated with it that provide the same
* information but are associated with the library instead of the header file.
* Refer to [ph7_lib_version()], [ph7_lib_signature()], [ph7_lib_ident()] and
* [ph7_lib_copyright()] for more information.
*/
/*
* The PH7_VERSION C preprocessor macroevaluates to a string literal
* that is the ph7 version in the format "X.Y.Z" where X is the major
@ -70,12 +62,6 @@
* number.
*/
#define PH7_VERSION "2.1.4"
/*
* The PH7_VERSION_NUMBER C preprocessor macro resolves to an integer
* with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same
* numbers used in [PH7_VERSION].
*/
#define PH7_VERSION_NUMBER 2001004
/*
* The PH7_SIG C preprocessor macro evaluates to a string
* literal which is the public signature of the ph7 engine.
@ -84,13 +70,6 @@
* Server: YourWebServer/x.x PH7/x.x.x \r\n
*/
#define PH7_SIG "PH7/2.1.4"
/*
* PH7 identification in the Symisc source tree:
* Each particular check-in of a particular software released
* by symisc systems have an unique identifier associated with it.
* This macro hold the one associated with ph7.
*/
#define PH7_IDENT "ph7:c193f4d8a6b90ee60f9afad11840f1010054fdf9"
/*
* Copyright notice.
* If you have any questions about the licensing situation,please
@ -353,6 +332,8 @@ struct SyMutexMethods {
#endif
typedef sxi64 ph7_int64;
#define PH7_APIEXPORT SX_APIEXPORT
#define PH7_APIIMPORT SX_APIIMPORT
/*
* Engine Configuration Commands.
*
@ -441,14 +422,14 @@ typedef sxi64 ph7_int64;
#define PH7_LIB_CONFIG_VFS 6 /* ONE ARGUMENT: const ph7_vfs *pVfs */
/*
* Compile-time flags.
* The new compile interfaces [ph7_compile_v2()] and [ph7_compile_file()] takes
* as their last argument zero or more combination of compile time flags.
* These flags are used to control the behavior of the PH7 compiler while
*
* VmEvalChunk and PH7_CompileAerScript takes iFlags argument
* which controls the behavior of the PH7 Engine while
* processing the input.
* Refer to the official documentation for additional information.
*/
#define PH7_PHP_CODE 0x01 /* PHP Block of Code */
#define PH7_PHP_EXPR 0x02 /* PHP Simple Expression */
#define PH7_AERSCRIPT_CODE 0x01 /* AerScript Code */
#define PH7_AERSCRIPT_CHNK 0x02 /* AerScript Chunk of Code */
#define PH7_AERSCRIPT_EXPR 0x04 /* AerScript Expression */
/*
* Call Context Error Message Severity Level.
*
@ -510,10 +491,13 @@ struct ph7_vfs {
ph7_int64(*xFileAtime)(const char *); /* Gets last access time of file */
ph7_int64(*xFileMtime)(const char *); /* Gets file modification time */
ph7_int64(*xFileCtime)(const char *); /* Gets inode change time of file */
ph7_int64(*xFileGroup)(const char *); /* Gets file group */
ph7_int64(*xFileInode)(const char *); /* Gets file inode */
ph7_int64(*xFileOwner)(const char *); /* Gets file owner */
int (*xStat)(const char *, ph7_value *, ph7_value *); /* Gives information about a file */
int (*xlStat)(const char *, ph7_value *, ph7_value *); /* Gives information about a file */
int (*xIsfile)(const char *); /* Tells whether the filename is a regular file */
int (*xIslink)(const char *); /* Tells whether the filename is a symbolic link */
int (*xIsFile)(const char *); /* Tells whether the filename is a regular file */
int (*xIsLink)(const char *); /* Tells whether the filename is a symbolic link */
int (*xReadable)(const char *); /* Tells whether a file exists and is readable */
int (*xWritable)(const char *); /* Tells whether the filename is writable */
int (*xExecutable)(const char *); /* Tells whether the filename is executable */
@ -606,9 +590,8 @@ PH7_APIEXPORT int ph7_init(ph7 **ppEngine);
PH7_APIEXPORT int ph7_config(ph7 *pEngine, int nConfigOp, ...);
PH7_APIEXPORT int ph7_release(ph7 *pEngine);
/* Compile Interfaces */
PH7_APIEXPORT int ph7_compile(ph7 *pEngine, const char *zSource, int nLen, ph7_vm **ppOutVm);
PH7_APIEXPORT int ph7_compile_v2(ph7 *pEngine, const char *zSource, int nLen, ph7_vm **ppOutVm, int iFlags);
PH7_APIEXPORT int ph7_compile_file(ph7 *pEngine, const char *zFilePath, ph7_vm **ppOutVm, int iFlags);
PH7_APIEXPORT int ph7_compile_code(ph7 *pEngine, const char *zSource, int nLen, ph7_vm **ppOutVm);
PH7_APIEXPORT int ph7_compile_file(ph7 *pEngine, const char *zFilePath, ph7_vm **ppOutVm);
/* Virtual Machine Handling Interfaces */
PH7_APIEXPORT int ph7_vm_config(ph7_vm *pVm, int iConfigOp, ...);
PH7_APIEXPORT int ph7_vm_exec(ph7_vm *pVm, int *pExitStatus);

View File

@ -60,6 +60,7 @@ typedef struct ph7_class ph7_class;
typedef unsigned short int sxu16; /* 16 bits(2 bytes) unsigned integer */
typedef int sxi32; /* 32 bits(4 bytes) integer */
typedef unsigned int sxu32; /* 32 bits(4 bytes) unsigned integer */
typedef int sxbool; /* boolean */
typedef long sxptr;
typedef unsigned long sxuptr;
typedef long sxlong;
@ -1255,38 +1256,16 @@ struct ph7_vm {
#define PH7_VM_EXEC 0xCAFE2DAD /* VM executing PH7 bytecode */
#define PH7_VM_STALE 0xBAD1DEAD /* Stale VM */
/*
* Error codes according to the PHP language reference manual.
* Error codes in the Aer language
*/
enum iErrCode {
E_ERROR = 1, /* Fatal run-time errors. These indicate errors that can not be recovered
* from, such as a memory allocation problem. Execution of the script is
* halted.
* The only fatal error under PH7 is an out-of-memory. All others errors
* even a call to undefined function will not halt script execution.
*/
E_WARNING = 2, /* Run-time warnings (non-fatal errors). Execution of the script is not halted. */
E_PARSE = 4, /* Compile-time parse errors. Parse errors should only be generated by the parser.*/
E_NOTICE = 8, /* Run-time notices. Indicate that the script encountered something that could
* indicate an error, but could also happen in the normal course of running a script.
*/
E_CORE_WARNING = 16, /* Fatal errors that occur during PHP's initial startup. This is like an E_ERROR
* except it is generated by the core of PHP.
*/
E_USER_ERROR = 256, /* User-generated error message.*/
E_USER_WARNING = 512, /* User-generated warning message.*/
E_USER_NOTICE = 1024, /* User-generated notice message.*/
E_STRICT = 2048, /* Enable to have PHP suggest changes to your code which will ensure the best interoperability
* and forward compatibility of your code.
*/
E_RECOVERABLE_ERROR = 4096, /* Catchable fatal error. It indicates that a probably dangerous error ocurred, but did not
* leave the Engine in an unstable state. If the error is not caught by a user defined handle
* the application aborts as it was an E_ERROR.
*/
E_DEPRECATED = 8192, /* Run-time notices. Enable this to receive warnings about code that will not
* work in future versions.
*/
E_USER_DEPRECATED = 16384, /* User-generated warning message. */
E_ALL = 32767 /* All errors and warnings */
E_ERROR = 1, /* Fatal errors. These indicate errors that can not be recovered from,
* such as a memory allocation problem or compile-time parse/syntax errors.
* Execution of the script is halted. */
E_WARNING = 2, /* Run-time warnings (non-fatal errors). Execution of the script is not halted. */
E_NOTICE = 4, /* Run-time notices. Indicate that the script encountered something that could
* indicate an error, but could also happen in the normal course of running a script. */
E_DEPRECATED = 8 /* Run-time notices, informing about a code that will not work in future versions. */
};
/*
* Each VM instruction resulting from compiling a PHP script is represented
@ -1472,60 +1451,60 @@ enum ph7_expr_id {
* You cannot use any of the following words as constants, class names, function or method names.
* Using them as variable names is generally OK, but could lead to confusion.
*/
#define PH7_TKWRD_EXTENDS 1 /* extends */
#define PH7_TKWRD_SWITCH 3 /* switch */
#define PH7_TKWRD_INTERFACE 5 /* interface */
#define PH7_KEYWORD_EXTENDS 1 /* extends */
#define PH7_KEYWORD_SWITCH 3 /* switch */
#define PH7_KEYWORD_INTERFACE 5 /* interface */
/* The number '8' is reserved for PH7_TK_ID */
#define PH7_TKWRD_REQONCE 9 /* require_once */
#define PH7_TKWRD_REQUIRE 10 /* require */
#define PH7_TKWRD_ELIF 0x4000000 /* elseif: MUST BE A POWER OF TWO */
#define PH7_TKWRD_ELSE 0x8000000 /* else: MUST BE A POWER OF TWO */
#define PH7_TKWRD_IF 13 /* if */
#define PH7_TKWRD_FINAL 14 /* final */
#define PH7_TKWRD_LIST 15 /* list */
#define PH7_TKWRD_STATIC 16 /* static */
#define PH7_TKWRD_CASE 17 /* case */
#define PH7_TKWRD_SELF 18 /* self */
#define PH7_TKWRD_FUNCTION 19 /* function */
#define PH7_TKWRD_NAMESPACE 20 /* namespace */
#define PH7_TKWRD_CLONE 0x80 /* clone: MUST BE A POWER OF TWO */
#define PH7_TKWRD_NEW 0x100 /* new: MUST BE A POWER OF TWO */
#define PH7_TKWRD_CONST 22 /* const */
#define PH7_TKWRD_THROW 23 /* throw */
#define PH7_TKWRD_USING 24 /* using */
#define PH7_TKWRD_WHILE 26 /* while */
#define PH7_TKWRD_EVAL 27 /* eval */
#define PH7_TKWRD_VAR 28 /* var */
#define PH7_TKWRD_ARRAY 0x200 /* array: MUST BE A POWER OF TWO */
#define PH7_TKWRD_VIRTUAL 29 /* virtual */
#define PH7_TKWRD_TRY 30 /* try */
#define PH7_TKWRD_DEFAULT 31 /* default */
#define PH7_TKWRD_CLASS 32 /* class */
#define PH7_TKWRD_AS 33 /* as */
#define PH7_TKWRD_CONTINUE 34 /* continue */
#define PH7_TKWRD_EXIT 35 /* exit */
#define PH7_TKWRD_IMPLEMENTS 39 /* implements */
#define PH7_TKWRD_INCONCE 40 /* include_once */
#define PH7_TKWRD_INCLUDE 41 /* include */
#define PH7_TKWRD_EMPTY 42 /* empty */
#define PH7_TKWRD_INSTANCEOF 0x800 /* instanceof: MUST BE A POWER OF TWO */
#define PH7_TKWRD_ISSET 43 /* isset */
#define PH7_TKWRD_PARENT 44 /* parent */
#define PH7_TKWRD_PRIVATE 45 /* private */
#define PH7_TKWRD_FOR 48 /* for */
#define PH7_TKWRD_FOREACH 49 /* foreach */
#define PH7_TKWRD_PROTECTED 50 /* protected */
#define PH7_TKWRD_DO 51 /* do */
#define PH7_TKWRD_PUBLIC 52 /* public */
#define PH7_TKWRD_CATCH 53 /* catch */
#define PH7_TKWRD_RETURN 54 /* return */
#define PH7_TKWRD_UNSET 0x2000 /* unset: MUST BE A POWER OF TWO */
#define PH7_TKWRD_BREAK 55 /* break */
#define PH7_TKWRD_BOOL 0x8000 /* bool: MUST BE A POWER OF TWO */
#define PH7_TKWRD_INT 0x10000 /* int: MUST BE A POWER OF TWO */
#define PH7_TKWRD_FLOAT 0x20000 /* float: MUST BE A POWER OF TWO */
#define PH7_TKWRD_STRING 0x40000 /* string: MUST BE A POWER OF TWO */
#define PH7_TKWRD_OBJECT 0x80000 /* object: MUST BE A POWER OF TWO */
#define PH7_KEYWORD_IMPORT 9 /* import */
#define PH7_KEYWORD_REQUIRE 10 /* require */
#define PH7_KEYWORD_ELIF 0x4000000 /* elseif: MUST BE A POWER OF TWO */
#define PH7_KEYWORD_ELSE 0x8000000 /* else: MUST BE A POWER OF TWO */
#define PH7_KEYWORD_IF 13 /* if */
#define PH7_KEYWORD_FINAL 14 /* final */
#define PH7_KEYWORD_LIST 15 /* list */
#define PH7_KEYWORD_STATIC 16 /* static */
#define PH7_KEYWORD_CASE 17 /* case */
#define PH7_KEYWORD_SELF 18 /* self */
#define PH7_KEYWORD_FUNCTION 19 /* function */
#define PH7_KEYWORD_NAMESPACE 20 /* namespace */
#define PH7_KEYWORD_CLONE 0x80 /* clone: MUST BE A POWER OF TWO */
#define PH7_KEYWORD_NEW 0x100 /* new: MUST BE A POWER OF TWO */
#define PH7_KEYWORD_CONST 22 /* const */
#define PH7_KEYWORD_THROW 23 /* throw */
#define PH7_KEYWORD_USING 24 /* using */
#define PH7_KEYWORD_WHILE 26 /* while */
#define PH7_KEYWORD_EVAL 27 /* eval */
#define PH7_KEYWORD_VAR 28 /* var */
#define PH7_KEYWORD_ARRAY 0x200 /* array: MUST BE A POWER OF TWO */
#define PH7_KEYWORD_VIRTUAL 29 /* virtual */
#define PH7_KEYWORD_TRY 30 /* try */
#define PH7_KEYWORD_DEFAULT 31 /* default */
#define PH7_KEYWORD_CLASS 32 /* class */
#define PH7_KEYWORD_AS 33 /* as */
#define PH7_KEYWORD_CONTINUE 34 /* continue */
#define PH7_KEYWORD_EXIT 35 /* exit */
#define PH7_KEYWORD_FINALLY 36 /* finally */
#define PH7_KEYWORD_IMPLEMENTS 39 /* implements */
#define PH7_KEYWORD_INCLUDE 41 /* include */
#define PH7_KEYWORD_EMPTY 42 /* empty */
#define PH7_KEYWORD_INSTANCEOF 0x800 /* instanceof: MUST BE A POWER OF TWO */
#define PH7_KEYWORD_ISSET 43 /* isset */
#define PH7_KEYWORD_PARENT 44 /* parent */
#define PH7_KEYWORD_PRIVATE 45 /* private */
#define PH7_KEYWORD_FOR 48 /* for */
#define PH7_KEYWORD_FOREACH 49 /* foreach */
#define PH7_KEYWORD_PROTECTED 50 /* protected */
#define PH7_KEYWORD_DO 51 /* do */
#define PH7_KEYWORD_PUBLIC 52 /* public */
#define PH7_KEYWORD_CATCH 53 /* catch */
#define PH7_KEYWORD_RETURN 54 /* return */
#define PH7_KEYWORD_UNSET 0x2000 /* unset: MUST BE A POWER OF TWO */
#define PH7_KEYWORD_BREAK 55 /* break */
#define PH7_KEYWORD_BOOL 0x8000 /* bool: MUST BE A POWER OF TWO */
#define PH7_KEYWORD_INT 0x10000 /* int: MUST BE A POWER OF TWO */
#define PH7_KEYWORD_FLOAT 0x20000 /* float: MUST BE A POWER OF TWO */
#define PH7_KEYWORD_STRING 0x40000 /* string: MUST BE A POWER OF TWO */
#define PH7_KEYWORD_OBJECT 0x80000 /* object: MUST BE A POWER OF TWO */
/* JSON encoding/decoding related definition */
enum json_err_code {
JSON_ERROR_NONE = 0, /* No error has occurred. */
@ -1572,7 +1551,7 @@ PH7_PRIVATE sxi32 PH7_MemObjToBool(ph7_value *pObj);
PH7_PRIVATE sxi64 PH7_TokenValueToInt64(SyString *pData);
/* lex.c function prototypes */
PH7_PRIVATE sxi32 PH7_TokenizeRawText(const char *zInput, sxu32 nLen, SySet *pOut);
PH7_PRIVATE sxi32 PH7_TokenizePHP(const char *zInput, sxu32 nLen, sxu32 nLineStart, SySet *pOut);
PH7_PRIVATE sxi32 PH7_TokenizeAerScript(const char *zInput, sxu32 nLen, sxu32 nLineStart, SySet *pOut);
/* vm.c function prototypes */
PH7_PRIVATE void PH7_VmReleaseContextValue(ph7_context *pCtx, ph7_value *pValue);
PH7_PRIVATE sxi32 PH7_VmInitFuncState(ph7_vm *pVm, ph7_vm_func *pFunc, const char *zName, sxu32 nByte,
@ -1627,7 +1606,6 @@ PH7_PRIVATE int PH7_Utf8Read(
const unsigned char **pzNext /* Write first byte past UTF-8 char here */
);
/* parse.c function prototypes */
PH7_PRIVATE int PH7_IsLangConstruct(sxu32 nKeyID, sxu8 bCheckFunc);
PH7_PRIVATE sxi32 PH7_ExprMakeTree(ph7_gen_state *pGen, SySet *pExprNode, ph7_expr_node **ppRoot);
PH7_PRIVATE sxi32 PH7_GetNextExpr(SyToken *pStart, SyToken *pEnd, SyToken **ppNext);
PH7_PRIVATE void PH7_DelimitNestedTokens(SyToken *pIn, SyToken *pEnd, sxu32 nTokStart, sxu32 nTokEnd, SyToken **ppEnd);
@ -1642,11 +1620,11 @@ PH7_PRIVATE sxi32 PH7_CompileSimpleString(ph7_gen_state *pGen, sxi32 iCompileFla
PH7_PRIVATE sxi32 PH7_CompileString(ph7_gen_state *pGen, sxi32 iCompileFlag);
PH7_PRIVATE sxi32 PH7_CompileArray(ph7_gen_state *pGen, sxi32 iCompileFlag);
PH7_PRIVATE sxi32 PH7_CompileList(ph7_gen_state *pGen, sxi32 iCompileFlag);
PH7_PRIVATE sxi32 PH7_CompileAnnonFunc(ph7_gen_state *pGen, sxi32 iCompileFlag);
PH7_PRIVATE sxi32 PH7_CompileClosure(ph7_gen_state *pGen, sxi32 iCompileFlag);
PH7_PRIVATE sxi32 PH7_InitCodeGenerator(ph7_vm *pVm, ProcConsumer xErr, void *pErrData);
PH7_PRIVATE sxi32 PH7_ResetCodeGenerator(ph7_vm *pVm, ProcConsumer xErr, void *pErrData);
PH7_PRIVATE sxi32 PH7_GenCompileError(ph7_gen_state *pGen, sxi32 nErrType, sxu32 nLine, const char *zFormat, ...);
PH7_PRIVATE sxi32 PH7_CompileScript(ph7_vm *pVm, SyString *pScript, sxi32 iFlags);
PH7_PRIVATE sxi32 PH7_CompileAerScript(ph7_vm *pVm, SyString *pScript, sxi32 iFlags);
/* constant.c function prototypes */
PH7_PRIVATE void PH7_RegisterBuiltInConstant(ph7_vm *pVm);
/* builtin.c function prototypes */

View File

@ -624,6 +624,70 @@ static int PH7_builtin_hypot(ph7_context *pCtx, int nArg, ph7_value **apArg) {
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float/int64 max(float/int64 $arg )
* Absolute value.
* Parameter
* The number to process.
* Return
* The absolute value of number.
*/
static int PH7_builtin_max(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(nArg < 2) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
if(ph7_value_is_float(apArg[0]) && ph7_value_is_float(apArg[1])) {
double a, b;
a = ph7_value_to_double(apArg[0]);
b = ph7_value_to_double(apArg[1]);
/* Perform the requested operation */
ph7_result_double(pCtx, SXMAX(a, b));
} else if(ph7_value_is_int(apArg[0]) && ph7_value_is_int(apArg[1])) {
sxi64 a, b;
a = ph7_value_to_int64(apArg[0]);
b = ph7_value_to_int64(apArg[1]);
/* Perform the requested operation */
ph7_result_int64(pCtx, SXMAX(a, b));
} else {
/* Two parameters of different type */
ph7_result_int(pCtx, 0);
}
return PH7_OK;
}
/*
* float/int64 min(float/int64 $arg )
* Absolute value.
* Parameter
* The number to process.
* Return
* The absolute value of number.
*/
static int PH7_builtin_min(ph7_context *pCtx, int nArg, ph7_value **apArg) {
if(nArg < 2) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
if(ph7_value_is_float(apArg[0]) && ph7_value_is_float(apArg[1])) {
double a, b;
a = ph7_value_to_double(apArg[0]);
b = ph7_value_to_double(apArg[1]);
/* Perform the requested operation */
ph7_result_double(pCtx, SXMIN(a, b));
} else if(ph7_value_is_int(apArg[0]) && ph7_value_is_int(apArg[1])) {
sxi64 a, b;
a = ph7_value_to_int64(apArg[0]);
b = ph7_value_to_int64(apArg[1]);
/* Perform the requested operation */
ph7_result_int64(pCtx, SXMIN(a, b));
} else {
/* Two parameters of different type */
ph7_result_int(pCtx, 0);
}
return PH7_OK;
}
PH7_PRIVATE sxi32 initializeModule(ph7_vm *pVm, ph7_real *ver, SyString *desc) {
sxi32 rc;

View File

@ -51,6 +51,8 @@ static int PH7_builtin_pow(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_pi(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_fmod(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_hypot(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_max(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_min(ph7_context *pCtx, int nArg, ph7_value **apArg);
PH7_PRIVATE sxi32 initializeModule(ph7_vm *pVm, ph7_real *ver, SyString *desc);
static const ph7_builtin_constant mathConstList[] = {
@ -94,7 +96,9 @@ static const ph7_builtin_func mathFuncList[] = {
{ "pow", PH7_builtin_pow },
{ "pi", PH7_builtin_pi },
{ "fmod", PH7_builtin_fmod },
{ "hypot", PH7_builtin_hypot }
{ "hypot", PH7_builtin_hypot },
{ "max", PH7_builtin_max },
{ "min", PH7_builtin_min }
};
#endif

View File

@ -186,8 +186,7 @@ int main(int argc, char **argv) {
rc = ph7_compile_file(
pEngine, /* PH7 Engine */
argv[n], /* Path to the PHP file to compile */
&pVm, /* OUT: Compiled PHP program */
0 /* IN: Compile flags */
&pVm /* OUT: Compiled PHP program */
);
if(rc != PH7_OK) { /* Compile error */
if(rc == PH7_IO_ERR) {

View File

@ -1,4 +1,4 @@
class Main {
class Program {
private function num2Roman($num) {
$n = intval($num);
@ -15,7 +15,7 @@ class Main {
return $result;
}
public function __construct() {
public function main() {
print(' 7 => ' + $this->num2Roman(7) + "\n");
print(' 9 => ' + $this->num2Roman(9) + "\n");
print(' 11 => ' + $this->num2Roman(11) + "\n");
@ -28,5 +28,3 @@ class Main {
}
}
new Main();

View File

@ -1,6 +1,6 @@
class Main {
class Program {
function __construct() {
function main() {
$this->b($this->a('First A'), $this->a('Second A'), $this->a('Third A'));
}
@ -19,5 +19,3 @@ class Main {
}
}
new Main();

View File

@ -1,9 +1,7 @@
class Main {
class Program {
public function __construct() {
public function main() {
print('Hello world!');
}
}
new Main();

View File

@ -1,9 +1,7 @@
final class Main {
function __construct() {
final class Program {
function main() {
var_dump(function_exists('dummy_function'));
var_dump(import('dummy'));
var_dump(function_exists('dummy_function'));
}
}
new Main();

View File

@ -1,11 +1,11 @@
class Main {
class Program {
private $s = 'monkey';
private $t = 'many monkeys';
private $n = 43951789;
private $u = -43951789;
private $c = 65;
public function __construct() {
public function main() {
$this->testMonkey();
$this->testNumbers();
}
@ -36,5 +36,3 @@ class Main {
}
}
new Main();

View File

@ -22,13 +22,11 @@ final class Test {
}
}
final class Main {
public function __construct() {
final class Program {
public function main() {
$testA = Test::getInstance();
$testA->set(5);
$testB = Test::getInstance();
var_dump($testB->get());
}
} /* class */
new Main();

View File

@ -1,6 +1,6 @@
class Main {
class Program {
function __construct() {
function main() {
$foo = '0';
var_dump($foo);
$foo += 2;
@ -23,5 +23,3 @@ class Main {
var_dump($foo);
}
}
new Main();

View File

@ -47,13 +47,11 @@ class Unicode {
}
final class Main {
final class Program {
public function __construct() {
public function main() {
$unicode = new Unicode();
var_dump($unicode->unicon("ИфйжБЦ"));
}
}
new Main();

View File

@ -1,7 +1,7 @@
class Main {
class Program {
private $概要 = "AerScript Interpreter";
public function __construct() {
public function main() {
$this->ダウンロード();
var_dump($this->概要);
var_dump($this->isUTF8('hello'));
@ -39,5 +39,3 @@ class Main {
return true;
}
}
new Main();