Compiler rework merge #43
56
engine/api.c
56
engine/api.c
@ -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);
|
||||
|
1052
engine/compiler.c
1052
engine/compiler.c
File diff suppressed because it is too large
Load Diff
124
engine/lexer.c
124
engine/lexer.c
@ -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 */
|
||||
|
@ -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);
|
||||
|
382
engine/vfs.c
382
engine/vfs.c
@ -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 },
|
||||
|
394
engine/vm.c
394
engine/vm.c
@ -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
156
include/compiler.h
Normal 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_ */
|
@ -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);
|
||||
|
152
include/ph7int.h
152
include/ph7int.h
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -1,9 +1,7 @@
|
||||
class Main {
|
||||
class Program {
|
||||
|
||||
public function __construct() {
|
||||
public function main() {
|
||||
print('Hello world!');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
new Main();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user