summaryrefslogtreecommitdiffstats
path: root/common/unqlite/jx9_api.c
diff options
context:
space:
mode:
authorAaron Seigo <aseigo@kde.org>2014-12-07 10:08:07 +0100
committerAaron Seigo <aseigo@kde.org>2014-12-11 01:07:08 +0100
commit9ee8378d393778ac67314be7ea8d5bcbaeee9ee0 (patch)
treecf93471a69f9f4bbb4940de55ae134106fcd8380 /common/unqlite/jx9_api.c
parentee6f068dff6b15441e553ffbfb2bf8aa97b26f57 (diff)
downloadsink-9ee8378d393778ac67314be7ea8d5bcbaeee9ee0.tar.gz
sink-9ee8378d393778ac67314be7ea8d5bcbaeee9ee0.zip
try out unqlite
Diffstat (limited to 'common/unqlite/jx9_api.c')
-rw-r--r--common/unqlite/jx9_api.c1744
1 files changed, 1744 insertions, 0 deletions
diff --git a/common/unqlite/jx9_api.c b/common/unqlite/jx9_api.c
new file mode 100644
index 0000000..efad097
--- /dev/null
+++ b/common/unqlite/jx9_api.c
@@ -0,0 +1,1744 @@
1/*
2 * Symisc JX9: A Highly Efficient Embeddable Scripting Engine Based on JSON.
3 * Copyright (C) 2012-2013, Symisc Systems http://jx9.symisc.net/
4 * Version 1.7.2
5 * For information on licensing, redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES
6 * please contact Symisc Systems via:
7 * legal@symisc.net
8 * licensing@symisc.net
9 * contact@symisc.net
10 * or visit:
11 * http://jx9.symisc.net/
12 */
13 /* $SymiscID: api.c v1.7 FreeBSD 2012-12-18 06:54 stable <chm@symisc.net> $ */
14#ifndef JX9_AMALGAMATION
15#include "jx9Int.h"
16#endif
17/* This file implement the public interfaces presented to host-applications.
18 * Routines in other files are for internal use by JX9 and should not be
19 * accessed by users of the library.
20 */
21#define JX9_ENGINE_MAGIC 0xF874BCD7
22#define JX9_ENGINE_MISUSE(ENGINE) (ENGINE == 0 || ENGINE->nMagic != JX9_ENGINE_MAGIC)
23#define JX9_VM_MISUSE(VM) (VM == 0 || VM->nMagic == JX9_VM_STALE)
24/* If another thread have released a working instance, the following macros
25 * evaluates to true. These macros are only used when the library
26 * is built with threading support enabled which is not the case in
27 * the default built.
28 */
29#define JX9_THRD_ENGINE_RELEASE(ENGINE) (ENGINE->nMagic != JX9_ENGINE_MAGIC)
30#define JX9_THRD_VM_RELEASE(VM) (VM->nMagic == JX9_VM_STALE)
31/* IMPLEMENTATION: jx9@embedded@symisc 311-12-32 */
32/*
33 * All global variables are collected in the structure named "sJx9MPGlobal".
34 * That way it is clear in the code when we are using static variable because
35 * its name start with sJx9MPGlobal.
36 */
37static struct Jx9Global_Data
38{
39 SyMemBackend sAllocator; /* Global low level memory allocator */
40#if defined(JX9_ENABLE_THREADS)
41 const SyMutexMethods *pMutexMethods; /* Mutex methods */
42 SyMutex *pMutex; /* Global mutex */
43 sxu32 nThreadingLevel; /* Threading level: 0 == Single threaded/1 == Multi-Threaded
44 * The threading level can be set using the [jx9_lib_config()]
45 * interface with a configuration verb set to
46 * JX9_LIB_CONFIG_THREAD_LEVEL_SINGLE or
47 * JX9_LIB_CONFIG_THREAD_LEVEL_MULTI
48 */
49#endif
50 const jx9_vfs *pVfs; /* Underlying virtual file system */
51 sxi32 nEngine; /* Total number of active engines */
52 jx9 *pEngines; /* List of active engine */
53 sxu32 nMagic; /* Sanity check against library misuse */
54}sJx9MPGlobal = {
55 {0, 0, 0, 0, 0, 0, 0, 0, {0}},
56#if defined(JX9_ENABLE_THREADS)
57 0,
58 0,
59 0,
60#endif
61 0,
62 0,
63 0,
64 0
65};
66#define JX9_LIB_MAGIC 0xEA1495BA
67#define JX9_LIB_MISUSE (sJx9MPGlobal.nMagic != JX9_LIB_MAGIC)
68/*
69 * Supported threading level.
70 * These options have meaning only when the library is compiled with multi-threading
71 * support.That is, the JX9_ENABLE_THREADS compile time directive must be defined
72 * when JX9 is built.
73 * JX9_THREAD_LEVEL_SINGLE:
74 * In this mode, mutexing is disabled and the library can only be used by a single thread.
75 * JX9_THREAD_LEVEL_MULTI
76 * In this mode, all mutexes including the recursive mutexes on [jx9] objects
77 * are enabled so that the application is free to share the same engine
78 * between different threads at the same time.
79 */
80#define JX9_THREAD_LEVEL_SINGLE 1
81#define JX9_THREAD_LEVEL_MULTI 2
82/*
83 * Configure a running JX9 engine instance.
84 * return JX9_OK on success.Any other return
85 * value indicates failure.
86 * Refer to [jx9_config()].
87 */
88JX9_PRIVATE sxi32 jx9EngineConfig(jx9 *pEngine, sxi32 nOp, va_list ap)
89{
90 jx9_conf *pConf = &pEngine->xConf;
91 int rc = JX9_OK;
92 /* Perform the requested operation */
93 switch(nOp){
94 case JX9_CONFIG_ERR_LOG:{
95 /* Extract compile-time error log if any */
96 const char **pzPtr = va_arg(ap, const char **);
97 int *pLen = va_arg(ap, int *);
98 if( pzPtr == 0 ){
99 rc = JX9_CORRUPT;
100 break;
101 }
102 /* NULL terminate the error-log buffer */
103 SyBlobNullAppend(&pConf->sErrConsumer);
104 /* Point to the error-log buffer */
105 *pzPtr = (const char *)SyBlobData(&pConf->sErrConsumer);
106 if( pLen ){
107 if( SyBlobLength(&pConf->sErrConsumer) > 1 /* NULL '\0' terminator */ ){
108 *pLen = (int)SyBlobLength(&pConf->sErrConsumer);
109 }else{
110 *pLen = 0;
111 }
112 }
113 break;
114 }
115 case JX9_CONFIG_ERR_ABORT:
116 /* Reserved for future use */
117 break;
118 default:
119 /* Unknown configuration verb */
120 rc = JX9_CORRUPT;
121 break;
122 } /* Switch() */
123 return rc;
124}
125/*
126 * Configure the JX9 library.
127 * Return JX9_OK on success. Any other return value indicates failure.
128 * Refer to [jx9_lib_config()].
129 */
130static sxi32 Jx9CoreConfigure(sxi32 nOp, va_list ap)
131{
132 int rc = JX9_OK;
133 switch(nOp){
134 case JX9_LIB_CONFIG_VFS:{
135 /* Install a virtual file system */
136 const jx9_vfs *pVfs = va_arg(ap, const jx9_vfs *);
137 sJx9MPGlobal.pVfs = pVfs;
138 break;
139 }
140 case JX9_LIB_CONFIG_USER_MALLOC: {
141 /* Use an alternative low-level memory allocation routines */
142 const SyMemMethods *pMethods = va_arg(ap, const SyMemMethods *);
143 /* Save the memory failure callback (if available) */
144 ProcMemError xMemErr = sJx9MPGlobal.sAllocator.xMemError;
145 void *pMemErr = sJx9MPGlobal.sAllocator.pUserData;
146 if( pMethods == 0 ){
147 /* Use the built-in memory allocation subsystem */
148 rc = SyMemBackendInit(&sJx9MPGlobal.sAllocator, xMemErr, pMemErr);
149 }else{
150 rc = SyMemBackendInitFromOthers(&sJx9MPGlobal.sAllocator, pMethods, xMemErr, pMemErr);
151 }
152 break;
153 }
154 case JX9_LIB_CONFIG_MEM_ERR_CALLBACK: {
155 /* Memory failure callback */
156 ProcMemError xMemErr = va_arg(ap, ProcMemError);
157 void *pUserData = va_arg(ap, void *);
158 sJx9MPGlobal.sAllocator.xMemError = xMemErr;
159 sJx9MPGlobal.sAllocator.pUserData = pUserData;
160 break;
161 }
162 case JX9_LIB_CONFIG_USER_MUTEX: {
163#if defined(JX9_ENABLE_THREADS)
164 /* Use an alternative low-level mutex subsystem */
165 const SyMutexMethods *pMethods = va_arg(ap, const SyMutexMethods *);
166#if defined (UNTRUST)
167 if( pMethods == 0 ){
168 rc = JX9_CORRUPT;
169 }
170#endif
171 /* Sanity check */
172 if( pMethods->xEnter == 0 || pMethods->xLeave == 0 || pMethods->xNew == 0){
173 /* At least three criticial callbacks xEnter(), xLeave() and xNew() must be supplied */
174 rc = JX9_CORRUPT;
175 break;
176 }
177 if( sJx9MPGlobal.pMutexMethods ){
178 /* Overwrite the previous mutex subsystem */
179 SyMutexRelease(sJx9MPGlobal.pMutexMethods, sJx9MPGlobal.pMutex);
180 if( sJx9MPGlobal.pMutexMethods->xGlobalRelease ){
181 sJx9MPGlobal.pMutexMethods->xGlobalRelease();
182 }
183 sJx9MPGlobal.pMutex = 0;
184 }
185 /* Initialize and install the new mutex subsystem */
186 if( pMethods->xGlobalInit ){
187 rc = pMethods->xGlobalInit();
188 if ( rc != JX9_OK ){
189 break;
190 }
191 }
192 /* Create the global mutex */
193 sJx9MPGlobal.pMutex = pMethods->xNew(SXMUTEX_TYPE_FAST);
194 if( sJx9MPGlobal.pMutex == 0 ){
195 /*
196 * If the supplied mutex subsystem is so sick that we are unable to
197 * create a single mutex, there is no much we can do here.
198 */
199 if( pMethods->xGlobalRelease ){
200 pMethods->xGlobalRelease();
201 }
202 rc = JX9_CORRUPT;
203 break;
204 }
205 sJx9MPGlobal.pMutexMethods = pMethods;
206 if( sJx9MPGlobal.nThreadingLevel == 0 ){
207 /* Set a default threading level */
208 sJx9MPGlobal.nThreadingLevel = JX9_THREAD_LEVEL_MULTI;
209 }
210#endif
211 break;
212 }
213 case JX9_LIB_CONFIG_THREAD_LEVEL_SINGLE:
214#if defined(JX9_ENABLE_THREADS)
215 /* Single thread mode(Only one thread is allowed to play with the library) */
216 sJx9MPGlobal.nThreadingLevel = JX9_THREAD_LEVEL_SINGLE;
217#endif
218 break;
219 case JX9_LIB_CONFIG_THREAD_LEVEL_MULTI:
220#if defined(JX9_ENABLE_THREADS)
221 /* Multi-threading mode (library is thread safe and JX9 engines and virtual machines
222 * may be shared between multiple threads).
223 */
224 sJx9MPGlobal.nThreadingLevel = JX9_THREAD_LEVEL_MULTI;
225#endif
226 break;
227 default:
228 /* Unknown configuration option */
229 rc = JX9_CORRUPT;
230 break;
231 }
232 return rc;
233}
234/*
235 * [CAPIREF: jx9_lib_config()]
236 * Please refer to the official documentation for function purpose and expected parameters.
237 */
238JX9_PRIVATE int jx9_lib_config(int nConfigOp, ...)
239{
240 va_list ap;
241 int rc;
242 if( sJx9MPGlobal.nMagic == JX9_LIB_MAGIC ){
243 /* Library is already initialized, this operation is forbidden */
244 return JX9_LOOKED;
245 }
246 va_start(ap, nConfigOp);
247 rc = Jx9CoreConfigure(nConfigOp, ap);
248 va_end(ap);
249 return rc;
250}
251/*
252 * Global library initialization
253 * Refer to [jx9_lib_init()]
254 * This routine must be called to initialize the memory allocation subsystem, the mutex
255 * subsystem prior to doing any serious work with the library.The first thread to call
256 * this routine does the initialization process and set the magic number so no body later
257 * can re-initialize the library.If subsequent threads call this routine before the first
258 * thread have finished the initialization process, then the subsequent threads must block
259 * until the initialization process is done.
260 */
261static sxi32 Jx9CoreInitialize(void)
262{
263 const jx9_vfs *pVfs; /* Built-in vfs */
264#if defined(JX9_ENABLE_THREADS)
265 const SyMutexMethods *pMutexMethods = 0;
266 SyMutex *pMaster = 0;
267#endif
268 int rc;
269 /*
270 * If the library is already initialized, then a call to this routine
271 * is a no-op.
272 */
273 if( sJx9MPGlobal.nMagic == JX9_LIB_MAGIC ){
274 return JX9_OK; /* Already initialized */
275 }
276 /* Point to the built-in vfs */
277 pVfs = jx9ExportBuiltinVfs();
278 /* Install it */
279 jx9_lib_config(JX9_LIB_CONFIG_VFS, pVfs);
280#if defined(JX9_ENABLE_THREADS)
281 if( sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_SINGLE ){
282 pMutexMethods = sJx9MPGlobal.pMutexMethods;
283 if( pMutexMethods == 0 ){
284 /* Use the built-in mutex subsystem */
285 pMutexMethods = SyMutexExportMethods();
286 if( pMutexMethods == 0 ){
287 return JX9_CORRUPT; /* Can't happen */
288 }
289 /* Install the mutex subsystem */
290 rc = jx9_lib_config(JX9_LIB_CONFIG_USER_MUTEX, pMutexMethods);
291 if( rc != JX9_OK ){
292 return rc;
293 }
294 }
295 /* Obtain a static mutex so we can initialize the library without calling malloc() */
296 pMaster = SyMutexNew(pMutexMethods, SXMUTEX_TYPE_STATIC_1);
297 if( pMaster == 0 ){
298 return JX9_CORRUPT; /* Can't happen */
299 }
300 }
301 /* Lock the master mutex */
302 rc = JX9_OK;
303 SyMutexEnter(pMutexMethods, pMaster); /* NO-OP if sJx9MPGlobal.nThreadingLevel == JX9_THREAD_LEVEL_SINGLE */
304 if( sJx9MPGlobal.nMagic != JX9_LIB_MAGIC ){
305#endif
306 if( sJx9MPGlobal.sAllocator.pMethods == 0 ){
307 /* Install a memory subsystem */
308 rc = jx9_lib_config(JX9_LIB_CONFIG_USER_MALLOC, 0); /* zero mean use the built-in memory backend */
309 if( rc != JX9_OK ){
310 /* If we are unable to initialize the memory backend, there is no much we can do here.*/
311 goto End;
312 }
313 }
314#if defined(JX9_ENABLE_THREADS)
315 if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE ){
316 /* Protect the memory allocation subsystem */
317 rc = SyMemBackendMakeThreadSafe(&sJx9MPGlobal.sAllocator, sJx9MPGlobal.pMutexMethods);
318 if( rc != JX9_OK ){
319 goto End;
320 }
321 }
322#endif
323 /* Our library is initialized, set the magic number */
324 sJx9MPGlobal.nMagic = JX9_LIB_MAGIC;
325 rc = JX9_OK;
326#if defined(JX9_ENABLE_THREADS)
327 } /* sJx9MPGlobal.nMagic != JX9_LIB_MAGIC */
328#endif
329End:
330#if defined(JX9_ENABLE_THREADS)
331 /* Unlock the master mutex */
332 SyMutexLeave(pMutexMethods, pMaster); /* NO-OP if sJx9MPGlobal.nThreadingLevel == JX9_THREAD_LEVEL_SINGLE */
333#endif
334 return rc;
335}
336/*
337 * Release an active JX9 engine and it's associated active virtual machines.
338 */
339static sxi32 EngineRelease(jx9 *pEngine)
340{
341 jx9_vm *pVm, *pNext;
342 /* Release all active VM */
343 pVm = pEngine->pVms;
344 for(;;){
345 if( pEngine->iVm < 1 ){
346 break;
347 }
348 pNext = pVm->pNext;
349 jx9VmRelease(pVm);
350 pVm = pNext;
351 pEngine->iVm--;
352 }
353 /* Set a dummy magic number */
354 pEngine->nMagic = 0x7635;
355 /* Release the private memory subsystem */
356 SyMemBackendRelease(&pEngine->sAllocator);
357 return JX9_OK;
358}
359/*
360 * Release all resources consumed by the library.
361 * If JX9 is already shut when this routine is invoked then this
362 * routine is a harmless no-op.
363 * Note: This call is not thread safe. Refer to [jx9_lib_shutdown()].
364 */
365static void JX9CoreShutdown(void)
366{
367 jx9 *pEngine, *pNext;
368 /* Release all active engines first */
369 pEngine = sJx9MPGlobal.pEngines;
370 for(;;){
371 if( sJx9MPGlobal.nEngine < 1 ){
372 break;
373 }
374 pNext = pEngine->pNext;
375 EngineRelease(pEngine);
376 pEngine = pNext;
377 sJx9MPGlobal.nEngine--;
378 }
379#if defined(JX9_ENABLE_THREADS)
380 /* Release the mutex subsystem */
381 if( sJx9MPGlobal.pMutexMethods ){
382 if( sJx9MPGlobal.pMutex ){
383 SyMutexRelease(sJx9MPGlobal.pMutexMethods, sJx9MPGlobal.pMutex);
384 sJx9MPGlobal.pMutex = 0;
385 }
386 if( sJx9MPGlobal.pMutexMethods->xGlobalRelease ){
387 sJx9MPGlobal.pMutexMethods->xGlobalRelease();
388 }
389 sJx9MPGlobal.pMutexMethods = 0;
390 }
391 sJx9MPGlobal.nThreadingLevel = 0;
392#endif
393 if( sJx9MPGlobal.sAllocator.pMethods ){
394 /* Release the memory backend */
395 SyMemBackendRelease(&sJx9MPGlobal.sAllocator);
396 }
397 sJx9MPGlobal.nMagic = 0x1928;
398}
399/*
400 * [CAPIREF: jx9_lib_shutdown()]
401 * Please refer to the official documentation for function purpose and expected parameters.
402 */
403JX9_PRIVATE int jx9_lib_shutdown(void)
404{
405 if( sJx9MPGlobal.nMagic != JX9_LIB_MAGIC ){
406 /* Already shut */
407 return JX9_OK;
408 }
409 JX9CoreShutdown();
410 return JX9_OK;
411}
412/*
413 * [CAPIREF: jx9_lib_signature()]
414 * Please refer to the official documentation for function purpose and expected parameters.
415 */
416JX9_PRIVATE const char * jx9_lib_signature(void)
417{
418 return JX9_SIG;
419}
420/*
421 * [CAPIREF: jx9_init()]
422 * Please refer to the official documentation for function purpose and expected parameters.
423 */
424JX9_PRIVATE int jx9_init(jx9 **ppEngine)
425{
426 jx9 *pEngine;
427 int rc;
428#if defined(UNTRUST)
429 if( ppEngine == 0 ){
430 return JX9_CORRUPT;
431 }
432#endif
433 *ppEngine = 0;
434 /* One-time automatic library initialization */
435 rc = Jx9CoreInitialize();
436 if( rc != JX9_OK ){
437 return rc;
438 }
439 /* Allocate a new engine */
440 pEngine = (jx9 *)SyMemBackendPoolAlloc(&sJx9MPGlobal.sAllocator, sizeof(jx9));
441 if( pEngine == 0 ){
442 return JX9_NOMEM;
443 }
444 /* Zero the structure */
445 SyZero(pEngine, sizeof(jx9));
446 /* Initialize engine fields */
447 pEngine->nMagic = JX9_ENGINE_MAGIC;
448 rc = SyMemBackendInitFromParent(&pEngine->sAllocator, &sJx9MPGlobal.sAllocator);
449 if( rc != JX9_OK ){
450 goto Release;
451 }
452#if defined(JX9_ENABLE_THREADS)
453 SyMemBackendDisbaleMutexing(&pEngine->sAllocator);
454#endif
455 /* Default configuration */
456 SyBlobInit(&pEngine->xConf.sErrConsumer, &pEngine->sAllocator);
457 /* Install a default compile-time error consumer routine */
458 pEngine->xConf.xErr = jx9VmBlobConsumer;
459 pEngine->xConf.pErrData = &pEngine->xConf.sErrConsumer;
460 /* Built-in vfs */
461 pEngine->pVfs = sJx9MPGlobal.pVfs;
462#if defined(JX9_ENABLE_THREADS)
463 if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE ){
464 /* Associate a recursive mutex with this instance */
465 pEngine->pMutex = SyMutexNew(sJx9MPGlobal.pMutexMethods, SXMUTEX_TYPE_RECURSIVE);
466 if( pEngine->pMutex == 0 ){
467 rc = JX9_NOMEM;
468 goto Release;
469 }
470 }
471#endif
472 /* Link to the list of active engines */
473#if defined(JX9_ENABLE_THREADS)
474 /* Enter the global mutex */
475 SyMutexEnter(sJx9MPGlobal.pMutexMethods, sJx9MPGlobal.pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel == JX9_THREAD_LEVEL_SINGLE */
476#endif
477 MACRO_LD_PUSH(sJx9MPGlobal.pEngines, pEngine);
478 sJx9MPGlobal.nEngine++;
479#if defined(JX9_ENABLE_THREADS)
480 /* Leave the global mutex */
481 SyMutexLeave(sJx9MPGlobal.pMutexMethods, sJx9MPGlobal.pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel == JX9_THREAD_LEVEL_SINGLE */
482#endif
483 /* Write a pointer to the new instance */
484 *ppEngine = pEngine;
485 return JX9_OK;
486Release:
487 SyMemBackendRelease(&pEngine->sAllocator);
488 SyMemBackendPoolFree(&sJx9MPGlobal.sAllocator,pEngine);
489 return rc;
490}
491/*
492 * [CAPIREF: jx9_release()]
493 * Please refer to the official documentation for function purpose and expected parameters.
494 */
495JX9_PRIVATE int jx9_release(jx9 *pEngine)
496{
497 int rc;
498 if( JX9_ENGINE_MISUSE(pEngine) ){
499 return JX9_CORRUPT;
500 }
501#if defined(JX9_ENABLE_THREADS)
502 /* Acquire engine mutex */
503 SyMutexEnter(sJx9MPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */
504 if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE &&
505 JX9_THRD_ENGINE_RELEASE(pEngine) ){
506 return JX9_ABORT; /* Another thread have released this instance */
507 }
508#endif
509 /* Release the engine */
510 rc = EngineRelease(&(*pEngine));
511#if defined(JX9_ENABLE_THREADS)
512 /* Leave engine mutex */
513 SyMutexLeave(sJx9MPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */
514 /* Release engine mutex */
515 SyMutexRelease(sJx9MPGlobal.pMutexMethods, pEngine->pMutex) /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */
516#endif
517#if defined(JX9_ENABLE_THREADS)
518 /* Enter the global mutex */
519 SyMutexEnter(sJx9MPGlobal.pMutexMethods, sJx9MPGlobal.pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel == JX9_THREAD_LEVEL_SINGLE */
520#endif
521 /* Unlink from the list of active engines */
522 MACRO_LD_REMOVE(sJx9MPGlobal.pEngines, pEngine);
523 sJx9MPGlobal.nEngine--;
524#if defined(JX9_ENABLE_THREADS)
525 /* Leave the global mutex */
526 SyMutexLeave(sJx9MPGlobal.pMutexMethods, sJx9MPGlobal.pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel == JX9_THREAD_LEVEL_SINGLE */
527#endif
528 /* Release the memory chunk allocated to this engine */
529 SyMemBackendPoolFree(&sJx9MPGlobal.sAllocator, pEngine);
530 return rc;
531}
532/*
533 * Compile a raw JX9 script.
534 * To execute a JX9 code, it must first be compiled into a bytecode program using this routine.
535 * If something goes wrong [i.e: compile-time error], your error log [i.e: error consumer callback]
536 * should display the appropriate error message and this function set ppVm to null and return
537 * an error code that is different from JX9_OK. Otherwise when the script is successfully compiled
538 * ppVm should hold the JX9 bytecode and it's safe to call [jx9_vm_exec(), jx9_vm_reset(), etc.].
539 * This API does not actually evaluate the JX9 code. It merely compile and prepares the JX9 script
540 * for evaluation.
541 */
542static sxi32 ProcessScript(
543 jx9 *pEngine, /* Running JX9 engine */
544 jx9_vm **ppVm, /* OUT: A pointer to the virtual machine */
545 SyString *pScript, /* Raw JX9 script to compile */
546 sxi32 iFlags, /* Compile-time flags */
547 const char *zFilePath /* File path if script come from a file. NULL otherwise */
548 )
549{
550 jx9_vm *pVm;
551 int rc;
552 /* Allocate a new virtual machine */
553 pVm = (jx9_vm *)SyMemBackendPoolAlloc(&pEngine->sAllocator, sizeof(jx9_vm));
554 if( pVm == 0 ){
555 /* If the supplied memory subsystem is so sick that we are unable to allocate
556 * a tiny chunk of memory, there is no much we can do here. */
557 if( ppVm ){
558 *ppVm = 0;
559 }
560 return JX9_NOMEM;
561 }
562 if( iFlags < 0 ){
563 /* Default compile-time flags */
564 iFlags = 0;
565 }
566 /* Initialize the Virtual Machine */
567 rc = jx9VmInit(pVm, &(*pEngine));
568 if( rc != JX9_OK ){
569 SyMemBackendPoolFree(&pEngine->sAllocator, pVm);
570 if( ppVm ){
571 *ppVm = 0;
572 }
573 return JX9_VM_ERR;
574 }
575 if( zFilePath ){
576 /* Push processed file path */
577 jx9VmPushFilePath(pVm, zFilePath, -1, TRUE, 0);
578 }
579 /* Reset the error message consumer */
580 SyBlobReset(&pEngine->xConf.sErrConsumer);
581 /* Compile the script */
582 jx9CompileScript(pVm, &(*pScript), iFlags);
583 if( pVm->sCodeGen.nErr > 0 || pVm == 0){
584 sxu32 nErr = pVm->sCodeGen.nErr;
585 /* Compilation error or null ppVm pointer, release this VM */
586 SyMemBackendRelease(&pVm->sAllocator);
587 SyMemBackendPoolFree(&pEngine->sAllocator, pVm);
588 if( ppVm ){
589 *ppVm = 0;
590 }
591 return nErr > 0 ? JX9_COMPILE_ERR : JX9_OK;
592 }
593 /* Prepare the virtual machine for bytecode execution */
594 rc = jx9VmMakeReady(pVm);
595 if( rc != JX9_OK ){
596 goto Release;
597 }
598 /* Install local import path which is the current directory */
599 jx9_vm_config(pVm, JX9_VM_CONFIG_IMPORT_PATH, "./");
600#if defined(JX9_ENABLE_THREADS)
601 if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE ){
602 /* Associate a recursive mutex with this instance */
603 pVm->pMutex = SyMutexNew(sJx9MPGlobal.pMutexMethods, SXMUTEX_TYPE_RECURSIVE);
604 if( pVm->pMutex == 0 ){
605 goto Release;
606 }
607 }
608#endif
609 /* Script successfully compiled, link to the list of active virtual machines */
610 MACRO_LD_PUSH(pEngine->pVms, pVm);
611 pEngine->iVm++;
612 /* Point to the freshly created VM */
613 *ppVm = pVm;
614 /* Ready to execute JX9 bytecode */
615 return JX9_OK;
616Release:
617 SyMemBackendRelease(&pVm->sAllocator);
618 SyMemBackendPoolFree(&pEngine->sAllocator, pVm);
619 *ppVm = 0;
620 return JX9_VM_ERR;
621}
622/*
623 * [CAPIREF: jx9_compile()]
624 * Please refer to the official documentation for function purpose and expected parameters.
625 */
626JX9_PRIVATE int jx9_compile(jx9 *pEngine, const char *zSource, int nLen, jx9_vm **ppOutVm)
627{
628 SyString sScript;
629 int rc;
630 if( JX9_ENGINE_MISUSE(pEngine) ){
631 return JX9_CORRUPT;
632 }
633 if( zSource == 0 ){
634 /* Empty Jx9 statement ';' */
635 zSource = ";";
636 nLen = (int)sizeof(char);
637 }
638 if( nLen < 0 ){
639 /* Compute input length automatically */
640 nLen = (int)SyStrlen(zSource);
641 }
642 SyStringInitFromBuf(&sScript, zSource, nLen);
643#if defined(JX9_ENABLE_THREADS)
644 /* Acquire engine mutex */
645 SyMutexEnter(sJx9MPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */
646 if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE &&
647 JX9_THRD_ENGINE_RELEASE(pEngine) ){
648 return JX9_ABORT; /* Another thread have released this instance */
649 }
650#endif
651 /* Compile the script */
652 rc = ProcessScript(&(*pEngine),ppOutVm,&sScript,0,0);
653#if defined(JX9_ENABLE_THREADS)
654 /* Leave engine mutex */
655 SyMutexLeave(sJx9MPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */
656#endif
657 /* Compilation result */
658 return rc;
659}
660/*
661 * [CAPIREF: jx9_compile_file()]
662 * Please refer to the official documentation for function purpose and expected parameters.
663 */
664JX9_PRIVATE int jx9_compile_file(jx9 *pEngine, const char *zFilePath, jx9_vm **ppOutVm)
665{
666 const jx9_vfs *pVfs;
667 int rc;
668 if( ppOutVm ){
669 *ppOutVm = 0;
670 }
671 rc = JX9_OK; /* cc warning */
672 if( JX9_ENGINE_MISUSE(pEngine) || SX_EMPTY_STR(zFilePath) ){
673 return JX9_CORRUPT;
674 }
675#if defined(JX9_ENABLE_THREADS)
676 /* Acquire engine mutex */
677 SyMutexEnter(sJx9MPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */
678 if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE &&
679 JX9_THRD_ENGINE_RELEASE(pEngine) ){
680 return JX9_ABORT; /* Another thread have released this instance */
681 }
682#endif
683 /*
684 * Check if the underlying vfs implement the memory map
685 * [i.e: mmap() under UNIX/MapViewOfFile() under windows] function.
686 */
687 pVfs = pEngine->pVfs;
688 if( pVfs == 0 || pVfs->xMmap == 0 ){
689 /* Memory map routine not implemented */
690 rc = JX9_IO_ERR;
691 }else{
692 void *pMapView = 0; /* cc warning */
693 jx9_int64 nSize = 0; /* cc warning */
694 SyString sScript;
695 /* Try to get a memory view of the whole file */
696 rc = pVfs->xMmap(zFilePath, &pMapView, &nSize);
697 if( rc != JX9_OK ){
698 /* Assume an IO error */
699 rc = JX9_IO_ERR;
700 }else{
701 /* Compile the file */
702 SyStringInitFromBuf(&sScript, pMapView, nSize);
703 rc = ProcessScript(&(*pEngine), ppOutVm, &sScript,0,zFilePath);
704 /* Release the memory view of the whole file */
705 if( pVfs->xUnmap ){
706 pVfs->xUnmap(pMapView, nSize);
707 }
708 }
709 }
710#if defined(JX9_ENABLE_THREADS)
711 /* Leave engine mutex */
712 SyMutexLeave(sJx9MPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */
713#endif
714 /* Compilation result */
715 return rc;
716}
717/*
718 * [CAPIREF: jx9_vm_config()]
719 * Please refer to the official documentation for function purpose and expected parameters.
720 */
721JX9_PRIVATE int jx9_vm_config(jx9_vm *pVm, int iConfigOp, ...)
722{
723 va_list ap;
724 int rc;
725 /* Ticket 1433-002: NULL VM is harmless operation */
726 if ( JX9_VM_MISUSE(pVm) ){
727 return JX9_CORRUPT;
728 }
729#if defined(JX9_ENABLE_THREADS)
730 /* Acquire VM mutex */
731 SyMutexEnter(sJx9MPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */
732 if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE &&
733 JX9_THRD_VM_RELEASE(pVm) ){
734 return JX9_ABORT; /* Another thread have released this instance */
735 }
736#endif
737 /* Confiugure the virtual machine */
738 va_start(ap, iConfigOp);
739 rc = jx9VmConfigure(&(*pVm), iConfigOp, ap);
740 va_end(ap);
741#if defined(JX9_ENABLE_THREADS)
742 /* Leave VM mutex */
743 SyMutexLeave(sJx9MPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */
744#endif
745 return rc;
746}
747/*
748 * [CAPIREF: jx9_vm_release()]
749 * Please refer to the official documentation for function purpose and expected parameters.
750 */
751JX9_PRIVATE int jx9_vm_release(jx9_vm *pVm)
752{
753 jx9 *pEngine;
754 int rc;
755 /* Ticket 1433-002: NULL VM is harmless operation */
756 if ( JX9_VM_MISUSE(pVm) ){
757 return JX9_CORRUPT;
758 }
759#if defined(JX9_ENABLE_THREADS)
760 /* Acquire VM mutex */
761 SyMutexEnter(sJx9MPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */
762 if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE &&
763 JX9_THRD_VM_RELEASE(pVm) ){
764 return JX9_ABORT; /* Another thread have released this instance */
765 }
766#endif
767 pEngine = pVm->pEngine;
768 rc = jx9VmRelease(&(*pVm));
769#if defined(JX9_ENABLE_THREADS)
770 /* Leave VM mutex */
771 SyMutexLeave(sJx9MPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */
772 /* Release VM mutex */
773 SyMutexRelease(sJx9MPGlobal.pMutexMethods, pVm->pMutex) /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */
774#endif
775 if( rc == JX9_OK ){
776 /* Unlink from the list of active VM */
777#if defined(JX9_ENABLE_THREADS)
778 /* Acquire engine mutex */
779 SyMutexEnter(sJx9MPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */
780 if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE &&
781 JX9_THRD_ENGINE_RELEASE(pEngine) ){
782 return JX9_ABORT; /* Another thread have released this instance */
783 }
784#endif
785 MACRO_LD_REMOVE(pEngine->pVms, pVm);
786 pEngine->iVm--;
787 /* Release the memory chunk allocated to this VM */
788 SyMemBackendPoolFree(&pEngine->sAllocator, pVm);
789#if defined(JX9_ENABLE_THREADS)
790 /* Leave engine mutex */
791 SyMutexLeave(sJx9MPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */
792#endif
793 }
794 return rc;
795}
796/*
797 * [CAPIREF: jx9_create_function()]
798 * Please refer to the official documentation for function purpose and expected parameters.
799 */
800JX9_PRIVATE int jx9_create_function(jx9_vm *pVm, const char *zName, int (*xFunc)(jx9_context *, int, jx9_value **), void *pUserData)
801{
802 SyString sName;
803 int rc;
804 /* Ticket 1433-002: NULL VM is harmless operation */
805 if ( JX9_VM_MISUSE(pVm) ){
806 return JX9_CORRUPT;
807 }
808 SyStringInitFromBuf(&sName, zName, SyStrlen(zName));
809 /* Remove leading and trailing white spaces */
810 SyStringFullTrim(&sName);
811 /* Ticket 1433-003: NULL values are not allowed */
812 if( sName.nByte < 1 || xFunc == 0 ){
813 return JX9_CORRUPT;
814 }
815#if defined(JX9_ENABLE_THREADS)
816 /* Acquire VM mutex */
817 SyMutexEnter(sJx9MPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */
818 if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE &&
819 JX9_THRD_VM_RELEASE(pVm) ){
820 return JX9_ABORT; /* Another thread have released this instance */
821 }
822#endif
823 /* Install the foreign function */
824 rc = jx9VmInstallForeignFunction(&(*pVm), &sName, xFunc, pUserData);
825#if defined(JX9_ENABLE_THREADS)
826 /* Leave VM mutex */
827 SyMutexLeave(sJx9MPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */
828#endif
829 return rc;
830}
831JX9_PRIVATE int jx9DeleteFunction(jx9_vm *pVm,const char *zName)
832{
833 jx9_user_func *pFunc = 0; /* cc warning */
834 int rc;
835 /* Perform the deletion */
836 rc = SyHashDeleteEntry(&pVm->hHostFunction, (const void *)zName, SyStrlen(zName), (void **)&pFunc);
837 if( rc == JX9_OK ){
838 /* Release internal fields */
839 SySetRelease(&pFunc->aAux);
840 SyMemBackendFree(&pVm->sAllocator, (void *)SyStringData(&pFunc->sName));
841 SyMemBackendPoolFree(&pVm->sAllocator, pFunc);
842 }
843 return rc;
844}
845/*
846 * [CAPIREF: jx9_create_constant()]
847 * Please refer to the official documentation for function purpose and expected parameters.
848 */
849JX9_PRIVATE int jx9_create_constant(jx9_vm *pVm, const char *zName, void (*xExpand)(jx9_value *, void *), void *pUserData)
850{
851 SyString sName;
852 int rc;
853 /* Ticket 1433-002: NULL VM is harmless operation */
854 if ( JX9_VM_MISUSE(pVm) ){
855 return JX9_CORRUPT;
856 }
857 SyStringInitFromBuf(&sName, zName, SyStrlen(zName));
858 /* Remove leading and trailing white spaces */
859 SyStringFullTrim(&sName);
860 if( sName.nByte < 1 ){
861 /* Empty constant name */
862 return JX9_CORRUPT;
863 }
864 /* TICKET 1433-003: NULL pointer is harmless operation */
865 if( xExpand == 0 ){
866 return JX9_CORRUPT;
867 }
868#if defined(JX9_ENABLE_THREADS)
869 /* Acquire VM mutex */
870 SyMutexEnter(sJx9MPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */
871 if( sJx9MPGlobal.nThreadingLevel > JX9_THREAD_LEVEL_SINGLE &&
872 JX9_THRD_VM_RELEASE(pVm) ){
873 return JX9_ABORT; /* Another thread have released this instance */
874 }
875#endif
876 /* Perform the registration */
877 rc = jx9VmRegisterConstant(&(*pVm), &sName, xExpand, pUserData);
878#if defined(JX9_ENABLE_THREADS)
879 /* Leave VM mutex */
880 SyMutexLeave(sJx9MPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sJx9MPGlobal.nThreadingLevel != JX9_THREAD_LEVEL_MULTI */
881#endif
882 return rc;
883}
884JX9_PRIVATE int Jx9DeleteConstant(jx9_vm *pVm,const char *zName)
885{
886 jx9_constant *pCons;
887 int rc;
888 /* Query the constant hashtable */
889 rc = SyHashDeleteEntry(&pVm->hConstant, (const void *)zName, SyStrlen(zName), (void **)&pCons);
890 if( rc == JX9_OK ){
891 /* Perform the deletion */
892 SyMemBackendFree(&pVm->sAllocator, (void *)SyStringData(&pCons->sName));
893 SyMemBackendPoolFree(&pVm->sAllocator, pCons);
894 }
895 return rc;
896}
897/*
898 * [CAPIREF: jx9_new_scalar()]
899 * Please refer to the official documentation for function purpose and expected parameters.
900 */
901JX9_PRIVATE jx9_value * jx9_new_scalar(jx9_vm *pVm)
902{
903 jx9_value *pObj;
904 /* Ticket 1433-002: NULL VM is harmless operation */
905 if ( JX9_VM_MISUSE(pVm) ){
906 return 0;
907 }
908 /* Allocate a new scalar variable */
909 pObj = (jx9_value *)SyMemBackendPoolAlloc(&pVm->sAllocator, sizeof(jx9_value));
910 if( pObj == 0 ){
911 return 0;
912 }
913 /* Nullify the new scalar */
914 jx9MemObjInit(pVm, pObj);
915 return pObj;
916}
917/*
918 * [CAPIREF: jx9_new_array()]
919 * Please refer to the official documentation for function purpose and expected parameters.
920 */
921JX9_PRIVATE jx9_value * jx9_new_array(jx9_vm *pVm)
922{
923 jx9_hashmap *pMap;
924 jx9_value *pObj;
925 /* Ticket 1433-002: NULL VM is harmless operation */
926 if ( JX9_VM_MISUSE(pVm) ){
927 return 0;
928 }
929 /* Create a new hashmap first */
930 pMap = jx9NewHashmap(&(*pVm), 0, 0);
931 if( pMap == 0 ){
932 return 0;
933 }
934 /* Associate a new jx9_value with this hashmap */
935 pObj = (jx9_value *)SyMemBackendPoolAlloc(&pVm->sAllocator, sizeof(jx9_value));
936 if( pObj == 0 ){
937 jx9HashmapRelease(pMap, TRUE);
938 return 0;
939 }
940 jx9MemObjInitFromArray(pVm, pObj, pMap);
941 return pObj;
942}
943/*
944 * [CAPIREF: jx9_release_value()]
945 * Please refer to the official documentation for function purpose and expected parameters.
946 */
947JX9_PRIVATE int jx9_release_value(jx9_vm *pVm, jx9_value *pValue)
948{
949 /* Ticket 1433-002: NULL VM is a harmless operation */
950 if ( JX9_VM_MISUSE(pVm) ){
951 return JX9_CORRUPT;
952 }
953 if( pValue ){
954 /* Release the value */
955 jx9MemObjRelease(pValue);
956 SyMemBackendPoolFree(&pVm->sAllocator, pValue);
957 }
958 return JX9_OK;
959}
960/*
961 * [CAPIREF: jx9_value_to_int()]
962 * Please refer to the official documentation for function purpose and expected parameters.
963 */
964JX9_PRIVATE int jx9_value_to_int(jx9_value *pValue)
965{
966 int rc;
967 rc = jx9MemObjToInteger(pValue);
968 if( rc != JX9_OK ){
969 return 0;
970 }
971 return (int)pValue->x.iVal;
972}
973/*
974 * [CAPIREF: jx9_value_to_bool()]
975 * Please refer to the official documentation for function purpose and expected parameters.
976 */
977JX9_PRIVATE int jx9_value_to_bool(jx9_value *pValue)
978{
979 int rc;
980 rc = jx9MemObjToBool(pValue);
981 if( rc != JX9_OK ){
982 return 0;
983 }
984 return (int)pValue->x.iVal;
985}
986/*
987 * [CAPIREF: jx9_value_to_int64()]
988 * Please refer to the official documentation for function purpose and expected parameters.
989 */
990JX9_PRIVATE jx9_int64 jx9_value_to_int64(jx9_value *pValue)
991{
992 int rc;
993 rc = jx9MemObjToInteger(pValue);
994 if( rc != JX9_OK ){
995 return 0;
996 }
997 return pValue->x.iVal;
998}
999/*
1000 * [CAPIREF: jx9_value_to_double()]
1001 * Please refer to the official documentation for function purpose and expected parameters.
1002 */
1003JX9_PRIVATE double jx9_value_to_double(jx9_value *pValue)
1004{
1005 int rc;
1006 rc = jx9MemObjToReal(pValue);
1007 if( rc != JX9_OK ){
1008 return (double)0;
1009 }
1010 return (double)pValue->x.rVal;
1011}
1012/*
1013 * [CAPIREF: jx9_value_to_string()]
1014 * Please refer to the official documentation for function purpose and expected parameters.
1015 */
1016JX9_PRIVATE const char * jx9_value_to_string(jx9_value *pValue, int *pLen)
1017{
1018 jx9MemObjToString(pValue);
1019 if( SyBlobLength(&pValue->sBlob) > 0 ){
1020 SyBlobNullAppend(&pValue->sBlob);
1021 if( pLen ){
1022 *pLen = (int)SyBlobLength(&pValue->sBlob);
1023 }
1024 return (const char *)SyBlobData(&pValue->sBlob);
1025 }else{
1026 /* Return the empty string */
1027 if( pLen ){
1028 *pLen = 0;
1029 }
1030 return "";
1031 }
1032}
1033/*
1034 * [CAPIREF: jx9_value_to_resource()]
1035 * Please refer to the official documentation for function purpose and expected parameters.
1036 */
1037JX9_PRIVATE void * jx9_value_to_resource(jx9_value *pValue)
1038{
1039 if( (pValue->iFlags & MEMOBJ_RES) == 0 ){
1040 /* Not a resource, return NULL */
1041 return 0;
1042 }
1043 return pValue->x.pOther;
1044}
1045/*
1046 * [CAPIREF: jx9_value_compare()]
1047 * Please refer to the official documentation for function purpose and expected parameters.
1048 */
1049JX9_PRIVATE int jx9_value_compare(jx9_value *pLeft, jx9_value *pRight, int bStrict)
1050{
1051 int rc;
1052 if( pLeft == 0 || pRight == 0 ){
1053 /* TICKET 1433-24: NULL values is harmless operation */
1054 return 1;
1055 }
1056 /* Perform the comparison */
1057 rc = jx9MemObjCmp(&(*pLeft), &(*pRight), bStrict, 0);
1058 /* Comparison result */
1059 return rc;
1060}
1061/*
1062 * [CAPIREF: jx9_result_int()]
1063 * Please refer to the official documentation for function purpose and expected parameters.
1064 */
1065JX9_PRIVATE int jx9_result_int(jx9_context *pCtx, int iValue)
1066{
1067 return jx9_value_int(pCtx->pRet, iValue);
1068}
1069/*
1070 * [CAPIREF: jx9_result_int64()]
1071 * Please refer to the official documentation for function purpose and expected parameters.
1072 */
1073JX9_PRIVATE int jx9_result_int64(jx9_context *pCtx, jx9_int64 iValue)
1074{
1075 return jx9_value_int64(pCtx->pRet, iValue);
1076}
1077/*
1078 * [CAPIREF: jx9_result_bool()]
1079 * Please refer to the official documentation for function purpose and expected parameters.
1080 */
1081JX9_PRIVATE int jx9_result_bool(jx9_context *pCtx, int iBool)
1082{
1083 return jx9_value_bool(pCtx->pRet, iBool);
1084}
1085/*
1086 * [CAPIREF: jx9_result_double()]
1087 * Please refer to the official documentation for function purpose and expected parameters.
1088 */
1089JX9_PRIVATE int jx9_result_double(jx9_context *pCtx, double Value)
1090{
1091 return jx9_value_double(pCtx->pRet, Value);
1092}
1093/*
1094 * [CAPIREF: jx9_result_null()]
1095 * Please refer to the official documentation for function purpose and expected parameters.
1096 */
1097JX9_PRIVATE int jx9_result_null(jx9_context *pCtx)
1098{
1099 /* Invalidate any prior representation and set the NULL flag */
1100 jx9MemObjRelease(pCtx->pRet);
1101 return JX9_OK;
1102}
1103/*
1104 * [CAPIREF: jx9_result_string()]
1105 * Please refer to the official documentation for function purpose and expected parameters.
1106 */
1107JX9_PRIVATE int jx9_result_string(jx9_context *pCtx, const char *zString, int nLen)
1108{
1109 return jx9_value_string(pCtx->pRet, zString, nLen);
1110}
1111/*
1112 * [CAPIREF: jx9_result_string_format()]
1113 * Please refer to the official documentation for function purpose and expected parameters.
1114 */
1115JX9_PRIVATE int jx9_result_string_format(jx9_context *pCtx, const char *zFormat, ...)
1116{
1117 jx9_value *p;
1118 va_list ap;
1119 int rc;
1120 p = pCtx->pRet;
1121 if( (p->iFlags & MEMOBJ_STRING) == 0 ){
1122 /* Invalidate any prior representation */
1123 jx9MemObjRelease(p);
1124 MemObjSetType(p, MEMOBJ_STRING);
1125 }
1126 /* Format the given string */
1127 va_start(ap, zFormat);
1128 rc = SyBlobFormatAp(&p->sBlob, zFormat, ap);
1129 va_end(ap);
1130 return rc;
1131}
1132/*
1133 * [CAPIREF: jx9_result_value()]
1134 * Please refer to the official documentation for function purpose and expected parameters.
1135 */
1136JX9_PRIVATE int jx9_result_value(jx9_context *pCtx, jx9_value *pValue)
1137{
1138 int rc = JX9_OK;
1139 if( pValue == 0 ){
1140 jx9MemObjRelease(pCtx->pRet);
1141 }else{
1142 rc = jx9MemObjStore(pValue, pCtx->pRet);
1143 }
1144 return rc;
1145}
1146/*
1147 * [CAPIREF: jx9_result_resource()]
1148 * Please refer to the official documentation for function purpose and expected parameters.
1149 */
1150JX9_PRIVATE int jx9_result_resource(jx9_context *pCtx, void *pUserData)
1151{
1152 return jx9_value_resource(pCtx->pRet, pUserData);
1153}
1154/*
1155 * [CAPIREF: jx9_context_new_scalar()]
1156 * Please refer to the official documentation for function purpose and expected parameters.
1157 */
1158JX9_PRIVATE jx9_value * jx9_context_new_scalar(jx9_context *pCtx)
1159{
1160 jx9_value *pVal;
1161 pVal = jx9_new_scalar(pCtx->pVm);
1162 if( pVal ){
1163 /* Record value address so it can be freed automatically
1164 * when the calling function returns.
1165 */
1166 SySetPut(&pCtx->sVar, (const void *)&pVal);
1167 }
1168 return pVal;
1169}
1170/*
1171 * [CAPIREF: jx9_context_new_array()]
1172 * Please refer to the official documentation for function purpose and expected parameters.
1173 */
1174JX9_PRIVATE jx9_value * jx9_context_new_array(jx9_context *pCtx)
1175{
1176 jx9_value *pVal;
1177 pVal = jx9_new_array(pCtx->pVm);
1178 if( pVal ){
1179 /* Record value address so it can be freed automatically
1180 * when the calling function returns.
1181 */
1182 SySetPut(&pCtx->sVar, (const void *)&pVal);
1183 }
1184 return pVal;
1185}
1186/*
1187 * [CAPIREF: jx9_context_release_value()]
1188 * Please refer to the official documentation for function purpose and expected parameters.
1189 */
1190JX9_PRIVATE void jx9_context_release_value(jx9_context *pCtx, jx9_value *pValue)
1191{
1192 jx9VmReleaseContextValue(&(*pCtx), pValue);
1193}
1194/*
1195 * [CAPIREF: jx9_context_alloc_chunk()]
1196 * Please refer to the official documentation for function purpose and expected parameters.
1197 */
1198JX9_PRIVATE void * jx9_context_alloc_chunk(jx9_context *pCtx, unsigned int nByte, int ZeroChunk, int AutoRelease)
1199{
1200 void *pChunk;
1201 pChunk = SyMemBackendAlloc(&pCtx->pVm->sAllocator, nByte);
1202 if( pChunk ){
1203 if( ZeroChunk ){
1204 /* Zero the memory chunk */
1205 SyZero(pChunk, nByte);
1206 }
1207 if( AutoRelease ){
1208 jx9_aux_data sAux;
1209 /* Track the chunk so that it can be released automatically
1210 * upon this context is destroyed.
1211 */
1212 sAux.pAuxData = pChunk;
1213 SySetPut(&pCtx->sChunk, (const void *)&sAux);
1214 }
1215 }
1216 return pChunk;
1217}
1218/*
1219 * Check if the given chunk address is registered in the call context
1220 * chunk container.
1221 * Return TRUE if registered.FALSE otherwise.
1222 * Refer to [jx9_context_realloc_chunk(), jx9_context_free_chunk()].
1223 */
1224static jx9_aux_data * ContextFindChunk(jx9_context *pCtx, void *pChunk)
1225{
1226 jx9_aux_data *aAux, *pAux;
1227 sxu32 n;
1228 if( SySetUsed(&pCtx->sChunk) < 1 ){
1229 /* Don't bother processing, the container is empty */
1230 return 0;
1231 }
1232 /* Perform the lookup */
1233 aAux = (jx9_aux_data *)SySetBasePtr(&pCtx->sChunk);
1234 for( n = 0; n < SySetUsed(&pCtx->sChunk) ; ++n ){
1235 pAux = &aAux[n];
1236 if( pAux->pAuxData == pChunk ){
1237 /* Chunk found */
1238 return pAux;
1239 }
1240 }
1241 /* No such allocated chunk */
1242 return 0;
1243}
1244/*
1245 * [CAPIREF: jx9_context_realloc_chunk()]
1246 * Please refer to the official documentation for function purpose and expected parameters.
1247 */
1248JX9_PRIVATE void * jx9_context_realloc_chunk(jx9_context *pCtx, void *pChunk, unsigned int nByte)
1249{
1250 jx9_aux_data *pAux;
1251 void *pNew;
1252 pNew = SyMemBackendRealloc(&pCtx->pVm->sAllocator, pChunk, nByte);
1253 if( pNew ){
1254 pAux = ContextFindChunk(pCtx, pChunk);
1255 if( pAux ){
1256 pAux->pAuxData = pNew;
1257 }
1258 }
1259 return pNew;
1260}
1261/*
1262 * [CAPIREF: jx9_context_free_chunk()]
1263 * Please refer to the official documentation for function purpose and expected parameters.
1264 */
1265JX9_PRIVATE void jx9_context_free_chunk(jx9_context *pCtx, void *pChunk)
1266{
1267 jx9_aux_data *pAux;
1268 if( pChunk == 0 ){
1269 /* TICKET-1433-93: NULL chunk is a harmless operation */
1270 return;
1271 }
1272 pAux = ContextFindChunk(pCtx, pChunk);
1273 if( pAux ){
1274 /* Mark as destroyed */
1275 pAux->pAuxData = 0;
1276 }
1277 SyMemBackendFree(&pCtx->pVm->sAllocator, pChunk);
1278}
1279/*
1280 * [CAPIREF: jx9_array_fetch()]
1281 * Please refer to the official documentation for function purpose and expected parameters.
1282 */
1283JX9_PRIVATE jx9_value * jx9_array_fetch(jx9_value *pArray, const char *zKey, int nByte)
1284{
1285 jx9_hashmap_node *pNode;
1286 jx9_value *pValue;
1287 jx9_value skey;
1288 int rc;
1289 /* Make sure we are dealing with a valid hashmap */
1290 if( (pArray->iFlags & MEMOBJ_HASHMAP) == 0 ){
1291 return 0;
1292 }
1293 if( nByte < 0 ){
1294 nByte = (int)SyStrlen(zKey);
1295 }
1296 /* Convert the key to a jx9_value */
1297 jx9MemObjInit(pArray->pVm, &skey);
1298 jx9MemObjStringAppend(&skey, zKey, (sxu32)nByte);
1299 /* Perform the lookup */
1300 rc = jx9HashmapLookup((jx9_hashmap *)pArray->x.pOther, &skey, &pNode);
1301 jx9MemObjRelease(&skey);
1302 if( rc != JX9_OK ){
1303 /* No such entry */
1304 return 0;
1305 }
1306 /* Extract the target value */
1307 pValue = (jx9_value *)SySetAt(&pArray->pVm->aMemObj, pNode->nValIdx);
1308 return pValue;
1309}
1310/*
1311 * [CAPIREF: jx9_array_walk()]
1312 * Please refer to the official documentation for function purpose and expected parameters.
1313 */
1314JX9_PRIVATE int jx9_array_walk(jx9_value *pArray, int (*xWalk)(jx9_value *pValue, jx9_value *, void *), void *pUserData)
1315{
1316 int rc;
1317 if( xWalk == 0 ){
1318 return JX9_CORRUPT;
1319 }
1320 /* Make sure we are dealing with a valid hashmap */
1321 if( (pArray->iFlags & MEMOBJ_HASHMAP) == 0 ){
1322 return JX9_CORRUPT;
1323 }
1324 /* Start the walk process */
1325 rc = jx9HashmapWalk((jx9_hashmap *)pArray->x.pOther, xWalk, pUserData);
1326 return rc != JX9_OK ? JX9_ABORT /* User callback request an operation abort*/ : JX9_OK;
1327}
1328/*
1329 * [CAPIREF: jx9_array_add_elem()]
1330 * Please refer to the official documentation for function purpose and expected parameters.
1331 */
1332JX9_PRIVATE int jx9_array_add_elem(jx9_value *pArray, jx9_value *pKey, jx9_value *pValue)
1333{
1334 int rc;
1335 /* Make sure we are dealing with a valid hashmap */
1336 if( (pArray->iFlags & MEMOBJ_HASHMAP) == 0 ){
1337 return JX9_CORRUPT;
1338 }
1339 /* Perform the insertion */
1340 rc = jx9HashmapInsert((jx9_hashmap *)pArray->x.pOther, &(*pKey), &(*pValue));
1341 return rc;
1342}
1343/*
1344 * [CAPIREF: jx9_array_add_strkey_elem()]
1345 * Please refer to the official documentation for function purpose and expected parameters.
1346 */
1347JX9_PRIVATE int jx9_array_add_strkey_elem(jx9_value *pArray, const char *zKey, jx9_value *pValue)
1348{
1349 int rc;
1350 /* Make sure we are dealing with a valid hashmap */
1351 if( (pArray->iFlags & MEMOBJ_HASHMAP) == 0 ){
1352 return JX9_CORRUPT;
1353 }
1354 /* Perform the insertion */
1355 if( SX_EMPTY_STR(zKey) ){
1356 /* Empty key, assign an automatic index */
1357 rc = jx9HashmapInsert((jx9_hashmap *)pArray->x.pOther, 0, &(*pValue));
1358 }else{
1359 jx9_value sKey;
1360 jx9MemObjInitFromString(pArray->pVm, &sKey, 0);
1361 jx9MemObjStringAppend(&sKey, zKey, (sxu32)SyStrlen(zKey));
1362 rc = jx9HashmapInsert((jx9_hashmap *)pArray->x.pOther, &sKey, &(*pValue));
1363 jx9MemObjRelease(&sKey);
1364 }
1365 return rc;
1366}
1367/*
1368 * [CAPIREF: jx9_array_count()]
1369 * Please refer to the official documentation for function purpose and expected parameters.
1370 */
1371JX9_PRIVATE unsigned int jx9_array_count(jx9_value *pArray)
1372{
1373 jx9_hashmap *pMap;
1374 /* Make sure we are dealing with a valid hashmap */
1375 if( (pArray->iFlags & MEMOBJ_HASHMAP) == 0 ){
1376 return 0;
1377 }
1378 /* Point to the internal representation of the hashmap */
1379 pMap = (jx9_hashmap *)pArray->x.pOther;
1380 return pMap->nEntry;
1381}
1382/*
1383 * [CAPIREF: jx9_context_output()]
1384 * Please refer to the official documentation for function purpose and expected parameters.
1385 */
1386JX9_PRIVATE int jx9_context_output(jx9_context *pCtx, const char *zString, int nLen)
1387{
1388 SyString sData;
1389 int rc;
1390 if( nLen < 0 ){
1391 nLen = (int)SyStrlen(zString);
1392 }
1393 SyStringInitFromBuf(&sData, zString, nLen);
1394 rc = jx9VmOutputConsume(pCtx->pVm, &sData);
1395 return rc;
1396}
1397/*
1398 * [CAPIREF: jx9_context_throw_error()]
1399 * Please refer to the official documentation for function purpose and expected parameters.
1400 */
1401JX9_PRIVATE int jx9_context_throw_error(jx9_context *pCtx, int iErr, const char *zErr)
1402{
1403 int rc = JX9_OK;
1404 if( zErr ){
1405 rc = jx9VmThrowError(pCtx->pVm, &pCtx->pFunc->sName, iErr, zErr);
1406 }
1407 return rc;
1408}
1409/*
1410 * [CAPIREF: jx9_context_throw_error_format()]
1411 * Please refer to the official documentation for function purpose and expected parameters.
1412 */
1413JX9_PRIVATE int jx9_context_throw_error_format(jx9_context *pCtx, int iErr, const char *zFormat, ...)
1414{
1415 va_list ap;
1416 int rc;
1417 if( zFormat == 0){
1418 return JX9_OK;
1419 }
1420 va_start(ap, zFormat);
1421 rc = jx9VmThrowErrorAp(pCtx->pVm, &pCtx->pFunc->sName, iErr, zFormat, ap);
1422 va_end(ap);
1423 return rc;
1424}
1425/*
1426 * [CAPIREF: jx9_context_random_num()]
1427 * Please refer to the official documentation for function purpose and expected parameters.
1428 */
1429JX9_PRIVATE unsigned int jx9_context_random_num(jx9_context *pCtx)
1430{
1431 sxu32 n;
1432 n = jx9VmRandomNum(pCtx->pVm);
1433 return n;
1434}
1435/*
1436 * [CAPIREF: jx9_context_random_string()]
1437 * Please refer to the official documentation for function purpose and expected parameters.
1438 */
1439JX9_PRIVATE int jx9_context_random_string(jx9_context *pCtx, char *zBuf, int nBuflen)
1440{
1441 if( nBuflen < 3 ){
1442 return JX9_CORRUPT;
1443 }
1444 jx9VmRandomString(pCtx->pVm, zBuf, nBuflen);
1445 return JX9_OK;
1446}
1447/*
1448 * [CAPIREF: jx9_context_user_data()]
1449 * Please refer to the official documentation for function purpose and expected parameters.
1450 */
1451JX9_PRIVATE void * jx9_context_user_data(jx9_context *pCtx)
1452{
1453 return pCtx->pFunc->pUserData;
1454}
1455/*
1456 * [CAPIREF: jx9_context_push_aux_data()]
1457 * Please refer to the official documentation for function purpose and expected parameters.
1458 */
1459JX9_PRIVATE int jx9_context_push_aux_data(jx9_context *pCtx, void *pUserData)
1460{
1461 jx9_aux_data sAux;
1462 int rc;
1463 sAux.pAuxData = pUserData;
1464 rc = SySetPut(&pCtx->pFunc->aAux, (const void *)&sAux);
1465 return rc;
1466}
1467/*
1468 * [CAPIREF: jx9_context_peek_aux_data()]
1469 * Please refer to the official documentation for function purpose and expected parameters.
1470 */
1471JX9_PRIVATE void * jx9_context_peek_aux_data(jx9_context *pCtx)
1472{
1473 jx9_aux_data *pAux;
1474 pAux = (jx9_aux_data *)SySetPeek(&pCtx->pFunc->aAux);
1475 return pAux ? pAux->pAuxData : 0;
1476}
1477/*
1478 * [CAPIREF: jx9_context_pop_aux_data()]
1479 * Please refer to the official documentation for function purpose and expected parameters.
1480 */
1481JX9_PRIVATE void * jx9_context_pop_aux_data(jx9_context *pCtx)
1482{
1483 jx9_aux_data *pAux;
1484 pAux = (jx9_aux_data *)SySetPop(&pCtx->pFunc->aAux);
1485 return pAux ? pAux->pAuxData : 0;
1486}
1487/*
1488 * [CAPIREF: jx9_context_result_buf_length()]
1489 * Please refer to the official documentation for function purpose and expected parameters.
1490 */
1491JX9_PRIVATE unsigned int jx9_context_result_buf_length(jx9_context *pCtx)
1492{
1493 return SyBlobLength(&pCtx->pRet->sBlob);
1494}
1495/*
1496 * [CAPIREF: jx9_function_name()]
1497 * Please refer to the official documentation for function purpose and expected parameters.
1498 */
1499JX9_PRIVATE const char * jx9_function_name(jx9_context *pCtx)
1500{
1501 SyString *pName;
1502 pName = &pCtx->pFunc->sName;
1503 return pName->zString;
1504}
1505/*
1506 * [CAPIREF: jx9_value_int()]
1507 * Please refer to the official documentation for function purpose and expected parameters.
1508 */
1509JX9_PRIVATE int jx9_value_int(jx9_value *pVal, int iValue)
1510{
1511 /* Invalidate any prior representation */
1512 jx9MemObjRelease(pVal);
1513 pVal->x.iVal = (jx9_int64)iValue;
1514 MemObjSetType(pVal, MEMOBJ_INT);
1515 return JX9_OK;
1516}
1517/*
1518 * [CAPIREF: jx9_value_int64()]
1519 * Please refer to the official documentation for function purpose and expected parameters.
1520 */
1521JX9_PRIVATE int jx9_value_int64(jx9_value *pVal, jx9_int64 iValue)
1522{
1523 /* Invalidate any prior representation */
1524 jx9MemObjRelease(pVal);
1525 pVal->x.iVal = iValue;
1526 MemObjSetType(pVal, MEMOBJ_INT);
1527 return JX9_OK;
1528}
1529/*
1530 * [CAPIREF: jx9_value_bool()]
1531 * Please refer to the official documentation for function purpose and expected parameters.
1532 */
1533JX9_PRIVATE int jx9_value_bool(jx9_value *pVal, int iBool)
1534{
1535 /* Invalidate any prior representation */
1536 jx9MemObjRelease(pVal);
1537 pVal->x.iVal = iBool ? 1 : 0;
1538 MemObjSetType(pVal, MEMOBJ_BOOL);
1539 return JX9_OK;
1540}
1541/*
1542 * [CAPIREF: jx9_value_null()]
1543 * Please refer to the official documentation for function purpose and expected parameters.
1544 */
1545JX9_PRIVATE int jx9_value_null(jx9_value *pVal)
1546{
1547 /* Invalidate any prior representation and set the NULL flag */
1548 jx9MemObjRelease(pVal);
1549 return JX9_OK;
1550}
1551/*
1552 * [CAPIREF: jx9_value_double()]
1553 * Please refer to the official documentation for function purpose and expected parameters.
1554 */
1555JX9_PRIVATE int jx9_value_double(jx9_value *pVal, double Value)
1556{
1557 /* Invalidate any prior representation */
1558 jx9MemObjRelease(pVal);
1559 pVal->x.rVal = (jx9_real)Value;
1560 MemObjSetType(pVal, MEMOBJ_REAL);
1561 /* Try to get an integer representation also */
1562 jx9MemObjTryInteger(pVal);
1563 return JX9_OK;
1564}
1565/*
1566 * [CAPIREF: jx9_value_string()]
1567 * Please refer to the official documentation for function purpose and expected parameters.
1568 */
1569JX9_PRIVATE int jx9_value_string(jx9_value *pVal, const char *zString, int nLen)
1570{
1571 if((pVal->iFlags & MEMOBJ_STRING) == 0 ){
1572 /* Invalidate any prior representation */
1573 jx9MemObjRelease(pVal);
1574 MemObjSetType(pVal, MEMOBJ_STRING);
1575 }
1576 if( zString ){
1577 if( nLen < 0 ){
1578 /* Compute length automatically */
1579 nLen = (int)SyStrlen(zString);
1580 }
1581 SyBlobAppend(&pVal->sBlob, (const void *)zString, (sxu32)nLen);
1582 }
1583 return JX9_OK;
1584}
1585/*
1586 * [CAPIREF: jx9_value_string_format()]
1587 * Please refer to the official documentation for function purpose and expected parameters.
1588 */
1589JX9_PRIVATE int jx9_value_string_format(jx9_value *pVal, const char *zFormat, ...)
1590{
1591 va_list ap;
1592 int rc;
1593 if((pVal->iFlags & MEMOBJ_STRING) == 0 ){
1594 /* Invalidate any prior representation */
1595 jx9MemObjRelease(pVal);
1596 MemObjSetType(pVal, MEMOBJ_STRING);
1597 }
1598 va_start(ap, zFormat);
1599 rc = SyBlobFormatAp(&pVal->sBlob, zFormat, ap);
1600 va_end(ap);
1601 return JX9_OK;
1602}
1603/*
1604 * [CAPIREF: jx9_value_reset_string_cursor()]
1605 * Please refer to the official documentation for function purpose and expected parameters.
1606 */
1607JX9_PRIVATE int jx9_value_reset_string_cursor(jx9_value *pVal)
1608{
1609 /* Reset the string cursor */
1610 SyBlobReset(&pVal->sBlob);
1611 return JX9_OK;
1612}
1613/*
1614 * [CAPIREF: jx9_value_resource()]
1615 * Please refer to the official documentation for function purpose and expected parameters.
1616 */
1617JX9_PRIVATE int jx9_value_resource(jx9_value *pVal, void *pUserData)
1618{
1619 /* Invalidate any prior representation */
1620 jx9MemObjRelease(pVal);
1621 /* Reflect the new type */
1622 pVal->x.pOther = pUserData;
1623 MemObjSetType(pVal, MEMOBJ_RES);
1624 return JX9_OK;
1625}
1626/*
1627 * [CAPIREF: jx9_value_release()]
1628 * Please refer to the official documentation for function purpose and expected parameters.
1629 */
1630JX9_PRIVATE int jx9_value_release(jx9_value *pVal)
1631{
1632 jx9MemObjRelease(pVal);
1633 return JX9_OK;
1634}
1635/*
1636 * [CAPIREF: jx9_value_is_int()]
1637 * Please refer to the official documentation for function purpose and expected parameters.
1638 */
1639JX9_PRIVATE int jx9_value_is_int(jx9_value *pVal)
1640{
1641 return (pVal->iFlags & MEMOBJ_INT) ? TRUE : FALSE;
1642}
1643/*
1644 * [CAPIREF: jx9_value_is_float()]
1645 * Please refer to the official documentation for function purpose and expected parameters.
1646 */
1647JX9_PRIVATE int jx9_value_is_float(jx9_value *pVal)
1648{
1649 return (pVal->iFlags & MEMOBJ_REAL) ? TRUE : FALSE;
1650}
1651/*
1652 * [CAPIREF: jx9_value_is_bool()]
1653 * Please refer to the official documentation for function purpose and expected parameters.
1654 */
1655JX9_PRIVATE int jx9_value_is_bool(jx9_value *pVal)
1656{
1657 return (pVal->iFlags & MEMOBJ_BOOL) ? TRUE : FALSE;
1658}
1659/*
1660 * [CAPIREF: jx9_value_is_string()]
1661 * Please refer to the official documentation for function purpose and expected parameters.
1662 */
1663JX9_PRIVATE int jx9_value_is_string(jx9_value *pVal)
1664{
1665 return (pVal->iFlags & MEMOBJ_STRING) ? TRUE : FALSE;
1666}
1667/*
1668 * [CAPIREF: jx9_value_is_null()]
1669 * Please refer to the official documentation for function purpose and expected parameters.
1670 */
1671JX9_PRIVATE int jx9_value_is_null(jx9_value *pVal)
1672{
1673 return (pVal->iFlags & MEMOBJ_NULL) ? TRUE : FALSE;
1674}
1675/*
1676 * [CAPIREF: jx9_value_is_numeric()]
1677 * Please refer to the official documentation for function purpose and expected parameters.
1678 */
1679JX9_PRIVATE int jx9_value_is_numeric(jx9_value *pVal)
1680{
1681 int rc;
1682 rc = jx9MemObjIsNumeric(pVal);
1683 return rc;
1684}
1685/*
1686 * [CAPIREF: jx9_value_is_callable()]
1687 * Please refer to the official documentation for function purpose and expected parameters.
1688 */
1689JX9_PRIVATE int jx9_value_is_callable(jx9_value *pVal)
1690{
1691 int rc;
1692 rc = jx9VmIsCallable(pVal->pVm, pVal);
1693 return rc;
1694}
1695/*
1696 * [CAPIREF: jx9_value_is_scalar()]
1697 * Please refer to the official documentation for function purpose and expected parameters.
1698 */
1699JX9_PRIVATE int jx9_value_is_scalar(jx9_value *pVal)
1700{
1701 return (pVal->iFlags & MEMOBJ_SCALAR) ? TRUE : FALSE;
1702}
1703/*
1704 * [CAPIREF: jx9_value_is_json_array()]
1705 * Please refer to the official documentation for function purpose and expected parameters.
1706 */
1707JX9_PRIVATE int jx9_value_is_json_array(jx9_value *pVal)
1708{
1709 return (pVal->iFlags & MEMOBJ_HASHMAP) ? TRUE : FALSE;
1710}
1711/*
1712 * [CAPIREF: jx9_value_is_json_object()]
1713 * Please refer to the official documentation for function purpose and expected parameters.
1714 */
1715JX9_PRIVATE int jx9_value_is_json_object(jx9_value *pVal)
1716{
1717 jx9_hashmap *pMap;
1718 if( (pVal->iFlags & MEMOBJ_HASHMAP) == 0 ){
1719 return FALSE;
1720 }
1721 pMap = (jx9_hashmap *)pVal->x.pOther;
1722 if( (pMap->iFlags & HASHMAP_JSON_OBJECT) == 0 ){
1723 return FALSE;
1724 }
1725 return TRUE;
1726}
1727/*
1728 * [CAPIREF: jx9_value_is_resource()]
1729 * Please refer to the official documentation for function purpose and expected parameters.
1730 */
1731JX9_PRIVATE int jx9_value_is_resource(jx9_value *pVal)
1732{
1733 return (pVal->iFlags & MEMOBJ_RES) ? TRUE : FALSE;
1734}
1735/*
1736 * [CAPIREF: jx9_value_is_empty()]
1737 * Please refer to the official documentation for function purpose and expected parameters.
1738 */
1739JX9_PRIVATE int jx9_value_is_empty(jx9_value *pVal)
1740{
1741 int rc;
1742 rc = jx9MemObjIsEmpty(pVal);
1743 return rc;
1744}