/home/travis/build/MoarVM/MoarVM/src/6model/reprs/P6opaque.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* This is how an instance with the P6opaque representation starts. However, what |
2 | | * follows on from this depends on the declaration. For object attributes, it will |
3 | | * be a pointer size and point to another MVMObject. For native integers and |
4 | | * numbers, it will be the appropriate sized piece of memory to store them |
5 | | * right there in the object. Note that P6opaque does not do packed storage, so |
6 | | * an int2 gets as much space as an int. */ |
7 | | struct MVMP6opaqueBody { |
8 | | /* If we get mixed into, we may change size. If so, we can't really resize |
9 | | * the object, so instead we hang its post-resize form off this pointer. |
10 | | * In the future, more clever things are possible (like only putting the |
11 | | * new fields into this object). */ |
12 | | void *replaced; |
13 | | }; |
14 | | struct MVMP6opaque { |
15 | | MVMObject common; |
16 | | MVMP6opaqueBody body; |
17 | | }; |
18 | | |
19 | | /* This is used in the name to slot mapping. Indicates the class key that |
20 | | * we have the mappings for, followed by arrays of names and slots. (Yeah, |
21 | | * could use a hash, but much code will resolve these statically to the |
22 | | * slots). */ |
23 | | struct MVMP6opaqueNameMap { |
24 | | MVMObject *class_key; |
25 | | MVMString **names; |
26 | | MVMuint16 *slots; |
27 | | MVMuint32 num_attrs; |
28 | | }; |
29 | | |
30 | | /* The P6opaque REPR data has the slot mapping, allocation size and |
31 | | * various other bits of info. It hangs off the REPR_data pointer |
32 | | * in the s-table. */ |
33 | | struct MVMP6opaqueREPRData { |
34 | | /* The number of attributes we have allocated slots for. Note that |
35 | | * slots can vary in size. */ |
36 | | MVMuint16 num_attributes; |
37 | | |
38 | | /* Slot containing object to delegate for positional things. */ |
39 | | MVMint16 pos_del_slot; |
40 | | |
41 | | /* Slot containing object to delegate for associative things. */ |
42 | | MVMint16 ass_del_slot; |
43 | | |
44 | | /* Flags if we are MI or not. */ |
45 | | MVMuint16 mi; |
46 | | |
47 | | /* Slot to delegate to when we need to unbox to a native integer. */ |
48 | | MVMint16 unbox_int_slot; |
49 | | |
50 | | /* Slot to delegate to when we need to unbox to a native number. */ |
51 | | MVMint16 unbox_num_slot; |
52 | | |
53 | | /* Slot to delegate to when we need to unbox to a native string. */ |
54 | | MVMint16 unbox_str_slot; |
55 | | |
56 | | /* Offsets into the object that are eligible for GC marking, and how |
57 | | * many of them we have. */ |
58 | | MVMuint16 gc_obj_mark_offsets_count; |
59 | | MVMuint16 *gc_obj_mark_offsets; |
60 | | |
61 | | /* Maps attribute position numbers to the byte offset in the object. */ |
62 | | MVMuint16 *attribute_offsets; |
63 | | |
64 | | /* If the attribute was actually flattened in to this object from another |
65 | | * representation, this is the s-table of the type of that attribute. NULL |
66 | | * for attributes that are just reference types. */ |
67 | | MVMSTable **flattened_stables; |
68 | | |
69 | | /* Instantiated objects are just a blank piece of memory that needs to |
70 | | * be set up. However, in some cases we'd like them to magically turn in |
71 | | * to some container type. */ |
72 | | MVMObject **auto_viv_values; |
73 | | |
74 | | /* If we have any other flattened boxings, this array can be indexed by |
75 | | * REPR ID to find the slot in the object where it is embedded. */ |
76 | | MVMuint16 *unbox_slots; |
77 | | |
78 | | /* A table mapping attribute names to indexes (which can then be looked |
79 | | * up in the offset table). Uses a final null entry as a sentinel. */ |
80 | | MVMP6opaqueNameMap *name_to_index_mapping; |
81 | | |
82 | | /* Slots holding flattened objects that need another REPR to initialize |
83 | | * them; terminated with -1. */ |
84 | | MVMint16 *initialize_slots; |
85 | | |
86 | | /* Slots holding flattened objects that need another REPR to mark them; |
87 | | * terminated with -1. */ |
88 | | MVMint16 *gc_mark_slots; |
89 | | |
90 | | /* Slots holding flattened objects that need another REPR to clean them; |
91 | | * terminated with -1. */ |
92 | | MVMint16 *gc_cleanup_slots; |
93 | | |
94 | | /* Hold the storage spec */ |
95 | | MVMStorageSpec storage_spec; |
96 | | }; |
97 | | |
98 | | /* Function for REPR setup. */ |
99 | | const MVMREPROps * MVMP6opaque_initialize(MVMThreadContext *tc); |
100 | | |
101 | | /* If an object gets mixed in to, we need to be sure we look at its real body, |
102 | | * which may have been moved to hang off the specified pointer. |
103 | | * |
104 | | * NB: This has been hardcoded into the jit compilation. Thus, consider it |
105 | | * set into stone :-). That is the price you pay for disintermediation. */ |
106 | 0 | MVM_STATIC_INLINE void * MVM_p6opaque_real_data(MVMThreadContext *tc, void *data) { |
107 | 0 | MVMP6opaqueBody *body = (MVMP6opaqueBody *)data; |
108 | 0 | return body->replaced ? body->replaced : data; |
109 | 0 | } |
110 | | |
111 | | /* Reads an attribute using an offset. This is only safe on an exact type |
112 | | * match. */ |
113 | | MVM_STATIC_INLINE MVMObject * MVM_p6opaque_read_object(MVMThreadContext *tc, |
114 | 0 | MVMObject *o, size_t offset) { |
115 | 0 | char *data = MVM_p6opaque_real_data(tc, OBJECT_BODY(o)); |
116 | 0 | return *((MVMObject **)(data + offset)); |
117 | 0 | } |
118 | | MVM_STATIC_INLINE MVMint64 MVM_p6opaque_read_int64(MVMThreadContext *tc, |
119 | 0 | MVMObject *o, size_t offset) { |
120 | 0 | char *data = MVM_p6opaque_real_data(tc, OBJECT_BODY(o)); |
121 | 0 | return *((MVMint64 *)(data + offset)); |
122 | 0 | } |
123 | | |
124 | | size_t MVM_p6opaque_attr_offset(MVMThreadContext *tc, MVMObject *type, |
125 | | MVMObject *class_handle, MVMString *name); |
126 | | void MVM_P6opaque_at_pos(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMint64 index, MVMRegister *value, MVMuint16 kind); |