#ifndef __GRAVITY_VALUES__
#define __GRAVITY_VALUES__
#include "gravity_memory.h"
#include "gravity_utils.h"
#include "gravity_array.h"
#include "gravity_json.h"
#include "debug_macros.h"
#define GRAVITY_VERSION "0.2.5"
#define GRAVITY_VERSION_NUMBER 0x000205
#define GRAVITY_BUILD_DATE __DATE__
#define GRAVITY_ENABLE_DOUBLE 1
#define GRAVITY_ENABLE_INT64 1
#define GRAVITY_COMPUTED_GOTO 1
#define GRAVITY_NULL_SILENT 1
#define GRAVITY_MAP_DOTSUGAR 0
#define MAIN_FUNCTION "main"
#define ITERATOR_INIT_FUNCTION "iterate"
#define ITERATOR_NEXT_FUNCTION "next"
#define INITMODULE_NAME "$moduleinit"
#define CLASS_INTERNAL_INIT_NAME "$init"
#define CLASS_CONSTRUCTOR_NAME "init"
#define CLASS_DESTRUCTOR_NAME "deinit"
#define SELF_PARAMETER_NAME "self"
#define OUTER_IVAR_NAME "outer"
#define GETTER_FUNCTION_NAME "get"
#define SETTER_FUNCTION_NAME "set"
#define SETTER_PARAMETER_NAME "value"
#define GLOBALS_DEFAULT_SLOT 4096
#define CPOOL_INDEX_MAX 4096
#define CPOOL_VALUE_SUPER CPOOL_INDEX_MAX+1
#define CPOOL_VALUE_NULL CPOOL_INDEX_MAX+2
#define CPOOL_VALUE_UNDEFINED CPOOL_INDEX_MAX+3
#define CPOOL_VALUE_ARGUMENTS CPOOL_INDEX_MAX+4
#define CPOOL_VALUE_TRUE CPOOL_INDEX_MAX+5
#define CPOOL_VALUE_FALSE CPOOL_INDEX_MAX+6
#define CPOOL_VALUE_FUNC CPOOL_INDEX_MAX+7
#define MAX_INSTRUCTION_OPCODE 64
#define MAX_REGISTERS 256
#define MAX_LOCALS 200
#define MAX_UPVALUES 200
#define MAX_INLINE_INT 131072
#define MAX_FIELDSxFLUSH 64
#define MAX_IVARS 768
#define DEFAULT_CONTEXT_SIZE 256
#define DEFAULT_MINSTRING_SIZE 64
#define DEFAULT_MINSTACK_SIZE 256
#define DEFAULT_MINCFRAME_SIZE 32
#define DEFAULT_CG_THRESHOLD 5*1024*1024
#define DEFAULT_CG_MINTHRESHOLD 1024*1024
#define DEFAULT_CG_RATIO 0.5
#define MAXNUM(a,b) ((a) > (b) ? a : b)
#define MINNUM(a,b) ((a) < (b) ? a : b)
#define EPSILON 0.000001
#define GRAVITY_DATA_REGISTER UINT32_MAX
#define GRAVITY_FIBER_REGISTER UINT32_MAX-1
#define GRAVITY_MSG_REGISTER UINT32_MAX-2
#define GRAVITY_BRIDGE_INDEX UINT16_MAX
#define GRAVITY_COMPUTED_INDEX UINT16_MAX-1
#if GRAVITY_ENABLE_DOUBLE
typedef double gravity_float_t;
#else
typedef float gravity_float_t;
#endif
#if GRAVITY_ENABLE_INT64
typedef int64_t gravity_int_t;
#else
typedef int32_t gravity_int_t;
#endif
typedef struct gravity_class_s gravity_class_t;
typedef struct gravity_class_s gravity_object_t;
typedef struct {
gravity_class_t *isa;
union {
gravity_int_t n;
gravity_float_t f;
gravity_object_t *p;
};
} gravity_value_t;
extern gravity_class_t *gravity_class_object;
extern gravity_class_t *gravity_class_bool;
extern gravity_class_t *gravity_class_null;
extern gravity_class_t *gravity_class_undefined;
extern gravity_class_t *gravity_class_int;
extern gravity_class_t *gravity_class_float;
extern gravity_class_t *gravity_class_function;
extern gravity_class_t *gravity_class_closure;
extern gravity_class_t *gravity_class_fiber;
extern gravity_class_t *gravity_class_class;
extern gravity_class_t *gravity_class_string;
extern gravity_class_t *gravity_class_instance;
extern gravity_class_t *gravity_class_list;
extern gravity_class_t *gravity_class_map;
extern gravity_class_t *gravity_class_module;
extern gravity_class_t *gravity_class_range;
extern gravity_class_t *gravity_class_upvalue;
typedef marray_t(gravity_value_t) gravity_value_r;
typedef struct gravity_hash_t gravity_hash_t;
typedef struct gravity_vm gravity_vm;
typedef bool (*gravity_c_internal)(gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex);
typedef enum {
EXEC_TYPE_SPECIAL_GETTER = 0,
EXEC_TYPE_SPECIAL_SETTER = 1,
} gravity_special_index;
typedef enum {
EXEC_TYPE_NATIVE,
EXEC_TYPE_INTERNAL,
EXEC_TYPE_BRIDGED,
EXEC_TYPE_SPECIAL
} gravity_exec_type;
typedef struct {
bool isdark;
gravity_object_t *next;
} gravity_gc_t;
typedef struct {
gravity_class_t *isa;
gravity_gc_t gc;
void *xdata;
const char *identifier;
uint16_t nparams;
uint16_t nlocals;
uint16_t ntemps;
uint16_t nupvalues;
gravity_exec_type tag;
union {
struct {
gravity_value_r cpool;
uint32_t ninsts;
uint32_t *bytecode;
float purity;
bool useargs;
};
gravity_c_internal internal;
struct {
uint16_t index;
void *special[2];
};
};
} gravity_function_t;
typedef struct upvalue_s {
gravity_class_t *isa;
gravity_gc_t gc;
gravity_value_t *value;
gravity_value_t closed;
struct upvalue_s *next;
} gravity_upvalue_t;
typedef struct {
gravity_class_t *isa;
gravity_gc_t gc;
gravity_function_t *f;
gravity_upvalue_t **upvalue;
} gravity_closure_t;
typedef struct {
gravity_class_t *isa;
gravity_gc_t gc;
gravity_value_r array;
} gravity_list_t;
typedef struct {
gravity_class_t *isa;
gravity_gc_t gc;
gravity_hash_t *hash;
} gravity_map_t;
typedef struct {
uint32_t *ip;
uint32_t dest;
uint16_t nargs;
gravity_list_t *args;
gravity_closure_t *closure;
gravity_value_t *stackstart;
bool outloop;
} gravity_callframe_t;
typedef struct fiber_s {
gravity_class_t *isa;
gravity_gc_t gc;
gravity_value_t *stack;
gravity_value_t *stacktop;
uint32_t stackalloc;
gravity_callframe_t *frames;
uint32_t nframes;
uint32_t framesalloc;
gravity_upvalue_t *upvalues;
char *error;
bool trying;
struct fiber_s *caller;
gravity_value_t result;
} gravity_fiber_t;
typedef struct gravity_class_s {
gravity_class_t *isa;
gravity_gc_t gc;
gravity_class_t *objclass;
const char *identifier;
bool has_outer;
bool is_struct;
bool is_inited;
bool unused;
void *xdata;
struct gravity_class_s *superclass;
gravity_hash_t *htable;
uint32_t nivars;
gravity_value_t *ivars;
} gravity_class_t;
typedef struct {
gravity_class_t *isa;
gravity_gc_t gc;
const char *identifier;
gravity_hash_t *htable;
} gravity_module_t;
typedef struct {
gravity_class_t *isa;
gravity_gc_t gc;
gravity_class_t *objclass;
void *xdata;
gravity_value_t ivars[];
} gravity_instance_t;
typedef struct {
gravity_class_t *isa;
gravity_gc_t gc;
char *s;
uint32_t hash;
uint32_t len;
uint32_t alloc;
} gravity_string_t;
typedef struct {
gravity_class_t *isa;
gravity_gc_t gc;
gravity_int_t from;
gravity_int_t to;
} gravity_range_t;
typedef void (*code_dump_function) (void *code);
typedef marray_t(gravity_function_t*) gravity_function_r;
typedef marray_t(gravity_class_t*) gravity_class_r;
typedef marray_t(gravity_object_t*) gravity_object_r;
gravity_module_t *gravity_module_new (gravity_vm *vm, const char *identifier);
void gravity_module_free (gravity_vm *vm, gravity_module_t *m);
void gravity_module_blacken (gravity_vm *vm, gravity_module_t *m);
uint32_t gravity_module_size (gravity_vm *vm, gravity_module_t *m);
gravity_function_t *gravity_function_new (gravity_vm *vm, const char *identifier, uint16_t nparams, uint16_t nlocals, uint16_t ntemps, void *code);
gravity_function_t *gravity_function_new_internal (gravity_vm *vm, const char *identifier, gravity_c_internal exec, uint16_t nparams);
gravity_function_t *gravity_function_new_special (gravity_vm *vm, const char *identifier, uint16_t index, void *getter, void *setter);
gravity_function_t *gravity_function_new_bridged (gravity_vm *vm, const char *identifier, void *xdata);
uint16_t gravity_function_cpool_add (gravity_vm *vm, gravity_function_t *f, gravity_value_t v);
gravity_value_t gravity_function_cpool_get (gravity_function_t *f, uint16_t i);
void gravity_function_dump (gravity_function_t *f, code_dump_function codef);
void gravity_function_setouter (gravity_function_t *f, gravity_object_t *outer);
void gravity_function_setxdata (gravity_function_t *f, void *xdata);
void gravity_function_serialize (gravity_function_t *f, json_t *json);
uint32_t *gravity_bytecode_deserialize (const char *buffer, size_t len, uint32_t *ninst);
gravity_function_t *gravity_function_deserialize (gravity_vm *vm, json_value *json);
void gravity_function_free (gravity_vm *vm, gravity_function_t *f);
void gravity_function_blacken (gravity_vm *vm, gravity_function_t *f);
uint32_t gravity_function_size (gravity_vm *vm, gravity_function_t *f);
gravity_closure_t *gravity_closure_new (gravity_vm *vm, gravity_function_t *f);
void gravity_closure_free (gravity_vm *vm, gravity_closure_t *closure);
uint32_t gravity_closure_size (gravity_vm *vm, gravity_closure_t *closure);
void gravity_closure_blacken (gravity_vm *vm, gravity_closure_t *closure);
gravity_upvalue_t *gravity_upvalue_new (gravity_vm *vm, gravity_value_t *value);
uint32_t gravity_upvalue_size (gravity_vm *vm, gravity_upvalue_t *upvalue);
void gravity_upvalue_blacken (gravity_vm *vm, gravity_upvalue_t *upvalue);
void gravity_upvalue_free(gravity_vm *vm, gravity_upvalue_t *upvalue);
void gravity_class_bind (gravity_class_t *c, const char *key, gravity_value_t value);
gravity_class_t *gravity_class_getsuper (gravity_class_t *c);
bool gravity_class_grow (gravity_class_t *c, uint32_t n);
bool gravity_class_setsuper (gravity_class_t *subclass, gravity_class_t *superclass);
gravity_class_t *gravity_class_new_single (gravity_vm *vm, const char *identifier, uint32_t nfields);
gravity_class_t *gravity_class_new_pair (gravity_vm *vm, const char *identifier, gravity_class_t *superclass, uint32_t nivar, uint32_t nsvar);
gravity_class_t *gravity_class_get_meta (gravity_class_t *c);
bool gravity_class_is_meta (gravity_class_t *c);
uint32_t gravity_class_count_ivars (gravity_class_t *c);
void gravity_class_dump (gravity_class_t *c);
void gravity_class_setxdata (gravity_class_t *c, void *xdata);
int16_t gravity_class_add_ivar (gravity_class_t *c, const char *identifier);
void gravity_class_serialize (gravity_class_t *c, json_t *json);
gravity_class_t *gravity_class_deserialize (gravity_vm *vm, json_value *json);
void gravity_class_free (gravity_vm *vm, gravity_class_t *c);
void gravity_class_free_core (gravity_vm *vm, gravity_class_t *c);
gravity_object_t *gravity_class_lookup (gravity_class_t *c, gravity_value_t key);
gravity_closure_t *gravity_class_lookup_closure (gravity_class_t *c, gravity_value_t key);
gravity_closure_t *gravity_class_lookup_constructor (gravity_class_t *c, uint32_t nparams);
void gravity_class_blacken (gravity_vm *vm, gravity_class_t *c);
uint32_t gravity_class_size (gravity_vm *vm, gravity_class_t *c);
gravity_fiber_t *gravity_fiber_new (gravity_vm *vm, gravity_closure_t *closure, uint32_t nstack, uint32_t nframes);
void gravity_fiber_reassign (gravity_fiber_t *fiber, gravity_closure_t *closure, uint16_t nargs);
void gravity_fiber_seterror (gravity_fiber_t *fiber, const char *error);
void gravity_fiber_free (gravity_vm *vm, gravity_fiber_t *fiber);
void gravity_fiber_blacken (gravity_vm *vm, gravity_fiber_t *fiber);
uint32_t gravity_fiber_size (gravity_vm *vm, gravity_fiber_t *fiber);
gravity_instance_t *gravity_instance_new (gravity_vm *vm, gravity_class_t *c);
gravity_instance_t *gravity_instance_dup (gravity_vm *vm, gravity_instance_t *src);
void gravity_instance_setivar (gravity_instance_t *instance, uint32_t idx, gravity_value_t value);
void gravity_instance_setxdata (gravity_instance_t *i, void *xdata);
void gravity_instance_free (gravity_vm *vm, gravity_instance_t *i);
gravity_closure_t *gravity_instance_lookup_event (gravity_instance_t *i, const char *name);
void gravity_instance_blacken (gravity_vm *vm, gravity_instance_t *i);
uint32_t gravity_instance_size (gravity_vm *vm, gravity_instance_t *i);
bool gravity_value_equals (gravity_value_t v1, gravity_value_t v2);
uint32_t gravity_value_hash (gravity_value_t value);
gravity_class_t *gravity_value_getclass (gravity_value_t v);
gravity_class_t *gravity_value_getsuper (gravity_value_t v);
void gravity_value_free (gravity_vm *vm, gravity_value_t v);
void gravity_value_serialize (gravity_value_t v, json_t *json);
void gravity_value_dump (gravity_value_t v, char *buffer, uint16_t len);
bool gravity_value_isobject (gravity_value_t v);
void *gravity_value_xdata (gravity_value_t value);
void gravity_value_blacken (gravity_vm *vm, gravity_value_t v);
uint32_t gravity_value_size (gravity_vm *vm, gravity_value_t v);
void gravity_object_serialize (gravity_object_t *obj, json_t *json);
bool gravity_object_deserialize (gravity_vm *vm, json_value *entry, gravity_object_t **obj);
void gravity_object_free (gravity_vm *vm, gravity_object_t *obj);
void gravity_object_blacken (gravity_vm *vm, gravity_object_t *obj);
uint32_t gravity_object_size (gravity_vm *vm, gravity_object_t *obj);
const char *gravity_object_debug (gravity_object_t *obj);
gravity_list_t *gravity_list_new (gravity_vm *vm, uint32_t n);
gravity_list_t *gravity_list_from_array (gravity_vm *vm, uint32_t n, gravity_value_t *p);
void gravity_list_free (gravity_vm *vm, gravity_list_t *list);
void gravity_list_append_list (gravity_vm *vm, gravity_list_t *list1, gravity_list_t *list2);
void gravity_list_blacken (gravity_vm *vm, gravity_list_t *list);
uint32_t gravity_list_size (gravity_vm *vm, gravity_list_t *list);
gravity_map_t *gravity_map_new (gravity_vm *vm, uint32_t n);
void gravity_map_free (gravity_vm *vm, gravity_map_t *map);
void gravity_map_append_map (gravity_vm *vm, gravity_map_t *map1, gravity_map_t *map2);
void gravity_map_insert (gravity_vm *vm, gravity_map_t *map, gravity_value_t key, gravity_value_t value);
void gravity_map_blacken (gravity_vm *vm, gravity_map_t *map);
uint32_t gravity_map_size (gravity_vm *vm, gravity_map_t *map);
gravity_range_t *gravity_range_new (gravity_vm *vm, gravity_int_t from, gravity_int_t to, bool inclusive);
void gravity_range_free (gravity_vm *vm, gravity_range_t *range);
void gravity_range_blacken (gravity_vm *vm, gravity_range_t *range);
uint32_t gravity_range_size (gravity_vm *vm, gravity_range_t *range);
gravity_value_t gravity_string_to_value (gravity_vm *vm, const char *s, uint32_t len);
gravity_string_t *gravity_string_new (gravity_vm *vm, char *s, uint32_t len, uint32_t alloc);
inline void gravity_string_set (gravity_string_t *obj, char *s, uint32_t len);
void gravity_string_free (gravity_vm *vm, gravity_string_t *value);
void gravity_string_blacken (gravity_vm *vm, gravity_string_t *string);
uint32_t gravity_string_size (gravity_vm *vm, gravity_string_t *string);
void gravity_hash_keyvaluefree (gravity_hash_t *table, gravity_value_t key, gravity_value_t value, void *data);
void gravity_hash_keyfree (gravity_hash_t *table, gravity_value_t key, gravity_value_t value, void *data);
void gravity_hash_valuefree (gravity_hash_t *table, gravity_value_t key, gravity_value_t value, void *data);
#endif