Compare commits
25 Commits
serialize_
...
syntax
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3888e96c9 | ||
|
|
a24331aae5 | ||
|
|
c1cb922b64 | ||
|
|
aacb0b48bf | ||
|
|
b38aec95b6 | ||
|
|
b29d3c2fe0 | ||
|
|
1cc3005b68 | ||
|
|
b86cd042fc | ||
|
|
8b7af0c22a | ||
|
|
f71f6a296b | ||
|
|
9bd764b11b | ||
|
|
058cdfd2e4 | ||
|
|
1ef837c6ff | ||
|
|
cd21de3d70 | ||
|
|
a98faa4dbb | ||
|
|
08559234c4 | ||
|
|
c3dc27eac6 | ||
|
|
7170a9c7eb | ||
|
|
a08ee50f84 | ||
|
|
ed7dd91c3f | ||
|
|
3abe20fee0 | ||
|
|
a92a96118e | ||
|
|
ab74cdc173 | ||
|
|
2c9d039271 | ||
|
|
d4635f2a75 |
@@ -65,6 +65,7 @@ scripts = [
|
||||
'net/enet.c',
|
||||
'wildstar.c',
|
||||
'archive/miniz.c',
|
||||
'source/cJSON.c'
|
||||
]
|
||||
|
||||
foreach file: scripts
|
||||
|
||||
3191
source/cJSON.c
Normal file
3191
source/cJSON.c
Normal file
File diff suppressed because it is too large
Load Diff
306
source/cJSON.h
Normal file
306
source/cJSON.h
Normal file
@@ -0,0 +1,306 @@
|
||||
/*
|
||||
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
|
||||
#define __WINDOWS__
|
||||
#endif
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
|
||||
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
|
||||
|
||||
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
|
||||
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
|
||||
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
||||
|
||||
For *nix builds that support visibility attribute, you can define similar behavior by
|
||||
|
||||
setting default visibility to hidden by adding
|
||||
-fvisibility=hidden (for gcc)
|
||||
or
|
||||
-xldscope=hidden (for sun cc)
|
||||
to CFLAGS
|
||||
|
||||
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
|
||||
|
||||
*/
|
||||
|
||||
#define CJSON_CDECL __cdecl
|
||||
#define CJSON_STDCALL __stdcall
|
||||
|
||||
/* export symbols by default, this is necessary for copy pasting the C and header file */
|
||||
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_EXPORT_SYMBOLS
|
||||
#endif
|
||||
|
||||
#if defined(CJSON_HIDE_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) type CJSON_STDCALL
|
||||
#elif defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
|
||||
#elif defined(CJSON_IMPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
|
||||
#endif
|
||||
#else /* !__WINDOWS__ */
|
||||
#define CJSON_CDECL
|
||||
#define CJSON_STDCALL
|
||||
|
||||
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
|
||||
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
|
||||
#else
|
||||
#define CJSON_PUBLIC(type) type
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* project version */
|
||||
#define CJSON_VERSION_MAJOR 1
|
||||
#define CJSON_VERSION_MINOR 7
|
||||
#define CJSON_VERSION_PATCH 19
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_Invalid (0)
|
||||
#define cJSON_False (1 << 0)
|
||||
#define cJSON_True (1 << 1)
|
||||
#define cJSON_NULL (1 << 2)
|
||||
#define cJSON_Number (1 << 3)
|
||||
#define cJSON_String (1 << 4)
|
||||
#define cJSON_Array (1 << 5)
|
||||
#define cJSON_Object (1 << 6)
|
||||
#define cJSON_Raw (1 << 7) /* raw json */
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
#define cJSON_StringIsConst 512
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON
|
||||
{
|
||||
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *next;
|
||||
struct cJSON *prev;
|
||||
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
struct cJSON *child;
|
||||
|
||||
/* The type of the item, as above. */
|
||||
int type;
|
||||
|
||||
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
||||
char *valuestring;
|
||||
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
||||
int valueint;
|
||||
/* The item's number, if type==cJSON_Number */
|
||||
double valuedouble;
|
||||
|
||||
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
char *string;
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks
|
||||
{
|
||||
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
|
||||
void *(CJSON_CDECL *malloc_fn)(size_t sz);
|
||||
void (CJSON_CDECL *free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
typedef int cJSON_bool;
|
||||
|
||||
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
|
||||
* This is to prevent stack overflows. */
|
||||
#ifndef CJSON_NESTING_LIMIT
|
||||
#define CJSON_NESTING_LIMIT 1000
|
||||
#endif
|
||||
|
||||
/* Limits the length of circular references can be before cJSON rejects to parse them.
|
||||
* This is to prevent stack overflows. */
|
||||
#ifndef CJSON_CIRCULAR_LIMIT
|
||||
#define CJSON_CIRCULAR_LIMIT 10000
|
||||
#endif
|
||||
|
||||
/* returns the version of cJSON as a string */
|
||||
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
|
||||
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||
|
||||
/* Render a cJSON entity to text for transfer/storage. */
|
||||
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
||||
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
|
||||
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
|
||||
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
||||
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
||||
|
||||
/* Check item type and return its value */
|
||||
CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
|
||||
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
|
||||
|
||||
/* These functions check the type of an item */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||
/* raw json */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
||||
|
||||
/* Create a string where valuestring references a string so
|
||||
* it will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
||||
/* Create an object/array that only references it's elements so
|
||||
* they will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
||||
|
||||
/* These utilities create an Array of count items.
|
||||
* The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
|
||||
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
|
||||
* writing to `item->string` */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||
|
||||
/* Remove/Detach items from Arrays/Objects. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
||||
|
||||
/* Duplicate a cJSON item */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||
* need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||
* The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
|
||||
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
|
||||
|
||||
/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
|
||||
* The input pointer json cannot point to a read-only address area, such as a string constant,
|
||||
* but should point to a readable and writable address area. */
|
||||
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
||||
|
||||
/* Helper functions for creating and adding items to an object at the same time.
|
||||
* They return the added item or NULL on failure. */
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
||||
|
||||
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
|
||||
/* helper for the cJSON_SetNumberValue macro */
|
||||
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
||||
/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
|
||||
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
|
||||
|
||||
/* If the object is not a boolean type this does nothing and returns cJSON_Invalid else it returns the new type*/
|
||||
#define cJSON_SetBoolValue(object, boolValue) ( \
|
||||
(object != NULL && ((object)->type & (cJSON_False|cJSON_True))) ? \
|
||||
(object)->type=((object)->type &(~(cJSON_False|cJSON_True)))|((boolValue)?cJSON_True:cJSON_False) : \
|
||||
cJSON_Invalid\
|
||||
)
|
||||
|
||||
/* Macro for iterating over an array or object */
|
||||
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
||||
|
||||
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
|
||||
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
||||
CJSON_PUBLIC(void) cJSON_free(void *object);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
365
source/cell.c
365
source/cell.c
@@ -125,12 +125,8 @@ JSValue js_wota_use(JSContext *js);
|
||||
void script_startup(cell_rt *prt)
|
||||
{
|
||||
JSRuntime *rt = JS_NewRuntime();
|
||||
JSContext *js = JS_NewContextRaw(rt);
|
||||
JS_SetInterruptHandler(rt, (JSInterruptHandler *)actor_interrupt_cb, prt);
|
||||
|
||||
JS_AddIntrinsicBaseObjects(js);
|
||||
JS_AddIntrinsicEval(js);
|
||||
JS_AddIntrinsicRegExp(js);
|
||||
JSContext *js = JS_NewContext(rt);
|
||||
|
||||
JS_SetContextOpaque(js, prt);
|
||||
prt->context = js;
|
||||
@@ -214,15 +210,13 @@ static int run_test_suite(size_t heap_size)
|
||||
return 1;
|
||||
}
|
||||
|
||||
JSContext *ctx = JS_NewContextRawWithHeapSize(rt, heap_size);
|
||||
JSContext *ctx = JS_NewContextWithHeapSize(rt, heap_size);
|
||||
if (!ctx) {
|
||||
printf("Failed to create JS context\n");
|
||||
JS_FreeRuntime(rt);
|
||||
return 1;
|
||||
}
|
||||
|
||||
JS_AddIntrinsicBaseObjects(ctx);
|
||||
|
||||
int result = run_c_test_suite(ctx);
|
||||
|
||||
JS_FreeContext(ctx);
|
||||
@@ -272,7 +266,7 @@ static int run_eval(const char *script_or_file, int print_bytecode, int use_boot
|
||||
return 1;
|
||||
}
|
||||
|
||||
JSContext *ctx = JS_NewContextRaw(rt);
|
||||
JSContext *ctx = JS_NewContext(rt);
|
||||
if (!ctx) {
|
||||
printf("Failed to create JS context\n");
|
||||
JS_FreeRuntime(rt);
|
||||
@@ -280,10 +274,6 @@ static int run_eval(const char *script_or_file, int print_bytecode, int use_boot
|
||||
return 1;
|
||||
}
|
||||
|
||||
JS_AddIntrinsicBaseObjects(ctx);
|
||||
JS_AddIntrinsicEval(ctx);
|
||||
JS_AddIntrinsicRegExp(ctx);
|
||||
|
||||
int result = 0;
|
||||
|
||||
JSGCRef bytecode_ref;
|
||||
@@ -350,6 +340,355 @@ int cell_init(int argc, char **argv)
|
||||
return run_test_suite(heap_size);
|
||||
}
|
||||
|
||||
/* Check for --ast flag to output AST JSON */
|
||||
if (argc >= 3 && strcmp(argv[1], "--ast") == 0) {
|
||||
const char *script_or_file = argv[2];
|
||||
char *script = NULL;
|
||||
char *allocated_script = NULL;
|
||||
const char *filename = "<eval>";
|
||||
|
||||
struct stat st;
|
||||
if (stat(script_or_file, &st) == 0 && S_ISREG(st.st_mode)) {
|
||||
FILE *f = fopen(script_or_file, "r");
|
||||
if (!f) {
|
||||
printf("Failed to open file: %s\n", script_or_file);
|
||||
return 1;
|
||||
}
|
||||
allocated_script = malloc(st.st_size + 1);
|
||||
if (!allocated_script) {
|
||||
fclose(f);
|
||||
printf("Failed to allocate memory for script\n");
|
||||
return 1;
|
||||
}
|
||||
size_t read_size = fread(allocated_script, 1, st.st_size, f);
|
||||
fclose(f);
|
||||
allocated_script[read_size] = '\0';
|
||||
script = allocated_script;
|
||||
filename = script_or_file;
|
||||
} else {
|
||||
script = (char *)script_or_file;
|
||||
}
|
||||
|
||||
JSRuntime *rt = JS_NewRuntime();
|
||||
if (!rt) {
|
||||
printf("Failed to create JS runtime\n");
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
JSContext *ctx = JS_NewContext(rt);
|
||||
if (!ctx) {
|
||||
printf("Failed to create JS context\n");
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *json = JS_AST(ctx, script, strlen(script), filename);
|
||||
if (json) {
|
||||
printf("%s\n", json);
|
||||
free(json);
|
||||
} else {
|
||||
printf("Failed to parse AST\n");
|
||||
}
|
||||
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return json ? 0 : 1;
|
||||
}
|
||||
|
||||
/* Check for --tokenize flag to output token array JSON */
|
||||
if (argc >= 3 && strcmp(argv[1], "--tokenize") == 0) {
|
||||
const char *script_or_file = argv[2];
|
||||
char *script = NULL;
|
||||
char *allocated_script = NULL;
|
||||
const char *filename = "<eval>";
|
||||
|
||||
struct stat st;
|
||||
if (stat(script_or_file, &st) == 0 && S_ISREG(st.st_mode)) {
|
||||
FILE *f = fopen(script_or_file, "r");
|
||||
if (!f) {
|
||||
printf("Failed to open file: %s\n", script_or_file);
|
||||
return 1;
|
||||
}
|
||||
allocated_script = malloc(st.st_size + 1);
|
||||
if (!allocated_script) {
|
||||
fclose(f);
|
||||
printf("Failed to allocate memory for script\n");
|
||||
return 1;
|
||||
}
|
||||
size_t read_size = fread(allocated_script, 1, st.st_size, f);
|
||||
fclose(f);
|
||||
allocated_script[read_size] = '\0';
|
||||
script = allocated_script;
|
||||
filename = script_or_file;
|
||||
} else {
|
||||
script = (char *)script_or_file;
|
||||
}
|
||||
|
||||
JSRuntime *rt = JS_NewRuntime();
|
||||
if (!rt) {
|
||||
printf("Failed to create JS runtime\n");
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
JSContext *ctx = JS_NewContext(rt);
|
||||
if (!ctx) {
|
||||
printf("Failed to create JS context\n");
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *json = JS_Tokenize(ctx, script, strlen(script), filename);
|
||||
if (json) {
|
||||
printf("%s\n", json);
|
||||
free(json);
|
||||
} else {
|
||||
printf("Failed to tokenize\n");
|
||||
}
|
||||
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return json ? 0 : 1;
|
||||
}
|
||||
|
||||
/* Check for --mach flag to output machine code JSON */
|
||||
if (argc >= 3 && strcmp(argv[1], "--mach") == 0) {
|
||||
const char *script_or_file = argv[2];
|
||||
char *script = NULL;
|
||||
char *allocated_script = NULL;
|
||||
const char *filename = "<eval>";
|
||||
|
||||
struct stat st;
|
||||
if (stat(script_or_file, &st) == 0 && S_ISREG(st.st_mode)) {
|
||||
FILE *f = fopen(script_or_file, "r");
|
||||
if (!f) {
|
||||
printf("Failed to open file: %s\n", script_or_file);
|
||||
return 1;
|
||||
}
|
||||
allocated_script = malloc(st.st_size + 1);
|
||||
if (!allocated_script) {
|
||||
fclose(f);
|
||||
printf("Failed to allocate memory for script\n");
|
||||
return 1;
|
||||
}
|
||||
size_t read_size = fread(allocated_script, 1, st.st_size, f);
|
||||
fclose(f);
|
||||
allocated_script[read_size] = '\0';
|
||||
script = allocated_script;
|
||||
filename = script_or_file;
|
||||
} else {
|
||||
script = (char *)script_or_file;
|
||||
}
|
||||
|
||||
JSRuntime *rt = JS_NewRuntime();
|
||||
if (!rt) {
|
||||
printf("Failed to create JS runtime\n");
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
JSContext *ctx = JS_NewContext(rt);
|
||||
if (!ctx) {
|
||||
printf("Failed to create JS context\n");
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *ast_json = JS_AST(ctx, script, strlen(script), filename);
|
||||
if (!ast_json) {
|
||||
printf("Failed to parse AST\n");
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *mach_json = JS_Mach(ctx, ast_json);
|
||||
free(ast_json);
|
||||
|
||||
if (mach_json) {
|
||||
printf("%s\n", mach_json);
|
||||
free(mach_json);
|
||||
} else {
|
||||
printf("Failed to generate machine code\n");
|
||||
}
|
||||
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return mach_json ? 0 : 1;
|
||||
}
|
||||
|
||||
/* Check for --vmcode flag to dump linked register VM bytecode */
|
||||
if (argc >= 3 && strcmp(argv[1], "--vmcode") == 0) {
|
||||
const char *script_or_file = argv[2];
|
||||
char *script = NULL;
|
||||
char *allocated_script = NULL;
|
||||
const char *filename = "<eval>";
|
||||
|
||||
struct stat st;
|
||||
if (stat(script_or_file, &st) == 0 && S_ISREG(st.st_mode)) {
|
||||
FILE *f = fopen(script_or_file, "r");
|
||||
if (!f) {
|
||||
printf("Failed to open file: %s\n", script_or_file);
|
||||
return 1;
|
||||
}
|
||||
allocated_script = malloc(st.st_size + 1);
|
||||
if (!allocated_script) {
|
||||
fclose(f);
|
||||
printf("Failed to allocate memory for script\n");
|
||||
return 1;
|
||||
}
|
||||
size_t read_size = fread(allocated_script, 1, st.st_size, f);
|
||||
fclose(f);
|
||||
allocated_script[read_size] = '\0';
|
||||
script = allocated_script;
|
||||
filename = script_or_file;
|
||||
} else {
|
||||
script = (char *)script_or_file;
|
||||
}
|
||||
|
||||
JSRuntime *rt = JS_NewRuntime();
|
||||
if (!rt) {
|
||||
printf("Failed to create JS runtime\n");
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
JSContext *ctx = JS_NewContext(rt);
|
||||
if (!ctx) {
|
||||
printf("Failed to create JS context\n");
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *ast_json = JS_AST(ctx, script, strlen(script), filename);
|
||||
if (!ast_json) {
|
||||
printf("Failed to parse AST\n");
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *mach_json = JS_Mach(ctx, ast_json);
|
||||
free(ast_json);
|
||||
|
||||
if (mach_json) {
|
||||
JS_DumpRegisterMach(ctx, mach_json, JS_NULL);
|
||||
free(mach_json);
|
||||
} else {
|
||||
printf("Failed to generate machine code\n");
|
||||
}
|
||||
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return mach_json ? 0 : 1;
|
||||
}
|
||||
|
||||
/* Check for --mach-run flag to generate and run machine code through register VM */
|
||||
fprintf(stderr, "DEBUG: argc=%d argv[1]=%s\n", argc, argc > 1 ? argv[1] : "NULL");
|
||||
fflush(stderr);
|
||||
if (argc >= 3 && strcmp(argv[1], "--mach-run") == 0) {
|
||||
const char *script_or_file = argv[2];
|
||||
char *script = NULL;
|
||||
char *allocated_script = NULL;
|
||||
const char *filename = "<eval>";
|
||||
|
||||
struct stat st;
|
||||
if (stat(script_or_file, &st) == 0 && S_ISREG(st.st_mode)) {
|
||||
FILE *f = fopen(script_or_file, "r");
|
||||
if (!f) {
|
||||
printf("Failed to open file: %s\n", script_or_file);
|
||||
return 1;
|
||||
}
|
||||
allocated_script = malloc(st.st_size + 1);
|
||||
if (!allocated_script) {
|
||||
fclose(f);
|
||||
printf("Failed to allocate memory for script\n");
|
||||
return 1;
|
||||
}
|
||||
size_t read_size = fread(allocated_script, 1, st.st_size, f);
|
||||
fclose(f);
|
||||
allocated_script[read_size] = '\0';
|
||||
script = allocated_script;
|
||||
filename = script_or_file;
|
||||
} else {
|
||||
script = (char *)script_or_file;
|
||||
}
|
||||
|
||||
JSRuntime *rt = JS_NewRuntime();
|
||||
if (!rt) {
|
||||
printf("Failed to create JS runtime\n");
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
JSContext *ctx = JS_NewContextWithHeapSize(rt, 1024 * 1024); /* 1MB heap for register VM */
|
||||
if (!ctx) {
|
||||
printf("Failed to create JS context\n");
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Parse to AST */
|
||||
char *ast_json = JS_AST(ctx, script, strlen(script), filename);
|
||||
if (!ast_json) {
|
||||
printf("Failed to parse AST\n");
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Generate machine code */
|
||||
char *mach_json = JS_Mach(ctx, ast_json);
|
||||
free(ast_json);
|
||||
|
||||
if (!mach_json) {
|
||||
printf("Failed to generate machine code\n");
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Execute through register VM */
|
||||
fprintf(stderr, "DEBUG: About to execute mach code\n");
|
||||
fflush(stderr);
|
||||
JSValue result = JS_IntegrateRegister(ctx, mach_json, JS_NULL);
|
||||
fprintf(stderr, "DEBUG: Execution done, result tag=%d\n", (int)(result >> 48));
|
||||
fflush(stderr);
|
||||
free(mach_json);
|
||||
|
||||
int exit_code = 0;
|
||||
if (JS_IsException(result)) {
|
||||
JSValue exc = JS_GetException(ctx);
|
||||
const char *err_str = JS_ToCString(ctx, exc);
|
||||
if (err_str) {
|
||||
printf("Error: %s\n", err_str);
|
||||
JS_FreeCString(ctx, err_str);
|
||||
}
|
||||
exit_code = 1;
|
||||
} else if (!JS_IsNull(result)) {
|
||||
/* Print result */
|
||||
const char *str = JS_ToCString(ctx, result);
|
||||
if (str) {
|
||||
printf("%s\n", str);
|
||||
JS_FreeCString(ctx, str);
|
||||
}
|
||||
}
|
||||
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
free(allocated_script);
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
/* Check for -e or --eval flag to run immediate script */
|
||||
/* Also check for -p flag to print bytecode */
|
||||
/* -s / --serializers flag provides json, nota, wota in env */
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
extern int cell_init(int argc, char **argv);
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
fprintf(stderr, "MAIN: starting\n");
|
||||
fflush(stderr);
|
||||
return cell_init(argc, argv);
|
||||
}
|
||||
@@ -205,6 +205,7 @@ DEF( set_up, 4, 1, 0, u8_u16) /* value, depth:u8, slot:u16 -> */
|
||||
/* Name resolution with bytecode patching */
|
||||
DEF( get_name, 5, 0, 1, const) /* cpool_idx -> value, patches itself */
|
||||
DEF( get_env_slot, 3, 0, 1, u16) /* slot -> value (patched from get_name) */
|
||||
DEF( set_env_slot, 3, 1, 0, u16) /* value -> slot (patched from put_var) */
|
||||
DEF(get_global_slot, 3, 0, 1, u16) /* slot -> value (patched from get_var) */
|
||||
DEF(set_global_slot, 3, 1, 0, u16) /* value -> slot (patched from put_var) */
|
||||
|
||||
|
||||
8825
source/quickjs.c
8825
source/quickjs.c
File diff suppressed because it is too large
Load Diff
227
source/quickjs.h
227
source/quickjs.h
@@ -92,6 +92,7 @@ static inline int objhdr_s (objhdr_t h) { return (h & OBJHDR_S_MASK) != 0; }
|
||||
typedef struct JSRuntime JSRuntime; // the entire VM
|
||||
typedef struct JSContext JSContext; // Each actor
|
||||
typedef struct JSClass JSClass;
|
||||
typedef struct JSFunctionBytecode JSFunctionBytecode;
|
||||
typedef uint32_t JSClassID;
|
||||
|
||||
/* Forward declaration - JSGCRef moved after JSValue definition */
|
||||
@@ -176,8 +177,6 @@ void JS_DeleteGCRef(JSContext *ctx, JSGCRef *ref);
|
||||
Value Extraction
|
||||
============================================================ */
|
||||
|
||||
#define JS_VALUE_GET_INT(v) ((int)(v) >> 1)
|
||||
|
||||
/* Get primary tag (low 2-3 bits) */
|
||||
static inline int
|
||||
JS_VALUE_GET_TAG (JSValue v) {
|
||||
@@ -334,13 +333,8 @@ JS_IsShortFloat (JSValue v) {
|
||||
#define JS_DEFAULT_STACK_SIZE (1024 * 1024)
|
||||
#endif
|
||||
|
||||
/* Internal eval flags */
|
||||
#define JS_EVAL_TYPE_GLOBAL (0 << 0) /* global code (default) */
|
||||
#define JS_EVAL_TYPE_DIRECT (2 << 0) /* direct call (internal use) */
|
||||
#define JS_EVAL_TYPE_INDIRECT (3 << 0) /* indirect call (internal use) */
|
||||
#define JS_EVAL_TYPE_MASK (3 << 0)
|
||||
/* Internal compile flags */
|
||||
#define JS_EVAL_FLAG_COMPILE_ONLY (1 << 5) /* internal use */
|
||||
#define JS_EVAL_FLAG_BACKTRACE_BARRIER (1 << 6) /* internal use */
|
||||
|
||||
typedef JSValue JSCFunction (JSContext *ctx, JSValue this_val, int argc,
|
||||
JSValue *argv);
|
||||
@@ -395,10 +389,7 @@ JSRuntime *JS_GetRuntime (JSContext *ctx);
|
||||
void JS_SetClassProto (JSContext *ctx, JSClassID class_id, JSValue obj);
|
||||
JSValue JS_GetClassProto (JSContext *ctx, JSClassID class_id);
|
||||
|
||||
/* the following functions are used to select the intrinsic object to
|
||||
save memory */
|
||||
JSContext *JS_NewContextRaw (JSRuntime *rt);
|
||||
JSContext *JS_NewContextRawWithHeapSize (JSRuntime *rt, size_t heap_size);
|
||||
JSContext *JS_NewContextWithHeapSize (JSRuntime *rt, size_t heap_size);
|
||||
|
||||
typedef struct JSMemoryUsage {
|
||||
int64_t malloc_size, malloc_limit, memory_used_size;
|
||||
@@ -733,7 +724,6 @@ JSValue JS_Compile (JSContext *ctx, const char *input, size_t input_len,
|
||||
env should be stoned record or null.
|
||||
Variables resolve: env first, then global intrinsics. */
|
||||
JSValue JS_Integrate (JSContext *ctx, JSValue bytecode, JSValue env);
|
||||
JSValue JS_GetGlobalObject (JSContext *ctx);
|
||||
void JS_SetOpaque (JSValue obj, void *opaque);
|
||||
void *JS_GetOpaque (JSValue obj, JSClassID class_id);
|
||||
void *JS_GetOpaque2 (JSContext *ctx, JSValue obj, JSClassID class_id);
|
||||
@@ -793,7 +783,14 @@ typedef enum JSCFunctionEnum {
|
||||
JS_CFUNC_1, /* JSValue f(ctx, this_val, arg0) */
|
||||
JS_CFUNC_2, /* JSValue f(ctx, this_val, arg0, arg1) */
|
||||
JS_CFUNC_3, /* JSValue f(ctx, this_val, arg0, arg1, arg2) */
|
||||
JS_CFUNC_4
|
||||
JS_CFUNC_4,
|
||||
/* Pure functions (no this_val) - for global utility functions */
|
||||
JS_CFUNC_PURE, /* JSValue f(ctx, argc, argv) - generic pure */
|
||||
JS_CFUNC_PURE_0, /* JSValue f(ctx) */
|
||||
JS_CFUNC_PURE_1, /* JSValue f(ctx, arg0) */
|
||||
JS_CFUNC_PURE_2, /* JSValue f(ctx, arg0, arg1) */
|
||||
JS_CFUNC_PURE_3, /* JSValue f(ctx, arg0, arg1, arg2) */
|
||||
JS_CFUNC_PURE_4 /* JSValue f(ctx, arg0, arg1, arg2, arg3) */
|
||||
} JSCFunctionEnum;
|
||||
|
||||
/* Fixed-arity C function types for fast paths */
|
||||
@@ -809,6 +806,16 @@ typedef JSValue JSCFunction4 (JSContext *ctx, JSValue this_val,
|
||||
JSValue arg0, JSValue arg1,
|
||||
JSValue arg2, JSValue arg3);
|
||||
|
||||
/* Pure function types (no this_val) */
|
||||
typedef JSValue JSCFunctionPure (JSContext *ctx, int argc, JSValue *argv);
|
||||
typedef JSValue JSCFunctionPure0 (JSContext *ctx);
|
||||
typedef JSValue JSCFunctionPure1 (JSContext *ctx, JSValue arg0);
|
||||
typedef JSValue JSCFunctionPure2 (JSContext *ctx, JSValue arg0, JSValue arg1);
|
||||
typedef JSValue JSCFunctionPure3 (JSContext *ctx, JSValue arg0, JSValue arg1,
|
||||
JSValue arg2);
|
||||
typedef JSValue JSCFunctionPure4 (JSContext *ctx, JSValue arg0, JSValue arg1,
|
||||
JSValue arg2, JSValue arg3);
|
||||
|
||||
typedef union JSCFunctionType {
|
||||
JSCFunction *generic;
|
||||
JSValue (*generic_magic) (JSContext *ctx, JSValue this_val, int argc,
|
||||
@@ -821,6 +828,13 @@ typedef union JSCFunctionType {
|
||||
JSCFunction2 *f2;
|
||||
JSCFunction3 *f3;
|
||||
JSCFunction4 *f4;
|
||||
/* Pure function pointers */
|
||||
JSCFunctionPure *pure;
|
||||
JSCFunctionPure0 *pure0;
|
||||
JSCFunctionPure1 *pure1;
|
||||
JSCFunctionPure2 *pure2;
|
||||
JSCFunctionPure3 *pure3;
|
||||
JSCFunctionPure4 *pure4;
|
||||
} JSCFunctionType;
|
||||
|
||||
JSValue JS_NewCFunction2 (JSContext *ctx, JSCFunction *func, const char *name,
|
||||
@@ -937,6 +951,43 @@ typedef struct JSCFunctionListEntry {
|
||||
.u \
|
||||
= {.func = { 3, JS_CFUNC_3, { .f3 = func1 } } } \
|
||||
}
|
||||
/* Pure function (no this_val) macros */
|
||||
#define JS_CFUNC_PURE_DEF(name, length, func1) \
|
||||
{ \
|
||||
name, 0, JS_DEF_CFUNC, 0, \
|
||||
.u \
|
||||
= {.func = { length, JS_CFUNC_PURE, { .pure = func1 } } } \
|
||||
}
|
||||
#define JS_CFUNC_PURE0_DEF(name, func1) \
|
||||
{ \
|
||||
name, 0, JS_DEF_CFUNC, 0, \
|
||||
.u \
|
||||
= {.func = { 0, JS_CFUNC_PURE_0, { .pure0 = func1 } } } \
|
||||
}
|
||||
#define JS_CFUNC_PURE1_DEF(name, func1) \
|
||||
{ \
|
||||
name, 0, JS_DEF_CFUNC, 0, \
|
||||
.u \
|
||||
= {.func = { 1, JS_CFUNC_PURE_1, { .pure1 = func1 } } } \
|
||||
}
|
||||
#define JS_CFUNC_PURE2_DEF(name, func1) \
|
||||
{ \
|
||||
name, 0, JS_DEF_CFUNC, 0, \
|
||||
.u \
|
||||
= {.func = { 2, JS_CFUNC_PURE_2, { .pure2 = func1 } } } \
|
||||
}
|
||||
#define JS_CFUNC_PURE3_DEF(name, func1) \
|
||||
{ \
|
||||
name, 0, JS_DEF_CFUNC, 0, \
|
||||
.u \
|
||||
= {.func = { 3, JS_CFUNC_PURE_3, { .pure3 = func1 } } } \
|
||||
}
|
||||
#define JS_CFUNC_PURE4_DEF(name, func1) \
|
||||
{ \
|
||||
name, 0, JS_DEF_CFUNC, 0, \
|
||||
.u \
|
||||
= {.func = { 4, JS_CFUNC_PURE_4, { .pure4 = func1 } } } \
|
||||
}
|
||||
#define JS_ITERATOR_NEXT_DEF(name, length, func1, magic) \
|
||||
{ \
|
||||
name, 0, JS_DEF_CFUNC, magic, .u = { \
|
||||
@@ -1049,11 +1100,149 @@ void *js_malloc_rt (size_t size);
|
||||
void *js_mallocz_rt (size_t size);
|
||||
void js_free_rt (void *ptr);
|
||||
|
||||
/* Intrinsic setup functions */
|
||||
void JS_AddIntrinsicBaseObjects (JSContext *ctx);
|
||||
void JS_AddIntrinsicBasicObjects (JSContext *ctx);
|
||||
void JS_AddIntrinsicEval (JSContext *ctx);
|
||||
void JS_AddIntrinsicRegExp (JSContext *ctx);
|
||||
/* ============================================================================
|
||||
Context-Neutral Module Format (CellModule)
|
||||
============================================================================ */
|
||||
|
||||
/* Capture descriptor - what a nested function closes over */
|
||||
typedef enum {
|
||||
CAP_FROM_PARENT_LOCAL = 1, /* capture local from parent function */
|
||||
CAP_FROM_PARENT_UPVALUE = 2 /* forward upvalue from parent's upvalues */
|
||||
} CellCapKind;
|
||||
|
||||
typedef struct CellCapDesc {
|
||||
uint8_t kind; /* CAP_FROM_PARENT_LOCAL or CAP_FROM_PARENT_UPVALUE */
|
||||
uint16_t index; /* local index in parent, or upvalue index in parent */
|
||||
} CellCapDesc;
|
||||
|
||||
/* External relocation - for integrate-time patching */
|
||||
typedef enum {
|
||||
EXT_GET = 1, /* OP_get_var -> OP_get_env_slot or OP_get_global_slot */
|
||||
EXT_SET = 2 /* OP_put_var -> OP_set_env_slot or OP_set_global_slot */
|
||||
} CellExtKind;
|
||||
|
||||
typedef struct CellExternalReloc {
|
||||
uint32_t pc_offset; /* where operand lives in bytecode */
|
||||
uint32_t name_sid; /* string id of the external name */
|
||||
uint8_t kind; /* EXT_GET or EXT_SET */
|
||||
} CellExternalReloc;
|
||||
|
||||
/* Constant types in cpool */
|
||||
typedef enum {
|
||||
CELL_CONST_NULL = 0,
|
||||
CELL_CONST_INT = 1,
|
||||
CELL_CONST_FLOAT = 2,
|
||||
CELL_CONST_STRING = 3, /* string_sid into module string table */
|
||||
CELL_CONST_UNIT = 4 /* unit_id for nested function */
|
||||
} CellConstType;
|
||||
|
||||
typedef struct CellConst {
|
||||
uint8_t type; /* CellConstType */
|
||||
union {
|
||||
int32_t i32;
|
||||
double f64;
|
||||
uint32_t string_sid;
|
||||
uint32_t unit_id;
|
||||
};
|
||||
} CellConst;
|
||||
|
||||
/* Per-unit structure (context-neutral, flattened) */
|
||||
typedef struct CellUnit {
|
||||
/* Constant pool */
|
||||
uint32_t const_count;
|
||||
CellConst *constants;
|
||||
|
||||
/* Bytecode */
|
||||
uint32_t bytecode_len;
|
||||
uint8_t *bytecode;
|
||||
|
||||
/* Stack requirements */
|
||||
uint16_t arg_count;
|
||||
uint16_t var_count;
|
||||
uint16_t stack_size;
|
||||
|
||||
/* Upvalue (capture) descriptors */
|
||||
uint16_t upvalue_count;
|
||||
CellCapDesc *upvalues;
|
||||
|
||||
/* External relocations */
|
||||
uint32_t external_count;
|
||||
CellExternalReloc *externals;
|
||||
|
||||
/* Debug info (optional) */
|
||||
uint32_t pc2line_len;
|
||||
uint8_t *pc2line;
|
||||
uint32_t name_sid; /* unit name for stack traces */
|
||||
} CellUnit;
|
||||
|
||||
/* Module-level structure (context-neutral) */
|
||||
#define CELL_MODULE_MAGIC 0x4C4C4543 /* "CELL" */
|
||||
#define CELL_MODULE_VERSION 1
|
||||
|
||||
typedef struct CellModule {
|
||||
uint32_t magic; /* CELL_MODULE_MAGIC */
|
||||
uint8_t version; /* CELL_MODULE_VERSION */
|
||||
uint8_t flags;
|
||||
|
||||
/* Shared string table (module-global) */
|
||||
uint32_t string_count;
|
||||
uint32_t string_data_size;
|
||||
uint8_t *string_data; /* concatenated UTF-8 strings */
|
||||
uint32_t *string_offsets; /* offset for each string */
|
||||
|
||||
/* Unit table (entry 0 is the main/entry unit) */
|
||||
uint32_t unit_count;
|
||||
CellUnit *units;
|
||||
|
||||
/* Debug: source stored once at module level */
|
||||
uint32_t source_len;
|
||||
char *source;
|
||||
} CellModule;
|
||||
|
||||
/* Free a CellModule and all its contents */
|
||||
void cell_module_free (CellModule *mod);
|
||||
|
||||
/* Write a CellModule to a byte buffer.
|
||||
Returns allocated buffer (caller must free with pjs_free), or NULL on error. */
|
||||
uint8_t *cell_module_write (CellModule *mod, size_t *out_len);
|
||||
|
||||
/* Read a CellModule from a byte buffer.
|
||||
Returns allocated CellModule (caller must free with cell_module_free), or NULL on error. */
|
||||
CellModule *cell_module_read (const uint8_t *buf, size_t buf_len);
|
||||
|
||||
/* Convert compiled JSFunctionBytecode to CellModule.
|
||||
Returns allocated CellModule (caller must free with cell_module_free), or NULL on error. */
|
||||
CellModule *cell_module_from_bytecode (JSContext *ctx, JSFunctionBytecode *main_func);
|
||||
|
||||
/* Compile source code directly to CellModule.
|
||||
Returns allocated CellModule (caller must free with cell_module_free), or NULL on error. */
|
||||
CellModule *JS_CompileModule (JSContext *ctx, const char *input, size_t input_len, const char *filename);
|
||||
|
||||
/* Parse source code and return AST as JSON string.
|
||||
Returns malloc'd JSON string (caller must free), or NULL on error. */
|
||||
char *JS_AST (JSContext *ctx, const char *source, size_t len, const char *filename);
|
||||
|
||||
/* Tokenize source code and return token array as JSON string.
|
||||
Returns malloc'd JSON string (caller must free), or NULL on error. */
|
||||
char *JS_Tokenize (JSContext *ctx, const char *source, size_t len, const char *filename);
|
||||
|
||||
/* Generate register-based machine code from AST JSON.
|
||||
Returns malloc'd JSON string (caller must free), or NULL on error. */
|
||||
char *JS_Mach (JSContext *ctx, const char *ast_json);
|
||||
|
||||
/* Link and execute register-based machine code.
|
||||
mach_json: JSON output from JS_Mach
|
||||
env: stone record for external variable resolution (or JS_NULL)
|
||||
Returns result of execution, or JS_EXCEPTION on error. */
|
||||
JSValue JS_IntegrateRegister (JSContext *ctx, const char *mach_json, JSValue env);
|
||||
|
||||
/* Dump linked register VM bytecode to stdout for debugging.
|
||||
Links mach_json and prints the resulting bytecode with resolved labels. */
|
||||
void JS_DumpRegisterMach (JSContext *ctx, const char *mach_json, JSValue env);
|
||||
|
||||
/* Integrate a CellModule with an environment and execute.
|
||||
Returns callable function value, or JS_EXCEPTION on error. */
|
||||
JSValue cell_module_integrate (JSContext *ctx, CellModule *mod, JSValue env);
|
||||
|
||||
#undef js_unlikely
|
||||
#undef inline
|
||||
|
||||
178
source/suite.c
178
source/suite.c
@@ -954,24 +954,6 @@ TEST(array_foreach_basic) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
GLOBAL OBJECT TEST
|
||||
============================================================================ */
|
||||
|
||||
TEST(global_object) {
|
||||
JSGCRef global_ref;
|
||||
JS_PushGCRef(ctx, &global_ref);
|
||||
global_ref.val = JS_GetGlobalObject(ctx);
|
||||
ASSERT(JS_IsRecord(global_ref.val));
|
||||
|
||||
/* Set something on global */
|
||||
JS_SetPropertyStr(ctx, global_ref.val, "testGlobal", JS_NewInt32(ctx, 777));
|
||||
JSValue val = JS_GetPropertyStr(ctx, global_ref.val, "testGlobal");
|
||||
JS_PopGCRef(ctx, &global_ref);
|
||||
ASSERT_INT(val, 777);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
VALUE CONVERSION TESTS
|
||||
============================================================================ */
|
||||
@@ -1521,23 +1503,6 @@ TEST(new_cfunction_with_args) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(call_function_on_global) {
|
||||
JSGCRef func_ref, global_ref;
|
||||
JS_PushGCRef(ctx, &global_ref);
|
||||
JS_PushGCRef(ctx, &func_ref);
|
||||
global_ref.val = JS_GetGlobalObject(ctx);
|
||||
func_ref.val = JS_NewCFunction(ctx, cfunc_return_42, "testFunc", 0);
|
||||
JS_SetPropertyStr(ctx, global_ref.val, "testFunc", func_ref.val);
|
||||
JSValue got = JS_GetPropertyStr(ctx, global_ref.val, "testFunc");
|
||||
int is_func = JS_IsFunction(got);
|
||||
JSValue result = JS_Call(ctx, got, JS_NULL, 0, NULL);
|
||||
JS_PopGCRef(ctx, &func_ref);
|
||||
JS_PopGCRef(ctx, &global_ref);
|
||||
ASSERT(is_func);
|
||||
ASSERT_INT(result, 42);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
PROPERTY ACCESS TESTS
|
||||
============================================================================ */
|
||||
@@ -2035,6 +2000,138 @@ TEST(wota_encode_blob) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
CELL MODULE TESTS - Serialize/Deserialize bytecode
|
||||
============================================================================ */
|
||||
|
||||
TEST(cell_module_compile_basic) {
|
||||
/* Compile simple source to CellModule */
|
||||
const char *source = "1 + 2";
|
||||
CellModule *mod = JS_CompileModule(ctx, source, strlen(source), "<test>");
|
||||
ASSERT_MSG(mod != NULL, "JS_CompileModule returned NULL");
|
||||
|
||||
/* Check module has units */
|
||||
ASSERT_MSG(mod->unit_count > 0, "Module has no units");
|
||||
ASSERT_MSG(mod->units[0].bytecode_len > 0, "Unit has no bytecode");
|
||||
|
||||
cell_module_free(mod);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(cell_module_write_read) {
|
||||
/* Compile, serialize, deserialize */
|
||||
const char *source = "var x = 10; x * 2";
|
||||
CellModule *mod = JS_CompileModule(ctx, source, strlen(source), "<test>");
|
||||
ASSERT_MSG(mod != NULL, "JS_CompileModule returned NULL");
|
||||
|
||||
/* Serialize */
|
||||
size_t len;
|
||||
uint8_t *buf = cell_module_write(mod, &len);
|
||||
ASSERT_MSG(buf != NULL, "cell_module_write returned NULL");
|
||||
ASSERT_MSG(len > 0, "cell_module_write produced empty buffer");
|
||||
|
||||
/* Deserialize */
|
||||
CellModule *mod2 = cell_module_read(buf, len);
|
||||
free(buf);
|
||||
ASSERT_MSG(mod2 != NULL, "cell_module_read returned NULL");
|
||||
|
||||
/* Verify structure matches */
|
||||
ASSERT_MSG(mod2->unit_count == mod->unit_count, "unit_count mismatch");
|
||||
ASSERT_MSG(mod2->string_count == mod->string_count, "string_count mismatch");
|
||||
|
||||
cell_module_free(mod);
|
||||
cell_module_free(mod2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(cell_module_integrate_basic) {
|
||||
/* Compile, then integrate and execute */
|
||||
const char *source = "3 + 4";
|
||||
CellModule *mod = JS_CompileModule(ctx, source, strlen(source), "<test>");
|
||||
ASSERT_MSG(mod != NULL, "JS_CompileModule returned NULL");
|
||||
|
||||
/* Integrate into context */
|
||||
JSValue func = cell_module_integrate(ctx, mod, JS_NULL);
|
||||
if (JS_IsException(func)) {
|
||||
cell_module_free(mod);
|
||||
ASSERT_MSG(0, "cell_module_integrate threw exception");
|
||||
}
|
||||
|
||||
/* Execute */
|
||||
JSValue result = JS_Call(ctx, func, JS_NULL, 0, NULL);
|
||||
JS_FreeValue(ctx, func);
|
||||
cell_module_free(mod);
|
||||
|
||||
if (JS_IsException(result)) {
|
||||
ASSERT_MSG(0, "JS_Call threw exception");
|
||||
}
|
||||
|
||||
ASSERT_INT(result, 7);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(cell_module_roundtrip_execute) {
|
||||
/* Full round-trip: compile -> write -> read -> integrate -> execute */
|
||||
const char *source = "var a = 5; var b = 3; a * b";
|
||||
CellModule *mod = JS_CompileModule(ctx, source, strlen(source), "<test>");
|
||||
ASSERT_MSG(mod != NULL, "JS_CompileModule returned NULL");
|
||||
|
||||
/* Serialize */
|
||||
size_t len;
|
||||
uint8_t *buf = cell_module_write(mod, &len);
|
||||
cell_module_free(mod);
|
||||
ASSERT_MSG(buf != NULL, "cell_module_write returned NULL");
|
||||
|
||||
/* Deserialize */
|
||||
CellModule *mod2 = cell_module_read(buf, len);
|
||||
free(buf);
|
||||
ASSERT_MSG(mod2 != NULL, "cell_module_read returned NULL");
|
||||
|
||||
/* Integrate and execute */
|
||||
JSValue func = cell_module_integrate(ctx, mod2, JS_NULL);
|
||||
cell_module_free(mod2);
|
||||
if (JS_IsException(func)) {
|
||||
ASSERT_MSG(0, "cell_module_integrate threw exception");
|
||||
}
|
||||
|
||||
JSValue result = JS_Call(ctx, func, JS_NULL, 0, NULL);
|
||||
JS_FreeValue(ctx, func);
|
||||
|
||||
if (JS_IsException(result)) {
|
||||
ASSERT_MSG(0, "JS_Call threw exception");
|
||||
}
|
||||
|
||||
ASSERT_INT(result, 15);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(cell_module_string_constant) {
|
||||
/* Test string constant handling */
|
||||
const char *source = "'hello' + ' world'";
|
||||
CellModule *mod = JS_CompileModule(ctx, source, strlen(source), "<test>");
|
||||
ASSERT_MSG(mod != NULL, "JS_CompileModule returned NULL");
|
||||
|
||||
/* Verify string table has entries */
|
||||
ASSERT_MSG(mod->string_count > 0, "Module has no strings");
|
||||
|
||||
/* Integrate and execute */
|
||||
JSValue func = cell_module_integrate(ctx, mod, JS_NULL);
|
||||
cell_module_free(mod);
|
||||
if (JS_IsException(func)) {
|
||||
ASSERT_MSG(0, "cell_module_integrate threw exception");
|
||||
}
|
||||
|
||||
JSValue result = JS_Call(ctx, func, JS_NULL, 0, NULL);
|
||||
JS_FreeValue(ctx, func);
|
||||
|
||||
if (JS_IsException(result)) {
|
||||
ASSERT_MSG(0, "JS_Call threw exception");
|
||||
}
|
||||
|
||||
ASSERT_STR(result, "hello world");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
MAIN TEST RUNNER
|
||||
============================================================================ */
|
||||
@@ -2113,9 +2210,6 @@ int run_c_test_suite(JSContext *ctx)
|
||||
RUN_TEST(strict_eq_null);
|
||||
RUN_TEST(strict_eq_bool);
|
||||
|
||||
printf("\nGlobal Object:\n");
|
||||
RUN_TEST(global_object);
|
||||
|
||||
printf("\nValue Conversions:\n");
|
||||
RUN_TEST(to_bool_true_values);
|
||||
RUN_TEST(to_bool_false_values);
|
||||
@@ -2188,7 +2282,6 @@ int run_c_test_suite(JSContext *ctx)
|
||||
printf("\nC Functions:\n");
|
||||
RUN_TEST(new_cfunction_no_args);
|
||||
RUN_TEST(new_cfunction_with_args);
|
||||
RUN_TEST(call_function_on_global);
|
||||
|
||||
printf("\nProperty Access:\n");
|
||||
RUN_TEST(get_property_with_jsvalue_key);
|
||||
@@ -2248,6 +2341,13 @@ int run_c_test_suite(JSContext *ctx)
|
||||
RUN_TEST(wota_encode_nested_array);
|
||||
RUN_TEST(wota_encode_blob);
|
||||
|
||||
// CellModule tests
|
||||
RUN_TEST(cell_module_compile_basic);
|
||||
RUN_TEST(cell_module_write_read);
|
||||
RUN_TEST(cell_module_integrate_basic);
|
||||
RUN_TEST(cell_module_roundtrip_execute);
|
||||
RUN_TEST(cell_module_string_constant);
|
||||
|
||||
printf("\n=================================\n");
|
||||
printf("Results: %d passed, %d failed\n", tests_passed, tests_failed);
|
||||
printf("=================================\n\n");
|
||||
|
||||
1
vm_test/arrow_block.txt
Normal file
1
vm_test/arrow_block.txt
Normal file
@@ -0,0 +1 @@
|
||||
var f = x => { return x }; f(1)
|
||||
1
vm_test/arrow_default.txt
Normal file
1
vm_test/arrow_default.txt
Normal file
@@ -0,0 +1 @@
|
||||
var f = (x = 10) => x; f()
|
||||
1
vm_test/arrow_expr.txt
Normal file
1
vm_test/arrow_expr.txt
Normal file
@@ -0,0 +1 @@
|
||||
var f = x => x * 2; f(5)
|
||||
1
vm_test/arrow_multi.txt
Normal file
1
vm_test/arrow_multi.txt
Normal file
@@ -0,0 +1 @@
|
||||
var f = (a, b) => a + b; f(2, 3)
|
||||
1
vm_test/arrow_no_param.txt
Normal file
1
vm_test/arrow_no_param.txt
Normal file
@@ -0,0 +1 @@
|
||||
var f = () => 42; f()
|
||||
1
vm_test/assign_add.txt
Normal file
1
vm_test/assign_add.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 5; x += 3; x
|
||||
1
vm_test/assign_and.txt
Normal file
1
vm_test/assign_and.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 7; x &= 3; x
|
||||
1
vm_test/assign_div.txt
Normal file
1
vm_test/assign_div.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 6; x /= 2; x
|
||||
1
vm_test/assign_land.txt
Normal file
1
vm_test/assign_land.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 5; x &&= 10; x
|
||||
1
vm_test/assign_lor.txt
Normal file
1
vm_test/assign_lor.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 0; x ||= 10; x
|
||||
1
vm_test/assign_mod.txt
Normal file
1
vm_test/assign_mod.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 7; x %= 3; x
|
||||
1
vm_test/assign_mul.txt
Normal file
1
vm_test/assign_mul.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 5; x *= 3; x
|
||||
1
vm_test/assign_nullish.txt
Normal file
1
vm_test/assign_nullish.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = null; x ??= 10; x
|
||||
1
vm_test/assign_or.txt
Normal file
1
vm_test/assign_or.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 5; x |= 2; x
|
||||
1
vm_test/assign_power.txt
Normal file
1
vm_test/assign_power.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 2; x **= 3; x
|
||||
1
vm_test/assign_shl.txt
Normal file
1
vm_test/assign_shl.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 2; x <<= 3; x
|
||||
1
vm_test/assign_shr.txt
Normal file
1
vm_test/assign_shr.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 8; x >>= 2; x
|
||||
1
vm_test/assign_shru.txt
Normal file
1
vm_test/assign_shru.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = -8; x >>>= 2; x
|
||||
1
vm_test/assign_sub.txt
Normal file
1
vm_test/assign_sub.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 5; x -= 3; x
|
||||
1
vm_test/assign_xor.txt
Normal file
1
vm_test/assign_xor.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 5; x ^= 3; x
|
||||
1
vm_test/chained_assign.txt
Normal file
1
vm_test/chained_assign.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x, y; x = y = 5; x + y
|
||||
1
vm_test/closure_basic.txt
Normal file
1
vm_test/closure_basic.txt
Normal file
@@ -0,0 +1 @@
|
||||
var f = function(x) { return function() { return x } }; f(5)()
|
||||
11
vm_test/closure_mutate.txt
Normal file
11
vm_test/closure_mutate.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
var counter = function() {
|
||||
var n = 0
|
||||
return function() {
|
||||
n = n + 1
|
||||
return n
|
||||
}
|
||||
}
|
||||
var c = counter()
|
||||
c()
|
||||
c()
|
||||
c()
|
||||
3
vm_test/comment.txt
Normal file
3
vm_test/comment.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
// simple test that comments work
|
||||
var x = 5
|
||||
// other comment
|
||||
1
vm_test/comment_block.txt
Normal file
1
vm_test/comment_block.txt
Normal file
@@ -0,0 +1 @@
|
||||
/* comment */ 5
|
||||
1
vm_test/comment_multi.txt
Normal file
1
vm_test/comment_multi.txt
Normal file
@@ -0,0 +1 @@
|
||||
1 /* a */ + /* b */ 2
|
||||
1
vm_test/def_basic.txt
Normal file
1
vm_test/def_basic.txt
Normal file
@@ -0,0 +1 @@
|
||||
def x = 5; x
|
||||
1
vm_test/do_while.txt
Normal file
1
vm_test/do_while.txt
Normal file
@@ -0,0 +1 @@
|
||||
var i = 0; do { i = i + 1 } while (i < 3); i
|
||||
1
vm_test/do_while_continue.txt
Normal file
1
vm_test/do_while_continue.txt
Normal file
@@ -0,0 +1 @@
|
||||
var s = 0; var i = 0; do { i = i + 1; if (i == 2) continue; s = s + i } while (i < 5); s
|
||||
1
vm_test/empty_statement.txt
Normal file
1
vm_test/empty_statement.txt
Normal file
@@ -0,0 +1 @@
|
||||
;;; 5
|
||||
1
vm_test/for_basic.txt
Normal file
1
vm_test/for_basic.txt
Normal file
@@ -0,0 +1 @@
|
||||
var s = 0; for (var i = 0; i < 3; i++) s = s + i; s
|
||||
1
vm_test/for_break.txt
Normal file
1
vm_test/for_break.txt
Normal file
@@ -0,0 +1 @@
|
||||
var s = 0; for (var i = 0; i < 10; i++) { if (i == 4) break; s = s + i }; s
|
||||
1
vm_test/for_continue.txt
Normal file
1
vm_test/for_continue.txt
Normal file
@@ -0,0 +1 @@
|
||||
var s = 0; for (var i = 0; i < 5; i++) { if (i == 2) continue; s = s + i }; s
|
||||
1
vm_test/func_expr.txt
Normal file
1
vm_test/func_expr.txt
Normal file
@@ -0,0 +1 @@
|
||||
var f = function(x) { return x * 2 }; f(3)
|
||||
1
vm_test/func_iife.txt
Normal file
1
vm_test/func_iife.txt
Normal file
@@ -0,0 +1 @@
|
||||
(function(x) { return x * 2 })(5)
|
||||
1
vm_test/func_recursive.txt
Normal file
1
vm_test/func_recursive.txt
Normal file
@@ -0,0 +1 @@
|
||||
function fac(n) { if (n <= 1) return 1; return n * fac(n - 1) }; fac(5)
|
||||
2
vm_test/go_basic.txt
Normal file
2
vm_test/go_basic.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
function a() { go b() }
|
||||
function b() { 1 }
|
||||
2
vm_test/go_method.txt
Normal file
2
vm_test/go_method.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
var o = {m: function() { 1 }}
|
||||
function f() { go o.m() }
|
||||
1
vm_test/if_basic.txt
Normal file
1
vm_test/if_basic.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 0; if (true) x = 1; x
|
||||
1
vm_test/if_else.txt
Normal file
1
vm_test/if_else.txt
Normal file
@@ -0,0 +1 @@
|
||||
if (false) 1 else 2
|
||||
1
vm_test/intrisic_link.txt
Normal file
1
vm_test/intrisic_link.txt
Normal file
@@ -0,0 +1 @@
|
||||
print("a")
|
||||
1
vm_test/label_break.txt
Normal file
1
vm_test/label_break.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 0; outer: { x = 1; break outer; x = 2 }; x
|
||||
1
vm_test/label_continue.txt
Normal file
1
vm_test/label_continue.txt
Normal file
@@ -0,0 +1 @@
|
||||
var s = 0; outer: for (var i = 0; i < 3; i++) { for (var j = 0; j < 3; j++) { if (j == 1) continue outer; s = s + 1 } }; s
|
||||
1
vm_test/multi_var.txt
Normal file
1
vm_test/multi_var.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 1, y = 2; x + y
|
||||
1
vm_test/nested_block.txt
Normal file
1
vm_test/nested_block.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 1; { var y = 2; { var z = 3; x = x + y + z } }; x
|
||||
1
vm_test/num_binary.txt
Normal file
1
vm_test/num_binary.txt
Normal file
@@ -0,0 +1 @@
|
||||
0b1010
|
||||
1
vm_test/num_exp.txt
Normal file
1
vm_test/num_exp.txt
Normal file
@@ -0,0 +1 @@
|
||||
1e3
|
||||
1
vm_test/num_float.txt
Normal file
1
vm_test/num_float.txt
Normal file
@@ -0,0 +1 @@
|
||||
3.14
|
||||
1
vm_test/num_hex.txt
Normal file
1
vm_test/num_hex.txt
Normal file
@@ -0,0 +1 @@
|
||||
0xff
|
||||
1
vm_test/num_octal.txt
Normal file
1
vm_test/num_octal.txt
Normal file
@@ -0,0 +1 @@
|
||||
0o17
|
||||
1
vm_test/num_underscore.txt
Normal file
1
vm_test/num_underscore.txt
Normal file
@@ -0,0 +1 @@
|
||||
1_000_000
|
||||
1
vm_test/op_arith.txt
Normal file
1
vm_test/op_arith.txt
Normal file
@@ -0,0 +1 @@
|
||||
1 + 2 * 3
|
||||
1
vm_test/op_bitwise.txt
Normal file
1
vm_test/op_bitwise.txt
Normal file
@@ -0,0 +1 @@
|
||||
5 & 3
|
||||
1
vm_test/op_bitwise_not.txt
Normal file
1
vm_test/op_bitwise_not.txt
Normal file
@@ -0,0 +1 @@
|
||||
~5
|
||||
1
vm_test/op_bitwise_or.txt
Normal file
1
vm_test/op_bitwise_or.txt
Normal file
@@ -0,0 +1 @@
|
||||
5 | 2
|
||||
1
vm_test/op_bitwise_xor.txt
Normal file
1
vm_test/op_bitwise_xor.txt
Normal file
@@ -0,0 +1 @@
|
||||
5 ^ 3
|
||||
1
vm_test/op_comma.txt
Normal file
1
vm_test/op_comma.txt
Normal file
@@ -0,0 +1 @@
|
||||
(1, 2, 3)
|
||||
1
vm_test/op_compare.txt
Normal file
1
vm_test/op_compare.txt
Normal file
@@ -0,0 +1 @@
|
||||
5 > 3
|
||||
1
vm_test/op_compare_eq.txt
Normal file
1
vm_test/op_compare_eq.txt
Normal file
@@ -0,0 +1 @@
|
||||
3 == 3
|
||||
1
vm_test/op_compare_gte.txt
Normal file
1
vm_test/op_compare_gte.txt
Normal file
@@ -0,0 +1 @@
|
||||
5 >= 5
|
||||
1
vm_test/op_compare_lt.txt
Normal file
1
vm_test/op_compare_lt.txt
Normal file
@@ -0,0 +1 @@
|
||||
3 < 5
|
||||
1
vm_test/op_compare_lte.txt
Normal file
1
vm_test/op_compare_lte.txt
Normal file
@@ -0,0 +1 @@
|
||||
3 <= 3
|
||||
1
vm_test/op_compare_neq.txt
Normal file
1
vm_test/op_compare_neq.txt
Normal file
@@ -0,0 +1 @@
|
||||
3 != 4
|
||||
1
vm_test/op_decrement_post.txt
Normal file
1
vm_test/op_decrement_post.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 5; x--; x
|
||||
1
vm_test/op_decrement_pre.txt
Normal file
1
vm_test/op_decrement_pre.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 5; --x
|
||||
1
vm_test/op_delete.txt
Normal file
1
vm_test/op_delete.txt
Normal file
@@ -0,0 +1 @@
|
||||
var o = {x: 1}; delete o.x; o.x
|
||||
1
vm_test/op_in.txt
Normal file
1
vm_test/op_in.txt
Normal file
@@ -0,0 +1 @@
|
||||
var o = {x: 1}; "x" in o
|
||||
1
vm_test/op_increment_post.txt
Normal file
1
vm_test/op_increment_post.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 5; x++; x
|
||||
1
vm_test/op_increment_pre.txt
Normal file
1
vm_test/op_increment_pre.txt
Normal file
@@ -0,0 +1 @@
|
||||
var x = 5; ++x
|
||||
1
vm_test/op_logical.txt
Normal file
1
vm_test/op_logical.txt
Normal file
@@ -0,0 +1 @@
|
||||
true && false
|
||||
1
vm_test/op_logical_not.txt
Normal file
1
vm_test/op_logical_not.txt
Normal file
@@ -0,0 +1 @@
|
||||
!false
|
||||
1
vm_test/op_logical_or.txt
Normal file
1
vm_test/op_logical_or.txt
Normal file
@@ -0,0 +1 @@
|
||||
false || true
|
||||
1
vm_test/op_nullish.txt
Normal file
1
vm_test/op_nullish.txt
Normal file
@@ -0,0 +1 @@
|
||||
null ?? 5
|
||||
1
vm_test/op_power.txt
Normal file
1
vm_test/op_power.txt
Normal file
@@ -0,0 +1 @@
|
||||
2 ** 3
|
||||
1
vm_test/op_shift_left.txt
Normal file
1
vm_test/op_shift_left.txt
Normal file
@@ -0,0 +1 @@
|
||||
2 << 3
|
||||
1
vm_test/op_shift_right.txt
Normal file
1
vm_test/op_shift_right.txt
Normal file
@@ -0,0 +1 @@
|
||||
8 >> 2
|
||||
1
vm_test/op_shift_right_unsigned.txt
Normal file
1
vm_test/op_shift_right_unsigned.txt
Normal file
@@ -0,0 +1 @@
|
||||
-8 >>> 2
|
||||
1
vm_test/op_ternary.txt
Normal file
1
vm_test/op_ternary.txt
Normal file
@@ -0,0 +1 @@
|
||||
true ? 1 : 2
|
||||
1
vm_test/op_unary_minus.txt
Normal file
1
vm_test/op_unary_minus.txt
Normal file
@@ -0,0 +1 @@
|
||||
-5
|
||||
1
vm_test/op_unary_plus.txt
Normal file
1
vm_test/op_unary_plus.txt
Normal file
@@ -0,0 +1 @@
|
||||
+"5"
|
||||
1
vm_test/optional_bracket.txt
Normal file
1
vm_test/optional_bracket.txt
Normal file
@@ -0,0 +1 @@
|
||||
var o = {a: 1}; o?.["a"]
|
||||
1
vm_test/optional_call.txt
Normal file
1
vm_test/optional_call.txt
Normal file
@@ -0,0 +1 @@
|
||||
var o = {f: () => 1}; o.f?.()
|
||||
1
vm_test/optional_null.txt
Normal file
1
vm_test/optional_null.txt
Normal file
@@ -0,0 +1 @@
|
||||
var o = null; o?.a
|
||||
1
vm_test/optional_prop.txt
Normal file
1
vm_test/optional_prop.txt
Normal file
@@ -0,0 +1 @@
|
||||
var o = {a: 1}; o?.a
|
||||
1
vm_test/paren_precedence.txt
Normal file
1
vm_test/paren_precedence.txt
Normal file
@@ -0,0 +1 @@
|
||||
(1 + 2) * 3
|
||||
1
vm_test/record_bracket.txt
Normal file
1
vm_test/record_bracket.txt
Normal file
@@ -0,0 +1 @@
|
||||
var a = {x: 1}; a["x"]
|
||||
1
vm_test/record_chain.txt
Normal file
1
vm_test/record_chain.txt
Normal file
@@ -0,0 +1 @@
|
||||
var o = {a: {b: {c: 1}}}; o.a.b.c
|
||||
1
vm_test/record_computed.txt
Normal file
1
vm_test/record_computed.txt
Normal file
@@ -0,0 +1 @@
|
||||
var k = "x"; var a = {x: 1}; a[k]
|
||||
1
vm_test/record_dot.txt
Normal file
1
vm_test/record_dot.txt
Normal file
@@ -0,0 +1 @@
|
||||
var a = {x: 1}; a.x
|
||||
1
vm_test/record_nested.txt
Normal file
1
vm_test/record_nested.txt
Normal file
@@ -0,0 +1 @@
|
||||
var o = {a: {b: 1}}; o.a.b
|
||||
1
vm_test/record_numeric_key.txt
Normal file
1
vm_test/record_numeric_key.txt
Normal file
@@ -0,0 +1 @@
|
||||
var o = {1: "one"}; o[1]
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user