diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..a3635ed --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +custom: https://paypal.me/pools/c/8hAZMn97vE diff --git a/engine/api.c b/engine/api.c index 798437c..455ea4f 100644 --- a/engine/api.c +++ b/engine/api.c @@ -27,14 +27,6 @@ */ static struct Global_Data { SyMemBackend sAllocator; /* Global low level memory allocator */ - const SyMutexMethods *pMutexMethods; /* Mutex methods */ - SyMutex *pMutex; /* Global mutex */ - sxu32 nThreadingLevel; /* Threading level: 0 == Single threaded/1 == Multi-Threaded - * The threading level can be set using the [ph7_lib_config()] - * interface with a configuration verb set to - * PH7_LIB_CONFIG_THREAD_LEVEL_SINGLE or - * PH7_LIB_CONFIG_THREAD_LEVEL_MULTI - */ const ph7_vfs *pVfs; /* Underlying virtual file system */ sxi32 nEngine; /* Total number of active engines */ ph7 *pEngines; /* List of active engine */ @@ -44,23 +36,9 @@ static struct Global_Data { 0, 0, 0, - 0, - 0, - 0, 0 }; #define PH7_LIB_MAGIC 0xEA1495BA -/* - * Supported threading level. - * PH7_THREAD_LEVEL_SINGLE: - * In this mode,mutexing is disabled and the library can only be used by a single thread. - * PH7_THREAD_LEVEL_MULTI - * In this mode, all mutexes including the recursive mutexes on [ph7] objects - * are enabled so that the application is free to share the same engine - * between different threads at the same time. - */ -#define PH7_THREAD_LEVEL_SINGLE 1 -#define PH7_THREAD_LEVEL_MULTI 2 /* * Configure a running PH7 engine instance. * return PH7_OK on success.Any other return @@ -186,63 +164,6 @@ static sxi32 PH7CoreConfigure(sxi32 nOp, va_list ap) { sMPGlobal.sAllocator.pUserData = pUserData; break; } - case PH7_LIB_CONFIG_USER_MUTEX: { - /* Use an alternative low-level mutex subsystem */ - const SyMutexMethods *pMethods = va_arg(ap, const SyMutexMethods *); - if(pMethods == 0) { - rc = PH7_CORRUPT; - } - /* Sanity check */ - if(pMethods->xEnter == 0 || pMethods->xLeave == 0 || pMethods->xNew == 0) { - /* At least three criticial callbacks xEnter(),xLeave() and xNew() must be supplied */ - rc = PH7_CORRUPT; - break; - } - if(sMPGlobal.pMutexMethods) { - /* Overwrite the previous mutex subsystem */ - SyMutexRelease(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); - if(sMPGlobal.pMutexMethods->xGlobalRelease) { - sMPGlobal.pMutexMethods->xGlobalRelease(); - } - sMPGlobal.pMutex = 0; - } - /* Initialize and install the new mutex subsystem */ - if(pMethods->xGlobalInit) { - rc = pMethods->xGlobalInit(); - if(rc != PH7_OK) { - break; - } - } - /* Create the global mutex */ - sMPGlobal.pMutex = pMethods->xNew(SXMUTEX_TYPE_FAST); - if(sMPGlobal.pMutex == 0) { - /* - * If the supplied mutex subsystem is so sick that we are unable to - * create a single mutex,there is no much we can do here. - */ - if(pMethods->xGlobalRelease) { - pMethods->xGlobalRelease(); - } - rc = PH7_CORRUPT; - break; - } - sMPGlobal.pMutexMethods = pMethods; - if(sMPGlobal.nThreadingLevel == 0) { - /* Set a default threading level */ - sMPGlobal.nThreadingLevel = PH7_THREAD_LEVEL_MULTI; - } - break; - } - case PH7_LIB_CONFIG_THREAD_LEVEL_SINGLE: - /* Single thread mode(Only one thread is allowed to play with the library) */ - sMPGlobal.nThreadingLevel = PH7_THREAD_LEVEL_SINGLE; - break; - case PH7_LIB_CONFIG_THREAD_LEVEL_MULTI: - /* Multi-threading mode (library is thread safe and PH7 engines and virtual machines - * may be shared between multiple threads). - */ - sMPGlobal.nThreadingLevel = PH7_THREAD_LEVEL_MULTI; - break; default: /* Unknown configuration option */ rc = PH7_CORRUPT; @@ -278,8 +199,6 @@ int ph7_lib_config(int nConfigOp, ...) { */ static sxi32 PH7CoreInitialize(void) { const ph7_vfs *pVfs; /* Built-in vfs */ - const SyMutexMethods *pMutexMethods = 0; - SyMutex *pMaster = 0; int rc; /* * If the library is already initialized,then a call to this routine @@ -292,30 +211,6 @@ static sxi32 PH7CoreInitialize(void) { pVfs = PH7_ExportBuiltinVfs(); /* Install it */ ph7_lib_config(PH7_LIB_CONFIG_VFS, pVfs); - if(sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_SINGLE) { - pMutexMethods = sMPGlobal.pMutexMethods; - if(pMutexMethods == 0) { - /* Use the built-in mutex subsystem */ - pMutexMethods = SyMutexExportMethods(); - if(pMutexMethods == 0) { - return PH7_CORRUPT; /* Can't happen */ - } - /* Install the mutex subsystem */ - rc = ph7_lib_config(PH7_LIB_CONFIG_USER_MUTEX, pMutexMethods); - if(rc != PH7_OK) { - return rc; - } - } - /* Obtain a static mutex so we can initialize the library without calling malloc() */ - pMaster = SyMutexNew(pMutexMethods, SXMUTEX_TYPE_STATIC_1); - if(pMaster == 0) { - return PH7_CORRUPT; /* Can't happen */ - } - } - /* Lock the master mutex */ - rc = PH7_OK; - SyMutexEnter(pMutexMethods, pMaster); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ - if(sMPGlobal.nMagic != PH7_LIB_MAGIC) { if(sMPGlobal.sAllocator.pMethods == 0) { /* Install a memory subsystem */ rc = ph7_lib_config(PH7_LIB_CONFIG_USER_MALLOC, 0); /* zero mean use the built-in memory backend */ @@ -324,20 +219,10 @@ static sxi32 PH7CoreInitialize(void) { goto End; } } - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE) { - /* Protect the memory allocation subsystem */ - rc = SyMemBackendMakeThreadSafe(&sMPGlobal.sAllocator, sMPGlobal.pMutexMethods); - if(rc != PH7_OK) { - goto End; - } - } /* Our library is initialized,set the magic number */ sMPGlobal.nMagic = PH7_LIB_MAGIC; rc = PH7_OK; - } /* sMPGlobal.nMagic != PH7_LIB_MAGIC */ End: - /* Unlock the master mutex */ - SyMutexLeave(pMutexMethods, pMaster); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ return rc; } /* @@ -391,18 +276,6 @@ static void PH7CoreShutdown(void) { pEngine = pNext; sMPGlobal.nEngine--; } - /* Release the mutex subsystem */ - if(sMPGlobal.pMutexMethods) { - if(sMPGlobal.pMutex) { - SyMutexRelease(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); - sMPGlobal.pMutex = 0; - } - if(sMPGlobal.pMutexMethods->xGlobalRelease) { - sMPGlobal.pMutexMethods->xGlobalRelease(); - } - sMPGlobal.pMutexMethods = 0; - } - sMPGlobal.nThreadingLevel = 0; if(sMPGlobal.sAllocator.pMethods) { /* Release the memory backend */ SyMemBackendRelease(&sMPGlobal.sAllocator); @@ -429,13 +302,7 @@ int ph7_lib_is_threadsafe(void) { if(sMPGlobal.nMagic != PH7_LIB_MAGIC) { return 0; } - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE) { - /* Muli-threading support is enabled */ - return 1; - } else { - /* Single-threading */ - return 0; - } + return 0; } /* * [CAPIREF: ph7_lib_version()] @@ -468,17 +335,9 @@ int ph7_config(ph7 *pEngine, int nConfigOp, ...) { if(PH7_ENGINE_MISUSE(pEngine)) { return PH7_CORRUPT; } - /* 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 */ - } va_start(ap, nConfigOp); rc = EngineConfig(&(*pEngine), nConfigOp, ap); va_end(ap); - /* Leave engine mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ return rc; } /* @@ -510,28 +369,15 @@ int ph7_init(ph7 **ppEngine) { if(rc != PH7_OK) { goto Release; } - SyMemBackendDisbaleMutexing(&pEngine->sAllocator); /* Default configuration */ SyBlobInit(&pEngine->xConf.sErrConsumer, &pEngine->sAllocator); /* Install a default compile-time error consumer routine */ ph7_config(pEngine, PH7_CONFIG_ERR_OUTPUT, PH7_VmBlobConsumer, &pEngine->xConf.sErrConsumer); /* Built-in vfs */ pEngine->pVfs = sMPGlobal.pVfs; - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE) { - /* Associate a recursive mutex with this instance */ - pEngine->pMutex = SyMutexNew(sMPGlobal.pMutexMethods, SXMUTEX_TYPE_RECURSIVE); - if(pEngine->pMutex == 0) { - rc = PH7_NOMEM; - goto Release; - } - } /* Link to the list of active engines */ - /* Enter the global mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ MACRO_LD_PUSH(sMPGlobal.pEngines, pEngine); sMPGlobal.nEngine++; - /* Leave the global mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ /* Write a pointer to the new instance */ *ppEngine = pEngine; return PH7_OK; @@ -549,25 +395,11 @@ int ph7_release(ph7 *pEngine) { if(PH7_ENGINE_MISUSE(pEngine)) { return PH7_CORRUPT; } - /* 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 */ - } /* Release the engine */ rc = EngineRelease(&(*pEngine)); - /* Leave engine mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - /* Release engine mutex */ - SyMutexRelease(sMPGlobal.pMutexMethods, pEngine->pMutex) /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - /* Enter the global mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ /* Unlink from the list of active engines */ MACRO_LD_REMOVE(sMPGlobal.pEngines, pEngine); sMPGlobal.nEngine--; - /* Leave the global mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ /* Release the memory chunk allocated to this engine */ SyMemBackendPoolFree(&sMPGlobal.sAllocator, pEngine); return rc; @@ -664,13 +496,6 @@ static sxi32 ProcessSourceFile( if(rc != PH7_OK) { goto Release; } - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE) { - /* Associate a recursive mutex with this instance */ - pVm->pMutex = SyMutexNew(sMPGlobal.pMutexMethods, SXMUTEX_TYPE_RECURSIVE); - if(pVm->pMutex == 0) { - goto Release; - } - } /* Script successfully compiled,link to the list of active virtual machines */ MACRO_LD_PUSH(pEngine->pVms, pVm); pEngine->iVm++; @@ -697,16 +522,8 @@ int ph7_compile_code(ph7 *pEngine, const char *zSource, int nLen, ph7_vm **ppOut nLen = (int)SyStrlen(zSource); } SyStringInitFromBuf(&sScript, zSource, nLen); - /* 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 */ - } /* Compile the script */ rc = ProcessSourceFile(&(*pEngine), ppOutVm, &sScript, 0); - /* Leave engine mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ /* Compilation result */ return rc; } @@ -721,12 +538,6 @@ int ph7_compile_file(ph7 *pEngine, const char *zFilePath, ph7_vm **ppOutVm) { if(PH7_ENGINE_MISUSE(pEngine) || SX_EMPTY_STR(zFilePath)) { return PH7_CORRUPT; } - /* 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 */ - } /* * Check if the underlying vfs implement the memory map * [i.e: mmap() under UNIX/MapViewOfFile() under windows] function. @@ -754,8 +565,6 @@ int ph7_compile_file(ph7 *pEngine, const char *zFilePath, ph7_vm **ppOutVm) { } } } - /* Leave engine mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ /* Compilation result */ return rc; } @@ -787,18 +596,10 @@ int ph7_vm_config(ph7_vm *pVm, int iConfigOp, ...) { if(PH7_VM_MISUSE(pVm)) { return PH7_CORRUPT; } - /* Acquire VM mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_VM_RELEASE(pVm)) { - return PH7_ABORT; /* Another thread have released this instance */ - } /* Configure the virtual machine */ va_start(ap, iConfigOp); rc = PH7_VmConfigure(&(*pVm), iConfigOp, ap); va_end(ap); - /* Leave VM mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ return rc; } /* @@ -811,20 +612,12 @@ int ph7_vm_exec(ph7_vm *pVm, int *pExitStatus) { if(PH7_VM_MISUSE(pVm)) { return PH7_CORRUPT; } - /* Acquire VM mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_VM_RELEASE(pVm)) { - return PH7_ABORT; /* Another thread have released this instance */ - } /* Execute PH7 byte-code */ rc = PH7_VmByteCodeExec(&(*pVm)); if(pExitStatus) { /* Exit status */ *pExitStatus = pVm->iExitStatus; } - /* Leave VM mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ /* Execution result */ return rc; } @@ -838,15 +631,7 @@ int ph7_vm_reset(ph7_vm *pVm) { if(PH7_VM_MISUSE(pVm)) { return PH7_CORRUPT; } - /* Acquire VM mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_VM_RELEASE(pVm)) { - return PH7_ABORT; /* Another thread have released this instance */ - } rc = PH7_VmReset(&(*pVm)); - /* Leave VM mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ return rc; } /* @@ -860,32 +645,14 @@ int ph7_vm_release(ph7_vm *pVm) { if(PH7_VM_MISUSE(pVm)) { return PH7_CORRUPT; } - /* Acquire VM mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_VM_RELEASE(pVm)) { - return PH7_ABORT; /* Another thread have released this instance */ - } pEngine = pVm->pEngine; rc = PH7_VmRelease(&(*pVm)); - /* Leave VM mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - /* free VM mutex */ - SyMutexRelease(sMPGlobal.pMutexMethods, pVm->pMutex); if(rc == PH7_OK) { /* Unlink from the list of active VM */ - /* 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 */ - } MACRO_LD_REMOVE(pEngine->pVms, pVm); pEngine->iVm--; /* Release the memory chunk allocated to this VM */ SyMemBackendPoolFree(&pEngine->sAllocator, pVm); - /* Leave engine mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ } return rc; } @@ -907,16 +674,8 @@ int ph7_create_function(ph7_vm *pVm, const char *zName, int (*xFunc)(ph7_context if(sName.nByte < 1 || xFunc == 0) { return PH7_CORRUPT; } - /* Acquire VM mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_VM_RELEASE(pVm)) { - return PH7_ABORT; /* Another thread have released this instance */ - } /* Install the foreign function */ rc = PH7_VmInstallForeignFunction(&(*pVm), &sName, xFunc, pUserData); - /* Leave VM mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ return rc; } /* @@ -930,12 +689,6 @@ int ph7_delete_function(ph7_vm *pVm, const char *zName) { if(PH7_VM_MISUSE(pVm)) { return PH7_CORRUPT; } - /* Acquire VM mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_VM_RELEASE(pVm)) { - return PH7_ABORT; /* Another thread have released this instance */ - } /* Perform the deletion */ rc = SyHashDeleteEntry(&pVm->hHostFunction, (const void *)zName, SyStrlen(zName), (void **)&pFunc); if(rc == PH7_OK) { @@ -944,8 +697,6 @@ int ph7_delete_function(ph7_vm *pVm, const char *zName) { SyMemBackendFree(&pVm->sAllocator, (void *)SyStringData(&pFunc->sName)); SyMemBackendPoolFree(&pVm->sAllocator, pFunc); } - /* Leave VM mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ return rc; } /* @@ -970,16 +721,8 @@ int ph7_create_constant(ph7_vm *pVm, const char *zName, void (*xExpand)(ph7_valu if(xExpand == 0) { return PH7_CORRUPT; } - /* Acquire VM mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_VM_RELEASE(pVm)) { - return PH7_ABORT; /* Another thread have released this instance */ - } /* Perform the registration */ rc = PH7_VmRegisterConstant(&(*pVm), &sName, xExpand, pUserData, TRUE); - /* Leave VM mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ return rc; } /* @@ -993,12 +736,6 @@ int ph7_delete_constant(ph7_vm *pVm, const char *zName) { if(PH7_VM_MISUSE(pVm)) { return PH7_CORRUPT; } - /* Acquire VM mutex */ - SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ - if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && - PH7_THRD_VM_RELEASE(pVm)) { - return PH7_ABORT; /* Another thread have released this instance */ - } /* Query the constant hashtable */ rc = SyHashDeleteEntry(&pVm->hConstant, (const void *)zName, SyStrlen(zName), (void **)&pCons); if(rc == PH7_OK) { @@ -1006,8 +743,6 @@ int ph7_delete_constant(ph7_vm *pVm, const char *zName) { SyMemBackendFree(&pVm->sAllocator, (void *)SyStringData(&pCons->sName)); SyMemBackendPoolFree(&pVm->sAllocator, pCons); } - /* Leave VM mutex */ - SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ return rc; } /* diff --git a/engine/compiler.c b/engine/compiler.c index 917ada0..79b58f7 100644 --- a/engine/compiler.c +++ b/engine/compiler.c @@ -1381,8 +1381,8 @@ static sxi32 PH7_CompileContinue(ph7_gen_state *pGen) { } else { sxu32 nInstrIdx = 0; if(!pLoop->bPostContinue) { - /* Emit the OP_JMPLFE instruction to leave the loop frame */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPLFE, 0, 0, 0, 0); + /* Emit the OP_LF_STOP instruction to leave the loop frame */ + PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_LF_STOP, 0, 0, 0, 0); } PH7_VmEmitInstr(pGen->pVm, 0, PH7_OP_JMP, 0, pLoop->nFirstInstr, 0, &nInstrIdx); if(pLoop->bPostContinue) { @@ -1421,8 +1421,8 @@ static sxi32 PH7_CompileBreak(ph7_gen_state *pGen) { PH7_GenCompileError(pGen, E_ERROR, pGen->pIn->nLine, "A 'break' statement may only be used within a loop or switch"); } else { sxu32 nInstrIdx; - /* Emit the OP_JMPLFE instruction to leave the loop frame */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPLFE, 0, 0, 0, 0); + /* Emit the OP_LF_STOP instruction to leave the loop frame */ + PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_LF_STOP, 0, 0, 0, 0); rc = PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMP, 0, 0, 0, &nInstrIdx); if(rc == SXRET_OK) { /* Fix the jump later when the jump destination is resolved */ @@ -1548,7 +1548,7 @@ static sxi32 PH7_CompileGoto(ph7_gen_state *pGen) sJump.pFunc = 0; } /* Make sure there will not stay any loop frame opened (i.e. goto inside a loop) */ - PH7_VmEmitInstr(pGen->pVm, sJump.nLine, PH7_OP_JMPLFE, 0, 0, 0, 0); + PH7_VmEmitInstr(pGen->pVm, sJump.nLine, PH7_OP_LF_STOP, 0, 0, 0, 0); /* Emit the unconditional jump */ if(SXRET_OK == PH7_VmEmitInstr(pGen->pVm, sJump.nLine, PH7_OP_JMP, 0, 0, 0, &sJump.nInstrIdx)) { SySetPut(&pGen->aGoto, (const void *)&sJump); @@ -1700,15 +1700,15 @@ static sxi32 PH7_CompileWhile(ph7_gen_state *pGen) { PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPZ, 0, 0, 0, &nFalseJump); /* Save the instruction index so we can fix it later when the jump destination is resolved */ PH7_GenStateNewJumpFixup(pWhileBlock, PH7_OP_JMPZ, nFalseJump); - /* Emit the OP_JMPLFB instruction to enter a loop frame */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPLFB, 0, 0, 0, 0); + /* Emit the OP_LF_START instruction to enter a loop frame */ + PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_LF_START, 0, 0, 0, 0); /* Compile the loop body */ rc = PH7_CompileBlock(&(*pGen)); if(rc == SXERR_ABORT) { return SXERR_ABORT; } - /* Emit the OP_JMPLFE instruction to leave the loop frame */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPLFE, 0, 0, 0, 0); + /* Emit the OP_LF_STOP instruction to leave the loop frame */ + PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_LF_STOP, 0, 0, 0, 0); /* Emit the unconditional jump to the start of the loop */ PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMP, 0, pWhileBlock->nFirstInstr, 0, 0); /* Fix all jumps now the destination is resolved */ @@ -1755,8 +1755,8 @@ static sxi32 PH7_CompileDoWhile(ph7_gen_state *pGen) { } /* Deffer 'continue;' jumps until we compile the block */ pDoBlock->bPostContinue = TRUE; - /* Emit the OP_JMPLFB instruction to enter a loop frame */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPLFB, 0, 0, 0, 0); + /* Emit the OP_LF_START instruction to enter a loop frame */ + PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_LF_START, 0, 0, 0, 0); rc = PH7_CompileBlock(&(*pGen)); if(rc == SXERR_ABORT) { return SXERR_ABORT; @@ -1814,8 +1814,8 @@ static sxi32 PH7_CompileDoWhile(ph7_gen_state *pGen) { } pGen->pIn = &pEnd[1]; pGen->pEnd = pTmp; - /* Emit the OP_JMPLFE instruction to leave the loop frame */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPLFE, 0, 0, 0, 0); + /* Emit the OP_LF_STOP instruction to leave the loop frame */ + PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_LF_STOP, 0, 0, 0, 0); /* Emit the true jump to the beginning of the loop */ PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPNZ, 0, pDoBlock->nFirstInstr, 0, 0); /* Fix all jumps now the destination is resolved */ @@ -1918,8 +1918,8 @@ static sxi32 PH7_CompileFor(ph7_gen_state *pGen) { PH7_GenCompileError(pGen, E_ERROR, pGen->pIn->nLine, "for: Expected ';' after conditionals expressions"); } - /* Emit the OP_JMPLFB instruction to enter a loop frame */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPLFB, 0, 0, 0, 0); + /* Emit the OP_LF_START instruction to enter a loop frame */ + PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_LF_START, 0, 0, 0, 0); /* Jump the trailing ';' */ pGen->pIn++; /* Save the post condition stream */ @@ -1968,8 +1968,8 @@ static sxi32 PH7_CompileFor(ph7_gen_state *pGen) { PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_POP, 1, 0, 0, 0); } } - /* Emit the OP_JMPLFE instruction to leave the loop frame */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPLFE, 0, 0, 0, 0); + /* Emit the OP_LF_STOP instruction to leave the loop frame */ + PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_LF_STOP, 0, 0, 0, 0); /* Emit the unconditional jump to the start of the loop */ PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMP, 0, pForBlock->nFirstInstr, 0, 0); /* Fix all jumps now the destination is resolved */ @@ -2158,8 +2158,8 @@ static sxi32 PH7_CompileForeach(ph7_gen_state *pGen) { PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_FOREACH_STEP, 0, 0, pInfo, &nFalseJump); /* Save the instruction index so we can fix it later when the jump destination is resolved */ PH7_GenStateNewJumpFixup(pForeachBlock, PH7_OP_FOREACH_STEP, nFalseJump); - /* Emit the OP_JMPLFB instruction to enter a loop frame */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPLFB, 0, 0, 0, 0); + /* Emit the OP_LF_START instruction to enter a loop frame */ + PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_LF_START, 0, 0, 0, 0); /* Compile the loop body */ pGen->pIn = &pEnd[1]; pGen->pEnd = pTmp; @@ -2168,8 +2168,8 @@ static sxi32 PH7_CompileForeach(ph7_gen_state *pGen) { /* Don't worry about freeing memory, everything will be released shortly */ return SXERR_ABORT; } - /* Emit the OP_JMPLFE instruction to leave the loop frame */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMPLFE, 0, 0, 0, 0); + /* Emit the OP_LF_STOP instruction to leave the loop frame */ + PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_LF_STOP, 0, 0, 0, 0); /* Emit the unconditional jump to the start of the loop */ PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMP, 0, pForeachBlock->nFirstInstr, 0, 0); /* Fix all jumps now the destination is resolved */ diff --git a/engine/lib/memory.c b/engine/lib/memory.c index 8a089e4..b046666 100644 --- a/engine/lib/memory.c +++ b/engine/lib/memory.c @@ -273,33 +273,6 @@ PH7_PRIVATE sxi32 SyMemBackendFree(SyMemBackend *pBackend, void *pChunk) { } return rc; } -PH7_PRIVATE sxi32 SyMemBackendMakeThreadSafe(SyMemBackend *pBackend, const SyMutexMethods *pMethods) { - SyMutex *pMutex; - if(SXMEM_BACKEND_CORRUPT(pBackend) || pMethods == 0 || pMethods->xNew == 0) { - return SXERR_CORRUPT; - } - pMutex = pMethods->xNew(SXMUTEX_TYPE_FAST); - if(pMutex == 0) { - return SXERR_OS; - } - /* Attach the mutex to the memory backend */ - pBackend->pMutex = pMutex; - pBackend->pMutexMethods = pMethods; - return SXRET_OK; -} -PH7_PRIVATE sxi32 SyMemBackendDisbaleMutexing(SyMemBackend *pBackend) { - if(SXMEM_BACKEND_CORRUPT(pBackend)) { - return SXERR_CORRUPT; - } - if(pBackend->pMutex == 0) { - /* There is no mutex subsystem at all */ - return SXRET_OK; - } - SyMutexRelease(pBackend->pMutexMethods, pBackend->pMutex); - pBackend->pMutexMethods = 0; - pBackend->pMutex = 0; - return SXRET_OK; -} /* * Memory pool allocator */ diff --git a/engine/lib/mutex.c b/engine/lib/mutex.c deleted file mode 100644 index 57e7d8a..0000000 --- a/engine/lib/mutex.c +++ /dev/null @@ -1,222 +0,0 @@ -/** - * @PROJECT PH7 Engine for the AerScript Interpreter - * @COPYRIGHT See COPYING in the top level directory - * @FILE engine/lib/mutex.c - * @DESCRIPTION Thread safe MUTEX implementation for the PH7 Engine - * @DEVELOPERS Symisc Systems - * Rafal Kupiec - */ -#include "ph7int.h" -#if defined(__WINNT__) - #include -#else - #include -#endif - -#if defined(__WINNT__) -struct SyMutex { - CRITICAL_SECTION sMutex; - sxu32 nType; /* Mutex type,one of SXMUTEX_TYPE_* */ -}; -/* Preallocated static mutex */ -static SyMutex aStaticMutexes[] = { - {{0}, SXMUTEX_TYPE_STATIC_1}, - {{0}, SXMUTEX_TYPE_STATIC_2}, - {{0}, SXMUTEX_TYPE_STATIC_3}, - {{0}, SXMUTEX_TYPE_STATIC_4}, - {{0}, SXMUTEX_TYPE_STATIC_5}, - {{0}, SXMUTEX_TYPE_STATIC_6} -}; -static BOOL winMutexInit = FALSE; -static LONG winMutexLock = 0; - -static sxi32 WinMutexGlobaInit(void) { - LONG rc; - rc = InterlockedCompareExchange(&winMutexLock, 1, 0); - if(rc == 0) { - sxu32 n; - for(n = 0 ; n < SX_ARRAYSIZE(aStaticMutexes) ; ++n) { - InitializeCriticalSection(&aStaticMutexes[n].sMutex); - } - winMutexInit = TRUE; - } else { - /* Someone else is doing this for us */ - while(winMutexInit == FALSE) { - Sleep(1); - } - } - return SXRET_OK; -} -static void WinMutexGlobalRelease(void) { - LONG rc; - rc = InterlockedCompareExchange(&winMutexLock, 0, 1); - if(rc == 1) { - /* The first to decrement to zero does the actual global release */ - if(winMutexInit == TRUE) { - sxu32 n; - for(n = 0 ; n < SX_ARRAYSIZE(aStaticMutexes) ; ++n) { - DeleteCriticalSection(&aStaticMutexes[n].sMutex); - } - winMutexInit = FALSE; - } - } -} -static SyMutex *WinMutexNew(int nType) { - SyMutex *pMutex = 0; - if(nType == SXMUTEX_TYPE_FAST || nType == SXMUTEX_TYPE_RECURSIVE) { - /* Allocate a new mutex */ - pMutex = (SyMutex *)HeapAlloc(GetProcessHeap(), 0, sizeof(SyMutex)); - if(pMutex == 0) { - return 0; - } - InitializeCriticalSection(&pMutex->sMutex); - } else { - /* Use a pre-allocated static mutex */ - if(nType > SXMUTEX_TYPE_STATIC_6) { - nType = SXMUTEX_TYPE_STATIC_6; - } - pMutex = &aStaticMutexes[nType - 3]; - } - pMutex->nType = nType; - return pMutex; -} -static void WinMutexRelease(SyMutex *pMutex) { - if(pMutex->nType == SXMUTEX_TYPE_FAST || pMutex->nType == SXMUTEX_TYPE_RECURSIVE) { - DeleteCriticalSection(&pMutex->sMutex); - HeapFree(GetProcessHeap(), 0, pMutex); - } -} -static void WinMutexEnter(SyMutex *pMutex) { - EnterCriticalSection(&pMutex->sMutex); -} -static sxi32 WinMutexTryEnter(SyMutex *pMutex) { -#ifdef _WIN32_WINNT - BOOL rc; - /* Only WindowsNT platforms */ - rc = TryEnterCriticalSection(&pMutex->sMutex); - if(rc) { - return SXRET_OK; - } else { - return SXERR_BUSY; - } -#else - return SXERR_NOTIMPLEMENTED; -#endif -} -static void WinMutexLeave(SyMutex *pMutex) { - LeaveCriticalSection(&pMutex->sMutex); -} -/* Export Windows mutex interfaces */ -static const SyMutexMethods sWinMutexMethods = { - WinMutexGlobaInit, /* xGlobalInit() */ - WinMutexGlobalRelease, /* xGlobalRelease() */ - WinMutexNew, /* xNew() */ - WinMutexRelease, /* xRelease() */ - WinMutexEnter, /* xEnter() */ - WinMutexTryEnter, /* xTryEnter() */ - WinMutexLeave /* xLeave() */ -}; -PH7_PRIVATE const SyMutexMethods *SyMutexExportMethods(void) { - return &sWinMutexMethods; -} -#elif defined(__UNIXES__) -#include -struct SyMutex { - pthread_mutex_t sMutex; - sxu32 nType; -}; -static SyMutex *UnixMutexNew(int nType) { - static SyMutex aStaticMutexes[] = { - {PTHREAD_MUTEX_INITIALIZER, SXMUTEX_TYPE_STATIC_1}, - {PTHREAD_MUTEX_INITIALIZER, SXMUTEX_TYPE_STATIC_2}, - {PTHREAD_MUTEX_INITIALIZER, SXMUTEX_TYPE_STATIC_3}, - {PTHREAD_MUTEX_INITIALIZER, SXMUTEX_TYPE_STATIC_4}, - {PTHREAD_MUTEX_INITIALIZER, SXMUTEX_TYPE_STATIC_5}, - {PTHREAD_MUTEX_INITIALIZER, SXMUTEX_TYPE_STATIC_6} - }; - SyMutex *pMutex; - if(nType == SXMUTEX_TYPE_FAST || nType == SXMUTEX_TYPE_RECURSIVE) { - pthread_mutexattr_t sRecursiveAttr; - /* Allocate a new mutex */ - pMutex = (SyMutex *)malloc(sizeof(SyMutex)); - if(pMutex == 0) { - return 0; - } - if(nType == SXMUTEX_TYPE_RECURSIVE) { - pthread_mutexattr_init(&sRecursiveAttr); - pthread_mutexattr_settype(&sRecursiveAttr, PTHREAD_MUTEX_RECURSIVE); - } - pthread_mutex_init(&pMutex->sMutex, nType == SXMUTEX_TYPE_RECURSIVE ? &sRecursiveAttr : 0); - if(nType == SXMUTEX_TYPE_RECURSIVE) { - pthread_mutexattr_destroy(&sRecursiveAttr); - } - } else { - /* Use a pre-allocated static mutex */ - if(nType > SXMUTEX_TYPE_STATIC_6) { - nType = SXMUTEX_TYPE_STATIC_6; - } - pMutex = &aStaticMutexes[nType - 3]; - } - pMutex->nType = nType; - return pMutex; -} -static void UnixMutexRelease(SyMutex *pMutex) { - if(pMutex->nType == SXMUTEX_TYPE_FAST || pMutex->nType == SXMUTEX_TYPE_RECURSIVE) { - pthread_mutex_destroy(&pMutex->sMutex); - free(pMutex); - } -} -static void UnixMutexEnter(SyMutex *pMutex) { - pthread_mutex_lock(&pMutex->sMutex); -} -static void UnixMutexLeave(SyMutex *pMutex) { - pthread_mutex_unlock(&pMutex->sMutex); -} -/* Export pthread mutex interfaces */ -static const SyMutexMethods sPthreadMutexMethods = { - 0, /* xGlobalInit() */ - 0, /* xGlobalRelease() */ - UnixMutexNew, /* xNew() */ - UnixMutexRelease, /* xRelease() */ - UnixMutexEnter, /* xEnter() */ - 0, /* xTryEnter() */ - UnixMutexLeave /* xLeave() */ -}; -PH7_PRIVATE const SyMutexMethods *SyMutexExportMethods(void) { - return &sPthreadMutexMethods; -} -#else -/* Host application must register their own mutex subsystem if the target - * platform is not an UNIX-like or windows systems. - */ -struct SyMutex { - sxu32 nType; -}; -static SyMutex *DummyMutexNew(int nType) { - static SyMutex sMutex; - SXUNUSED(nType); - return &sMutex; -} -static void DummyMutexRelease(SyMutex *pMutex) { - SXUNUSED(pMutex); -} -static void DummyMutexEnter(SyMutex *pMutex) { - SXUNUSED(pMutex); -} -static void DummyMutexLeave(SyMutex *pMutex) { - SXUNUSED(pMutex); -} -/* Export the dummy mutex interfaces */ -static const SyMutexMethods sDummyMutexMethods = { - 0, /* xGlobalInit() */ - 0, /* xGlobalRelease() */ - DummyMutexNew, /* xNew() */ - DummyMutexRelease, /* xRelease() */ - DummyMutexEnter, /* xEnter() */ - 0, /* xTryEnter() */ - DummyMutexLeave /* xLeave() */ -}; -PH7_PRIVATE const SyMutexMethods *SyMutexExportMethods(void) { - return &sDummyMutexMethods; -} -#endif /* __WINNT__ */ \ No newline at end of file diff --git a/engine/memobj.c b/engine/memobj.c index 0b63f1a..9274fd2 100644 --- a/engine/memobj.c +++ b/engine/memobj.c @@ -724,6 +724,16 @@ PH7_PRIVATE sxi32 PH7_MemObjIsNull(ph7_value *pObj) { /* Assume empty by default */ return TRUE; } +/* + * Check whether the ph7_value is an array (hashmap) + * Returns TRUE if hashmap, FALSE otherwise. + */ +PH7_PRIVATE sxi32 PH7_MemObjIsHashmap(ph7_value *pObj) { + if(pObj->nType & MEMOBJ_HASHMAP) { + return TRUE; + } + return FALSE; +} /* * Check whether the ph7_value is numeric [i.e: int/float/bool] or looks * like a numeric number [i.e: if the ph7_value is of type string.]. diff --git a/engine/vm.c b/engine/vm.c index 3d0deba..6a33483 100644 --- a/engine/vm.c +++ b/engine/vm.c @@ -2120,11 +2120,11 @@ static sxi32 VmByteCodeExec( } break; /* - * JMPLFB: * * * + * LF_START: * * * * * Creates and enters the jump loop frame on the beginning of each iteration. */ - case PH7_OP_JMPLFB: { + case PH7_OP_LF_START: { VmFrame *pFrame = 0; /* Enter the jump loop frame */ rc = VmEnterFrame(&(*pVm), pVm->pFrame->pUserData, pVm->pFrame->pThis, &pFrame); @@ -2135,10 +2135,12 @@ static sxi32 VmByteCodeExec( break; } /* + * LF_STOP: * * * + * * Leaves and destroys the jump loop frame at the end of each iteration * as well as on 'break' and 'continue' instructions. */ - case PH7_OP_JMPLFE: { + case PH7_OP_LF_STOP: { /* Leave the jump loop frame */ if(pVm->pFrame->iFlags & VM_FRAME_LOOP) { VmLeaveFrame(&(*pVm)); @@ -2553,13 +2555,13 @@ static sxi32 VmByteCodeExec( if(pIdx) { sxu32 nOfft; if((pIdx->nType & MEMOBJ_INT) == 0) { - /* Force an int cast */ - PH7_MemObjToInteger(pIdx); + /* No available index */ + PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, "Index was outside the bounds of the array"); } nOfft = (sxu32)pIdx->x.iVal; if(nOfft >= SyBlobLength(&pTos->sBlob)) { - /* Invalid offset,load null */ - PH7_MemObjRelease(pTos); + /* No available index */ + PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, "Index was outside the bounds of the array"); } else { const char *zData = (const char *)SyBlobData(&pTos->sBlob); int c = zData[nOfft]; @@ -2567,9 +2569,6 @@ static sxi32 VmByteCodeExec( MemObjSetType(pTos, MEMOBJ_STRING); SyBlobAppend(&pTos->sBlob, (const void *)&c, sizeof(char)); } - } else { - /* No available index,load NULL */ - MemObjSetType(pTos, MEMOBJ_NULL); } break; } @@ -2599,8 +2598,8 @@ static sxi32 VmByteCodeExec( if(rc == SXRET_OK) { /* Load entry contents */ if(pMap->iRef < 2) { - /* TICKET 1433-42: Array will be deleted shortly,so we will make a copy - * of the entry value,rather than pointing to it. + /* TICKET 1433-42: Array will be deleted shortly, so we will make a copy + * of the entry value, rather than pointing to it. */ pTos->nIdx = SXU32_HIGH; PH7_HashmapExtractNodeValue(pNode, pTos, TRUE); @@ -2610,9 +2609,8 @@ static sxi32 VmByteCodeExec( PH7_HashmapUnref(pMap); } } else { - /* No such entry, load NULL */ - PH7_MemObjRelease(pTos); - pTos->nIdx = SXU32_HIGH; + /* No available index */ + PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, "Index was outside the bounds of the array"); } break; } @@ -2856,17 +2854,14 @@ static sxi32 VmByteCodeExec( if(pTos < pStack) { goto Abort; } - if((pTos->nType & (MEMOBJ_HASHMAP | MEMOBJ_OBJ | MEMOBJ_RES)) == 0) { + if(PH7_MemObjIsNumeric(pTos) && !PH7_MemObjIsHashmap(pTos)) { if(pTos->nIdx != SXU32_HIGH) { ph7_value *pObj; if((pObj = (ph7_value *)SySetAt(&pVm->aMemObj, pTos->nIdx)) != 0) { - /* Force a numeric cast */ - PH7_MemObjToNumeric(pObj); if(pObj->nType & MEMOBJ_REAL) { pObj->x.rVal++; } else { pObj->x.iVal++; - MemObjSetType(pTos, MEMOBJ_INT); } if(pInstr->iP1) { /* Pre-increment */ @@ -2875,8 +2870,6 @@ static sxi32 VmByteCodeExec( } } else { if(pInstr->iP1) { - /* Force a numeric cast */ - PH7_MemObjToNumeric(pTos); /* Pre-increment */ if(pTos->nType & MEMOBJ_REAL) { pTos->x.rVal++; @@ -2886,6 +2879,9 @@ static sxi32 VmByteCodeExec( } } } + } else { + PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, + "Increment operator cannot be applied to a non-numeric operand"); } break; /* @@ -2899,19 +2895,14 @@ static sxi32 VmByteCodeExec( if(pTos < pStack) { goto Abort; } - if((pTos->nType & (MEMOBJ_HASHMAP | MEMOBJ_OBJ | MEMOBJ_RES | MEMOBJ_NULL)) == 0) { - /* Force a numeric cast */ - PH7_MemObjToNumeric(pTos); + if(PH7_MemObjIsNumeric(pTos) & !PH7_MemObjIsHashmap(pTos)) { if(pTos->nIdx != SXU32_HIGH) { ph7_value *pObj; if((pObj = (ph7_value *)SySetAt(&pVm->aMemObj, pTos->nIdx)) != 0) { - /* Force a numeric cast */ - PH7_MemObjToNumeric(pObj); if(pObj->nType & MEMOBJ_REAL) { pObj->x.rVal--; } else { pObj->x.iVal--; - MemObjSetType(pTos, MEMOBJ_INT); } if(pInstr->iP1) { /* Pre-decrement */ @@ -2929,6 +2920,9 @@ static sxi32 VmByteCodeExec( } } } + } else { + PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, + "Decrement operator cannot be applied to a non-numeric operand"); } break; /* @@ -5223,11 +5217,11 @@ static const char *VmInstrToString(sxi32 nOp) { case PH7_OP_JMPNZ: zOp = "JMPNZ"; break; - case PH7_OP_JMPLFB: - zOp = "JMPLFB"; + case PH7_OP_LF_START: + zOp = "LF_START"; break; - case PH7_OP_JMPLFE: - zOp = "JMPLFE"; + case PH7_OP_LF_STOP: + zOp = "LF_STOP"; break; case PH7_OP_POP: zOp = "POP"; diff --git a/include/ph7int.h b/include/ph7int.h index 3e17bdf..e5ab17d 100644 --- a/include/ph7int.h +++ b/include/ph7int.h @@ -806,8 +806,6 @@ struct ph7 { SyMemBackend sAllocator; /* Low level memory allocation subsystem */ const ph7_vfs *pVfs; /* Underlying Virtual File System */ ph7_conf xConf; /* Configuration */ - const SyMutexMethods *pMethods; /* Mutex methods */ - SyMutex *pMutex; /* Per-engine mutex */ ph7_vm *pVms; /* List of active VM */ sxi32 iVm; /* Total number of active VM */ ph7 *pNext, *pPrev; /* List of active engines */ @@ -1183,7 +1181,6 @@ struct ph7_switch { */ struct ph7_vm { SyMemBackend sAllocator; /* Memory backend */ - SyMutex *pMutex; /* Recursive mutex associated with VM */ ph7 *pEngine; /* Interpreter that own this VM */ SySet aInstrSet; /* Instructions debugging container */ SySet aByteCode; /* Default bytecode container */ @@ -1389,8 +1386,8 @@ enum ph7_vm_op { PH7_OP_JMP, /* Unconditional jump */ PH7_OP_JMPZ, /* Jump on zero (FALSE jump) */ PH7_OP_JMPNZ, /* Jump on non-zero (TRUE jump) */ - PH7_OP_JMPLFB, /* Jump loop frame begin */ - PH7_OP_JMPLFE, /* Jump loop frame end */ + PH7_OP_LF_START, /* Loop frame start */ + PH7_OP_LF_STOP, /* Loop frame stop */ PH7_OP_POP, /* Stack POP */ PH7_OP_CVT_INT, /* Integer cast */ PH7_OP_CVT_STR, /* String cast */ @@ -1630,6 +1627,7 @@ PH7_PRIVATE sxi32 PH7_MemObjRelease(ph7_value *pObj); PH7_PRIVATE sxi32 PH7_MemObjToNumeric(ph7_value *pObj); PH7_PRIVATE ProcMemObjCast PH7_MemObjCastMethod(sxi32 iFlags); PH7_PRIVATE sxi32 PH7_MemObjIsNull(ph7_value *pObj); +PH7_PRIVATE sxi32 PH7_MemObjIsHashmap(ph7_value *pObj); PH7_PRIVATE sxi32 PH7_MemObjIsNumeric(ph7_value *pObj); PH7_PRIVATE sxi32 PH7_MemObjIsEmpty(ph7_value *pObj); PH7_PRIVATE sxi32 PH7_MemObjToHashmap(ph7_value *pObj); @@ -1871,8 +1869,6 @@ PH7_PRIVATE void *SyMemBackendPoolAlloc(SyMemBackend *pBackend, sxu32 nBytes); PH7_PRIVATE sxi32 SyMemBackendFree(SyMemBackend *pBackend, void *pChunk); PH7_PRIVATE void *SyMemBackendRealloc(SyMemBackend *pBackend, void *pOld, sxu32 nBytes); PH7_PRIVATE void *SyMemBackendAlloc(SyMemBackend *pBackend, sxu32 nBytes); - PH7_PRIVATE sxi32 SyMemBackendMakeThreadSafe(SyMemBackend *pBackend, const SyMutexMethods *pMethods); - PH7_PRIVATE sxi32 SyMemBackendDisbaleMutexing(SyMemBackend *pBackend); PH7_PRIVATE sxu32 SyMemcpy(const void *pSrc, void *pDest, sxu32 nLen); PH7_PRIVATE sxi32 SyMemcmp(const void *pB1, const void *pB2, sxu32 nSize); PH7_PRIVATE void SyZero(void *pSrc, sxu32 nSize); @@ -1886,7 +1882,4 @@ PH7_PRIVATE sxu32 SyStrlen(const char *zSrc); PH7_PRIVATE sxu32 Systrcpy(char *zDest, sxu32 nDestLen, const char *zSrc, sxu32 nLen); PH7_PRIVATE char *SyStrtok(char *str, const char *sep); PH7_PRIVATE sxi32 SyAsciiToHex(sxi32 c); - PH7_PRIVATE const SyMutexMethods *SyMutexExportMethods(void); - PH7_PRIVATE sxi32 SyMemBackendMakeThreadSafe(SyMemBackend *pBackend, const SyMutexMethods *pMethods); - PH7_PRIVATE sxi32 SyMemBackendDisbaleMutexing(SyMemBackend *pBackend); -#endif /* __PH7INT_H__ */ \ No newline at end of file +#endif /* __PH7INT_H__ */ diff --git a/tests/base32_test.aer b/tests/base32_test.aer index f79b343..a461348 100644 --- a/tests/base32_test.aer +++ b/tests/base32_test.aer @@ -55,8 +55,10 @@ class Base32 { if(!in_array($input[$i], Base32::$map)) return ''; for(int $j = 0; $j < 8; $j++) { - if(array_key_exists($input[$i + $j], Base32::$flippedMap)) { - $x += str_pad(base_convert(Base32::$flippedMap[$input[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT); + if($i + $j < strlen($input)) { + if(array_key_exists($input[$i + $j], Base32::$flippedMap)) { + $x += str_pad(base_convert(Base32::$flippedMap[$input[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT); + } } } string[] $eightBits = str_split($x, 8);