The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

TITLE

Common vtable format for all variables

VERSION

CURRENT

   Maintainer: Dan Sugalski <dan@sidhe.org>
   Class: Internals
   PDD Number: 2
   Version: 1.2
   Status: Developing
   Last Modified: 22 June 2002
   PDD Format: 1
   Language: English

HISTORY

1.2

22 June 2002

1.1

13 May 2002

1.0

None. First version

CHANGES

1.2

Many cleanups and clarifications. Much detail added. Many missing methods added.

1.1

Cleaned up the definition. It was a mess.

1.0

None. First version

ABSTRACT

This RFC presents the vtable entries, and their order, that all variables MUST provide.

DESCRIPTION

All perl variables hide their guts behind a magic perl structure generally referred to as a PMC, or Perl Magic Cookie. Nothing outside the core of perl (in fact, nothing outside the data type's vtable routines) should infer anything about a PMC. (hence the Magic part)

The first parameter to all of these should be the current interpreter. The second parameter should be the PMC itself.

vtables are neat because they decouple the interface and implementation of various object functions. This does mean, though, that you need to either know what functions are available and what they do, or have some method of finding out. It's faster if you know which vtable entry does what, so that's the method perl's using.

The actual vtable structure contains pointers to functions that implement the methods for that particular vtable. All pointers must point to valid functions with appropriate prototypes.

IMPLEMENTATION

vtable functions

This is a list of each of the vtable methods, their prototypes, and a description of the method.

The following functions are singleton functions. (There are no keyed versions of these)

void init(INTERP, PMC* self)

The init vtable method takes an unused PMC as a parameter, and turns it into a PMC appropriate for the class owning the vtable. Called as a class method. There is also a form that accepts a PMC initializer as a third argument.

void init_pmc(INTERP, PMC* self, PMC* initializer)

This form of the init method takes a single initializer parameter. XXX - What is the initializer used for?

void morph(INTERP, PMC* self, INTVAL type)

turns the PMC into a PMC of type type. If the morphing can't be reasonably done, for example if an integer is asked to turn into a PerlArray, then the PMC is first destroyed, then recreated as an empty PMC of the new type.

This method is primarily used when the interpreter has need of coercing a PMC to a particular type, and isn't meant as a general purpose casting tool. Compilers should only emit valid transformations.

PMC* mark(INTERP, PMC* self, PMC* tail)

Called by the DOD when its sweeping through the PMCs and has detected that this PMC is both alive and has a custom mark routine. The second parameter is the PMC at the tail of the free PMC list, as passed to mark_used. This should return the new tail of the free PMC list.

If a PMC has this set, its responsible for marking all buffers and PMCs under its control as alive. If it does not, those PMCs or buffers may be collected later. This method does not have to call the mark method on any PMCs it marks--the DOD system takes care of that. (So no need to recurse into aggregate PMCs or anything of the sort)

This method may allocate no memory from Parrot, nor may it alter Parrot's internal structures. It should have no side-effects from the C level either.

This routine may not throw an exception.

void destroy(INTERP, PMC* self)

This method is called by the DOD when it determines that a PMC is dead, and that PMC has marked itself as having a destroy method.

When this method finishes, the PMC will be marked as dead. As such you should make sure that you do not leave any references to it in any parrot structure by the end of the method.

This method may not throw an exception. It will be ignored if it does.

The following functions have a plain form, a _keyed form, and a _keyed_int form. The keyed forms take a KEY* or INTVAL* for each PMC parameter. The KEY*/INTVAL* parameter for each PMC is NULL if there is no key for that PMC; this means that that arguement is unkeyed.

In some cases, the caller must provide a non-NULL key. Those cases are explicitly stated below. In the other cases, you may have to implement the keyed vtable methods and check for a NULL self key even if you are implementing a non-aggregate type. If the self key is non- NULL and the PMC class is a non-aggregate type, the _keyed_* methods should throw an exception.

If you do not implement the _keyed_int methods, the default will convert the INTVAL into a KEY and call the corresponding _keyed method.

The keyed methods should NOT assume that the key pointer will be valid after the method exits. The pointer may be to a stack variable in the calling function.

INTVAL type(INTERP, PMC* self)

Return the type of the PMC. Type is a unique tag associated with the PMC when the PMC's class is loaded. Negative numbers are considered interpreter-specific, non-public types.

INTVAL type_keyed(INTERP, PMC* self, KEY* key)
INTVAL type_keyed_int(INTERP, PMC* self, INTVAL* key)

Return the type of the PMC indexed by key. The key parameter is guaranteed not to be NULL for this method.

UINTVAL subtype(INTERP, PMC* self, INTVAL type)

Returns the subtype of a PMC. (Note that this may be unimplemented, and may go away) This is intended to return information about the PMC--what type of number or string it is, whether it's a scalar, hash, array, or list, and suchlike things.

UINTVAL subtype_keyed(INTERP, PMC* self, KEY* key, INTVAL type)
UINTVAL subtype_keyed_int(INTERP, PMC* self, INTVAL* key, INTVAL type)

Return the subtype of the PMC indexed by key. The key parameter is guaranteed not to be NULL for this method.

STRING* name(INTERP, PMC* self)

Return the name of the class for the PMC.

STRING* name_keyed(INTERP, PMC* self, KEY* key)
STRING* name_keyed_int(INTERP, PMC* self, INTVAL* key)

Return the name of the class of the PMC indexed by key. The key parameter is guaranteed not to be NULL for this method.

PMC* clone(INTERP, PMC* self)

Return a clone of yourself.

PMC* clone_keyed(INTERP, PMC* self, KEY* key)
PMC* clone_keyed_int(INTERP, PMC* self, INTVAL* key)

Return a clone of the PMC indexed by key. If the PMC is fake, for example we're asking for a clone of an element of an integer array, this must return an appropriate real PMC that holds the fake information. The key parameter is guaranteed not to be NULL for this method.

PMC* find_method(INTERP, PMC* self, STRING* method_name)

Returns a subroutine PMC for the passed method name. This subroutine PMC may be cached, so the method must return an equivalent sub PMC each time, or be capable of dealing with the returned sub PMCs being reused.

PMC* find_method_keyed(INTERP, PMC* self, KEY* key, STRING* method_name)
PMC* find_method_keyed_int(INTERP, PMC* self, INTVAL* key, STRING* method_name)

Returns a subroutine PMC for the passed method name. This subroutine PMC may be cached, so the method must return an equivalent sub PMC each time, or be capable of dealing with the returned sub PMCs being reused. The key parameter is guaranteed not to be NULL for this method.

INTVAL get_integer(INTERP, PMC* self)

Returns the native integer value of the PMC.

INTVAL get_integer_keyed(INTERP, PMC* self, KEY* key)
INTVAL get_integer_keyed_int(INTERP, PMC* self, INTVAL* key)

Returns the native integer value of the PMC indexed by key. The key parameter is guaranteed not to be NULL for this method.

FLOATVAL get_number(INTERP, PMC* self)

Returns the native floating-point value of the PMC.

FLOATVAL get_number_keyed(INTERP, PMC* self, KEY* key)
FLOATVAL get_number_keyed_int(INTERP, PMC* self, INTVAL* key)

Returns the native floating-point value of the PMC indexed by key. The key parameter is guaranteed not to be NULL for this method.

BIGNUM* get_bignum(INTERP, PMC* self)

Returns the value of the PMC as a bignum.

BIGNUM* get_bignum_keyed(INTERP, PMC* self, KEY* key)
BIGNUM* get_bignum_keyed_int(INTERP, PMC* self, INTVAL* key)

Returns the bignum value of the PMC indexed by key. The key parameter is guaranteed not to be NULL for this method.

STRING* get_string(INTERP, PMC* self)

Returns the native string value of the PMC. This may be in the encoding of the PMC's choice.

STRING* get_string_keyed(INTERP, PMC* self, KEY* key)
STRING* get_string_keyed_int(INTERP, PMC* self, INTVAL* key)

Returns the string value of the PMC indexed by key. The key parameter is guaranteed not to be NULL for this method.

INTVAL get_bool(INTERP, PMC* self)

Returns the constant TRUE if the PMC is true, or FALSE if the PMC is false.

INTVAL get_bool_keyed(INTERP, PMC* self, KEY* key)
INTVAL get_bool_keyed_int(INTERP, PMC* self, INTVAL* key)

Returns the constant TRUE if the PMC indexed by key is true, or FALSE if the PMC indexed by key is false. The key parameter is guaranteed not to be NULL for this method.

INTVAL elements(INTERP, PMC* self)

Returns the number of elements in the PMC.

INTVAL elements_keyed(INTERP, PMC* self, KEY* key)
INTVAL elements_keyed_int(INTERP, PMC* self, INTVAL* key)

Returns the number of elements in the PMC indexed by key. The key parameter is guaranteed not to be NULL for this method.

PMC* get_pmc(INTERP, PMC* self)

Returns the PMC for this PMC. While this may seem nonsensical, it's useful in several circumstances. If the thing being accessed may return something odd, for example a reference, it may return a value different than the PMC that get_pmc is being called on.

PMC* get_pmc_keyed(INTERP, PMC* self, KEY* key)
PMC* get_pmc_keyed_int(INTERP, PMC* self, INTVAL* key)

Returns the PMC indexed by key. The key parameter is guaranteed not to be NULL for this method.

INTVAL is_same(INTERP, PMC* self, PMC* value)

Returns TRUE if the PMCs are the same, and FALSE if they're not. In this case, "the same" means identical at a low level. For plain equality, use the is_equal method.

INTVAL is_same_keyed(INTERP, PMC* self, KEY* key, PMC* value, PMC* value_key)
INTVAL is_same_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key)

Returns TRUE if the PMC keyed by key is the same as the PMC in value keyed by value_key. At least one of the two keys is guaranteed not to be NULL.

void set_integer(INTERP, PMC* self, PMC* value)

Sets the PMC to the integer value of the PMC in value. What the PMC does with the passed in integer depends on the class.

void set_integer_native(INTERP, PMC* self, INTVAL value)

Sets the PMC to the integer value passed.

void set_integer_same(INTERP, PMC* self, PMC* value)

Sets the PMC to the integer value of the PMC in value. In this case, value is guaranteed to be of the same type as self so optimizations may be made.

void set_integer_keyed(INTERP, PMC* self, KEY* key, INTVAL value)
void set_integer_keyed_int(INTERP, PMC* self, INTVAL* key, INTVAL value)

Sets the PMC indexed by key to the integer value passed in value. The key parameter is guaranteed not to be NULL for this method.

void set_number(INTERP, PMC* self, PMC* value)

Sets the PMC to the floating-point value of the PMC in value.

void set_number_native(INTERP, PMC* self, FLOATVAL value)

Sets the PMC to the floating-point value passed.

void set_number_same(INTERP, PMC* self, PMC* value)

Sets the PMC to the floating-point value of the PMC in value. In this case, value is guaranteed to be of the same type as self so optimizations may be made.

void set_number_keyed(INTERP, PMC* self, KEY* key, FLOATVAL value)
void set_number_keyed_int(INTERP, PMC* self, INTVAL* key, FLOATVAL value)

Sets the PMC indexed by key to the floating-point value passed in value. The key parameter is guaranteed not to be NULL for this method.

void set_bignum(INTERP, PMC* self, PMC* value)

Sets the PMC to the bignum value of value.

void set_bignum_native(INTERP, PMC* self, BIGNUM* value)

Sets the PMC to the passed in bignum value.

void set_bignum_same(INTERP, PMC* self, PMC* value)

Sets the PMC to the bignum value of value. In this case, value is guaranteed to be of the same type as self so optimizations may be made.

void set_bignum_keyed(INTERP, PMC* self, KEY* key, BIGNUM* value)
void set_bignum_keyed_int(INTERP, PMC* self, INTVAL* key, BIGNUM* value)

Sets the PMC indexed by key to the bignum value passed in value. The key parameter is guaranteed not to be NULL for this method.

void set_string(INTERP, PMC* self, PMC* value)

Sets the PMC to the string value of value.

void set_string_native(INTERP, PMC* self, STRING* value)

Sets the PMC to the passed in string value.

void set_string_unicode(INTERP, PMC* self, STRING* value)

Sets the PMC to the passed in string value.

void set_string_other(INTERP, PMC* self, STRING* value)

Sets the PMC to the passed in string value.

void set_string_same(INTERP, PMC* self, PMC* value)

Sets the PMC to the string value of value. In this case, value is guaranteed to be of the same type as self so optimizations may be made.

void set_string_keyed(INTERP, PMC* self, KEY* key, STRING* value)
void set_string_keyed_int(INTERP, PMC* self, INTVAL* key, STRING* value)

Sets the PMC indexed by key to the string value passed in value. The key parameter is guaranteed not to be NULL for this method.

void set_pmc(INTERP, PMC* self, PMC* value)

Assigns the value of source PMC to the value of the PMC in value.

void set_pmc_keyed(INTERP, PMC* self, KEY* key, PMC* value, KEY* value_key)
void set_pmc_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key)

Sets the value of the PMC keyed by key to the value of the PMC in value keyed by value_key. At least one of the two keys is guaranteed not to be NULL.

void set_same(INTERP, PMC* self, PMC* value)

A shortcut version of set_pmc in those cases where the interpreter knows the source and destination PMCs are of the same type.

void set_same_keyed(INTERP, PMC* self, KEY* key, PMC* value, PMC* value_key)
void set_same_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key)

Sets the value keyed by key to the value of value keyed by value_key. Both self and value are guaranteed to be of the same type so optimizations may be made.

At least one of the two keys is guaranteed not to be NULL.

Because the two PMCs are guaranteed to be of the same type, this method may throw an exception if the PMC class is a non-aggregate type.

INTVAL pop_integer(INTERP, PMC* self)

Returns the integer value of the last item on the list, removing that item.

INTVAL pop_integer_keyed(INTERP, PMC* self, KEY* key)
INTVAL pop_integer_keyed_int(INTERP, PMC* self, INTVAL* key)

Returns the integer value of the last item of the list keyed by key, removing that item from the list. The key parameter is guaranteed not to be NULL for this method.

FLOATVAL pop_float(INTERP, PMC* self)

Returns the floating-point value of the last item on the list, removing that item.

FLOATVAL pop_float_keyed(INTERP, PMC* self, KEY* key)
FLOATVAL pop_float_keyed_int(INTERP, PMC* self, INTVAL* key)

Returns the floating-point value of the last item of the list keyed by key, removing that item from the list. The key parameter is guaranteed not to be NULL for this method.

BIGNUM* pop_bignum(INTERP, PMC* self)

Returns the bignum value of the last item on the list, removing that item.

BIGNUM* pop_bignum_keyed(INTERP, PMC* self, KEY* key)
BIGNUM* pop_bignum_keyed_int(INTERP, PMC* self, INTVAL* key)

Returns the bignum value of the last item of the list keyed by key, removing that item from the list. The key parameter is guaranteed not to be NULL for this method.

STRING* pop_string(INTERP, PMC* self)

Returns the string value of the last item on the list, removing that item.

STRING* pop_string_keyed(INTERP, PMC* self, KEY* key)
STRING* pop_string_keyed_int(INTERP, PMC* self, INTVAL* key)

Returns the string value of the last item of the list keyed by key, removing that item from the list. The key parameter is guaranteed not to be NULL for this method.

PMC* pop_pmc(INTERP, PMC* self)

Returns the PMC value of the last item on the list, removing that item.

PMC* pop_pmc_keyed(INTERP, PMC* self, KEY* key)
PMC* pop_pmc_keyed_int(INTERP, PMC* self, INTVAL* key)

Returns the PMC value of the last item of the list keyed by key, removing that item from the list. The key parameter is guaranteed not to be NULL for this method.

void push_integer(INTERP, PMC* self, INTVAL value)

Add the passed in integer value to the end of the list.

void push_integer_keyed(INTERP, PMC* self, KEY* key, INTVAL value)
void push_integer_keyed_int(INTERP, PMC* self, INTVAL* key, INTVAL value)

Add the passed in integer value to the end of the list keyed by key. The key parameter is guaranteed not to be NULL for this method.

void push_float(INTERP, PMC* self, FLOATVAL value)

Add the passed in floating-point number to the end of the list.

void push_float_keyed(INTERP, PMC* self, KEY* key, FLOATVAL value)
void push_float_keyed_int(INTERP, PMC* self, INTVAL* key, FLOATVAL value)

Add the passed in floating-point value to the end of the list keyed by key. The key parameter is guaranteed not to be NULL for this method.

void push_bignum(INTERP, PMC* self, BIGNUM* value)

Add the passed in bignum to the end of the list.

void push_bignum_keyed(INTERP, PMC* self, KEY* key, BIGNUM* value)
void push_bignum_keyed_int(INTERP, PMC* self, INTVAL* key, BIGNUM* value)

Add the passed in bignum to the end of the list keyed by key. The key parameter is guaranteed not to be NULL for this method.

void push_string(INTERP, PMC* self, STRING* value)

Add the passed in string to the end of the list.

void push_string_keyed(INTERP, PMC* self, KEY* key, STRING* value)
void push_string_keyed_int(INTERP, PMC* self, INTVAL* key, STRING* value)

Add the passed in bignum to the end of the list keyed by key. The key parameter is guaranteed not to be NULL for this method.

void push_pmc(INTERP, PMC* self, PMC* value)

Add the passed in PMC to the end of the list.

void push_pmc_keyed(INTERP, PMC* self, KEY* key, PMC* value, KEY* value_key)
void push_pmc_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key)

Add the passed in PMC to the end of the list keyed by key. At least one of the two keys is guaranteed not to be NULL. If key is NULL then the method will use self. If value_key is NULL then the method will use value.

INTVAL shift_integer(INTERP, PMC* self)

Returns the integer value of the first item on the list, removing that item.

INTVAL shift_integer_keyed(INTERP, PMC* self, KEY* key)
INTVAL shift_integer_keyed_int(INTERP, PMC* self, INTVAL* key)

Returns the integer value of the fisrt item of the list keyed by key, removing that item from the list. The key parameter is guaranteed not to be NULL for this method.

FLOATVAL shift_float(INTERP, PMC* self)

Returns the floating-point value of the first item on the list, removing that item.

FLOATVAL shift_float_keyed(INTERP, PMC* self, KEY* key)
FLOATVAL shift_float_keyed_int(INTERP, PMC* self, INTVAL* key)

Returns the floating-point value of the first item of the list keyed by key, removing that item from the list. The key parameter is guaranteed not to be NULL for this method.

BIGNUM* shift_bignum(INTERP, PMC* self)

Returns the bignum value of the first item on the list, removing that item.

BIGNUM* shift_bignum_keyed(INTERP, PMC* self, KEY* key)
BIGNUM* shift_bignum_keyed_int(INTERP, PMC* self, INTVAL* key)

Returns the bignum value of the first item of the list keyed by key, removing that item from the list. The key parameter is guaranteed not to be NULL for this method.

STRING* shift_string(INTERP, PMC* self)

Returns the string value of the first item on the list, removing that item.

STRING* shift_string_keyed(INTERP, PMC* self, KEY* key)
STRING* shift_string_keyed_int(INTERP, PMC* self, INTVAL* key)

Returns the string value of the first item of the list keyed by key, removing that item from the list. The key parameter is guaranteed not to be NULL for this method.

PMC* shift_pmc(INTERP, PMC* self)

Returns the PMC value of the first item on the list, removing that item.

PMC* shift_pmc_keyed(INTERP, PMC* self, KEY* key)
PMC* shift_pmc_keyed_int(INTERP, PMC* self, INTVAL* key)

Returns the PMC value of the first item of the list keyed by key, removing that item from the list. The key parameter is guaranteed not to be NULL for this method.

void unshift_integer(INTERP, PMC* self, INTVAL value)

Add the passed in integer value to the beginning of the list.

void unshift_integer_keyed(INTERP, PMC* self, KEY* key, INTVAL value)
void unshift_integer_keyed_int(INTERP, PMC* self, INTVAL* key, INTVAL value)

Add the passed in integer value to the beginning of the list keyed by key. The key parameter is guaranteed not to be NULL for this method.

void unshift_float(INTERP, PMC* self, FLOATVAL value)

Add the passed in floating-point number to the beginning of the list.

void unshift_float_keyed(INTERP, PMC* self, KEY* key, FLOATVAL value)
void unshift_float_keyed_int(INTERP, PMC* self, INTVAL* key, FLOATVAL value)

Add the passed in floating-point value to the beginning of the list keyed by key. The key parameter is guaranteed not to be NULL for this method.

void unshift_bignum(INTERP, PMC* self, BIGNUM* value)

Add the passed in bignum to the beginning of the list.

void unshift_bignum_keyed(INTERP, PMC* self, KEY* key, BIGNUM* value)
void unshift_bignum_keyed_int(INTERP, PMC* self, INTVAL* key, BIGNUM* value)

Add the passed in bignum to the beginning of the list keyed by key. The key parameter is guaranteed not to be NULL for this method.

void unshift_string(INTERP, PMC* self, STRING* value)

Add the passed in string to the beginning of the list.

void unshift_string_keyed(INTERP, PMC* self, KEY* key, STRING* value)
void unshift_string_keyed_int(INTERP, PMC* self, INTVAL* key, STRING* value)

Add the passed in bignum to the beginning of the list keyed by key. The key parameter is guaranteed not to be NULL for this method.

void unshift_pmc(INTERP, PMC* self, PMC* value)

Add the passed in PMC to the beginning of the list.

void unshift_pmc_keyed(INTERP, PMC* self, KEY* key, PMC* value, KEY* value_key)
void unshift_pmc_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key)

Add the passed in PMC to the beginning of the list keyed by key. At least one of the two keys is guaranteed not to be NULL.

void splice ???

XXX - Interface undetermined

void add(INTERP, PMC* self, PMC* value, PMC* dest)
void add_int(INTERP, PMC* self, INTVAL value, PMC* dest)
void add_bignum(INTERP, PMC* self, BIGNUM* value, PMC* dest)
void add_float(INTERP, PMC* self, FLOATVAL value, PMC* dest)

Add self to value and store the result in dest. Note that dest may be equal to self; in that case optimizations may be made.

void add_same(INTERP, PMC* self, PMC* value, PMC* dest)

Add self to value and store the result in dest. Note that dest may be equal to self; in that case optimizations may be made. In this case, it is guaranteed that self and value are of the same type.

void add_keyed(INTERP, PMC* self, KEY* key, PMC* value, KEY* value_key, PMC* dest, KEY* dest_key)
void add_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key)

Add the value in self keyed by key to the value in value keyed by value_key and store the result in dest keyed by dest_key.

At least one of the three keys is guaranteed to not be NULL.

void subtract(INTERP, PMC* self, PMC* value, PMC* dest)
void subtract_int(INTERP, PMC* self, INTVAL value, PMC* dest)
void subtract_bignum(INTERP, PMC* self, BIGNUM* value, PMC* dest)
void subtract_float(INTERP, PMC* self, FLOATVAL value, PMC* dest)

Subtract self from value and store the result in dest. Note that dest may be equal to self; in that case optimizations may be made.

void subtract_same(INTERP, PMC* self, PMC* value, PMC* dest)

Subtract self from value and store the result in dest. Note that dest may be equal to self; in that case optimizations may be made. In this case, it is guaranteed that self and value are of the same type.

void subtract_keyed(INTERP, PMC* self, KEY* key, PMC* value, KEY* value_key, PMC* dest, KEY* dest_key)
void subtract_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key)

Subtract the value in self keyed by key from the value in value keyed by value_key and store the result in dest keyed by dest_key.

At least one of the three keys is guaranteed to not be NULL.

void multiply(INTERP, PMC* self, PMC* value, PMC* dest)
void multiply_int(INTERP, PMC* self, INTVAL value, PMC* dest)
void multiply_bignum(INTERP, PMC* self, BIGNUM* value, PMC* dest)
void multiply_float(INTERP, PMC* self, FLOATVAL value, PMC* dest)

Multiply value by self and store the result in dest. Note that dest may be equal to self; in that case optimizations may be made.

void multiply_same(INTERP, PMC* self, PMC* value, PMC* dest)

Multiply value by self and store the result in dest. Note that dest may be equal to self; in that case optimizations may be made. In this case, it is guaranteed that self and value are of the same type.

void multiply_keyed(INTERP, PMC* self, KEY* key, PMC* value, KEY* value_key, PMC* dest, KEY* dest_key)
void multiply_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key)

Multiply the value in self keyed by key by the value in value keyed by value_key and store the result in dest keyed by dest_key.

At least one of the three keys is guaranteed to not be NULL.

void divide(INTERP, PMC* self, PMC* value, PMC* dest)
void divide_int(INTERP, PMC* self, INTVAL value, PMC* dest)
void divide_bignum(INTERP, PMC* self, BIGNUM* value, PMC* dest)
void divide_float(INTERP, PMC* self, FLOATVAL value, PMC* dest)

Divide self by value and store the result in dest. Note that dest may be equal to self; in that case optimizations may be made.

void divide_same(INTERP, PMC* self, PMC* value, PMC* dest)

Divide self by value and store the result in dest. Note that dest may be equal to self; in that case optimizations may be made. In this case, it is guaranteed that self and value are of the same type.

void divide_keyed(INTERP, PMC* self, KEY* key, PMC* value, KEY* value_key, PMC* dest, KEY* dest_key)
void divide_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key)

Divide the value in self keyed by key by the value in value keyed by value_key and store the result in dest keyed by dest_key.

At least one of the three keys is guaranteed to not be NULL.

void modulus(INTERP, PMC* self, PMC* value, PMC* dest)
void modulus_int(INTERP, PMC* self, INTVAL value, PMC* dest)
void modulus_bignum(INTERP, PMC* self, BIGNUM* value, PMC* dest)
void modulus_float(INTERP, PMC* self, FLOATVAL value, PMC* dest)

Divide self by value and store the remainder in dest. Note that dest may be equal to self; in that case optimizations may be made.

void modulus_same(INTERP, PMC* self, PMC* value, PMC* dest)

Divide self by value and store the remainder in dest. Note that dest may be equal to self; in that case optimizations may be made. In this case, it is guaranteed that self and value are of the same type.

void modulus_keyed(INTERP, PMC* self, KEY* key, PMC* value, KEY* value_key, PMC* dest, KEY* dest_key)
void modulus_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key)

Divide the value in self keyed by key by the value in value keyed by value_key and store the remainder in dest keyed by dest_key.

At least one of the three keys is guaranteed to not be NULL.

void neg(INTERP, PMC* self, PMC* dest)

Negate the sign of self and store the result in dest. Note that self and dest may refer to the same PMC, in which case optimizations may be made.

void bitwise_or(INTERP, PMC* self, PMC* value, PMC* dest)
void bitwise_or_int(INTERP, PMC* self, INTVAL value, PMC* dest)

Calculate the bitwise-OR of self and value and store the result in dest. Note that dest may be equal to self; in that case optimizations may be made.

void bitwise_or_same(INTERP, PMC* self, PMC* value, PMC* dest)

Calculate the bitwise-OR of self and value and store the result in dest. Note that dest may be equal to self; in that case optimizations may be made. In this case, it is guaranteed that self and value are of the same type.

void bitwise_or_keyed(INTERP, PMC* self, KEY* key, PMC* value, KEY* value_key, PMC* dest, KEY* dest_key)
void bitwise_or_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key)

Calculate the bitwise-OR of self keyed by key and value keyed by value_key, and store the result in dest_key.

At least one of the keys is guaranteed to be non-NULL.

void bitwise_and(INTERP, PMC* self, PMC* value, PMC* dest)
void bitwise_and_int(INTERP, PMC* self, INTVAL value, PMC* dest)

Calculate the bitwise-AND of self and value and store the result in dest. Note that dest may be equal to self; in that case optimizations may be made.

void bitwise_and_same(INTERP, PMC* self, PMC* value, PMC* dest)

Calculate the bitwise-AND of self and value and store the result in dest. Note that dest may be equal to self; in that case optimizations may be made. In this case, it is guaranteed that self and value are of the same type.

void bitwise_and_keyed(INTERP, PMC* self, KEY* key, PMC* value, KEY* value_key, PMC* dest, KEY* dest_key)
void bitwise_and_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key)

Calculate the bitwise-AND of self keyed by key and value keyed by value_key, and store the result in dest_key.

At least one of the keys is guaranteed to be non-NULL.

void bitwise_xor(INTERP, PMC* self, PMC* value, PMC* dest)
void bitwise_xor_int(INTERP, PMC* self, INTVAL value, PMC* dest)

Calculate the bitwise-XOR of self and value and store the result in dest. Note that dest may be equal to self; in that case optimizations may be made.

void bitwise_xor_same(INTERP, PMC* self, PMC* value, PMC* dest)

Calculate the bitwise-XOR of self and value and store the result in dest. Note that dest may be equal to self; in that case optimizations may be made. In this case, it is guaranteed that self and value are of the same type.

void bitwise_xor_keyed(INTERP, PMC* self, KEY* key, PMC* value, KEY* value_key, PMC* dest, KEY* dest_key)
void bitwise_xor_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key)

Calculate the bitwise-XOR of self keyed by key and value keyed by value_key, and store the result in dest_key.

At least one of the keys is guaranteed to be non-NULL.

void bitwise_not(INTERP, PMC* self, PMC* dest)

Applies a bitwise negation to self and stores the result in dest. Note that self and dest may refer to the same PMC; in that case optimizations may be made.

void bitwise_not_keyed(INTERP, PMC* self, KEY* key, PMC* dest, KEY* dest_key)
void bitwise_not_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* dest, INTVAL* dest_key)

Applies a bitwise negation to self keyed by key and stores the result in dest keyed by dest_key.

At least one key is guaranteed to be non-NULL.

void concatenate(INTERP, PMC* self, PMC* value, PMC* dest)
void concatenate_native(INTERP, PMC* self, STRING* value, PMC* dest)
void concatenate_unicode(INTERP, PMC* self, STRING* value, PMC* dest)
void concatenate_other(INTERP, PMC* self, STRING* value, PMC* dest)

Concatenate the strings in self and value and store the result in dest. Note that self and dest may refer to the same PMC; in that case optimizations may be made.

void concatenate_same(INTERP, PMC* self, PMC* value, PMC* dest)

Concatenate the strings in self and value and store the result in dest. Note that self and dest may refer to the same PMC; in that case optimizations may be made. In this case, self and value are guaranteed to be of the same type.

void concatenate_keyed(INTERP, PMC* self, KEY* key, PMC* value, KEY* value_key, PMC* dest, KEY* dest_key)
void concatenate_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key)

Concatentate the string in value keyed by value_key onto the string in self keyed by key and store the result in dest keyed by dest_key.

At least one of the three keys is guaranteed to not be NULL.

INTVAL is_equal(INTERP, PMC* self, PMC* value)

Returns TRUE if the two PMCs are generically equivalent, or FALSE if they aren't.

INTVAL is_equal_keyed(INTERP, PMC* self, KEY* key, PMC* value, KEY* value_key)

Returns TRUE if the PMC at self keyed by key is generally equivalent to the PMC at value keyed by value_key, or FALSE if they aren't.

INTVAL cmp(INTERP, PMC* self, PMC* value)

Compares the two PMCs as PMCs (whatever that means for the class). Returns -1 if self is smaller, 0 if the two are equal, and 1 if value is smaller.

INTVAL cmp_keyed(INTERP, PMC* self, KEY* key, PMC* value, KEY* value_key)
INTVAL cmp_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key)

Compares the PMC at self keyed by key with the PMC at value keyed by value_key as PMCs (whatever that means for the class). Returns -1 if self is smaller, 0 if the two are equal, and 1 if value is smaller.

At least one key is guaranteed to be not NULL.

INTVAL cmp_num(INTERP, PMC* self, PMC* value)

Compares the two PMCs numerically. Returns -1 if self is smaller, 0 if the two are equal, and 1 if value is smaller.

INTVAL cmp_num_keyed(INTERP, PMC* self, KEY* key, PMC* value, KEY* value_key)
INTVAL cmp_num_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key)

Compares the PMC at self keyed by key with the PMC at value keyed by value_key numerically. Returns -1 if self is smaller, 0 if the two are equal, and 1 if value is smaller.

At least one key is guaranteed to be not NULL.

INTVAL cmp_string(INTERP, PMC* self, PMC* value)

Compares the two PMCs as strings. Returns -1 if self is smaller, 0 if the two are equal, and 1 if value is smaller.

INTVAL cmp_string_keyed(INTERP, PMC* self, KEY* key, PMC* value, KEY* value_key)
INTVAL cmp_string_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key)

Compares the PMC at self keyed by key with the PMC at value keyed by value_key numerically. Returns -1 if self is smaller, 0 if the two are equal, and 1 if value is smaller.

At least one key is guaranteed to be not NULL.

void logical_or(INTERP, PMC* self, PMC* value, PMC* dest)

Does a short-circuiting logical-OR of self and value, storing the winner in dest.

void logical_or_keyed(INTERP, PMC* self, KEY* key, PMC* value, KEY* value_key, PMC* dest, KEY* dest_key)
void logical_or_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key)

Does a short-circuiting logical-OR of self keyed by key and value keyed by value_key, storing the winner in dest keyed by dest_key.

At least one key is guaranteed to be not NULL.

void logical_and(INTERP, PMC* self, PMC* value, PMC* dest)

Does a short-circuiting logical-AND of self and value, storing the winner in dest.

void logical_and_keyed(INTERP, PMC* self, KEY* key, PMC* value, KEY* value_key, PMC* dest, KEY* dest_key)
void logical_and_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key)

Does a short-circuiting logical-AND of self keyed by key and value keyed by value_key, storing the winner in dest keyed by dest_key.

At least one key is guaranteed to be not NULL.

void logical_xor(INTERP, PMC* self, PMC* value, PMC* dest)

If exactly one of self or value is true, store it in dest. Else set dest to be false.

void logical_xor_keyed(INTERP, PMC* self, KEY* key, PMC* value, KEY* value_key, PMC* dest, KEY* dest_key)
void logical_xor_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key)

If exactly one of self keyed by key or value keyed by value_key is true, store it in dest keyed by dest_key. Else set dest keyed by dest_key to be false.

At least one key is guaranteed to be not NULL.

void logical_not(INTERP, PMC* self, PMC* dest)

Does a logical-NOT on self and stores the result in dest.

void logical_not_keyed(INTERP, PMC* self, KEY* key, PMC* dest, KEY* dest_key)
void logical_not_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* dest, INTVAL* dest_key)

Does a logical-NOT on self keyed by key and stores the result in dest keyed by dest_key.

At least one key is guaranteed to be not NULL.

void repeat(INTERP, PMC* self, PMC* value, PMC* dest)
void repeat_int(INTERP, PMC* self, INTVAL value, PMC* dest)

Repeat the string value of self value times and store the resultant string in dest.

void repeat_keyed(INTERP, PMC* self, KEY* key, PMC* value, KEY* value_key, PMC* dest, KEY* dest_key)
void repeat_keyed_int(INTERP, PMC* self, INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key)

Repeat the string in self keyed by key by the quantity of value keyed by value_key and store the result in dest keyed by dest_key.

At least one key is guaranteed to be not NULL.

void repeat_int_keyed(INTERP, PMC* self, KEY* key, INTVAL value, PMC* dest, KEY* dest_key)
void repeat_int_keyed_int(INTERP, PMC* self, INTVAL* key, INTVAL value, PMC* dest, INTVAL* dest_key)

Repeat the string in self keyed by key value times and store the result in dest keyed by dest_key.

At least one key is guaranteed to be not NULL.

void increment(INTERP, PMC* self)

Autoincrement the PMC.

void increment_keyed(INTERP, PMC* self, KEY* key)
void increment_keyed_int(INTERP, PMC* self, INTVAL* key)

Autoincrement the PMC keyed by key. The key is guaranteed to be non-NULL.

void decrement(INTERP, PMC* self)

Autodecrement the PMC.

void decrement_keyed(INTERP, PMC* self, KEY* key)
void decrement_keyed_int(INTERP, PMC* self, INTVAL* key)

Autodecrement the PMC keyed by key. The key is guaranteed to be non-NULL.

INTVAL exists_keyed(INTERP, PMC* self, KEY* key)
INTVAL exists_keyed_int(INTERP, PMC* self, INTVAL* key)

This is only valid for keyed access. Returns TRUE or FALSE if the key exists or doesn't in the aggregate being queried.

The key is guaranteed to not be NULL.

INTVAL defined(INTERP, PMC* self)

Checks to see if the PMC is defined. Returns TRUE or FALSE.

INTVAL defined_keyed(INTERP, PMC* self, KEY* key)
INTVAL defined_keyed_int(INTERP, PMC* self, INTVAL* key)

Returns TRUE if the value of self keyed by key is defined, FALSE otherwise.

The key is guaranteed to be not NULL.

void delete_keyed(INTERP, PMC* self, KEY* key)
void delete_keyed_int(INTERP, PMC* self, INTVAL* key)

Delete the specified entry from the aggregate.

The key is guaranteed to be not NULL.

KEY* nextkey_keyed(INTERP, PMC* self, KEY* key)
KEY* nextkey_keyed_int(INTERP, PMC* self, INTVAL* key)

Given the passed in key for the PMC, return the next key.

The key is guaranteed to be not NULL.

void substr(INTERP, PMC* self, INTVAL offset, INTVAL length, PMC* dest)

Place the value of the substring of self into dest.

void substr_keyed(INTERP, PMC* self, KEY* key, INTVAL offset, INTVAL length, PMC* dest, KEY* dest_key)
void substr_keyed_int(INTERP, PMC* self, INTVAL* key, INTVAL offset, INTVAL length, PMC* dest, INTVAL* dest_key)

Place the value of the substring of self keyed by key into dest keyed by dest_key.

At least one key is guaranteed to be not NULL.

STRING* substr_str(INTERP, PMC* self, INTVAL offset, INTVAL length)

Return a substring of the passed in PMC.

STRING* substr_str_keyed(INTERP, PMC* self, KEY* key, INTVAL offset, INTVAL length)
STRING* substr_str_keyed_int(INTERP, PMC* self, INTVAL* key, INTVAL offset, INTVAL length)

Return a substring of self keyed by key.

The key is guaranteed to be not NULL.