1
/* This is the implementation of the P6str representation, which holds a native
4
#define PARROT_IN_EXTENSION
5
#include "parrot/parrot.h"
6
#include "parrot/extend.h"
7
#include "../sixmodelobject.h"
10
/* This representation's function pointer table. */
11
static REPROps *this_repr;
13
/* Creates a new type object of this representation, and associates it with
15
static PMC * type_object_for(PARROT_INTERP, PMC *HOW) {
16
/* Create new object instance. */
17
P6strInstance *obj = mem_allocate_zeroed_typed(P6strInstance);
19
/* Build an STable. */
20
PMC *st_pmc = create_stable(interp, this_repr, HOW);
21
STable *st = STABLE_STRUCT(st_pmc);
23
/* Create type object and point it back at the STable. */
24
obj->common.stable = st_pmc;
25
st->WHAT = wrap_object(interp, obj);
26
PARROT_GC_WRITE_BARRIER(interp, st_pmc);
28
/* Flag it as a type object. */
29
MARK_AS_TYPE_OBJECT(st->WHAT);
34
/* Composes the representation. */
35
static void compose(PARROT_INTERP, STable *st, PMC *repr_info) {
39
/* Creates a new instance based on the type object. */
40
static PMC * allocate(PARROT_INTERP, STable *st) {
41
P6strInstance *obj = mem_allocate_zeroed_typed(P6strInstance);
42
obj->common.stable = st->stable_pmc;
43
return wrap_object(interp, obj);
46
/* Initialize a new instance. */
47
static void initialize(PARROT_INTERP, STable *st, void *data) {
48
((P6strBody *)data)->value = STRINGNULL;
51
/* Copies to the body of one object to another. */
52
static void copy_to(PARROT_INTERP, STable *st, void *src, void *dest) {
53
/* Strings are immutable, so this is safe. */
54
*((STRING **)dest) = *((STRING **)src);
57
/* Used with boxing. Sets an integer value, for representations that can hold
59
static void set_int(PARROT_INTERP, STable *st, void *data, INTVAL value) {
60
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
61
"P6str cannot box a native int");
64
/* Used with boxing. Gets an integer value, for representations that can
66
static INTVAL get_int(PARROT_INTERP, STable *st, void *data) {
67
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
68
"P6str cannot unbox to a native int");
71
/* Used with boxing. Sets a floating point value, for representations that can
73
static void set_num(PARROT_INTERP, STable *st, void *data, FLOATVAL value) {
74
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
75
"P6str cannot box a native num");
78
/* Used with boxing. Gets a floating point value, for representations that can
80
static FLOATVAL get_num(PARROT_INTERP, STable *st, void *data) {
81
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
82
"P6str cannot unbox to a native num");
85
/* Used with boxing. Sets a string value, for representations that can hold
87
static void set_str(PARROT_INTERP, STable *st, void *data, STRING *value) {
88
((P6strBody *)data)->value = value;
91
/* Used with boxing. Gets a string value, for representations that can hold
93
static STRING * get_str(PARROT_INTERP, STable *st, void *data) {
94
return ((P6strBody *)data)->value;
97
/* Some objects serve primarily as boxes of others, inlining them. This gets
98
* gets the reference to such things, using the representation ID to distinguish
100
static void * get_boxed_ref(PARROT_INTERP, STable *st, void *data, INTVAL repr_id) {
101
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
102
"P6str cannot box other types");
105
/* This Parrot-specific addition to the API is used to mark an object. */
106
static void gc_mark(PARROT_INTERP, STable *st, void *data) {
107
P6strBody *body = (P6strBody *)data;
108
if (!STRING_IS_NULL(body->value))
109
Parrot_gc_mark_STRING_alive(interp, body->value);
112
/* This Parrot-specific addition to the API is used to free an object. */
113
static void gc_free(PARROT_INTERP, PMC *obj) {
114
mem_sys_free(PMC_data(obj));
115
PMC_data(obj) = NULL;
118
/* Gets the storage specification for this representation. */
119
static storage_spec get_storage_spec(PARROT_INTERP, STable *st) {
121
spec.inlineable = STORAGE_SPEC_INLINED;
122
spec.bits = sizeof(STRING *) * 8;
123
spec.align = ALIGNOF1(void *);
124
spec.boxed_primitive = STORAGE_SPEC_BP_STR;
125
spec.can_box = STORAGE_SPEC_CAN_BOX_STR;
129
/* Serializes the data. */
130
static void serialize(PARROT_INTERP, STable *st, void *data, SerializationWriter *writer) {
131
writer->write_str(interp, writer, ((P6strBody *)data)->value);
134
/* Deserializes the data. */
135
static void deserialize(PARROT_INTERP, STable *st, void *data, SerializationReader *reader) {
136
((P6strBody *)data)->value = reader->read_str(interp, reader);
139
/* Initializes the P6str representation. */
140
REPROps * P6str_initialize(PARROT_INTERP) {
141
/* Allocate and populate the representation function table. */
142
this_repr = mem_allocate_zeroed_typed(REPROps);
143
this_repr->type_object_for = type_object_for;
144
this_repr->compose = compose;
145
this_repr->allocate = allocate;
146
this_repr->initialize = initialize;
147
this_repr->copy_to = copy_to;
148
this_repr->box_funcs = mem_allocate_typed(REPROps_Boxing);
149
this_repr->box_funcs->set_int = set_int;
150
this_repr->box_funcs->get_int = get_int;
151
this_repr->box_funcs->set_num = set_num;
152
this_repr->box_funcs->get_num = get_num;
153
this_repr->box_funcs->set_str = set_str;
154
this_repr->box_funcs->get_str = get_str;
155
this_repr->box_funcs->get_boxed_ref = get_boxed_ref;
156
this_repr->gc_mark = gc_mark;
157
this_repr->gc_free = gc_free;
158
this_repr->get_storage_spec = get_storage_spec;
159
this_repr->serialize = serialize;
160
this_repr->deserialize = deserialize;