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). */
5
#define PARROT_IN_EXTENSION
6
#include "parrot/parrot.h"
7
#include "parrot/extend.h"
8
#include "../sixmodelobject.h"
9
#include "HashAttrStore.h"
11
/* This representation's function pointer table. */
12
static REPROps *this_repr;
14
/* Creates a new type object of this representation, and associates it with
16
static PMC * type_object_for(PARROT_INTERP, PMC *HOW) {
17
/* Create new object instance. */
18
HashAttrStoreInstance *obj = mem_allocate_zeroed_typed(HashAttrStoreInstance);
20
/* Build an STable. */
21
PMC *st_pmc = create_stable(interp, this_repr, HOW);
22
STable *st = STABLE_STRUCT(st_pmc);
24
/* Create type object and point it back at the STable. We leave the
25
* hash store pointer null to flag it's the type object. */
26
obj->common.stable = st_pmc;
27
st->WHAT = wrap_object(interp, obj);
28
PARROT_GC_WRITE_BARRIER(interp, st_pmc);
30
/* Flag it as a type object. */
31
MARK_AS_TYPE_OBJECT(st->WHAT);
36
/* Composes the representation. */
37
static void compose(PARROT_INTERP, STable *st, PMC *repr_info) {
41
/* Creates a new instance based on the type object. */
42
static PMC * allocate(PARROT_INTERP, STable *st) {
43
HashAttrStoreInstance *obj;
44
obj = (HashAttrStoreInstance *) Parrot_gc_allocate_fixed_size_storage(interp, sizeof(HashAttrStoreInstance));
45
obj->common.stable = st->stable_pmc;
46
return wrap_object(interp, obj);
49
/* Initialize a new instance. */
50
static void initialize(PARROT_INTERP, STable *st, void *data) {
51
((HashAttrStoreBody *)data)->store = Parrot_pmc_new(interp, enum_class_Hash);
54
/* Copies to the body of one object to another. */
55
static void copy_to(PARROT_INTERP, STable *st, void *src, void *dest) {
56
HashAttrStoreBody *src_body = (HashAttrStoreBody *)src;
57
HashAttrStoreBody *dest_body = (HashAttrStoreBody *)dest;
58
dest_body->store = VTABLE_clone(interp, src_body->store);
61
/* Gets the current value for an attribute. */
62
static PMC * get_attribute_boxed(PARROT_INTERP, STable *st, void *data, PMC *class_handle, STRING *name, INTVAL hint) {
63
HashAttrStoreBody *body = (HashAttrStoreBody *)data;
64
return VTABLE_get_pmc_keyed_str(interp, body->store, name);
66
static void get_attribute_native(PARROT_INTERP, STable *st, void *data, PMC *class_handle, STRING *name, INTVAL hint, NativeValue *value) {
67
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
68
"HashAttrStore representation does not support value type attributes");
70
static STable *get_attribute_stable(PARROT_INTERP, STable *st, PMC *class_handle, STRING *name, INTVAL hint) {
71
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
72
"HashAttrStore representation does not support value type attributes");
75
/* Binds the given value to the specified attribute. */
76
static void bind_attribute_boxed(PARROT_INTERP, STable *st, void *data, PMC *class_handle, STRING *name, INTVAL hint, PMC *value) {
77
HashAttrStoreBody *body = (HashAttrStoreBody *)data;
78
VTABLE_set_pmc_keyed_str(interp, body->store, name, value);
80
static void bind_attribute_native(PARROT_INTERP, STable *st, void *data, PMC *class_handle, STRING *name, INTVAL hint, NativeValue *value) {
81
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
82
"HashAttrStore representation does not support native attribute storage");
85
/* Checks if an attribute has been initialized. */
86
static INTVAL is_attribute_initialized(PARROT_INTERP, STable *st, void *data, PMC *class_handle, STRING *name, INTVAL hint) {
87
HashAttrStoreBody *body = (HashAttrStoreBody *)data;
88
return VTABLE_exists_keyed_str(interp, body->store, name);
91
/* Gets the hint for the given attribute ID. */
92
static INTVAL hint_for(PARROT_INTERP, STable *st, PMC *class_handle, STRING *name) {
96
/* This Parrot-specific addition to the API is used to mark an object. */
97
static void gc_mark(PARROT_INTERP, STable *st, void *data) {
98
HashAttrStoreBody *body = (HashAttrStoreBody *)data;
99
if (!PMC_IS_NULL(body->store))
100
Parrot_gc_mark_PMC_alive(interp, body->store);
103
/* This Parrot-specific addition to the API is used to free an object. */
104
static void gc_free(PARROT_INTERP, PMC *obj) {
105
Parrot_gc_free_fixed_size_storage(interp, sizeof(HashAttrStoreInstance), PMC_data(obj));
106
PMC_data(obj) = NULL;
109
/* Gets the storage specification for this representation. */
110
static storage_spec get_storage_spec(PARROT_INTERP, STable *st) {
112
spec.inlineable = STORAGE_SPEC_REFERENCE;
113
spec.boxed_primitive = STORAGE_SPEC_BP_NONE;
115
spec.bits = sizeof(void *);
116
spec.align = ALIGNOF1(void *);
120
/* Initializes the HashAttrStore representation. */
121
REPROps * HashAttrStore_initialize(PARROT_INTERP) {
122
/* Allocate and populate the representation function table. */
123
this_repr = mem_allocate_zeroed_typed(REPROps);
124
this_repr->type_object_for = type_object_for;
125
this_repr->compose = compose;
126
this_repr->allocate = allocate;
127
this_repr->initialize = initialize;
128
this_repr->copy_to = copy_to;
129
this_repr->attr_funcs = mem_allocate_typed(REPROps_Attribute);
130
this_repr->attr_funcs->get_attribute_boxed = get_attribute_boxed;
131
this_repr->attr_funcs->get_attribute_native = get_attribute_native;
132
this_repr->attr_funcs->bind_attribute_boxed = bind_attribute_boxed;
133
this_repr->attr_funcs->bind_attribute_native = bind_attribute_native;
134
this_repr->attr_funcs->is_attribute_initialized = is_attribute_initialized;
135
this_repr->attr_funcs->hint_for = hint_for;
136
this_repr->gc_mark = gc_mark;
137
this_repr->gc_free = gc_free;
138
this_repr->get_storage_spec = get_storage_spec;