Browse Source

Merge branch 'master' of AerScript/Aer into release/v0.1

tags/v0.1.1
Rafal Kupiec 9 months ago
committed by Gitea
parent
commit
7076a6f3ed
9 changed files with 66 additions and 580 deletions
  1. +1
    -0
      .github/FUNDING.yml
  2. +1
    -266
      engine/api.c
  3. +21
    -21
      engine/compiler.c
  4. +0
    -27
      engine/lib/memory.c
  5. +0
    -222
      engine/lib/mutex.c
  6. +10
    -0
      engine/memobj.c
  7. +25
    -31
      engine/vm.c
  8. +4
    -11
      include/ph7int.h
  9. +4
    -2
      tests/base32_test.aer

+ 1
- 0
.github/FUNDING.yml View File

@@ -0,0 +1 @@
custom: https://paypal.me/pools/c/8hAZMn97vE

+ 1
- 266
engine/api.c View File

@@ -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;
}
/*


+ 21
- 21
engine/compiler.c View File

@@ -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 */


+ 0
- 27
engine/lib/memory.c View File

@@ -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
*/


+ 0
- 222
engine/lib/mutex.c View File

@@ -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 <devel@symisc.net>
* Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include "ph7int.h"
#if defined(__WINNT__)
#include <Windows.h>
#else
#include <stdlib.h>
#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 <pthread.h>
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__ */

+ 10
- 0
engine/memobj.c View File

@@ -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.].


+ 25
- 31
engine/vm.c View File

@@ -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";


+ 4
- 11
include/ph7int.h View File

@@ -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__ */
#endif /* __PH7INT_H__ */

+ 4
- 2
tests/base32_test.aer View File

@@ -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);


Loading…
Cancel
Save