2 Copyright (C) 2008-2009, Parrot Foundation.
7 src/pmc/cpointer.pmc - CPointer
11 The CPointer PMC creates a PMC abstraction for a typed C pointer. It is
12 particularly used by the C<CallSignature> PMC, for the return values of a
13 C-level PCC invocation using a C<CallSignature> to pass the arguments and fetch
18 A CPointer PMC has two attributes:
24 A C<void *> pointer to an integer, number, string, or PMC.
28 A string signature for the pointer. The possible signature values follow the
29 standard defined for PCC.
31 I a Parrot integer (INTVAL)
32 N a Parrot number (FLOATVAL)
33 S a Parrot string (STRING *)
34 P a Parrot object (PMC *)
39 =head2 Vtable Functions
41 These are the vtable functions for the CPointer class.
49 pmclass CPointer auto_attrs {
50 ATTR void *pointer; /* The stored pointer. */
51 ATTR STRING *sig; /* A string signature for the pointer. */
57 Initializes the pointer object.
64 SET_ATTR_pointer(INTERP, SELF, NULL);
65 SET_ATTR_sig(INTERP, SELF, NULL);
67 PObj_custom_mark_destroy_SETALL(SELF);
74 Marks the signature as live. Also marks a STRING or PMC pointed to by the
83 GET_ATTR_sig(INTERP, SELF, sig);
86 GET_ATTR_pointer(INTERP, SELF, pointer);
87 Parrot_gc_mark_PObj_alive(interp, (PObj *)sig);
90 if (Parrot_str_equal(interp, sig, CONST_STRING(interp, "P"))) {
91 PMC ** const pmc_pointer = (PMC **) pointer;
92 PARROT_ASSERT(*pmc_pointer);
93 Parrot_gc_mark_PObj_alive(interp, (PObj *) *pmc_pointer);
95 else if (Parrot_str_equal(interp, sig, CONST_STRING(interp, "S"))) {
96 STRING ** const str_pointer = (STRING **) pointer;
97 PARROT_ASSERT(*str_pointer);
98 Parrot_gc_mark_PObj_alive(interp, (PObj *) *str_pointer);
106 =item C<void destroy()>
108 Destroys the PMC and frees all allocated memory.
114 VTABLE void destroy() {
119 =item C<PMC *clone()>
121 Creates and returns a clone of the pointer.
127 VTABLE PMC *clone() {
128 PMC * const dest = pmc_new_noinit(INTERP, SELF->vtable->base_type);
129 PObj_custom_mark_SET(dest);
130 PMC_data(dest) = PMC_data(SELF);
136 =item C<void *get_pointer()>
144 VTABLE void *get_pointer() {
145 Parrot_CPointer_attributes * const data = PARROT_CPOINTER(SELF);
146 return data->pointer;
151 =item C<void set_pointer(void *)>
159 VTABLE void set_pointer(void *value) {
160 Parrot_CPointer_attributes * const data = PARROT_CPOINTER(SELF);
161 data->pointer = value;
166 =item C<STRING *get_string_keyed_str(STRING *key)>
168 Returns the string signature.
174 VTABLE STRING *get_string_keyed_str(STRING *key) {
175 Parrot_CPointer_attributes * const data = PARROT_CPOINTER(SELF);
183 =item C<void set_string_keyed_str(STRING *key, STRING *value)>
185 Sets the string signature.
191 VTABLE void set_string_keyed_str(STRING *key, STRING *value) {
192 Parrot_CPointer_attributes * const data = PARROT_CPOINTER(SELF);
200 =item C<INTVAL get_integer()>
202 Returns the integer value that the pointer points to (if the pointer is to an
209 VTABLE INTVAL get_integer() {
210 Parrot_CPointer_attributes * const data = PARROT_CPOINTER(SELF);
212 if (Parrot_str_equal(interp, data->sig, CONST_STRING(interp, "I"))) {
213 const INTVAL * const int_pointer = (INTVAL *) data->pointer;
216 else if (Parrot_str_equal(interp, data->sig, CONST_STRING(interp, "P"))) {
217 PMC ** const pmc_pointer = (PMC **) data->pointer;
218 return VTABLE_get_integer(interp, *pmc_pointer);
220 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
221 "Unable to fetch integer value, the pointer is not an integer");
227 =item C<void set_integer_native(INTVAL value)>
229 Sets the integer value that the pointer points to (if the pointer is to an
236 VTABLE void set_integer_native(INTVAL value) {
237 Parrot_CPointer_attributes * const data = PARROT_CPOINTER(SELF);
239 if (Parrot_str_equal(interp, data->sig, CONST_STRING(interp, "I"))) {
240 INTVAL * const int_pointer = (INTVAL *) data->pointer;
241 *int_pointer = value;
243 else if (Parrot_str_equal(interp, data->sig, CONST_STRING(interp, "P"))) {
244 PMC ** const pmc_pointer = (PMC **) data->pointer;
245 VTABLE_set_integer_native(interp, *pmc_pointer, value);
248 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
249 "Unable to set integer value, the pointer is not an integer");
255 =item C<FLOATVAL get_number()>
257 Returns the floating point value that the pointer points to (if the pointer is
264 VTABLE FLOATVAL get_number() {
265 Parrot_CPointer_attributes * const data = PARROT_CPOINTER(SELF);
267 if (Parrot_str_equal(interp, data->sig, CONST_STRING(interp, "N"))) {
268 const FLOATVAL * const num_pointer = (FLOATVAL *) data->pointer;
271 else if (Parrot_str_equal(interp, data->sig, CONST_STRING(interp, "P"))) {
272 PMC ** const pmc_pointer = (PMC **) data->pointer;
273 return VTABLE_get_number(interp, *pmc_pointer);
275 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
276 "Unable to fetch number value, the pointer is not a number");
281 =item C<void set_number_native(FLOATVAL value)>
283 Sets the floating point value that the pointer points to (if the pointer is
290 VTABLE void set_number_native(FLOATVAL value) {
291 Parrot_CPointer_attributes * const data = PARROT_CPOINTER(SELF);
293 if (Parrot_str_equal(interp, data->sig, CONST_STRING(interp, "N"))) {
294 FLOATVAL * const num_pointer = (FLOATVAL *) data->pointer;
295 *num_pointer = value;
297 else if (Parrot_str_equal(interp, data->sig, CONST_STRING(interp, "P"))) {
298 PMC ** const pmc_pointer = (PMC **) data->pointer;
299 VTABLE_set_number_native(interp, *pmc_pointer, value);
302 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
303 "Unable to set number value, the pointer is not a number");
309 =item C<STRING *get_string()>
311 Returns the Parrot string value that the pointer points to (if the pointer is
318 VTABLE STRING *get_string() {
319 Parrot_CPointer_attributes * const data = PARROT_CPOINTER(SELF);
321 if (Parrot_str_equal(interp, data->sig, CONST_STRING(interp, "S"))) {
322 STRING ** const str_pointer = (STRING **) data->pointer;
325 else if (Parrot_str_equal(interp, data->sig, CONST_STRING(interp, "P"))) {
326 PMC ** const pmc_pointer = (PMC **) data->pointer;
327 return VTABLE_get_string(interp, *pmc_pointer);
329 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
330 "Unable to fetch string value, the pointer is not a string");
335 =item C<void set_string_native(STRING *value)>
337 Sets the Parrot string value that the pointer points to (if the pointer is
344 VTABLE void set_string_native(STRING *value) {
345 Parrot_CPointer_attributes * const data = PARROT_CPOINTER(SELF);
347 if (Parrot_str_equal(interp, data->sig, CONST_STRING(interp, "S"))) {
348 STRING ** const str_pointer = (STRING **) data->pointer;
349 *str_pointer = value;
351 else if (Parrot_str_equal(interp, data->sig, CONST_STRING(interp, "P"))) {
352 PMC ** const pmc_pointer = (PMC **) data->pointer;
353 VTABLE_set_string_native(interp, *pmc_pointer, value);
356 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
357 "Unable to set string value, the pointer is not a string");
363 =item C<PMC *get_pmc()>
365 Returns the PMC value that the pointer points to (if the pointer is to a PMC).
371 VTABLE PMC *get_pmc() {
372 const Parrot_CPointer_attributes * const data = PARROT_CPOINTER(SELF);
374 if (Parrot_str_equal(interp, data->sig, CONST_STRING(interp, "P"))) {
375 PMC ** const pmc_pointer = (PMC **) data->pointer;
378 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
379 "Unable to fetch PMC value, the pointer is not a PMC");
384 =item C<void set_pmc(PMC *value)>
386 Sets the PMC value that the pointer points to (if the pointer is to a PMC).
392 VTABLE void set_pmc(PMC *value) {
393 const Parrot_CPointer_attributes * const data = PARROT_CPOINTER(SELF);
395 if (Parrot_str_equal(interp, data->sig, CONST_STRING(interp, "P"))) {
396 PMC ** const pmc_pointer = (PMC **) data->pointer;
397 *pmc_pointer = value;
400 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
401 "Unable to set PMC value, the pointer is not a PMC");
407 =item C<INTVAL get_bool()>
409 Returns whether the pointer is not C<NULL>.
415 VTABLE INTVAL get_bool() {
416 const Parrot_CPointer_attributes * const data = PARROT_CPOINTER(SELF);
417 return (INTVAL)(data->pointer != NULL);
422 =item C<INTVAL is_same(PMC *pmc2)>
424 Returns whether the pointer has the same value as C<*pmc2>.
430 VTABLE INTVAL is_same(PMC *pmc2) {
431 const Parrot_CPointer_attributes * const data = PARROT_CPOINTER(SELF);
432 return (INTVAL)(SELF->vtable == pmc2->vtable &&
433 data->pointer == VTABLE_get_pointer(interp, pmc2));
447 * c-file-style: "parrot"
449 * vim: expandtab shiftwidth=4: