From 91601deb844848dc02959679fd41e1441a76aff4 Mon Sep 17 00:00:00 2001 From: Aaron Seigo Date: Sun, 14 Dec 2014 12:30:27 +0100 Subject: the all-in-one-file version of unqlite --- common/unqlite/jx9_api.c | 1744 ---------------------------------------------- 1 file changed, 1744 deletions(-) delete mode 100644 common/unqlite/jx9_api.c (limited to 'common/unqlite/jx9_api.c') diff --git a/common/unqlite/jx9_api.c b/common/unqlite/jx9_api.c deleted file mode 100644 index efad097..0000000 --- a/common/unqlite/jx9_api.c +++ /dev/null @@ -1,1744 +0,0 @@ -/* - * Symisc JX9: A Highly Efficient Embeddable Scripting Engine Based on JSON. - * Copyright (C) 2012-2013, Symisc Systems http://jx9.symisc.net/ - * Version 1.7.2 - * For information on licensing, redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES - * please contact Symisc Systems via: - * legal@symisc.net - * licensing@symisc.net - * contact@symisc.net - * or visit: - * http://jx9.symisc.net/ - */ - /* $SymiscID: api.c v1.7 FreeBSD 2012-12-18 06:54 stable $ */ -#ifndef JX9_AMALGAMATION -#include "jx9Int.h" -#endif -/* This file implement the public interfaces presented to host-applications. - * Routines in other files are for internal use by JX9 and should not be - * accessed by users of the library. - */ -#define JX9_ENGINE_MAGIC 0xF874BCD7 -#define JX9_ENGINE_MISUSE(ENGINE) (ENGINE == 0 || ENGINE->nMagic != JX9_ENGINE_MAGIC) -#define JX9_VM_MISUSE(VM) (VM == 0 || VM->nMagic == JX9_VM_STALE) -/* If another thread have released a working instance, the following macros - * evaluates to true. These macros are only used when the library - * is built with threading support enabled which is not the case in - * the default built. - */ -#define JX9_THRD_ENGINE_RELEASE(ENGINE) (ENGINE->nMagic != JX9_ENGINE_MAGIC) -#define JX9_THRD_VM_RELEASE(VM) (VM->nMagic == JX9_VM_STALE) -/* IMPLEMENTATION: jx9@embedded@symisc 311-12-32 */ -/* - * All global variables are collected in the structure named "sJx9MPGlobal". - * That way it is clear in the code when we are using static variable because - * its name start with sJx9MPGlobal. - */ -static struct Jx9Global_Data -{ - SyMemBackend sAllocator; /* Global low level memory allocator */ -#if defined(JX9_ENABLE_THREADS) - 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 [jx9_lib_config()] - * interface with a configuration verb set to - * JX9_LIB_CONFIG_THREAD_LEVEL_SINGLE or - * JX9_LIB_CONFIG_THREAD_LEVEL_MULTI - */ -#endif - const jx9_vfs *pVfs; /* Underlying virtual file system */ - sxi32 nEngine; /* Total number of active engines */ - jx9 *pEngines; /* List of active engine */ - sxu32 nMagic; /* Sanity check against library misuse */ -}sJx9MPGlobal = { - {0, 0, 0, 0, 0, 0, 0, 0, {0}}, -#if defined(JX9_ENABLE_THREADS) - 0, - 0, - 0, -#endif - 0, - 0, - 0, - 0 -}; -#define JX9_LIB_MAGIC 0xEA1495BA -#define JX9_LIB_MISUSE (sJx9MPGlobal.nMagic != JX9_LIB_MAGIC) -/* - * Supported threading level. - * These options have meaning only when the library is compiled with multi-threading - * support.That is, the JX9_ENABLE_THREADS compile time directive must be defined - * when JX9 is built. - * JX9_THREAD_LEVEL_SINGLE: - * In this mode, mutexing is disabled and the library can only be used by a single thread. - * JX9_THREAD_LEVEL_MULTI - * In this mode, all mutexes including the recursive mutexes on [jx9] objects - * are enabled so that the application is free to share the same engine - * between different threads at the same time. - */ -#define JX9_THREAD_LEVEL_SINGLE 1 -#define JX9_THREAD_LEVEL_MULTI 2 -/* - * Configure a running JX9 engine instance. - * return JX9_OK on success.Any other return - * value indicates failure. - * Refer to [jx9_config()]. - */ -JX9_PRIVATE sxi32 jx9EngineConfig(jx9 *pEngine, sxi32 nOp, va_list ap) -{ - jx9_conf *pConf = &pEngine->xConf; - int rc = JX9_OK; - /* Perform the requested operation */ - switch(nOp){ - case JX9_CONFIG_ERR_LOG:{ - /* Extract compile-time error log if any */ - const char **pzPtr = va_arg(ap, const char **); - int *pLen = va_arg(ap, int *); - if( pzPtr == 0 ){ - rc = JX9_CORRUPT; - break; - } - /* NULL terminate the error-log buffer */ - SyBlobNullAppend(&pConf->sErrConsumer); - /* Point to the error-log buffer */ - *pzPtr = (const char *)SyBlobData(&pConf->sErrConsumer); - if( pLen ){ - if( SyBlobLength(&pConf->sErrConsumer) > 1 /* NULL '\0' terminator */ ){ - *pLen = (int)SyBlobLength(&pConf->sErrConsumer); - }else{ - *pLen = 0; - } - } - break; - } - case JX9_CONFIG_ERR_ABORT: - /* Reserved for future use */ - break; - default: - /* Unknown configuration verb */ - rc = JX9_CORRUPT; - break; - } /* Switch() */ - return rc; -} -/* - * Configure the JX9 library. - * Return JX9_OK on success. Any other return value indicates failure. - * Refer to [jx9_lib_config()]. - */ -static sxi32 Jx9CoreConfigure(sxi32 nOp, va_list ap) -{ - int rc = JX9_OK; - switch(nOp){ - case JX9_LIB_CONFIG_VFS:{ - /* Install a virtual file system */ - const jx9_vfs *pVfs = va_arg(ap, const jx9_vfs *); - sJx9MPGlobal.pVfs = pVfs; - break; - } - case JX9_LIB_CONFIG_USER_MALLOC: { - /* Use an alternative low-level memory allocation routines */ - const SyMemMethods *pMethods = va_arg(ap, const SyMemMethods *); - /* Save the memory failure callback (if available) */ - ProcMemError xMemErr = sJx9MPGlobal.sAllocator.xMemError; - void *pMemErr = sJx9MPGlobal.sAllocator.pUserData; - if( pMethods == 0 ){ - /* Use the built-in memory allocation subsystem */ - rc = SyMemBackendInit(&sJx9MPGlobal.sAllocator, xMemErr, pMemErr); - }else{ - rc = SyMemBackendInitFromOthers(&sJx9MPGlobal.sAllocator, pMethods, xMemErr, pMemErr); - } - break; - } - case JX9_LIB_CONFIG_MEM_ERR_CALLBACK: { - /* Memory failure callback */ - ProcMemError xMemErr = va_arg(ap, ProcMemError); - void *pUserData = va_arg(ap, void *); - sJx9MPGlobal.sAllocator.xMemError = xMemErr; - sJx9MPGlobal.sAllocator.pUserData = pUserData; - break; - } - case JX9_LIB_CONFIG_USER_MUTEX: { -#if defined(JX9_ENABLE_THREADS) - /* Use an alternative low-level mutex subsystem */ - const SyMutexMethods *pMethods = va_arg(ap, const SyMutexMethods *); -#if defined (UNTRUST) - if( pMethods == 0 ){ - rc = JX9_CORRUPT; - } -#endif - /* 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 = JX9_CORRUPT; - break; - } - if( sJx9MPGlobal.pMutexMethods ){ - /* Overwrite the previous mutex subsystem */ - SyMutexRelease(sJx9MPGlobal.pMutexMethods, sJx9MPGlobal.pMutex); - if( sJx9MPGlobal.pMutexMethods->xGlobalRelease ){ - sJx9MPGlobal.pMutexMethods->xGlobalRelease(); - } - sJx9MPGlobal.pMutex = 0; - } - /* Initialize and install the new mutex subsystem */ - if( pMethods->xGlobalInit ){ - rc = pMethods->xGlobalInit(); - if ( rc != JX9_OK ){ - break; - } - } - /* Create the global mutex */ - sJx9MPGlobal.pMutex = pMethods->xNew(SXMUTEX_TYPE_FAST); - if( sJx9MPGlobal.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 = JX9_CORRUPT; - break; - } - sJx9MPGlobal.pMutexMethods = pMethods; - if( sJx9MPGlobal.nThreadingLevel == 0 ){ - /* Set a default threading level */ - sJx9MPGlobal.nThreadingLevel = JX9_THREAD_LEVEL_MULTI; - } -#endif - break; - } - case JX9_LIB_CONFIG_THREAD_LEVEL_SINGLE: -#if defined(JX9_ENABLE_THREADS) - /* Single thread mode(Only one thread is allowed to play with the library) */ - sJx9MPGlobal.nThreadingLevel = JX9_THREAD_LEVEL_SINGLE; -#endif - break; - case JX9_LIB_CONFIG_THREAD_LEVEL_MULTI: -#if defined(JX9_ENABLE_THREADS) - /* Multi-threading mode (library is thread safe and JX9 engines and virtual machines - * may be shared between multiple threads). - */ - sJx9MPGlobal.nThreadingLevel = JX9_THREAD_LEVEL_MULTI; -#endif - break; - default: - /* Unknown configuration option */ - rc = JX9_CORRUPT; - break; - } - return rc; -} -/* - * [CAPIREF: jx9_lib_config()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_lib_config(int nConfigOp, ...) -{ - va_list ap; - int rc; - if( sJx9MPGlobal.nMagic == JX9_LIB_MAGIC ){ - /* Library is already initialized, this operation is forbidden */ - return JX9_LOOKED; - } - va_start(ap, nConfigOp); - rc = Jx9CoreConfigure(nConfigOp, ap); - va_end(ap); - return rc; -} -/* - * Global library initialization - * Refer to [jx9_lib_init()] - * This routine must be called to initialize the memory allocation subsystem, the mutex - * subsystem prior to doing any serious work with the library.The first thread to call - * this routine does the initialization process and set the magic number so no body later - * can re-initialize the library.If subsequent threads call this routine before the first - * thread have finished the initialization process, then the subsequent threads must block - * until the initialization process is done. - */ -static sxi32 Jx9CoreInitialize(void) -{ - const jx9_vfs *pVfs; /* Built-in vfs */ -#if defined(JX9_ENABLE_THREADS) - const SyMutexMethods *pMutexMethods = 0; - SyMutex *pMaster = 0; -#endif - int rc; - /* - * If the library is already initialized, then a call to this routine - * is a no-op. - */ - if( sJx9MPGlobal.nMagic == JX9_LIB_MAGIC ){ - return JX9_OK; /* Already initialized */ - } - /* Point to the built-in vfs */ - pVfs = jx9ExportBuiltinVfs(); - /* Install it */ - jx9_lib_config(JX9_LIB_CONFIG_VFS, pVfs); -#if defined(JX9_ENABLE_THREADS) - if( sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_SINGLE ){ - pMutexMethods = sJx9MPGlobal.pMutexMethods; - if( pMutexMethods == 0 ){ - /* Use the built-in mutex subsystem */ - pMutexMethods = SyMutexExportMethods(); - if( pMutexMethods == 0 ){ - return JX9_CORRUPT; /* Can't happen */ - } - /* Install the mutex subsystem */ - rc = jx9_lib_config(JX9_LIB_CONFIG_USER_MUTEX, pMutexMethods); - if( rc != JX9_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 JX9_CORRUPT; /* Can't happen */ - } - } - /* Lock the master mutex */ - rc = JX9_OK; - SyMutexEnter(pMutexMethods, pMaster); /* NO-OP if sJx9MPGlobal.nThreadingLevel == JX9_THREAD_LEVEL_SINGLE */ - if( sJx9MPGlobal.nMagic != JX9_LIB_MAGIC ){ -#endif - if( sJx9MPGlobal.sAllocator.pMethods == 0 ){ - /* Install a memory subsystem */ - rc = jx9_lib_config(JX9_LIB_CONFIG_USER_MALLOC, 0); /* zero mean use the built-in memory backend */ - if( rc != JX9_OK ){ - /* If we are unable to initialize the memory backend, there is no much we can do here.*/ - goto End; - } - } -#if defined(JX9_ENABLE_THREADS) - if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE ){ - /* Protect the memory allocation subsystem */ - rc = SyMemBackendMakeThreadSafe(&sJx9MPGlobal.sAllocator, sJx9MPGlobal.pMutexMethods); - if( rc != JX9_OK ){ - goto End; - } - } -#endif - /* Our library is initialized, set the magic number */ - sJx9MPGlobal.nMagic = JX9_LIB_MAGIC; - rc = JX9_OK; -#if defined(JX9_ENABLE_THREADS) - } /* sJx9MPGlobal.nMagic != JX9_LIB_MAGIC */ -#endif -End: -#if defined(JX9_ENABLE_THREADS) - /* Unlock the master mutex */ - SyMutexLeave(pMutexMethods, pMaster); /* NO-OP if sJx9MPGlobal.nThreadingLevel == JX9_THREAD_LEVEL_SINGLE */ -#endif - return rc; -} -/* - * Release an active JX9 engine and it's associated active virtual machines. - */ -static sxi32 EngineRelease(jx9 *pEngine) -{ - jx9_vm *pVm, *pNext; - /* Release all active VM */ - pVm = pEngine->pVms; - for(;;){ - if( pEngine->iVm < 1 ){ - break; - } - pNext = pVm->pNext; - jx9VmRelease(pVm); - pVm = pNext; - pEngine->iVm--; - } - /* Set a dummy magic number */ - pEngine->nMagic = 0x7635; - /* Release the private memory subsystem */ - SyMemBackendRelease(&pEngine->sAllocator); - return JX9_OK; -} -/* - * Release all resources consumed by the library. - * If JX9 is already shut when this routine is invoked then this - * routine is a harmless no-op. - * Note: This call is not thread safe. Refer to [jx9_lib_shutdown()]. - */ -static void JX9CoreShutdown(void) -{ - jx9 *pEngine, *pNext; - /* Release all active engines first */ - pEngine = sJx9MPGlobal.pEngines; - for(;;){ - if( sJx9MPGlobal.nEngine < 1 ){ - break; - } - pNext = pEngine->pNext; - EngineRelease(pEngine); - pEngine = pNext; - sJx9MPGlobal.nEngine--; - } -#if defined(JX9_ENABLE_THREADS) - /* Release the mutex subsystem */ - if( sJx9MPGlobal.pMutexMethods ){ - if( sJx9MPGlobal.pMutex ){ - SyMutexRelease(sJx9MPGlobal.pMutexMethods, sJx9MPGlobal.pMutex); - sJx9MPGlobal.pMutex = 0; - } - if( sJx9MPGlobal.pMutexMethods->xGlobalRelease ){ - sJx9MPGlobal.pMutexMethods->xGlobalRelease(); - } - sJx9MPGlobal.pMutexMethods = 0; - } - sJx9MPGlobal.nThreadingLevel = 0; -#endif - if( sJx9MPGlobal.sAllocator.pMethods ){ - /* Release the memory backend */ - SyMemBackendRelease(&sJx9MPGlobal.sAllocator); - } - sJx9MPGlobal.nMagic = 0x1928; -} -/* - * [CAPIREF: jx9_lib_shutdown()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_lib_shutdown(void) -{ - if( sJx9MPGlobal.nMagic != JX9_LIB_MAGIC ){ - /* Already shut */ - return JX9_OK; - } - JX9CoreShutdown(); - return JX9_OK; -} -/* - * [CAPIREF: jx9_lib_signature()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE const char * jx9_lib_signature(void) -{ - return JX9_SIG; -} -/* - * [CAPIREF: jx9_init()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_init(jx9 **ppEngine) -{ - jx9 *pEngine; - int rc; -#if defined(UNTRUST) - if( ppEngine == 0 ){ - return JX9_CORRUPT; - } -#endif - *ppEngine = 0; - /* One-time automatic library initialization */ - rc = Jx9CoreInitialize(); - if( rc != JX9_OK ){ - return rc; - } - /* Allocate a new engine */ - pEngine = (jx9 *)SyMemBackendPoolAlloc(&sJx9MPGlobal.sAllocator, sizeof(jx9)); - if( pEngine == 0 ){ - return JX9_NOMEM; - } - /* Zero the structure */ - SyZero(pEngine, sizeof(jx9)); - /* Initialize engine fields */ - pEngine->nMagic = JX9_ENGINE_MAGIC; - rc = SyMemBackendInitFromParent(&pEngine->sAllocator, &sJx9MPGlobal.sAllocator); - if( rc != JX9_OK ){ - goto Release; - } -#if defined(JX9_ENABLE_THREADS) - SyMemBackendDisbaleMutexing(&pEngine->sAllocator); -#endif - /* Default configuration */ - SyBlobInit(&pEngine->xConf.sErrConsumer, &pEngine->sAllocator); - /* Install a default compile-time error consumer routine */ - pEngine->xConf.xErr = jx9VmBlobConsumer; - pEngine->xConf.pErrData = &pEngine->xConf.sErrConsumer; - /* Built-in vfs */ - pEngine->pVfs = sJx9MPGlobal.pVfs; -#if defined(JX9_ENABLE_THREADS) - if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE ){ - /* Associate a recursive mutex with this instance */ - pEngine->pMutex = SyMutexNew(sJx9MPGlobal.pMutexMethods, SXMUTEX_TYPE_RECURSIVE); - if( pEngine->pMutex == 0 ){ - rc = JX9_NOMEM; - goto Release; - } - } -#endif - /* Link to the list of active engines */ -#if defined(JX9_ENABLE_THREADS) - /* Enter the global mutex */ - SyMutexEnter(sJx9MPGlobal.pMutexMethods, sJx9MPGlobal.pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel == JX9_THREAD_LEVEL_SINGLE */ -#endif - MACRO_LD_PUSH(sJx9MPGlobal.pEngines, pEngine); - sJx9MPGlobal.nEngine++; -#if defined(JX9_ENABLE_THREADS) - /* Leave the global mutex */ - SyMutexLeave(sJx9MPGlobal.pMutexMethods, sJx9MPGlobal.pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel == JX9_THREAD_LEVEL_SINGLE */ -#endif - /* Write a pointer to the new instance */ - *ppEngine = pEngine; - return JX9_OK; -Release: - SyMemBackendRelease(&pEngine->sAllocator); - SyMemBackendPoolFree(&sJx9MPGlobal.sAllocator,pEngine); - return rc; -} -/* - * [CAPIREF: jx9_release()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_release(jx9 *pEngine) -{ - int rc; - if( JX9_ENGINE_MISUSE(pEngine) ){ - return JX9_CORRUPT; - } -#if defined(JX9_ENABLE_THREADS) - /* Acquire engine mutex */ - SyMutexEnter(sJx9MPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */ - if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE && - JX9_THRD_ENGINE_RELEASE(pEngine) ){ - return JX9_ABORT; /* Another thread have released this instance */ - } -#endif - /* Release the engine */ - rc = EngineRelease(&(*pEngine)); -#if defined(JX9_ENABLE_THREADS) - /* Leave engine mutex */ - SyMutexLeave(sJx9MPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */ - /* Release engine mutex */ - SyMutexRelease(sJx9MPGlobal.pMutexMethods, pEngine->pMutex) /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */ -#endif -#if defined(JX9_ENABLE_THREADS) - /* Enter the global mutex */ - SyMutexEnter(sJx9MPGlobal.pMutexMethods, sJx9MPGlobal.pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel == JX9_THREAD_LEVEL_SINGLE */ -#endif - /* Unlink from the list of active engines */ - MACRO_LD_REMOVE(sJx9MPGlobal.pEngines, pEngine); - sJx9MPGlobal.nEngine--; -#if defined(JX9_ENABLE_THREADS) - /* Leave the global mutex */ - SyMutexLeave(sJx9MPGlobal.pMutexMethods, sJx9MPGlobal.pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel == JX9_THREAD_LEVEL_SINGLE */ -#endif - /* Release the memory chunk allocated to this engine */ - SyMemBackendPoolFree(&sJx9MPGlobal.sAllocator, pEngine); - return rc; -} -/* - * Compile a raw JX9 script. - * To execute a JX9 code, it must first be compiled into a bytecode program using this routine. - * If something goes wrong [i.e: compile-time error], your error log [i.e: error consumer callback] - * should display the appropriate error message and this function set ppVm to null and return - * an error code that is different from JX9_OK. Otherwise when the script is successfully compiled - * ppVm should hold the JX9 bytecode and it's safe to call [jx9_vm_exec(), jx9_vm_reset(), etc.]. - * This API does not actually evaluate the JX9 code. It merely compile and prepares the JX9 script - * for evaluation. - */ -static sxi32 ProcessScript( - jx9 *pEngine, /* Running JX9 engine */ - jx9_vm **ppVm, /* OUT: A pointer to the virtual machine */ - SyString *pScript, /* Raw JX9 script to compile */ - sxi32 iFlags, /* Compile-time flags */ - const char *zFilePath /* File path if script come from a file. NULL otherwise */ - ) -{ - jx9_vm *pVm; - int rc; - /* Allocate a new virtual machine */ - pVm = (jx9_vm *)SyMemBackendPoolAlloc(&pEngine->sAllocator, sizeof(jx9_vm)); - if( pVm == 0 ){ - /* If the supplied memory subsystem is so sick that we are unable to allocate - * a tiny chunk of memory, there is no much we can do here. */ - if( ppVm ){ - *ppVm = 0; - } - return JX9_NOMEM; - } - if( iFlags < 0 ){ - /* Default compile-time flags */ - iFlags = 0; - } - /* Initialize the Virtual Machine */ - rc = jx9VmInit(pVm, &(*pEngine)); - if( rc != JX9_OK ){ - SyMemBackendPoolFree(&pEngine->sAllocator, pVm); - if( ppVm ){ - *ppVm = 0; - } - return JX9_VM_ERR; - } - if( zFilePath ){ - /* Push processed file path */ - jx9VmPushFilePath(pVm, zFilePath, -1, TRUE, 0); - } - /* Reset the error message consumer */ - SyBlobReset(&pEngine->xConf.sErrConsumer); - /* Compile the script */ - jx9CompileScript(pVm, &(*pScript), iFlags); - if( pVm->sCodeGen.nErr > 0 || pVm == 0){ - sxu32 nErr = pVm->sCodeGen.nErr; - /* Compilation error or null ppVm pointer, release this VM */ - SyMemBackendRelease(&pVm->sAllocator); - SyMemBackendPoolFree(&pEngine->sAllocator, pVm); - if( ppVm ){ - *ppVm = 0; - } - return nErr > 0 ? JX9_COMPILE_ERR : JX9_OK; - } - /* Prepare the virtual machine for bytecode execution */ - rc = jx9VmMakeReady(pVm); - if( rc != JX9_OK ){ - goto Release; - } - /* Install local import path which is the current directory */ - jx9_vm_config(pVm, JX9_VM_CONFIG_IMPORT_PATH, "./"); -#if defined(JX9_ENABLE_THREADS) - if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE ){ - /* Associate a recursive mutex with this instance */ - pVm->pMutex = SyMutexNew(sJx9MPGlobal.pMutexMethods, SXMUTEX_TYPE_RECURSIVE); - if( pVm->pMutex == 0 ){ - goto Release; - } - } -#endif - /* Script successfully compiled, link to the list of active virtual machines */ - MACRO_LD_PUSH(pEngine->pVms, pVm); - pEngine->iVm++; - /* Point to the freshly created VM */ - *ppVm = pVm; - /* Ready to execute JX9 bytecode */ - return JX9_OK; -Release: - SyMemBackendRelease(&pVm->sAllocator); - SyMemBackendPoolFree(&pEngine->sAllocator, pVm); - *ppVm = 0; - return JX9_VM_ERR; -} -/* - * [CAPIREF: jx9_compile()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_compile(jx9 *pEngine, const char *zSource, int nLen, jx9_vm **ppOutVm) -{ - SyString sScript; - int rc; - if( JX9_ENGINE_MISUSE(pEngine) ){ - return JX9_CORRUPT; - } - if( zSource == 0 ){ - /* Empty Jx9 statement ';' */ - zSource = ";"; - nLen = (int)sizeof(char); - } - if( nLen < 0 ){ - /* Compute input length automatically */ - nLen = (int)SyStrlen(zSource); - } - SyStringInitFromBuf(&sScript, zSource, nLen); -#if defined(JX9_ENABLE_THREADS) - /* Acquire engine mutex */ - SyMutexEnter(sJx9MPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */ - if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE && - JX9_THRD_ENGINE_RELEASE(pEngine) ){ - return JX9_ABORT; /* Another thread have released this instance */ - } -#endif - /* Compile the script */ - rc = ProcessScript(&(*pEngine),ppOutVm,&sScript,0,0); -#if defined(JX9_ENABLE_THREADS) - /* Leave engine mutex */ - SyMutexLeave(sJx9MPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */ -#endif - /* Compilation result */ - return rc; -} -/* - * [CAPIREF: jx9_compile_file()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_compile_file(jx9 *pEngine, const char *zFilePath, jx9_vm **ppOutVm) -{ - const jx9_vfs *pVfs; - int rc; - if( ppOutVm ){ - *ppOutVm = 0; - } - rc = JX9_OK; /* cc warning */ - if( JX9_ENGINE_MISUSE(pEngine) || SX_EMPTY_STR(zFilePath) ){ - return JX9_CORRUPT; - } -#if defined(JX9_ENABLE_THREADS) - /* Acquire engine mutex */ - SyMutexEnter(sJx9MPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */ - if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE && - JX9_THRD_ENGINE_RELEASE(pEngine) ){ - return JX9_ABORT; /* Another thread have released this instance */ - } -#endif - /* - * Check if the underlying vfs implement the memory map - * [i.e: mmap() under UNIX/MapViewOfFile() under windows] function. - */ - pVfs = pEngine->pVfs; - if( pVfs == 0 || pVfs->xMmap == 0 ){ - /* Memory map routine not implemented */ - rc = JX9_IO_ERR; - }else{ - void *pMapView = 0; /* cc warning */ - jx9_int64 nSize = 0; /* cc warning */ - SyString sScript; - /* Try to get a memory view of the whole file */ - rc = pVfs->xMmap(zFilePath, &pMapView, &nSize); - if( rc != JX9_OK ){ - /* Assume an IO error */ - rc = JX9_IO_ERR; - }else{ - /* Compile the file */ - SyStringInitFromBuf(&sScript, pMapView, nSize); - rc = ProcessScript(&(*pEngine), ppOutVm, &sScript,0,zFilePath); - /* Release the memory view of the whole file */ - if( pVfs->xUnmap ){ - pVfs->xUnmap(pMapView, nSize); - } - } - } -#if defined(JX9_ENABLE_THREADS) - /* Leave engine mutex */ - SyMutexLeave(sJx9MPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */ -#endif - /* Compilation result */ - return rc; -} -/* - * [CAPIREF: jx9_vm_config()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_vm_config(jx9_vm *pVm, int iConfigOp, ...) -{ - va_list ap; - int rc; - /* Ticket 1433-002: NULL VM is harmless operation */ - if ( JX9_VM_MISUSE(pVm) ){ - return JX9_CORRUPT; - } -#if defined(JX9_ENABLE_THREADS) - /* Acquire VM mutex */ - SyMutexEnter(sJx9MPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */ - if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE && - JX9_THRD_VM_RELEASE(pVm) ){ - return JX9_ABORT; /* Another thread have released this instance */ - } -#endif - /* Confiugure the virtual machine */ - va_start(ap, iConfigOp); - rc = jx9VmConfigure(&(*pVm), iConfigOp, ap); - va_end(ap); -#if defined(JX9_ENABLE_THREADS) - /* Leave VM mutex */ - SyMutexLeave(sJx9MPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */ -#endif - return rc; -} -/* - * [CAPIREF: jx9_vm_release()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_vm_release(jx9_vm *pVm) -{ - jx9 *pEngine; - int rc; - /* Ticket 1433-002: NULL VM is harmless operation */ - if ( JX9_VM_MISUSE(pVm) ){ - return JX9_CORRUPT; - } -#if defined(JX9_ENABLE_THREADS) - /* Acquire VM mutex */ - SyMutexEnter(sJx9MPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */ - if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE && - JX9_THRD_VM_RELEASE(pVm) ){ - return JX9_ABORT; /* Another thread have released this instance */ - } -#endif - pEngine = pVm->pEngine; - rc = jx9VmRelease(&(*pVm)); -#if defined(JX9_ENABLE_THREADS) - /* Leave VM mutex */ - SyMutexLeave(sJx9MPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */ - /* Release VM mutex */ - SyMutexRelease(sJx9MPGlobal.pMutexMethods, pVm->pMutex) /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */ -#endif - if( rc == JX9_OK ){ - /* Unlink from the list of active VM */ -#if defined(JX9_ENABLE_THREADS) - /* Acquire engine mutex */ - SyMutexEnter(sJx9MPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */ - if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE && - JX9_THRD_ENGINE_RELEASE(pEngine) ){ - return JX9_ABORT; /* Another thread have released this instance */ - } -#endif - MACRO_LD_REMOVE(pEngine->pVms, pVm); - pEngine->iVm--; - /* Release the memory chunk allocated to this VM */ - SyMemBackendPoolFree(&pEngine->sAllocator, pVm); -#if defined(JX9_ENABLE_THREADS) - /* Leave engine mutex */ - SyMutexLeave(sJx9MPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */ -#endif - } - return rc; -} -/* - * [CAPIREF: jx9_create_function()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_create_function(jx9_vm *pVm, const char *zName, int (*xFunc)(jx9_context *, int, jx9_value **), void *pUserData) -{ - SyString sName; - int rc; - /* Ticket 1433-002: NULL VM is harmless operation */ - if ( JX9_VM_MISUSE(pVm) ){ - return JX9_CORRUPT; - } - SyStringInitFromBuf(&sName, zName, SyStrlen(zName)); - /* Remove leading and trailing white spaces */ - SyStringFullTrim(&sName); - /* Ticket 1433-003: NULL values are not allowed */ - if( sName.nByte < 1 || xFunc == 0 ){ - return JX9_CORRUPT; - } -#if defined(JX9_ENABLE_THREADS) - /* Acquire VM mutex */ - SyMutexEnter(sJx9MPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */ - if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE && - JX9_THRD_VM_RELEASE(pVm) ){ - return JX9_ABORT; /* Another thread have released this instance */ - } -#endif - /* Install the foreign function */ - rc = jx9VmInstallForeignFunction(&(*pVm), &sName, xFunc, pUserData); -#if defined(JX9_ENABLE_THREADS) - /* Leave VM mutex */ - SyMutexLeave(sJx9MPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */ -#endif - return rc; -} -JX9_PRIVATE int jx9DeleteFunction(jx9_vm *pVm,const char *zName) -{ - jx9_user_func *pFunc = 0; /* cc warning */ - int rc; - /* Perform the deletion */ - rc = SyHashDeleteEntry(&pVm->hHostFunction, (const void *)zName, SyStrlen(zName), (void **)&pFunc); - if( rc == JX9_OK ){ - /* Release internal fields */ - SySetRelease(&pFunc->aAux); - SyMemBackendFree(&pVm->sAllocator, (void *)SyStringData(&pFunc->sName)); - SyMemBackendPoolFree(&pVm->sAllocator, pFunc); - } - return rc; -} -/* - * [CAPIREF: jx9_create_constant()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_create_constant(jx9_vm *pVm, const char *zName, void (*xExpand)(jx9_value *, void *), void *pUserData) -{ - SyString sName; - int rc; - /* Ticket 1433-002: NULL VM is harmless operation */ - if ( JX9_VM_MISUSE(pVm) ){ - return JX9_CORRUPT; - } - SyStringInitFromBuf(&sName, zName, SyStrlen(zName)); - /* Remove leading and trailing white spaces */ - SyStringFullTrim(&sName); - if( sName.nByte < 1 ){ - /* Empty constant name */ - return JX9_CORRUPT; - } - /* TICKET 1433-003: NULL pointer is harmless operation */ - if( xExpand == 0 ){ - return JX9_CORRUPT; - } -#if defined(JX9_ENABLE_THREADS) - /* Acquire VM mutex */ - SyMutexEnter(sJx9MPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */ - if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE && - JX9_THRD_VM_RELEASE(pVm) ){ - return JX9_ABORT; /* Another thread have released this instance */ - } -#endif - /* Perform the registration */ - rc = jx9VmRegisterConstant(&(*pVm), &sName, xExpand, pUserData); -#if defined(JX9_ENABLE_THREADS) - /* Leave VM mutex */ - SyMutexLeave(sJx9MPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */ -#endif - return rc; -} -JX9_PRIVATE int Jx9DeleteConstant(jx9_vm *pVm,const char *zName) -{ - jx9_constant *pCons; - int rc; - /* Query the constant hashtable */ - rc = SyHashDeleteEntry(&pVm->hConstant, (const void *)zName, SyStrlen(zName), (void **)&pCons); - if( rc == JX9_OK ){ - /* Perform the deletion */ - SyMemBackendFree(&pVm->sAllocator, (void *)SyStringData(&pCons->sName)); - SyMemBackendPoolFree(&pVm->sAllocator, pCons); - } - return rc; -} -/* - * [CAPIREF: jx9_new_scalar()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE jx9_value * jx9_new_scalar(jx9_vm *pVm) -{ - jx9_value *pObj; - /* Ticket 1433-002: NULL VM is harmless operation */ - if ( JX9_VM_MISUSE(pVm) ){ - return 0; - } - /* Allocate a new scalar variable */ - pObj = (jx9_value *)SyMemBackendPoolAlloc(&pVm->sAllocator, sizeof(jx9_value)); - if( pObj == 0 ){ - return 0; - } - /* Nullify the new scalar */ - jx9MemObjInit(pVm, pObj); - return pObj; -} -/* - * [CAPIREF: jx9_new_array()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE jx9_value * jx9_new_array(jx9_vm *pVm) -{ - jx9_hashmap *pMap; - jx9_value *pObj; - /* Ticket 1433-002: NULL VM is harmless operation */ - if ( JX9_VM_MISUSE(pVm) ){ - return 0; - } - /* Create a new hashmap first */ - pMap = jx9NewHashmap(&(*pVm), 0, 0); - if( pMap == 0 ){ - return 0; - } - /* Associate a new jx9_value with this hashmap */ - pObj = (jx9_value *)SyMemBackendPoolAlloc(&pVm->sAllocator, sizeof(jx9_value)); - if( pObj == 0 ){ - jx9HashmapRelease(pMap, TRUE); - return 0; - } - jx9MemObjInitFromArray(pVm, pObj, pMap); - return pObj; -} -/* - * [CAPIREF: jx9_release_value()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_release_value(jx9_vm *pVm, jx9_value *pValue) -{ - /* Ticket 1433-002: NULL VM is a harmless operation */ - if ( JX9_VM_MISUSE(pVm) ){ - return JX9_CORRUPT; - } - if( pValue ){ - /* Release the value */ - jx9MemObjRelease(pValue); - SyMemBackendPoolFree(&pVm->sAllocator, pValue); - } - return JX9_OK; -} -/* - * [CAPIREF: jx9_value_to_int()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_to_int(jx9_value *pValue) -{ - int rc; - rc = jx9MemObjToInteger(pValue); - if( rc != JX9_OK ){ - return 0; - } - return (int)pValue->x.iVal; -} -/* - * [CAPIREF: jx9_value_to_bool()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_to_bool(jx9_value *pValue) -{ - int rc; - rc = jx9MemObjToBool(pValue); - if( rc != JX9_OK ){ - return 0; - } - return (int)pValue->x.iVal; -} -/* - * [CAPIREF: jx9_value_to_int64()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE jx9_int64 jx9_value_to_int64(jx9_value *pValue) -{ - int rc; - rc = jx9MemObjToInteger(pValue); - if( rc != JX9_OK ){ - return 0; - } - return pValue->x.iVal; -} -/* - * [CAPIREF: jx9_value_to_double()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE double jx9_value_to_double(jx9_value *pValue) -{ - int rc; - rc = jx9MemObjToReal(pValue); - if( rc != JX9_OK ){ - return (double)0; - } - return (double)pValue->x.rVal; -} -/* - * [CAPIREF: jx9_value_to_string()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE const char * jx9_value_to_string(jx9_value *pValue, int *pLen) -{ - jx9MemObjToString(pValue); - if( SyBlobLength(&pValue->sBlob) > 0 ){ - SyBlobNullAppend(&pValue->sBlob); - if( pLen ){ - *pLen = (int)SyBlobLength(&pValue->sBlob); - } - return (const char *)SyBlobData(&pValue->sBlob); - }else{ - /* Return the empty string */ - if( pLen ){ - *pLen = 0; - } - return ""; - } -} -/* - * [CAPIREF: jx9_value_to_resource()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE void * jx9_value_to_resource(jx9_value *pValue) -{ - if( (pValue->iFlags & MEMOBJ_RES) == 0 ){ - /* Not a resource, return NULL */ - return 0; - } - return pValue->x.pOther; -} -/* - * [CAPIREF: jx9_value_compare()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_compare(jx9_value *pLeft, jx9_value *pRight, int bStrict) -{ - int rc; - if( pLeft == 0 || pRight == 0 ){ - /* TICKET 1433-24: NULL values is harmless operation */ - return 1; - } - /* Perform the comparison */ - rc = jx9MemObjCmp(&(*pLeft), &(*pRight), bStrict, 0); - /* Comparison result */ - return rc; -} -/* - * [CAPIREF: jx9_result_int()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_result_int(jx9_context *pCtx, int iValue) -{ - return jx9_value_int(pCtx->pRet, iValue); -} -/* - * [CAPIREF: jx9_result_int64()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_result_int64(jx9_context *pCtx, jx9_int64 iValue) -{ - return jx9_value_int64(pCtx->pRet, iValue); -} -/* - * [CAPIREF: jx9_result_bool()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_result_bool(jx9_context *pCtx, int iBool) -{ - return jx9_value_bool(pCtx->pRet, iBool); -} -/* - * [CAPIREF: jx9_result_double()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_result_double(jx9_context *pCtx, double Value) -{ - return jx9_value_double(pCtx->pRet, Value); -} -/* - * [CAPIREF: jx9_result_null()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_result_null(jx9_context *pCtx) -{ - /* Invalidate any prior representation and set the NULL flag */ - jx9MemObjRelease(pCtx->pRet); - return JX9_OK; -} -/* - * [CAPIREF: jx9_result_string()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_result_string(jx9_context *pCtx, const char *zString, int nLen) -{ - return jx9_value_string(pCtx->pRet, zString, nLen); -} -/* - * [CAPIREF: jx9_result_string_format()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_result_string_format(jx9_context *pCtx, const char *zFormat, ...) -{ - jx9_value *p; - va_list ap; - int rc; - p = pCtx->pRet; - if( (p->iFlags & MEMOBJ_STRING) == 0 ){ - /* Invalidate any prior representation */ - jx9MemObjRelease(p); - MemObjSetType(p, MEMOBJ_STRING); - } - /* Format the given string */ - va_start(ap, zFormat); - rc = SyBlobFormatAp(&p->sBlob, zFormat, ap); - va_end(ap); - return rc; -} -/* - * [CAPIREF: jx9_result_value()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_result_value(jx9_context *pCtx, jx9_value *pValue) -{ - int rc = JX9_OK; - if( pValue == 0 ){ - jx9MemObjRelease(pCtx->pRet); - }else{ - rc = jx9MemObjStore(pValue, pCtx->pRet); - } - return rc; -} -/* - * [CAPIREF: jx9_result_resource()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_result_resource(jx9_context *pCtx, void *pUserData) -{ - return jx9_value_resource(pCtx->pRet, pUserData); -} -/* - * [CAPIREF: jx9_context_new_scalar()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE jx9_value * jx9_context_new_scalar(jx9_context *pCtx) -{ - jx9_value *pVal; - pVal = jx9_new_scalar(pCtx->pVm); - if( pVal ){ - /* Record value address so it can be freed automatically - * when the calling function returns. - */ - SySetPut(&pCtx->sVar, (const void *)&pVal); - } - return pVal; -} -/* - * [CAPIREF: jx9_context_new_array()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE jx9_value * jx9_context_new_array(jx9_context *pCtx) -{ - jx9_value *pVal; - pVal = jx9_new_array(pCtx->pVm); - if( pVal ){ - /* Record value address so it can be freed automatically - * when the calling function returns. - */ - SySetPut(&pCtx->sVar, (const void *)&pVal); - } - return pVal; -} -/* - * [CAPIREF: jx9_context_release_value()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE void jx9_context_release_value(jx9_context *pCtx, jx9_value *pValue) -{ - jx9VmReleaseContextValue(&(*pCtx), pValue); -} -/* - * [CAPIREF: jx9_context_alloc_chunk()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE void * jx9_context_alloc_chunk(jx9_context *pCtx, unsigned int nByte, int ZeroChunk, int AutoRelease) -{ - void *pChunk; - pChunk = SyMemBackendAlloc(&pCtx->pVm->sAllocator, nByte); - if( pChunk ){ - if( ZeroChunk ){ - /* Zero the memory chunk */ - SyZero(pChunk, nByte); - } - if( AutoRelease ){ - jx9_aux_data sAux; - /* Track the chunk so that it can be released automatically - * upon this context is destroyed. - */ - sAux.pAuxData = pChunk; - SySetPut(&pCtx->sChunk, (const void *)&sAux); - } - } - return pChunk; -} -/* - * Check if the given chunk address is registered in the call context - * chunk container. - * Return TRUE if registered.FALSE otherwise. - * Refer to [jx9_context_realloc_chunk(), jx9_context_free_chunk()]. - */ -static jx9_aux_data * ContextFindChunk(jx9_context *pCtx, void *pChunk) -{ - jx9_aux_data *aAux, *pAux; - sxu32 n; - if( SySetUsed(&pCtx->sChunk) < 1 ){ - /* Don't bother processing, the container is empty */ - return 0; - } - /* Perform the lookup */ - aAux = (jx9_aux_data *)SySetBasePtr(&pCtx->sChunk); - for( n = 0; n < SySetUsed(&pCtx->sChunk) ; ++n ){ - pAux = &aAux[n]; - if( pAux->pAuxData == pChunk ){ - /* Chunk found */ - return pAux; - } - } - /* No such allocated chunk */ - return 0; -} -/* - * [CAPIREF: jx9_context_realloc_chunk()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE void * jx9_context_realloc_chunk(jx9_context *pCtx, void *pChunk, unsigned int nByte) -{ - jx9_aux_data *pAux; - void *pNew; - pNew = SyMemBackendRealloc(&pCtx->pVm->sAllocator, pChunk, nByte); - if( pNew ){ - pAux = ContextFindChunk(pCtx, pChunk); - if( pAux ){ - pAux->pAuxData = pNew; - } - } - return pNew; -} -/* - * [CAPIREF: jx9_context_free_chunk()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE void jx9_context_free_chunk(jx9_context *pCtx, void *pChunk) -{ - jx9_aux_data *pAux; - if( pChunk == 0 ){ - /* TICKET-1433-93: NULL chunk is a harmless operation */ - return; - } - pAux = ContextFindChunk(pCtx, pChunk); - if( pAux ){ - /* Mark as destroyed */ - pAux->pAuxData = 0; - } - SyMemBackendFree(&pCtx->pVm->sAllocator, pChunk); -} -/* - * [CAPIREF: jx9_array_fetch()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE jx9_value * jx9_array_fetch(jx9_value *pArray, const char *zKey, int nByte) -{ - jx9_hashmap_node *pNode; - jx9_value *pValue; - jx9_value skey; - int rc; - /* Make sure we are dealing with a valid hashmap */ - if( (pArray->iFlags & MEMOBJ_HASHMAP) == 0 ){ - return 0; - } - if( nByte < 0 ){ - nByte = (int)SyStrlen(zKey); - } - /* Convert the key to a jx9_value */ - jx9MemObjInit(pArray->pVm, &skey); - jx9MemObjStringAppend(&skey, zKey, (sxu32)nByte); - /* Perform the lookup */ - rc = jx9HashmapLookup((jx9_hashmap *)pArray->x.pOther, &skey, &pNode); - jx9MemObjRelease(&skey); - if( rc != JX9_OK ){ - /* No such entry */ - return 0; - } - /* Extract the target value */ - pValue = (jx9_value *)SySetAt(&pArray->pVm->aMemObj, pNode->nValIdx); - return pValue; -} -/* - * [CAPIREF: jx9_array_walk()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_array_walk(jx9_value *pArray, int (*xWalk)(jx9_value *pValue, jx9_value *, void *), void *pUserData) -{ - int rc; - if( xWalk == 0 ){ - return JX9_CORRUPT; - } - /* Make sure we are dealing with a valid hashmap */ - if( (pArray->iFlags & MEMOBJ_HASHMAP) == 0 ){ - return JX9_CORRUPT; - } - /* Start the walk process */ - rc = jx9HashmapWalk((jx9_hashmap *)pArray->x.pOther, xWalk, pUserData); - return rc != JX9_OK ? JX9_ABORT /* User callback request an operation abort*/ : JX9_OK; -} -/* - * [CAPIREF: jx9_array_add_elem()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_array_add_elem(jx9_value *pArray, jx9_value *pKey, jx9_value *pValue) -{ - int rc; - /* Make sure we are dealing with a valid hashmap */ - if( (pArray->iFlags & MEMOBJ_HASHMAP) == 0 ){ - return JX9_CORRUPT; - } - /* Perform the insertion */ - rc = jx9HashmapInsert((jx9_hashmap *)pArray->x.pOther, &(*pKey), &(*pValue)); - return rc; -} -/* - * [CAPIREF: jx9_array_add_strkey_elem()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_array_add_strkey_elem(jx9_value *pArray, const char *zKey, jx9_value *pValue) -{ - int rc; - /* Make sure we are dealing with a valid hashmap */ - if( (pArray->iFlags & MEMOBJ_HASHMAP) == 0 ){ - return JX9_CORRUPT; - } - /* Perform the insertion */ - if( SX_EMPTY_STR(zKey) ){ - /* Empty key, assign an automatic index */ - rc = jx9HashmapInsert((jx9_hashmap *)pArray->x.pOther, 0, &(*pValue)); - }else{ - jx9_value sKey; - jx9MemObjInitFromString(pArray->pVm, &sKey, 0); - jx9MemObjStringAppend(&sKey, zKey, (sxu32)SyStrlen(zKey)); - rc = jx9HashmapInsert((jx9_hashmap *)pArray->x.pOther, &sKey, &(*pValue)); - jx9MemObjRelease(&sKey); - } - return rc; -} -/* - * [CAPIREF: jx9_array_count()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE unsigned int jx9_array_count(jx9_value *pArray) -{ - jx9_hashmap *pMap; - /* Make sure we are dealing with a valid hashmap */ - if( (pArray->iFlags & MEMOBJ_HASHMAP) == 0 ){ - return 0; - } - /* Point to the internal representation of the hashmap */ - pMap = (jx9_hashmap *)pArray->x.pOther; - return pMap->nEntry; -} -/* - * [CAPIREF: jx9_context_output()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_context_output(jx9_context *pCtx, const char *zString, int nLen) -{ - SyString sData; - int rc; - if( nLen < 0 ){ - nLen = (int)SyStrlen(zString); - } - SyStringInitFromBuf(&sData, zString, nLen); - rc = jx9VmOutputConsume(pCtx->pVm, &sData); - return rc; -} -/* - * [CAPIREF: jx9_context_throw_error()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_context_throw_error(jx9_context *pCtx, int iErr, const char *zErr) -{ - int rc = JX9_OK; - if( zErr ){ - rc = jx9VmThrowError(pCtx->pVm, &pCtx->pFunc->sName, iErr, zErr); - } - return rc; -} -/* - * [CAPIREF: jx9_context_throw_error_format()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_context_throw_error_format(jx9_context *pCtx, int iErr, const char *zFormat, ...) -{ - va_list ap; - int rc; - if( zFormat == 0){ - return JX9_OK; - } - va_start(ap, zFormat); - rc = jx9VmThrowErrorAp(pCtx->pVm, &pCtx->pFunc->sName, iErr, zFormat, ap); - va_end(ap); - return rc; -} -/* - * [CAPIREF: jx9_context_random_num()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE unsigned int jx9_context_random_num(jx9_context *pCtx) -{ - sxu32 n; - n = jx9VmRandomNum(pCtx->pVm); - return n; -} -/* - * [CAPIREF: jx9_context_random_string()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_context_random_string(jx9_context *pCtx, char *zBuf, int nBuflen) -{ - if( nBuflen < 3 ){ - return JX9_CORRUPT; - } - jx9VmRandomString(pCtx->pVm, zBuf, nBuflen); - return JX9_OK; -} -/* - * [CAPIREF: jx9_context_user_data()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE void * jx9_context_user_data(jx9_context *pCtx) -{ - return pCtx->pFunc->pUserData; -} -/* - * [CAPIREF: jx9_context_push_aux_data()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_context_push_aux_data(jx9_context *pCtx, void *pUserData) -{ - jx9_aux_data sAux; - int rc; - sAux.pAuxData = pUserData; - rc = SySetPut(&pCtx->pFunc->aAux, (const void *)&sAux); - return rc; -} -/* - * [CAPIREF: jx9_context_peek_aux_data()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE void * jx9_context_peek_aux_data(jx9_context *pCtx) -{ - jx9_aux_data *pAux; - pAux = (jx9_aux_data *)SySetPeek(&pCtx->pFunc->aAux); - return pAux ? pAux->pAuxData : 0; -} -/* - * [CAPIREF: jx9_context_pop_aux_data()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE void * jx9_context_pop_aux_data(jx9_context *pCtx) -{ - jx9_aux_data *pAux; - pAux = (jx9_aux_data *)SySetPop(&pCtx->pFunc->aAux); - return pAux ? pAux->pAuxData : 0; -} -/* - * [CAPIREF: jx9_context_result_buf_length()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE unsigned int jx9_context_result_buf_length(jx9_context *pCtx) -{ - return SyBlobLength(&pCtx->pRet->sBlob); -} -/* - * [CAPIREF: jx9_function_name()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE const char * jx9_function_name(jx9_context *pCtx) -{ - SyString *pName; - pName = &pCtx->pFunc->sName; - return pName->zString; -} -/* - * [CAPIREF: jx9_value_int()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_int(jx9_value *pVal, int iValue) -{ - /* Invalidate any prior representation */ - jx9MemObjRelease(pVal); - pVal->x.iVal = (jx9_int64)iValue; - MemObjSetType(pVal, MEMOBJ_INT); - return JX9_OK; -} -/* - * [CAPIREF: jx9_value_int64()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_int64(jx9_value *pVal, jx9_int64 iValue) -{ - /* Invalidate any prior representation */ - jx9MemObjRelease(pVal); - pVal->x.iVal = iValue; - MemObjSetType(pVal, MEMOBJ_INT); - return JX9_OK; -} -/* - * [CAPIREF: jx9_value_bool()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_bool(jx9_value *pVal, int iBool) -{ - /* Invalidate any prior representation */ - jx9MemObjRelease(pVal); - pVal->x.iVal = iBool ? 1 : 0; - MemObjSetType(pVal, MEMOBJ_BOOL); - return JX9_OK; -} -/* - * [CAPIREF: jx9_value_null()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_null(jx9_value *pVal) -{ - /* Invalidate any prior representation and set the NULL flag */ - jx9MemObjRelease(pVal); - return JX9_OK; -} -/* - * [CAPIREF: jx9_value_double()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_double(jx9_value *pVal, double Value) -{ - /* Invalidate any prior representation */ - jx9MemObjRelease(pVal); - pVal->x.rVal = (jx9_real)Value; - MemObjSetType(pVal, MEMOBJ_REAL); - /* Try to get an integer representation also */ - jx9MemObjTryInteger(pVal); - return JX9_OK; -} -/* - * [CAPIREF: jx9_value_string()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_string(jx9_value *pVal, const char *zString, int nLen) -{ - if((pVal->iFlags & MEMOBJ_STRING) == 0 ){ - /* Invalidate any prior representation */ - jx9MemObjRelease(pVal); - MemObjSetType(pVal, MEMOBJ_STRING); - } - if( zString ){ - if( nLen < 0 ){ - /* Compute length automatically */ - nLen = (int)SyStrlen(zString); - } - SyBlobAppend(&pVal->sBlob, (const void *)zString, (sxu32)nLen); - } - return JX9_OK; -} -/* - * [CAPIREF: jx9_value_string_format()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_string_format(jx9_value *pVal, const char *zFormat, ...) -{ - va_list ap; - int rc; - if((pVal->iFlags & MEMOBJ_STRING) == 0 ){ - /* Invalidate any prior representation */ - jx9MemObjRelease(pVal); - MemObjSetType(pVal, MEMOBJ_STRING); - } - va_start(ap, zFormat); - rc = SyBlobFormatAp(&pVal->sBlob, zFormat, ap); - va_end(ap); - return JX9_OK; -} -/* - * [CAPIREF: jx9_value_reset_string_cursor()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_reset_string_cursor(jx9_value *pVal) -{ - /* Reset the string cursor */ - SyBlobReset(&pVal->sBlob); - return JX9_OK; -} -/* - * [CAPIREF: jx9_value_resource()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_resource(jx9_value *pVal, void *pUserData) -{ - /* Invalidate any prior representation */ - jx9MemObjRelease(pVal); - /* Reflect the new type */ - pVal->x.pOther = pUserData; - MemObjSetType(pVal, MEMOBJ_RES); - return JX9_OK; -} -/* - * [CAPIREF: jx9_value_release()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_release(jx9_value *pVal) -{ - jx9MemObjRelease(pVal); - return JX9_OK; -} -/* - * [CAPIREF: jx9_value_is_int()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_is_int(jx9_value *pVal) -{ - return (pVal->iFlags & MEMOBJ_INT) ? TRUE : FALSE; -} -/* - * [CAPIREF: jx9_value_is_float()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_is_float(jx9_value *pVal) -{ - return (pVal->iFlags & MEMOBJ_REAL) ? TRUE : FALSE; -} -/* - * [CAPIREF: jx9_value_is_bool()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_is_bool(jx9_value *pVal) -{ - return (pVal->iFlags & MEMOBJ_BOOL) ? TRUE : FALSE; -} -/* - * [CAPIREF: jx9_value_is_string()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_is_string(jx9_value *pVal) -{ - return (pVal->iFlags & MEMOBJ_STRING) ? TRUE : FALSE; -} -/* - * [CAPIREF: jx9_value_is_null()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_is_null(jx9_value *pVal) -{ - return (pVal->iFlags & MEMOBJ_NULL) ? TRUE : FALSE; -} -/* - * [CAPIREF: jx9_value_is_numeric()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_is_numeric(jx9_value *pVal) -{ - int rc; - rc = jx9MemObjIsNumeric(pVal); - return rc; -} -/* - * [CAPIREF: jx9_value_is_callable()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_is_callable(jx9_value *pVal) -{ - int rc; - rc = jx9VmIsCallable(pVal->pVm, pVal); - return rc; -} -/* - * [CAPIREF: jx9_value_is_scalar()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_is_scalar(jx9_value *pVal) -{ - return (pVal->iFlags & MEMOBJ_SCALAR) ? TRUE : FALSE; -} -/* - * [CAPIREF: jx9_value_is_json_array()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_is_json_array(jx9_value *pVal) -{ - return (pVal->iFlags & MEMOBJ_HASHMAP) ? TRUE : FALSE; -} -/* - * [CAPIREF: jx9_value_is_json_object()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_is_json_object(jx9_value *pVal) -{ - jx9_hashmap *pMap; - if( (pVal->iFlags & MEMOBJ_HASHMAP) == 0 ){ - return FALSE; - } - pMap = (jx9_hashmap *)pVal->x.pOther; - if( (pMap->iFlags & HASHMAP_JSON_OBJECT) == 0 ){ - return FALSE; - } - return TRUE; -} -/* - * [CAPIREF: jx9_value_is_resource()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_is_resource(jx9_value *pVal) -{ - return (pVal->iFlags & MEMOBJ_RES) ? TRUE : FALSE; -} -/* - * [CAPIREF: jx9_value_is_empty()] - * Please refer to the official documentation for function purpose and expected parameters. - */ -JX9_PRIVATE int jx9_value_is_empty(jx9_value *pVal) -{ - int rc; - rc = jx9MemObjIsEmpty(pVal); - return rc; -} -- cgit v1.2.3