/*
Copyright (C) 2001-2011, Parrot Foundation.
=head1 NAME
src/pmc/capture.pmc - Capture PMC
=head1 DESCRIPTION
These are the vtable functions for the Capture PMC.
=head2 Functions
=over 4
=cut
*/
/* HEADERIZER HFILE: none */
/* HEADERIZER BEGIN: static */
/* HEADERIZER END: static */
#define CAPTURE_array_CREATE(i, obj, arr) \
do { \
GETATTR_Capture_array((i), (obj), (arr)); \
if (!(arr)) { \
PObj_custom_mark_SET(obj); \
(arr) = Parrot_pmc_new((i), enum_class_ResizablePMCArray); \
SETATTR_Capture_array((i), (obj), (arr)); \
PARROT_GC_WRITE_BARRIER((i), (obj)); \
} \
} while (0)
#define CAPTURE_hash_CREATE(i, obj, hsh) \
do { \
GETATTR_Capture_hash((i), (obj), (hsh)); \
if (!(hsh)) { \
PObj_custom_mark_SET(obj); \
(hsh) = Parrot_pmc_new((i), enum_class_Hash); \
SETATTR_Capture_hash((i), (obj), (hsh)); \
PARROT_GC_WRITE_BARRIER((i), (obj)); \
} \
} while (0)
pmclass Capture auto_attrs {
ATTR PMC *array;
ATTR PMC *hash;
/*
=item C<PMC *clone()>
Creates an identical copy of the Capture.
=cut
*/
VTABLE PMC *clone() {
PMC *array, *hash;
PMC * const dest = Parrot_pmc_new(INTERP, VTABLE_type(INTERP, SELF));
GET_ATTR_array(INTERP, SELF, array);
GET_ATTR_hash(INTERP, SELF, hash);
if (!PMC_IS_NULL(array)) {
PObj_custom_mark_SET(dest);
array = VTABLE_clone(INTERP, array);
SET_ATTR_array(INTERP, dest, array);
}
if (!PMC_IS_NULL(hash)) {
PObj_custom_mark_SET(dest);
hash = VTABLE_clone(INTERP, hash);
SET_ATTR_hash(INTERP, dest, hash);
}
/* clone of parts can trigger GC. Explicitely WB dest */
PARROT_GC_WRITE_BARRIER(INTERP, dest);
return dest;
}
/*
=item C<void set_number_keyed_int(INTVAL key, FLOATVAL value)>
=item C<void set_integer_keyed_int(INTVAL key, INTVAL value)>
=item C<void set_pmc_keyed_int(INTVAL key, PMC *value)>
=item C<void set_string_keyed_int(INTVAL key, STRING *value)>
Sets a value in the array component of the Capture.
=cut
*/
VTABLE void set_number_keyed_int(INTVAL key, FLOATVAL value) {
PMC *array;
CAPTURE_array_CREATE(INTERP, SELF, array);
VTABLE_set_number_keyed_int(INTERP, array, key, value);
}
VTABLE void set_integer_keyed_int(INTVAL key, INTVAL value) {
PMC *array;
CAPTURE_array_CREATE(INTERP, SELF, array);
VTABLE_set_integer_keyed_int(INTERP, array, key, value);
}
VTABLE void set_pmc_keyed_int(INTVAL key, PMC *value) {
PMC *array;
CAPTURE_array_CREATE(INTERP, SELF, array);
VTABLE_set_pmc_keyed_int(INTERP, array, key, value);
}
VTABLE void set_string_keyed_int(INTVAL key, STRING *value) {
PMC *array;
CAPTURE_array_CREATE(INTERP, SELF, array);
VTABLE_set_string_keyed_int(INTERP, array, key, value);
}
/*
=item C<FLOATVAL get_number_keyed_int(INTVAL key)>
=item C<INTVAL get_integer_keyed_int(INTVAL key)>
=item C<PMC *get_pmc_keyed_int(INTVAL key)>
=item C<STRING *get_string_keyed_int(INTVAL key)>
Retrieves a value in the array component of the Capture.
=cut
*/
VTABLE FLOATVAL get_number_keyed_int(INTVAL key) {
PMC *array;
GET_ATTR_array(INTERP, SELF, array);
if (!array)
return 0.0;
return VTABLE_get_number_keyed_int(INTERP, array, key);
}
VTABLE INTVAL get_integer_keyed_int(INTVAL key) {
PMC *array;
GET_ATTR_array(INTERP, SELF, array);
if (!array)
return 0;
return VTABLE_get_integer_keyed_int(INTERP, array, key);
}
VTABLE PMC *get_pmc_keyed_int(INTVAL key) {
PMC *array;
GET_ATTR_array(INTERP, SELF, array);
if (!array)
return PMCNULL;
return VTABLE_get_pmc_keyed_int(INTERP, array, key);
}
VTABLE STRING *get_string_keyed_int(INTVAL key) {
PMC *array;
GET_ATTR_array(INTERP, SELF, array);
if (!array)
return CONST_STRING(INTERP, "");
return VTABLE_get_string_keyed_int(INTERP, array, key);
}
/*
=item C<void push_float(FLOATVAL value)>
=item C<void push_integer(INTVAL value)>
=item C<void push_pmc(PMC *value)>
=item C<void push_string(STRING *value)>
Push a value onto the array component of the Capture.
=item C<void unshift_float(FLOATVAL value)>
=item C<void unshift_integer(INTVAL value)>
=item C<void unshift_pmc(PMC *value)>
=item C<void unshift_string(STRING *value)>
Unshift a value onto the array component of the Capture.
=cut
*/
VTABLE void push_float(FLOATVAL value) {
PMC *array;
CAPTURE_array_CREATE(INTERP, SELF, array);
VTABLE_push_float(INTERP, array, value);
}
VTABLE void push_integer(INTVAL value) {
PMC *array;
CAPTURE_array_CREATE(INTERP, SELF, array);
VTABLE_push_integer(INTERP, array, value);
}
VTABLE void push_pmc(PMC *value) {
PMC *array;
CAPTURE_array_CREATE(INTERP, SELF, array);
VTABLE_push_pmc(INTERP, array, value);
}
VTABLE void push_string(STRING *value) {
PMC *array;
CAPTURE_array_CREATE(INTERP, SELF, array);
VTABLE_push_string(INTERP, array, value);
}
VTABLE void unshift_float(FLOATVAL value) {
PMC *array;
CAPTURE_array_CREATE(INTERP, SELF, array);
VTABLE_unshift_float(INTERP, array, value);
}
VTABLE void unshift_integer(INTVAL value) {
PMC *array;
CAPTURE_array_CREATE(INTERP, SELF, array);
VTABLE_unshift_integer(INTERP, array, value);
}
VTABLE void unshift_pmc(PMC *value) {
PMC *array;
CAPTURE_array_CREATE(INTERP, SELF, array);
VTABLE_unshift_pmc(INTERP, array, value);
}
VTABLE void unshift_string(STRING *value) {
PMC *array;
CAPTURE_array_CREATE(INTERP, SELF, array);
VTABLE_unshift_string(INTERP, array, value);
}
/*
=item C<FLOATVAL pop_float()>
=item C<INTVAL pop_integer()>
=item C<PMC *pop_pmc()>
=item C<STRING *pop_string()>
Pop a value from the array component of the Capture.
=item C<FLOATVAL shift_float()>
=item C<INTVAL shift_integer()>
=item C<PMC *shift_pmc()>
=item C<STRING *shift_string()>
Shift a value from the array component of the Capture.
=cut
*/
VTABLE FLOATVAL pop_float() {
PMC *array;
CAPTURE_array_CREATE(INTERP, SELF, array);
return VTABLE_pop_float(INTERP, array);
}
VTABLE INTVAL pop_integer() {
PMC *array;
CAPTURE_array_CREATE(INTERP, SELF, array);
return VTABLE_pop_integer(INTERP, array);
}
VTABLE PMC *pop_pmc() {
PMC *array;
CAPTURE_array_CREATE(INTERP, SELF, array);
return VTABLE_pop_pmc(INTERP, array);
}
VTABLE STRING *pop_string() {
PMC *array;
CAPTURE_array_CREATE(INTERP, SELF, array);
return VTABLE_pop_string(INTERP, array);
}
VTABLE FLOATVAL shift_float() {
PMC *array;
CAPTURE_array_CREATE(INTERP, SELF, array);
return VTABLE_shift_float(INTERP, array);
}
VTABLE INTVAL shift_integer() {
PMC *array;
CAPTURE_array_CREATE(INTERP, SELF, array);
return VTABLE_shift_integer(INTERP, array);
}
VTABLE PMC *shift_pmc() {
PMC *array;
CAPTURE_array_CREATE(INTERP, SELF, array);
return VTABLE_shift_pmc(INTERP, array);
}
VTABLE STRING *shift_string() {
PMC *array;
CAPTURE_array_CREATE(INTERP, SELF, array);
return VTABLE_shift_string(INTERP, array);
}
/*
=item C<INTVAL elements()>
Return the number of elements in the array component of the Capture.
=item C<INTVAL defined_keyed_int(INTVAL key)>
Return true if element C<key> of the array component is defined.
=item C<INTVAL exists_keyed_int(INTVAL key)>
Return true if element C<key> of the array component exists.
=item C<void delete_keyed_int(INTVAL key)>
Delete the element corresponding to C<key> in the array component.
=cut
*/
VTABLE INTVAL elements() {
PMC *array;
GET_ATTR_array(INTERP, SELF, array);
if (!array)
return 0;
return VTABLE_elements(INTERP, array);
}
VTABLE INTVAL defined_keyed_int(INTVAL key) {
PMC *array;
GET_ATTR_array(INTERP, SELF, array);
if (!array)
return 0;
return VTABLE_defined_keyed_int(INTERP, array, key);
}
VTABLE INTVAL exists_keyed_int(INTVAL key) {
PMC *array;
GET_ATTR_array(INTERP, SELF, array);
if (!array)
return 0;
return VTABLE_exists_keyed_int(INTERP, array, key);
}
VTABLE void delete_keyed_int(INTVAL key) {
PMC *array;
GET_ATTR_array(INTERP, SELF, array);
if (array)
VTABLE_delete_keyed_int(INTERP, array, key);
}
/*
=item C<void set_number_keyed(PMC *key, FLOATVAL value)>
=item C<void set_integer_keyed(PMC *key, INTVAL value)>
=item C<void set_pmc_keyed(PMC *key, PMC *value)>
=item C<void set_string_keyed(PMC *key, STRING *value)>
Sets a value in the hash component of the Capture.
=cut
*/
VTABLE void set_number_keyed(PMC *key, FLOATVAL value) {
PMC *hash;
CAPTURE_hash_CREATE(INTERP, SELF, hash);
VTABLE_set_number_keyed(INTERP, hash, key, value);
}
VTABLE void set_integer_keyed(PMC *key, INTVAL value) {
PMC *hash;
CAPTURE_hash_CREATE(INTERP, SELF, hash);
VTABLE_set_integer_keyed(INTERP, hash, key, value);
}
VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
PMC *hash;
CAPTURE_hash_CREATE(INTERP, SELF, hash);
VTABLE_set_pmc_keyed(INTERP, hash, key, value);
}
VTABLE void set_string_keyed(PMC *key, STRING *value) {
PMC *hash;
CAPTURE_hash_CREATE(INTERP, SELF, hash);
VTABLE_set_string_keyed(INTERP, hash, key, value);
}
/*
=item C<FLOATVAL get_number_keyed(PMC *key)>
=item C<INTVAL get_integer_keyed(PMC *key)>
=item C<PMC *get_pmc_keyed(PMC *key)>
=item C<STRING *get_string_keyed(PMC *key)>
Retrieves a value from the hash component of the Capture.
=cut
*/
VTABLE FLOATVAL get_number_keyed(PMC *key) {
PMC *hash;
GET_ATTR_hash(INTERP, SELF, hash);
if (!hash)
return 0.0;
return VTABLE_get_number_keyed(INTERP, hash, key);
}
VTABLE INTVAL get_integer_keyed(PMC *key) {
PMC *hash;
GET_ATTR_hash(INTERP, SELF, hash);
if (!hash)
return 0;
return VTABLE_get_integer_keyed(INTERP, hash, key);
}
VTABLE PMC *get_pmc_keyed(PMC *key) {
PMC *hash;
GET_ATTR_hash(INTERP, SELF, hash);
if (!hash)
return PMCNULL;
return VTABLE_get_pmc_keyed(INTERP, hash, key);
}
VTABLE STRING *get_string_keyed(PMC *key) {
PMC *hash;
GET_ATTR_hash(INTERP, SELF, hash);
if (!hash)
return CONST_STRING(INTERP, "");
return VTABLE_get_string_keyed(INTERP, hash, key);
}
/*
=item C<void set_number_keyed_str(STRING *key, FLOATVAL value)>
=item C<void set_integer_keyed_str(STRING *key, INTVAL value)>
=item C<void set_pmc_keyed_str(STRING *key, PMC *value)>
=item C<void set_string_keyed_str(STRING *key, STRING *value)>
Sets a value in the hash component of the Capture.
=cut
*/
VTABLE void set_number_keyed_str(STRING *key, FLOATVAL value) {
PMC *hash;
CAPTURE_hash_CREATE(INTERP, SELF, hash);
VTABLE_set_number_keyed_str(INTERP, hash, key, value);
}
VTABLE void set_integer_keyed_str(STRING *key, INTVAL value) {
PMC *hash;
CAPTURE_hash_CREATE(INTERP, SELF, hash);
VTABLE_set_integer_keyed_str(INTERP, hash, key, value);
}
VTABLE void set_pmc_keyed_str(STRING *key, PMC *value) {
PMC *hash;
CAPTURE_hash_CREATE(INTERP, SELF, hash);
VTABLE_set_pmc_keyed_str(INTERP, hash, key, value);
}
VTABLE void set_string_keyed_str(STRING *key, STRING *value) {
PMC *hash;
CAPTURE_hash_CREATE(INTERP, SELF, hash);
VTABLE_set_string_keyed_str(INTERP, hash, key, value);
}
/*
=item C<FLOATVAL get_number_keyed_str(STRING *key)>
=item C<INTVAL get_integer_keyed_str(STRING *key)>
=item C<PMC *get_pmc_keyed_str(STRING *key)>
=item C<STRING *get_string_keyed_str(STRING *key)>
Retrieves a value in the hash component of the Capture.
=cut
*/
VTABLE FLOATVAL get_number_keyed_str(STRING *key) {
PMC *hash;
GET_ATTR_hash(INTERP, SELF, hash);
if (!hash)
return 0.0;
return VTABLE_get_number_keyed_str(INTERP, hash, key);
}
VTABLE INTVAL get_integer_keyed_str(STRING *key) {
PMC *hash;
GET_ATTR_hash(INTERP, SELF, hash);
if (!hash)
return 0;
return VTABLE_get_integer_keyed_str(INTERP, hash, key);
}
VTABLE PMC *get_pmc_keyed_str(STRING *key) {
PMC *hash;
GET_ATTR_hash(INTERP, SELF, hash);
if (!hash)
return PMCNULL;
return VTABLE_get_pmc_keyed_str(INTERP, hash, key);
}
VTABLE STRING *get_string_keyed_str(STRING *key) {
PMC *hash;
GET_ATTR_hash(INTERP, SELF, hash);
if (!hash)
return CONST_STRING(INTERP, "");
return VTABLE_get_string_keyed_str(INTERP, hash, key);
}
/*
=item C<INTVAL defined_keyed(PMC *key)>
Return true if element C<key> of the hash component is defined.
=item C<INTVAL exists_keyed(PMC *key)>
Return true if element C<key> of the hash component exists.
=item C<void delete_keyed(PMC *key)>
Delete the element corresponding to C<key> in the hash component.
=cut
*/
VTABLE INTVAL defined_keyed(PMC *key) {
PMC *hash;
GET_ATTR_hash(INTERP, SELF, hash);
if (!hash)
return 0;
return VTABLE_defined_keyed(INTERP, hash, key);
}
VTABLE INTVAL exists_keyed(PMC *key) {
PMC *hash;
GET_ATTR_hash(INTERP, SELF, hash);
if (!hash)
return 0;
return VTABLE_exists_keyed(INTERP, hash, key);
}
VTABLE void delete_keyed(PMC *key) {
PMC *hash;
GET_ATTR_hash(INTERP, SELF, hash);
if (hash)
VTABLE_delete_keyed(INTERP, hash, key);
}
/*
=item C<INTVAL defined_keyed_str(STRING *key)>
Return true if element C<key> of the hash component is defined.
=item C<INTVAL exists_keyed_str(STRING *key)>
Return true if element C<key> of the hash component exists.
=item C<void delete_keyed_str(STRING *key)>
Delete the element corresponding to C<key> in the hash component.
=cut
*/
VTABLE INTVAL defined_keyed_str(STRING *key) {
PMC *hash;
GET_ATTR_hash(INTERP, SELF, hash);
if (!hash)
return 0;
return VTABLE_defined_keyed_str(INTERP, hash, key);
}
VTABLE INTVAL exists_keyed_str(STRING *key) {
PMC *hash;
GET_ATTR_hash(INTERP, SELF, hash);
if (!hash)
return 0;
return VTABLE_exists_keyed_str(INTERP, hash, key);
}
VTABLE void delete_keyed_str(STRING *key) {
PMC *hash;
GET_ATTR_hash(INTERP, SELF, hash);
if (hash)
VTABLE_delete_keyed_str(INTERP, hash, key);
}
/*
=item C<void set_pmc(PMC *capture)>
Set this capture to hold the value of another. If set to PMCNULL,
erase the contents of the array and hash components.
=cut
*/
VTABLE void set_pmc(PMC *capture) {
if (PMC_IS_NULL(capture)) {
SET_ATTR_array(INTERP, SELF, NULL);
SET_ATTR_hash(INTERP, SELF, NULL);
}
else if (VTABLE_isa(INTERP, capture, CONST_STRING(INTERP, "Capture"))) {
PMC *array, *hash;
GET_ATTR_array(INTERP, capture, array);
GET_ATTR_hash(INTERP, capture, hash);
SET_ATTR_array(INTERP, SELF, array);
SET_ATTR_hash(INTERP, SELF, hash);
if (!PMC_IS_NULL(array) || !PMC_IS_NULL(hash))
PObj_custom_mark_SET(SELF);
}
else
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
"Can only set a capture to another capture.");
}
/*
=item C<STRING get_string()>
Return a string representation of the hash, showing class
and memory address.
=cut
*/
VTABLE STRING *get_string() {
const STRING * const classname = VTABLE_name(INTERP, SELF);
return Parrot_sprintf_c(INTERP, "%S[0x%x]", classname, SELF);
}
/*
=item C<void mark(void)>
Mark the array.
=cut
*/
VTABLE void mark() {
PMC *array, *hash;
GET_ATTR_array(INTERP, SELF, array);
GET_ATTR_hash(INTERP, SELF, hash);
Parrot_gc_mark_PMC_alive(INTERP, array);
Parrot_gc_mark_PMC_alive(INTERP, hash);
}
/*
=item C<void freeze()>
=item C<void thaw()>
Freeze/thaw Capture
=cut
*/
VTABLE void freeze(PMC *info) {
PMC *array, *hash;
GET_ATTR_array(INTERP, SELF, array);
GET_ATTR_hash(INTERP, SELF, hash);
VTABLE_push_pmc(INTERP, info, array);
VTABLE_push_pmc(INTERP, info, hash);
}
VTABLE void thaw(PMC *info) {
PMC *tmp;
tmp = VTABLE_shift_pmc(INTERP, info);
if (!PMC_IS_NULL(tmp)) {
SET_ATTR_array(INTERP, SELF, tmp);
PObj_custom_mark_SET(SELF);
}
tmp = VTABLE_shift_pmc(INTERP, info);
if (!PMC_IS_NULL(tmp)) {
SET_ATTR_hash(INTERP, SELF, tmp);
PObj_custom_mark_SET(SELF);
}
}
/*
=back
=head2 Methods
=over 4
=cut
*/
METHOD list() :manual_wb {
PMC *array;
PMC *capt;
/* XXX: This workaround is for when we get here as
part of a subclass of Capture */
if (PObj_is_object_TEST(SELF)) {
PMC *classobj;
PMC *ns = INTERP->root_namespace;
ns = Parrot_ns_get_namespace_keyed_str(INTERP, ns, CONST_STRING(INTERP, "parrot"));
ns = Parrot_ns_get_namespace_keyed_str(INTERP, ns, CONST_STRING(INTERP, "Capture"));
classobj = Parrot_oo_get_class(INTERP, ns);
capt = VTABLE_get_attr_keyed(INTERP, SELF, classobj, CONST_STRING(INTERP, "proxy"));
}
else
capt = SELF;
CAPTURE_array_CREATE(INTERP, capt, array);
RETURN(PMC *array);
}
METHOD hash() :manual_wb {
PMC *hash;
PMC *capt;
/* XXX: This workaround is for when we get here as
part of a subclass of Capture */
if (PObj_is_object_TEST(SELF)) {
STRING * const classname = CONST_STRING(INTERP, "Capture");
PMC * const classobj = Parrot_oo_get_class_str(INTERP, classname);
capt = VTABLE_get_attr_keyed(INTERP, SELF, classobj, CONST_STRING(INTERP, "proxy"));
}
else
capt = SELF;
CAPTURE_hash_CREATE(INTERP, capt, hash);
RETURN(PMC *hash);
}
}
/*
=back
=cut
*/
/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
*/