1 //
2 //  gravity_value.h
3 //  gravity
4 //
5 //  Created by Marco Bambini on 11/12/14.
6 //  Copyright (c) 2014 CreoLabs. All rights reserved.
7 //
8 
9 #ifndef __GRAVITY_VALUES__
10 #define __GRAVITY_VALUES__
11 
12 #include "gravity_memory.h"
13 #include "gravity_utils.h"
14 #include "gravity_array.h"
15 #include "gravity_json.h"
16 #include "debug_macros.h"
17 
18 // Gravity is a dynamically typed language so a variable (gravity_value_t) can hold a value of any type.
19 
20 // The representation of values in a dynamically typed language is very important since it can lead to a big
21 // difference in terms of performance. Such representation has several constraints:
22 // - fast access
23 // - must represent several kind of values
24 // - be able to cope with the garbage collector
25 // - low memory overhead (when allocating a lot of small values)
26 
27 // In modern 64bit processor with OS that always returns aligned allocated memory blocks that means that each ptr is 8 bytes.
28 // That means that passing a value as an argument or storing it involves copying these bytes around (requiring 2/4 machine words).
29 // Values are not pointers but structures.
30 
31 // The built-in types for booleans, numbers, floats, null, undefs are unboxed: their value is stored directly into gravity_value_t.
32 // Other types like classes, instances, functions, lists, and strings are all reference types. They are stored on the heap and
33 // the gravity_value_t just stores a pointer to it.
34 
35 // So each value is a pointer to a FIXED size block of memory (16 bytes). Having all values of the same size greatly reduce the complexity
36 // of a memory pool and since allocating a large amount of values is very common is a dynamically typed language like Gravity.
37 // In a future update I could introduce NaN tagging and squeeze value size to 8 bytes (that would mean nearly double performance).
38 
39 // Internal settings to set integer and float size.
40 // Default is to have both int and float as 64bit.
41 
42 // In a 64bit OS:
43 // sizeof(float)        => 4 bytes
44 // sizeof(double)       => 8 bytes
45 // sizeof(void*)        => 8 bytes
46 // sizeof(int64_t)      => 8 bytes
47 //
48 // sizeof various structs in a 64bit OS:
49 // STRUCT                       BYTES
50 // ======                       =====
51 // gravity_function_t           104
52 // gravity_value_t              16
53 // gravity_upvalue_t            56
54 // gravity_closure_t            40
55 // gravity_list_t               48
56 // gravity_map_t                32
57 // gravity_callframe_t          48
58 // gravity_fiber_t              112
59 // gravity_class_t              88
60 // gravity_module_t             40
61 // gravity_instance_t           40
62 // gravity_string_t             48
63 // gravity_range_t              40
64 
65 #ifdef __cplusplus
66 extern "C" {
67 #endif
68 
69 #define GRAVITY_VERSION						"0.8.5"     // git tag 0.8.5
70 #define GRAVITY_VERSION_NUMBER				0x000805    // git push --tags
71 #define GRAVITY_BUILD_DATE                  __DATE__
72 
73 #ifndef GRAVITY_ENABLE_DOUBLE
74 #define GRAVITY_ENABLE_DOUBLE               1           // if 1 enable gravity_float_t to be a double (instead of a float)
75 #endif
76 
77 #ifndef GRAVITY_ENABLE_INT64
78 #define GRAVITY_ENABLE_INT64                1           // if 1 enable gravity_int_t to be a 64bit int (instead of a 32bit int)
79 #endif
80 
81 #ifndef GRAVITY_COMPUTED_GOTO
82 #define GRAVITY_COMPUTED_GOTO               1           // if 1 enable faster computed goto (instead of switch) for compilers that support it
83 #endif
84 
85 #ifndef GRAVITY_NULL_SILENT
86 #define GRAVITY_NULL_SILENT                 1           // if 1 then messages sent to null does not produce any runtime error
87 #endif
88 
89 #ifndef GRAVITY_MAP_DOTSUGAR
90 #define GRAVITY_MAP_DOTSUGAR                1           // if 1 then map objects can be accessed with both map[key] and map.key
91 #endif
92 
93 #if defined(_MSC_VER) && !defined(__clang__)
94 #undef GRAVITY_COMPUTED_GOTO
95 #define GRAVITY_COMPUTED_GOTO               0           // MSVC does not support computed goto (supported if using clang on Windows)
96 #endif
97 
98 #define MAIN_FUNCTION                       "main"
99 #define ITERATOR_INIT_FUNCTION              "iterate"
100 #define ITERATOR_NEXT_FUNCTION              "next"
101 #define INITMODULE_NAME                     "$moduleinit"
102 #define CLASS_INTERNAL_INIT_NAME            "$init"
103 #define CLASS_CONSTRUCTOR_NAME              "init"
104 #define CLASS_DESTRUCTOR_NAME               "deinit"
105 #define SELF_PARAMETER_NAME                 "self"
106 #define OUTER_IVAR_NAME                     "outer"
107 #define GETTER_FUNCTION_NAME                "get"
108 #define SETTER_FUNCTION_NAME                "set"
109 #define SETTER_PARAMETER_NAME               "value"
110 
111 #define GLOBALS_DEFAULT_SLOT                4096
112 #define CPOOL_INDEX_MAX                     4096        // 2^12
113 #define CPOOL_VALUE_SUPER                   CPOOL_INDEX_MAX+1
114 #define CPOOL_VALUE_NULL                    CPOOL_INDEX_MAX+2
115 #define CPOOL_VALUE_UNDEFINED               CPOOL_INDEX_MAX+3
116 #define CPOOL_VALUE_ARGUMENTS               CPOOL_INDEX_MAX+4
117 #define CPOOL_VALUE_TRUE                    CPOOL_INDEX_MAX+5
118 #define CPOOL_VALUE_FALSE                   CPOOL_INDEX_MAX+6
119 #define CPOOL_VALUE_FUNC                    CPOOL_INDEX_MAX+7
120 
121 #define MAX_INSTRUCTION_OPCODE              64              // 2^6
122 #define MAX_REGISTERS                       256             // 2^8
123 #define MAX_LOCALS                          200             // maximum number of local variables
124 #define MAX_UPVALUES                        200             // maximum number of upvalues
125 #define MAX_INLINE_INT                      131072          // 32 - 6 (OPCODE) - 8 (register) - 1 bit sign = 17
126 #define MAX_FIELDSxFLUSH                    64              // used in list/map serialization
127 #define MAX_IVARS                           768             // 2^10 - 2^8
128 #define MAX_ALLOCATION                      4194304         // 1024 * 1024 * 4 (about 4 millions entry)
129 #define MAX_CCALLS                          100             // default maximum number of nested C calls
130 #define MAX_MEMORY_BLOCK                    157286400       // 150MB
131 
132 #define DEFAULT_CONTEXT_SIZE                256             // default VM context entries (can grow)
133 #define DEFAULT_MINSTRING_SIZE              32              // minimum string allocation size
134 #define DEFAULT_MINSTACK_SIZE               256             // sizeof(gravity_value_t) * 256     = 16 * 256 => 4 KB
135 #define DEFAULT_MINCFRAME_SIZE              32              // sizeof(gravity_callframe_t) * 48  = 32 * 48 => 1.5 KB
136 #define DEFAULT_CG_THRESHOLD                5*1024*1024     // 5MB
137 #define DEFAULT_CG_MINTHRESHOLD             1024*1024       // 1MB
138 #define DEFAULT_CG_RATIO                    0.5             // 50%
139 
140 #define MAXNUM(a,b)                         ((a) > (b) ? a : b)
141 #define MINNUM(a,b)                         ((a) < (b) ? a : b)
142 #define EPSILON                             0.000001
143 #define MIN_LIST_RESIZE                     12              // value used when a List is resized
144 
145 #define GRAVITY_DATA_REGISTER               UINT32_MAX
146 #define GRAVITY_FIBER_REGISTER              UINT32_MAX-1
147 #define GRAVITY_MSG_REGISTER                UINT32_MAX-2
148 
149 #define GRAVITY_BRIDGE_INDEX                UINT16_MAX
150 #define GRAVITY_COMPUTED_INDEX              UINT16_MAX-1
151 
152 //DLL export/import support for Windows
153 #if !defined(GRAVITY_API) && defined(_WIN32) && defined(BUILD_GRAVITY_API)
154   #define GRAVITY_API __declspec(dllexport)
155 #else
156   #define GRAVITY_API
157 #endif
158 
159 // MARK: - STRUCT -
160 
161 // FLOAT_MAX_DECIMALS FROM https://stackoverflow.com/questions/13542944/how-many-significant-digits-have-floats-and-doubles-in-java
162 #if GRAVITY_ENABLE_DOUBLE
163 typedef double                              gravity_float_t;
164 #define GRAVITY_FLOAT_MAX                   DBL_MAX
165 #define GRAVITY_FLOAT_MIN                   DBL_MIN
166 #define FLOAT_MAX_DECIMALS                  16
167 #define FLOAT_EPSILON                       0.00001
168 #else
169 typedef float                               gravity_float_t;
170 #define GRAVITY_FLOAT_MAX                   FLT_MAX
171 #define GRAVITY_FLOAT_MIN                   FLT_MIN
172 #define FLOAT_MAX_DECIMALS                  7
173 #define FLOAT_EPSILON                       0.00001
174 #endif
175 
176 #if GRAVITY_ENABLE_INT64
177 typedef int64_t                             gravity_int_t;
178 #define GRAVITY_INT_MAX                     9223372036854775807
179 #define GRAVITY_INT_MIN                     (-GRAVITY_INT_MAX-1LL)
180 #else
181 typedef int32_t                             gravity_int_t;
182 #define GRAVITY_INT_MAX                     2147483647
183 #define GRAVITY_INT_MIN                     -2147483648
184 #endif
185 
186 // Forward references (an object ptr is just its isa pointer)
187 typedef struct gravity_class_s              gravity_class_t;
188 typedef struct gravity_class_s              gravity_object_t;
189 
190 // Everything inside Gravity VM is a gravity_value_t struct
191 typedef struct {
192     gravity_class_t         *isa;           // EVERY object must have an ISA pointer (8 bytes on a 64bit system)
193     union {                                 // union takes 8 bytes on a 64bit system
194         gravity_int_t       n;              // integer slot
195         gravity_float_t     f;              // float/double slot
196         gravity_object_t    *p;             // ptr to object slot
197     };
198 } gravity_value_t;
199 
200 // All VM shares the same foundation classes
201 extern gravity_class_t *gravity_class_object;
202 extern gravity_class_t *gravity_class_bool;
203 extern gravity_class_t *gravity_class_null;
204 extern gravity_class_t *gravity_class_int;
205 extern gravity_class_t *gravity_class_float;
206 extern gravity_class_t *gravity_class_function;
207 extern gravity_class_t *gravity_class_closure;
208 extern gravity_class_t *gravity_class_fiber;
209 extern gravity_class_t *gravity_class_class;
210 extern gravity_class_t *gravity_class_string;
211 extern gravity_class_t *gravity_class_instance;
212 extern gravity_class_t *gravity_class_list;
213 extern gravity_class_t *gravity_class_map;
214 extern gravity_class_t *gravity_class_module;
215 extern gravity_class_t *gravity_class_range;
216 extern gravity_class_t *gravity_class_upvalue;
217 
218 typedef marray_t(gravity_value_t)        gravity_value_r;   // array of values
219 #ifndef GRAVITY_HASH_DEFINED
220 #define GRAVITY_HASH_DEFINED
221 typedef struct gravity_hash_t            gravity_hash_t;    // forward declaration
222 #endif
223 
224 #ifndef GRAVITY_VM_DEFINED
225 #define GRAVITY_VM_DEFINED
226 typedef struct gravity_vm                gravity_vm;        // vm is an opaque data type
227 #endif
228 
229 typedef bool (*gravity_c_internal)(gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex);
230 typedef uint32_t (*gravity_gc_callback)(gravity_vm *vm, gravity_object_t *obj);
231 
232 typedef enum {
233     EXEC_TYPE_SPECIAL_GETTER = 0,       // index inside special gravity_function_t union to represent getter func
234     EXEC_TYPE_SPECIAL_SETTER = 1,       // index inside special gravity_function_t union to represent setter func
235 } gravity_special_index;
236 
237 typedef enum {
238     EXEC_TYPE_NATIVE,           // native gravity code (can change stack)
239     EXEC_TYPE_INTERNAL,         // c internal code (can change stack)
240     EXEC_TYPE_BRIDGED,          // external code to be executed by delegate (can change stack)
241     EXEC_TYPE_SPECIAL           // special execution like getter and setter (can be NATIVE, INTERNAL)
242 } gravity_exec_type;
243 
244 typedef struct gravity_gc_s {
245     bool                    isdark;         // flag to check if object is reachable
246     bool                    visited;        // flag to check if object has already been counted in memory size
247     gravity_gc_callback     free;           // free callback
248     gravity_gc_callback     size;           // size callback
249     gravity_gc_callback     blacken;        // blacken callback
250     gravity_object_t        *next;          // to track next object in the linked list
251 } gravity_gc_t;
252 
253 typedef struct {
254     gravity_class_t         *isa;           // to be an object
255     gravity_gc_t            gc;             // to be collectable by the garbage collector
256 
257     void                    *xdata;         // extra bridged data
258     const char              *identifier;    // function name
259     uint16_t                nparams;        // number of formal parameters
260     uint16_t                nlocals;        // number of local variables
261     uint16_t                ntemps;         // number of temporary values used
262     uint16_t                nupvalues;      // number of up values (if any)
263     gravity_exec_type       tag;            // can be EXEC_TYPE_NATIVE (default), EXEC_TYPE_INTERNAL, EXEC_TYPE_BRIDGED or EXEC_TYPE_SPECIAL
264     union {
265         // tag == EXEC_TYPE_NATIVE
266         struct {
267             gravity_value_r cpool;          // constant pool
268             gravity_value_r pvalue;         // default param value
269             gravity_value_r pname;          // param names
270             uint32_t        ninsts;         // number of instructions in the bytecode
271             uint32_t        *bytecode;      // bytecode as array of 32bit values
272             uint32_t        *lineno;        // debug: line number <-> current instruction relation
273             float           purity;         // experimental value
274             bool            useargs;        // flag set by the compiler to optimize the creation of the arguments array only if needed
275         };
276 
277         // tag == EXEC_TYPE_INTERNAL
278         gravity_c_internal  internal;       // function callback
279 
280         // tag == EXEC_TYPE_SPECIAL
281         struct {
282             uint16_t        index;          // property index to speed-up default getter and setter
283             void            *special[2];    // getter/setter functions
284         };
285     };
286 } gravity_function_t;
287 
288 typedef struct upvalue_s {
289     gravity_class_t         *isa;           // to be an object
290     gravity_gc_t            gc;             // to be collectable by the garbage collector
291 
292     gravity_value_t         *value;         // ptr to open value on the stack or to closed value on this struct
293     gravity_value_t         closed;         // copy of the value once has been closed
294     struct upvalue_s        *next;          // ptr to the next open upvalue
295 } gravity_upvalue_t;
296 
297 typedef struct gravity_closure_s {
298     gravity_class_t         *isa;           // to be an object
299     gravity_gc_t            gc;             // to be collectable by the garbage collector
300 
301     gravity_vm              *vm;            // vm bound to this closure (useful when executed from a bridge)
302     gravity_function_t      *f;             // function prototype
303     gravity_object_t        *context;       // context where the closure has been created (or object bound by the user)
304     gravity_upvalue_t       **upvalue;      // upvalue array
305     uint32_t                refcount;       // bridge language sometimes needs to protect closures from GC
306 } gravity_closure_t;
307 
308 typedef struct {
309     gravity_class_t         *isa;           // to be an object
310     gravity_gc_t            gc;             // to be collectable by the garbage collector
311 
312     gravity_value_r         array;          // dynamic array of values
313 } gravity_list_t;
314 
315 typedef struct {
316     gravity_class_t         *isa;           // to be an object
317     gravity_gc_t            gc;             // to be collectable by the garbage collector
318 
319     gravity_hash_t          *hash;          // hash table
320 } gravity_map_t;
321 
322 // Call frame used for function call
323 typedef struct {
324     uint32_t                *ip;            // instruction pointer
325     uint32_t                dest;           // destination register that will receive result
326     uint16_t                nargs;          // number of effective arguments passed to the function
327     gravity_list_t          *args;          // implicit special _args array
328     gravity_closure_t       *closure;       // closure being executed
329     gravity_value_t         *stackstart;    // first stack slot used by this call frame (receiver, plus parameters, locals and temporaries)
330     bool                    outloop;        // special case for events or native code executed from C that must be executed separately
331 } gravity_callframe_t;
332 
333 typedef enum {
334     FIBER_NEVER_EXECUTED = 0,
335     FIBER_ABORTED_WITH_ERROR = 1,
336     FIBER_TERMINATED = 2,
337     FIBER_RUNNING = 3,
338     FIBER_TRYING = 4
339 } gravity_fiber_status;
340 
341 // Fiber is the core executable model
342 typedef struct fiber_s {
343     gravity_class_t         *isa;           // to be an object
344     gravity_gc_t            gc;             // to be collectable by the garbage collector
345 
346     gravity_value_t         *stack;         // stack buffer (grown as needed and it holds locals and temps)
347     gravity_value_t         *stacktop;      // current stack ptr
348     uint32_t                stackalloc;     // number of allocated values
349 
350     gravity_callframe_t     *frames;        // callframes buffer (grown as needed but never shrinks)
351     uint32_t                nframes;        // number of frames currently in use
352     uint32_t                framesalloc;    // number of allocated frames
353 
354     gravity_upvalue_t       *upvalues;      // linked list used to keep track of open upvalues
355 
356     char                    *error;         // runtime error message
357     bool                    trying;         // set when the try flag is set by the user
358     struct fiber_s          *caller;        // optional caller fiber
359     gravity_value_t         result;         // end result of the fiber
360 
361     gravity_fiber_status    status;         // Fiber status (see enum)
362     nanotime_t              lasttime;       // last time Fiber has been called
363     gravity_float_t         timewait;       // used in yieldTime
364     gravity_float_t         elapsedtime;    // time passed since last execution
365 } gravity_fiber_t;
366 
367 typedef struct gravity_class_s {
368     gravity_class_t         *isa;           // to be an object
369     gravity_gc_t            gc;             // to be collectable by the garbage collector
370 
371     gravity_class_t         *objclass;      // meta class
372     const char              *identifier;    // class name
373     bool                    has_outer;      // flag used to automatically set ivar 0 to outer class (if any)
374     bool                    is_struct;      // flag to mark class as a struct
375     bool                    is_inited;      // flag used to mark already init meta-classes (to be improved)
376     bool                    unused;         // unused padding byte
377     void                    *xdata;         // extra bridged data
378     struct gravity_class_s  *superclass;    // reference to the super class
379     const char              *superlook;     // when a superclass is set to extern a runtime lookup must be performed
380     gravity_hash_t          *htable;        // hash table
381     uint32_t                nivars;         // number of instance variables
382 	//gravity_value_r			inames;			    // ivar names
383     gravity_value_t         *ivars;         // static variables
384 } gravity_class_s;
385 
386 typedef struct {
387     gravity_class_t         *isa;           // to be an object
388     gravity_gc_t            gc;             // to be collectable by the garbage collector
389 
390     const char              *identifier;    // module name
391     gravity_hash_t          *htable;        // hash table
392 } gravity_module_t;
393 
394 typedef struct {
395     gravity_class_t         *isa;           // to be an object
396     gravity_gc_t            gc;             // to be collectable by the garbage collector
397 
398     gravity_class_t         *objclass;      // real instance class
399     void                    *xdata;         // extra bridged data
400     gravity_value_t         *ivars;         // instance variables
401 } gravity_instance_t;
402 
403 typedef struct {
404     gravity_class_t         *isa;           // to be an object
405     gravity_gc_t            gc;             // to be collectable by the garbage collector
406 
407     char                    *s;             // pointer to NULL terminated string
408     uint32_t                hash;           // string hash (type to be keept in sync with gravity_hash_size_t)
409     uint32_t                len;            // actual string length
410     uint32_t                alloc;          // bytes allocated for string
411 } gravity_string_t;
412 
413 typedef struct {
414     gravity_class_t         *isa;           // to be an object
415     gravity_gc_t            gc;             // to be collectable by the garbage collector
416 
417     gravity_int_t           from;           // range start
418     gravity_int_t           to;             // range end
419 } gravity_range_t;
420 
421 typedef void (*code_dump_function) (void *code);
422 typedef marray_t(gravity_function_t*)   gravity_function_r;     // array of functions
423 typedef marray_t(gravity_class_t*)      gravity_class_r;        // array of classes
424 typedef marray_t(gravity_object_t*)     gravity_object_r;       // array of objects
425 
426 // MARK: - MODULE -
427 GRAVITY_API gravity_module_t   *gravity_module_new (gravity_vm *vm, const char *identifier);
428 GRAVITY_API void                gravity_module_free (gravity_vm *vm, gravity_module_t *m);
429 GRAVITY_API void                gravity_module_blacken (gravity_vm *vm, gravity_module_t *m);
430 GRAVITY_API uint32_t            gravity_module_size (gravity_vm *vm, gravity_module_t *m);
431 
432 // MARK: - FUNCTION -
433 GRAVITY_API uint32_t           *gravity_bytecode_deserialize (const char *buffer, size_t len, uint32_t *ninst);
434 GRAVITY_API void                gravity_function_blacken (gravity_vm *vm, gravity_function_t *f);
435 GRAVITY_API uint16_t            gravity_function_cpool_add (gravity_vm *vm, gravity_function_t *f, gravity_value_t v);
436 GRAVITY_API gravity_value_t     gravity_function_cpool_get (gravity_function_t *f, uint16_t i);
437 GRAVITY_API gravity_function_t *gravity_function_deserialize (gravity_vm *vm, json_value *json);
438 GRAVITY_API void                gravity_function_dump (gravity_function_t *f, code_dump_function codef);
439 GRAVITY_API void                gravity_function_free (gravity_vm *vm, gravity_function_t *f);
440 GRAVITY_API gravity_function_t *gravity_function_new (gravity_vm *vm, const char *identifier, uint16_t nparams, uint16_t nlocals, uint16_t ntemps, void *code);
441 GRAVITY_API gravity_function_t *gravity_function_new_bridged (gravity_vm *vm, const char *identifier, void *xdata);
442 GRAVITY_API gravity_function_t *gravity_function_new_internal (gravity_vm *vm, const char *identifier, gravity_c_internal exec, uint16_t nparams);
443 GRAVITY_API gravity_function_t *gravity_function_new_special (gravity_vm *vm, const char *identifier, uint16_t index, void *getter, void *setter);
444 GRAVITY_API gravity_list_t     *gravity_function_params_get (gravity_vm *vm, gravity_function_t *f);
445 GRAVITY_API void                gravity_function_serialize (gravity_function_t *f, json_t *json);
446 GRAVITY_API void                gravity_function_setouter (gravity_function_t *f, gravity_object_t *outer);
447 GRAVITY_API void                gravity_function_setxdata (gravity_function_t *f, void *xdata);
448 GRAVITY_API uint32_t            gravity_function_size (gravity_vm *vm, gravity_function_t *f);
449 
450 // MARK: - CLOSURE -
451 GRAVITY_API void                gravity_closure_blacken (gravity_vm *vm, gravity_closure_t *closure);
452 GRAVITY_API void                gravity_closure_dec_refcount (gravity_vm *vm, gravity_closure_t *closure);
453 GRAVITY_API void                gravity_closure_inc_refcount (gravity_vm *vm, gravity_closure_t *closure);
454 GRAVITY_API void                gravity_closure_free (gravity_vm *vm, gravity_closure_t *closure);
455 GRAVITY_API uint32_t            gravity_closure_size (gravity_vm *vm, gravity_closure_t *closure);
456 GRAVITY_API gravity_closure_t  *gravity_closure_new (gravity_vm *vm, gravity_function_t *f);
457 
458 // MARK: - UPVALUE -
459 GRAVITY_API void                gravity_upvalue_blacken (gravity_vm *vm, gravity_upvalue_t *upvalue);
460 GRAVITY_API void                gravity_upvalue_free(gravity_vm *vm, gravity_upvalue_t *upvalue);
461 GRAVITY_API gravity_upvalue_t  *gravity_upvalue_new (gravity_vm *vm, gravity_value_t *value);
462 GRAVITY_API uint32_t            gravity_upvalue_size (gravity_vm *vm, gravity_upvalue_t *upvalue);
463 
464 // MARK: - CLASS -
465 GRAVITY_API void                gravity_class_blacken (gravity_vm *vm, gravity_class_t *c);
466 GRAVITY_API int16_t             gravity_class_add_ivar (gravity_class_t *c, const char *identifier);
467 GRAVITY_API void                gravity_class_bind (gravity_class_t *c, const char *key, gravity_value_t value);
468 GRAVITY_API uint32_t            gravity_class_count_ivars (gravity_class_t *c);
469 GRAVITY_API gravity_class_t    *gravity_class_deserialize (gravity_vm *vm, json_value *json);
470 GRAVITY_API void                gravity_class_dump (gravity_class_t *c);
471 GRAVITY_API void                gravity_class_free (gravity_vm *vm, gravity_class_t *c);
472 GRAVITY_API void                gravity_class_free_core (gravity_vm *vm, gravity_class_t *c);
473 GRAVITY_API gravity_class_t    *gravity_class_get_meta (gravity_class_t *c);
474 GRAVITY_API gravity_class_t    *gravity_class_getsuper (gravity_class_t *c);
475 GRAVITY_API bool                gravity_class_grow (gravity_class_t *c, uint32_t n);
476 GRAVITY_API bool                gravity_class_is_anon (gravity_class_t *c);
477 GRAVITY_API bool                gravity_class_is_meta (gravity_class_t *c);
478 GRAVITY_API gravity_object_t   *gravity_class_lookup (gravity_class_t *c, gravity_value_t key);
479 GRAVITY_API gravity_closure_t  *gravity_class_lookup_closure (gravity_class_t *c, gravity_value_t key);
480 GRAVITY_API gravity_closure_t  *gravity_class_lookup_constructor (gravity_class_t *c, uint32_t nparams);
481 GRAVITY_API gravity_class_t    *gravity_class_lookup_class_identifier (gravity_class_t *c, const char *identifier);
482 GRAVITY_API gravity_class_t    *gravity_class_new_pair (gravity_vm *vm, const char *identifier, gravity_class_t *superclass, uint32_t nivar, uint32_t nsvar);
483 GRAVITY_API gravity_class_t    *gravity_class_new_single (gravity_vm *vm, const char *identifier, uint32_t nfields);
484 GRAVITY_API void                gravity_class_serialize (gravity_class_t *c, json_t *json);
485 GRAVITY_API bool                gravity_class_setsuper (gravity_class_t *subclass, gravity_class_t *superclass);
486 GRAVITY_API bool                gravity_class_setsuper_extern (gravity_class_t *baseclass, const char *identifier);
487 GRAVITY_API void                gravity_class_setxdata (gravity_class_t *c, void *xdata);
488 GRAVITY_API uint32_t            gravity_class_size (gravity_vm *vm, gravity_class_t *c);
489 
490 // MARK: - FIBER -
491 GRAVITY_API void                gravity_fiber_blacken (gravity_vm *vm, gravity_fiber_t *fiber);
492 GRAVITY_API void                gravity_fiber_free (gravity_vm *vm, gravity_fiber_t *fiber);
493 GRAVITY_API gravity_fiber_t    *gravity_fiber_new (gravity_vm *vm, gravity_closure_t *closure, uint32_t nstack, uint32_t nframes);
494 GRAVITY_API void                gravity_fiber_reassign (gravity_fiber_t *fiber, gravity_closure_t *closure, uint16_t nargs);
495 GRAVITY_API void                gravity_fiber_reset (gravity_fiber_t *fiber);
496 GRAVITY_API void                gravity_fiber_seterror (gravity_fiber_t *fiber, const char *error);
497 GRAVITY_API uint32_t            gravity_fiber_size (gravity_vm *vm, gravity_fiber_t *fiber);
498 
499 // MARK: - INSTANCE -
500 GRAVITY_API void                gravity_instance_blacken (gravity_vm *vm, gravity_instance_t *i);
501 GRAVITY_API gravity_instance_t *gravity_instance_clone (gravity_vm *vm, gravity_instance_t *src_instance);
502 GRAVITY_API void                gravity_instance_deinit (gravity_vm *vm, gravity_instance_t *i);
503 GRAVITY_API void                gravity_instance_free (gravity_vm *vm, gravity_instance_t *i);
504 GRAVITY_API bool                gravity_instance_isstruct (gravity_instance_t *i);
505 GRAVITY_API gravity_closure_t  *gravity_instance_lookup_event (gravity_instance_t *i, const char *name);
506 GRAVITY_API gravity_value_t     gravity_instance_lookup_property (gravity_vm *vm, gravity_instance_t *i, gravity_value_t key);
507 GRAVITY_API gravity_instance_t *gravity_instance_new (gravity_vm *vm, gravity_class_t *c);
508 GRAVITY_API void                gravity_instance_serialize (gravity_instance_t *i, json_t *json);
509 GRAVITY_API void                gravity_instance_setivar (gravity_instance_t *instance, uint32_t idx, gravity_value_t value);
510 GRAVITY_API void                gravity_instance_setxdata (gravity_instance_t *i, void *xdata);
511 GRAVITY_API uint32_t            gravity_instance_size (gravity_vm *vm, gravity_instance_t *i);
512 
513 // MARK: - VALUE -
514 GRAVITY_API void                gravity_value_blacken (gravity_vm *vm, gravity_value_t v);
515 GRAVITY_API void                gravity_value_dump (gravity_vm *vm, gravity_value_t v, char *buffer, uint16_t len);
516 GRAVITY_API bool                gravity_value_equals (gravity_value_t v1, gravity_value_t v2);
517 GRAVITY_API void                gravity_value_free (gravity_vm *vm, gravity_value_t v);
518 GRAVITY_API gravity_class_t    *gravity_value_getclass (gravity_value_t v);
519 GRAVITY_API gravity_class_t    *gravity_value_getsuper (gravity_value_t v);
520 GRAVITY_API uint32_t            gravity_value_hash (gravity_value_t value);
521 GRAVITY_API bool                gravity_value_isobject (gravity_value_t v);
522 GRAVITY_API const char         *gravity_value_name (gravity_value_t value);
523 GRAVITY_API void                gravity_value_serialize (const char *key, gravity_value_t v, json_t *json);
524 GRAVITY_API uint32_t            gravity_value_size (gravity_vm *vm, gravity_value_t v);
525 GRAVITY_API bool                gravity_value_vm_equals (gravity_vm *vm, gravity_value_t v1, gravity_value_t v2);
526 GRAVITY_API void               *gravity_value_xdata (gravity_value_t value);
527 
528 GRAVITY_API gravity_value_t     gravity_value_from_bool(bool b);
529 GRAVITY_API gravity_value_t     gravity_value_from_error(const char* msg);
530 GRAVITY_API gravity_value_t     gravity_value_from_float(gravity_float_t f);
531 GRAVITY_API gravity_value_t     gravity_value_from_int(gravity_int_t n);
532 GRAVITY_API gravity_value_t     gravity_value_from_null(void);
533 GRAVITY_API gravity_value_t     gravity_value_from_object(void *obj);
534 GRAVITY_API gravity_value_t     gravity_value_from_undefined(void);
535 
536 // MARK: - OBJECT -
537 GRAVITY_API void                gravity_object_blacken (gravity_vm *vm, gravity_object_t *obj);
538 GRAVITY_API const char         *gravity_object_debug (gravity_object_t *obj, bool is_free);
539 GRAVITY_API gravity_object_t   *gravity_object_deserialize (gravity_vm *vm, json_value *entry);
540 GRAVITY_API void                gravity_object_free (gravity_vm *vm, gravity_object_t *obj);
541 GRAVITY_API void                gravity_object_serialize (gravity_object_t *obj, json_t *json);
542 GRAVITY_API uint32_t            gravity_object_size (gravity_vm *vm, gravity_object_t *obj);
543 
544 // MARK: - LIST -
545 GRAVITY_API void                gravity_list_append_list (gravity_vm *vm, gravity_list_t *list1, gravity_list_t *list2);
546 GRAVITY_API void                gravity_list_blacken (gravity_vm *vm, gravity_list_t *list);
547 GRAVITY_API void                gravity_list_free (gravity_vm *vm, gravity_list_t *list);
548 GRAVITY_API gravity_list_t     *gravity_list_from_array (gravity_vm *vm, uint32_t n, gravity_value_t *p);
549 GRAVITY_API gravity_list_t     *gravity_list_new (gravity_vm *vm, uint32_t n);
550 GRAVITY_API uint32_t            gravity_list_size (gravity_vm *vm, gravity_list_t *list);
551 
552 // MARK: - MAP -
553 GRAVITY_API void                gravity_map_blacken (gravity_vm *vm, gravity_map_t *map);
554 GRAVITY_API void                gravity_map_append_map (gravity_vm *vm, gravity_map_t *map1, gravity_map_t *map2);
555 GRAVITY_API void                gravity_map_free (gravity_vm *vm, gravity_map_t *map);
556 GRAVITY_API void                gravity_map_insert (gravity_vm *vm, gravity_map_t *map, gravity_value_t key, gravity_value_t value);
557 GRAVITY_API gravity_map_t      *gravity_map_new (gravity_vm *vm, uint32_t n);
558 GRAVITY_API uint32_t            gravity_map_size (gravity_vm *vm, gravity_map_t *map);
559 
560 // MARK: - RANGE -
561 GRAVITY_API void                gravity_range_blacken (gravity_vm *vm, gravity_range_t *range);
562 GRAVITY_API gravity_range_t    *gravity_range_deserialize (gravity_vm *vm, json_value *json);
563 GRAVITY_API void                gravity_range_free (gravity_vm *vm, gravity_range_t *range);
564 GRAVITY_API gravity_range_t    *gravity_range_new (gravity_vm *vm, gravity_int_t from, gravity_int_t to, bool inclusive);
565 GRAVITY_API void                gravity_range_serialize (gravity_range_t *r, json_t *json);
566 GRAVITY_API uint32_t            gravity_range_size (gravity_vm *vm, gravity_range_t *range);
567 
568 /// MARK: - STRING -
569 GRAVITY_API void                gravity_string_blacken (gravity_vm *vm, gravity_string_t *string);
570 GRAVITY_API void                gravity_string_free (gravity_vm *vm, gravity_string_t *value);
571 GRAVITY_API gravity_string_t   *gravity_string_new (gravity_vm *vm, char *s, uint32_t len, uint32_t alloc);
572 GRAVITY_API void                gravity_string_set(gravity_string_t *obj, char *s, uint32_t len);
573 GRAVITY_API uint32_t            gravity_string_size (gravity_vm *vm, gravity_string_t *string);
574 GRAVITY_API gravity_value_t     gravity_string_to_value (gravity_vm *vm, const char *s, uint32_t len);
575 
576 #ifdef __cplusplus
577 }
578 #endif
579 
580 #endif
581