Skip to content

Commit 82145f5

Browse files
committed
Add a simple REPR that just stores values in a flat hash for Tene++.
1 parent 95092bf commit 82145f5

File tree

4 files changed

+217
-1
lines changed

4 files changed

+217
-1
lines changed

build/Makefile.in

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,14 +160,15 @@ METAMODEL_SOURCE = src/metamodel/rakudoobject.h src/metamodel/rakudoobject.c \
160160
src/metamodel/reprs/P6int.h src/metamodel/reprs/P6int.c \
161161
src/metamodel/reprs/P6str.h src/metamodel/reprs/P6str.c \
162162
src/metamodel/reprs/P6num.h src/metamodel/reprs/P6num.c \
163+
src/metamodel/reprs/HashAttrStore.h src/metamodel/reprs/HashAttrStore.c \
163164
src/metamodel/multi_dispatch.h src/metamodel/multi_dispatch.c \
164165
src/metamodel/storage_spec.h
165166

166167
METAMODEL_OBJS = ../metamodel/rakudoobject$(O) ../metamodel/repr_registry$(O) \
167168
../metamodel/knowhow_bootstrapper$(O) ../metamodel/reprs/KnowHOWREPR$(O) \
168169
../metamodel/reprs/P6opaque$(O) ../metamodel/reprs/P6int$(O) \
169170
../metamodel/reprs/P6str$(O) ../metamodel/reprs/P6num$(O) \
170-
../metamodel/multi_dispatch$(O)
171+
../metamodel/reprs/HashAttrStore$(O) ../metamodel/multi_dispatch$(O)
171172

172173
HOW_SOURCES = src/metamodel/how/KnowHOWAttribute.pm src/metamodel/how/NQPClassHOW.pm \
173174
src/metamodel/how/NQPNativeHOW.pm src/metamodel/how/NQPAttribute.pm \
@@ -400,6 +401,7 @@ $(OPS_DIR)/$(OPS)$(LOAD_EXT): $(OPS_DIR)/$(OPS_SOURCE) $(DYNPMC)
400401
cd src/metamodel/reprs && $(CC) -c @cc_o_out@P6int$(O) -I../../../$(PMC_DIR) $(CINCLUDES) $(CFLAGS) P6int.c
401402
cd src/metamodel/reprs && $(CC) -c @cc_o_out@P6str$(O) -I../../../$(PMC_DIR) $(CINCLUDES) $(CFLAGS) P6str.c
402403
cd src/metamodel/reprs && $(CC) -c @cc_o_out@P6num$(O) -I../../../$(PMC_DIR) $(CINCLUDES) $(CFLAGS) P6num.c
404+
cd src/metamodel/reprs && $(CC) -c @cc_o_out@HashAttrStore$(O) -I../../../$(PMC_DIR) $(CINCLUDES) $(CFLAGS) HashAttrStore.c
403405
cd src/metamodel && $(CC) -c @cc_o_out@multi_dispatch$(O) -I../../$(PMC_DIR) $(CINCLUDES) $(CFLAGS) multi_dispatch.c
404406
cd $(OPS_DIR) && $(LD) @ld_out@$(OPS)$(LOAD_EXT) $(OPS)$(O) $(METAMODEL_OBJS) $(LINKARGS)
405407

src/metamodel/repr_registry.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "reprs/P6int.h"
1212
#include "reprs/P6num.h"
1313
#include "reprs/P6str.h"
14+
#include "reprs/HashAttrStore.h"
1415

1516
/* An array of representations. */
1617
static PMC *repr_registry = NULL;
@@ -47,6 +48,8 @@ void REPR_initialize_registry(PARROT_INTERP) {
4748
P6num_initialize(interp));
4849
register_repr(interp, Parrot_str_new_constant(interp, "P6str"),
4950
P6str_initialize(interp));
51+
register_repr(interp, Parrot_str_new_constant(interp, "HashAttrStore"),
52+
HashAttrStore_initialize(interp));
5053
}
5154

5255
/* Get a representation's ID from its name. Note that the IDs may change so
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
/* This REPR stores named attributes in a hash. It doesn't key by the
2+
* class at all - it's just a completely flat view. It also doesn't know
3+
* about allowing index-optimized access (at least, not yet). */
4+
5+
#define PARROT_IN_EXTENSION
6+
#include "parrot/parrot.h"
7+
#include "parrot/extend.h"
8+
#include "../rakudoobject.h"
9+
#include "HashAttrStore.h"
10+
11+
/* Creates a new type object of this representation, and associates it with
12+
* the given HOW. */
13+
static PMC * type_object_for(PARROT_INTERP, PMC *self, PMC *HOW) {
14+
/* Create new object instance. */
15+
HashAttrStoreInstance *obj = mem_allocate_zeroed_typed(HashAttrStoreInstance);
16+
17+
/* Build an STable. */
18+
PMC *st_pmc = create_stable(interp, self, HOW);
19+
STable *st = STABLE_STRUCT(st_pmc);
20+
21+
/* Create type object and point it back at the STable. We leave the
22+
* hash store pointer null to flag it's the type object. */
23+
st->WHAT = wrap_object(interp, obj);
24+
obj->common.stable = st_pmc;
25+
26+
return st->WHAT;
27+
}
28+
29+
/* Creates a new instance based on the type object. */
30+
static PMC * instance_of(PARROT_INTERP, PMC *self, PMC *WHAT) {
31+
HashAttrStoreInstance *obj;
32+
33+
/* Allocate and set up object instance. */
34+
obj = Parrot_gc_allocate_fixed_size_storage(interp, sizeof(HashAttrStoreInstance));
35+
obj->common.stable = STABLE_PMC(WHAT);
36+
obj->store = pmc_new(interp, enum_class_Hash);
37+
38+
return wrap_object(interp, obj);
39+
}
40+
41+
/* Checks if a given object is defined (from the point of view of the
42+
* representation). */
43+
static INTVAL defined(PARROT_INTERP, PMC *self, PMC *obj) {
44+
HashAttrStoreInstance *instance = (HashAttrStoreInstance *)PMC_data(obj);
45+
return instance->store != NULL;
46+
}
47+
48+
/* Gets the current value for an attribute. */
49+
static PMC * get_attribute(PARROT_INTERP, PMC *self, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint) {
50+
HashAttrStoreInstance *instance = (HashAttrStoreInstance *)PMC_data(obj);
51+
if (!instance->store)
52+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
53+
"Cannot access attributes in a type object");
54+
return VTABLE_get_pmc_keyed_str(interp, instance->store, name);
55+
}
56+
static INTVAL get_attribute_int(PARROT_INTERP, PMC *self, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint) {
57+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
58+
"HashAttrStore representation does not support native attribute storage");
59+
}
60+
static FLOATVAL get_attribute_num(PARROT_INTERP, PMC *self, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint) {
61+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
62+
"HashAttrStore representation does not support native attribute storage");
63+
}
64+
static STRING * get_attribute_str(PARROT_INTERP, PMC *self, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint) {
65+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
66+
"HashAttrStore representation does not support native attribute storage");
67+
}
68+
69+
/* Binds the given value to the specified attribute. */
70+
static void bind_attribute(PARROT_INTERP, PMC *self, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint, PMC *value) {
71+
HashAttrStoreInstance *instance = (HashAttrStoreInstance *)PMC_data(obj);
72+
if (!instance->store)
73+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
74+
"Cannot access attributes in a type object");
75+
VTABLE_set_pmc_keyed_str(interp, instance->store, name, value);
76+
}
77+
static void bind_attribute_int(PARROT_INTERP, PMC *self, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint, INTVAL value) {
78+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
79+
"HashAttrStore representation does not support native attribute storage");
80+
}
81+
static void bind_attribute_num(PARROT_INTERP, PMC *self, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint, FLOATVAL value) {
82+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
83+
"HashAttrStore representation does not support native attribute storage");
84+
}
85+
static void bind_attribute_str(PARROT_INTERP, PMC *self, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint, STRING *value) {
86+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
87+
"HashAttrStore representation does not support native attribute storage");
88+
}
89+
90+
/* Gets the hint for the given attribute ID. */
91+
static INTVAL hint_for(PARROT_INTERP, PMC *self, PMC *class_handle, STRING *name) {
92+
return NO_HINT;
93+
}
94+
95+
/* Used with boxing. Sets an integer value, for representations that can hold
96+
* one. */
97+
static void set_int(PARROT_INTERP, PMC *self, PMC *obj, INTVAL value) {
98+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
99+
"HashAttrStore cannot box a native int");
100+
}
101+
102+
/* Used with boxing. Gets an integer value, for representations that can
103+
* hold one. */
104+
static INTVAL get_int(PARROT_INTERP, PMC *self, PMC *obj) {
105+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
106+
"HashAttrStore cannot unbox to a native int");
107+
}
108+
109+
/* Used with boxing. Sets a floating point value, for representations that can
110+
* hold one. */
111+
static void set_num(PARROT_INTERP, PMC *self, PMC *obj, FLOATVAL value) {
112+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
113+
"HashAttrStore cannot box a native num");
114+
}
115+
116+
/* Used with boxing. Gets a floating point value, for representations that can
117+
* hold one. */
118+
static FLOATVAL get_num(PARROT_INTERP, PMC *self, PMC *obj) {
119+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
120+
"HashAttrStore cannot unbox to a native num");
121+
}
122+
123+
/* Used with boxing. Sets a string value, for representations that can hold
124+
* one. */
125+
static void set_str(PARROT_INTERP, PMC *self, PMC *obj, STRING *value) {
126+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
127+
"HashAttrStore cannot box a native string");
128+
}
129+
130+
/* Used with boxing. Gets a string value, for representations that can hold
131+
* one. */
132+
static STRING * get_str(PARROT_INTERP, PMC *self, PMC *obj) {
133+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
134+
"HashAttrStore cannot unbox to a native string");
135+
}
136+
137+
/* This Parrot-specific addition to the API is used to mark an object. */
138+
static void gc_mark(PARROT_INTERP, PMC *self, PMC *obj) {
139+
HashAttrStoreInstance *instance = (HashAttrStoreInstance *)PMC_data(obj);
140+
141+
/* Mark STable. */
142+
if (!PMC_IS_NULL(instance->common.stable))
143+
Parrot_gc_mark_PMC_alive(interp, instance->common.stable);
144+
145+
/* Mark store */
146+
if (!PMC_IS_NULL(instance->store))
147+
Parrot_gc_mark_PMC_alive(interp, instance->store);
148+
}
149+
150+
/* This Parrot-specific addition to the API is used to free an object. */
151+
static void gc_free(PARROT_INTERP, PMC *self, PMC *obj) {
152+
Parrot_gc_free_fixed_size_storage(interp, sizeof(HashAttrStoreInstance), PMC_data(obj));
153+
PMC_data(obj) = NULL;
154+
}
155+
156+
/* Gets the storage specification for this representation. */
157+
static storage_spec get_storage_spec(PARROT_INTERP, PMC *self) {
158+
storage_spec spec;
159+
spec.inlineable = STORAGE_SPEC_REFERENCE;
160+
spec.boxed_primitive = STORAGE_SPEC_BP_NONE;
161+
return spec;
162+
}
163+
164+
/* Initializes the HashAttrStore representation. */
165+
PMC * HashAttrStore_initialize(PARROT_INTERP) {
166+
REPRCommonalities *repr;
167+
PMC *repr_pmc;
168+
169+
/* Allocate and populate the representation function table. */
170+
repr = mem_allocate_zeroed_typed(REPRCommonalities);
171+
repr->type_object_for = type_object_for;
172+
repr->instance_of = instance_of;
173+
repr->defined = defined;
174+
repr->get_attribute = get_attribute;
175+
repr->get_attribute_int = get_attribute_int;
176+
repr->get_attribute_num = get_attribute_num;
177+
repr->get_attribute_str = get_attribute_str;
178+
repr->bind_attribute = bind_attribute;
179+
repr->bind_attribute_int = bind_attribute_int;
180+
repr->bind_attribute_num = bind_attribute_num;
181+
repr->bind_attribute_str = bind_attribute_str;
182+
repr->hint_for = hint_for;
183+
repr->set_int = set_int;
184+
repr->get_int = get_int;
185+
repr->set_num = set_num;
186+
repr->get_num = get_num;
187+
repr->set_str = set_str;
188+
repr->get_str = get_str;
189+
repr->gc_mark = gc_mark;
190+
repr->gc_free = gc_free;
191+
repr->get_storage_spec = get_storage_spec;
192+
193+
/* Wrap it in a PMC. */
194+
return wrap_repr(interp, repr);
195+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#ifndef HAS_H_GUARD
2+
#define HAS_H_GUARD
3+
4+
typedef struct {
5+
/* The commonalities all objects have. */
6+
RakudoObjectCommonalities common;
7+
8+
/* Storage slot (hash). Note in the future we could have a Parrot
9+
* Hash data structure right here and make every object 1 GC-able. */
10+
PMC *store;
11+
} HashAttrStoreInstance;
12+
13+
/* Initializes the Hash Attribute Store REPR. */
14+
PMC * HashAttrStore_initialize(PARROT_INTERP);
15+
16+
#endif

0 commit comments

Comments
 (0)