MIRROR: javascript for 馃悳's, a tiny runtime with big ambitions
1#ifndef ANT_OBJECT_H
2#define ANT_OBJECT_H
3
4#include "types.h"
5#include "sugar.h"
6#include "shapes.h"
7
8#include <utarray.h>
9#include <stdbool.h>
10#include <stddef.h>
11#include <stdint.h>
12
13typedef struct {
14 ant_value_t (*getter)(ant_t *, ant_value_t, const char *, size_t);
15 bool (*setter)(ant_t *, ant_value_t, const char *, size_t, ant_value_t);
16 bool (*deleter)(ant_t *, ant_value_t, const char *, size_t);
17} ant_exotic_ops_t;
18
19typedef struct promise_handler {
20 ant_value_t onFulfilled;
21 ant_value_t onRejected;
22 ant_value_t nextPromise;
23 struct coroutine *await_coro;
24} promise_handler_t;
25
26typedef struct {
27 ant_value_t value;
28 ant_value_t trigger_parent;
29 promise_handler_t inline_handler;
30 UT_array *handlers;
31 uint32_t promise_id;
32 uint16_t handler_count;
33 uint8_t state;
34 bool trigger_queued;
35 bool has_rejection_handler;
36 bool processing;
37 bool unhandled_reported;
38} ant_promise_state_t;
39
40typedef struct {
41 ant_value_t target;
42 ant_value_t handler;
43 bool revoked;
44} ant_proxy_state_t;
45
46typedef struct ant_object {
47 struct ant_object *next;
48
49 ant_value_t proto;
50 ant_shape_t *shape;
51 ant_value_t *overflow_prop;
52
53 const ant_exotic_ops_t *exotic_ops;
54 ant_value_t (*exotic_keys)(ant_t *, ant_value_t);
55
56 ant_promise_state_t *promise_state;
57 ant_proxy_state_t *proxy_state;
58 ant_value_t *extra_slots;
59
60 struct ant_object *gc_pending_next;
61 void (*finalizer)(ant_t *, struct ant_object *);
62 ant_value_t inobj[ANT_INOBJ_MAX_SLOTS];
63
64 struct {
65 void *ptr;
66 uint32_t tag;
67 } native;
68
69 union {
70 struct { ant_value_t *data; uint32_t len; uint32_t cap; } array;
71 struct { sv_closure_t *closure; } func;
72 struct { ant_value_t value; } data;
73 } u;
74
75 uint32_t prop_count;
76 uint32_t propref_count;
77
78 uint8_t mark_epoch;
79 uint8_t type_tag;
80 uint8_t inobj_limit;
81 uint8_t extra_count;
82
83 uint8_t extensible: 1;
84 uint8_t frozen: 1;
85 uint8_t sealed: 1;
86 uint8_t is_exotic: 1;
87 uint8_t is_constructor: 1;
88 uint8_t fast_array: 1;
89 uint8_t may_have_holes: 1;
90 uint8_t may_have_dense_elements: 1;
91 uint8_t gc_permanent: 1;
92 uint8_t generation: 1;
93 uint8_t in_remember_set: 1;
94
95 bool gc_pending_rooted;
96 uint8_t overflow_cap;
97} ant_object_t;
98
99typedef struct {
100 uint8_t slot;
101 ant_value_t value;
102} ant_extra_slot_t;
103
104typedef struct ant_prop_ref {
105 ant_object_t *obj;
106 uint32_t slot;
107 bool valid;
108} ant_prop_ref_t;
109
110static inline uint32_t ant_object_inobj_limit(const ant_object_t *obj) {
111 if (!obj) return ANT_INOBJ_MAX_SLOTS;
112 uint32_t limit = obj->inobj_limit;
113 return (limit > ANT_INOBJ_MAX_SLOTS) ? ANT_INOBJ_MAX_SLOTS : limit;
114}
115
116static inline ant_value_t ant_object_prop_get_unchecked(const ant_object_t *obj, uint32_t slot) {
117 uint32_t inobj_limit = ant_object_inobj_limit(obj);
118 return (slot < inobj_limit)
119 ? obj->inobj[slot]
120 : obj->overflow_prop[slot - inobj_limit];
121}
122
123static inline void ant_object_prop_set_unchecked(ant_object_t *obj, uint32_t slot, ant_value_t value) {
124 uint32_t inobj_limit = ant_object_inobj_limit(obj);
125 if (slot < inobj_limit) obj->inobj[slot] = value;
126 else obj->overflow_prop[slot - inobj_limit] = value;
127}
128
129#endif