Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tag: RELEASE_0_5_2
Fetching contributors…

Cannot retrieve contributors at this time

423 lines (270 sloc) 8.027 kb
/*
Copyright (C) 2001-2007, The Perl Foundation.
$Id$
=head1 NAME
src/pmc/exception.pmc - Exception PMC
=head1 DESCRIPTION
This is the exception base class.
For now, this class is based on C<ResziablePMCArray>. This will change when the
full PMC PDD is implemented.
An exception object has these attributes:
=over 4
=item 0 C<_message>
Textual representation of the exception.
=item 1 C<_type>
The exception type, (see F<include/parrot/exceptions.h>, F<except_type.pasm>).
=item 2 C<_severity>
The severity of the exception, (see F<src/exceptions.h>,
F<except_severity.pasm>).
=item 3 C<payload>
Additional data for the exception.
=item 4 C<unused>
=back
Optional:
=over 4
=item 5 C<_C_file>
The C code file in which the exception was raised.
=item 6 C<_C_line>
The line of C code on which the exception was raised.
=item 7 C<_P_file>
The PASM/PIR/Perl file in which the exception was raised.
=item 8 C<_P_line>
The line of PASM/PIR/Perl code on which the exception was raised.
=item 9, 10 C<unused>
Any information attached by the HL. This shouldn't start with an
underscore (that is reserved for Parrot's internal usage. These are
stored as properties.
Note: currently, HLL information must be indexed by number. Slots 9 and 10
are available for the HLL - This is subject to change.
=back
When an exception handler is called, the exception object is passed as
as the first argument, the message as the second argument of the call.
These arguments can be retrieved with the C<get_results> opcode.
=cut
*/
#include "parrot/parrot.h"
/* This finds the index of an attribute in an object's attribute store and
* returns it. Returns -1 if the attribute does not exist. */
static INTVAL
get_attrib_index(PARROT_INTERP, PMC *self, STRING *name)
{
if (!string_compare(interp, name, CONST_STRING(interp, "message")))
return 0;
if (!string_compare(interp, name, CONST_STRING(interp, "type")))
return 1;
if (!string_compare(interp, name, CONST_STRING(interp, "severity")))
return 2;
if (!string_compare(interp, name, CONST_STRING(interp, "payload")))
return 3;
return -1;
}
/*
=head2 Methods
=over 4
=cut
*/
pmclass Exception extends ResizablePMCArray need_ext {
/*
=item C<void init()>
Initializes the exception with default values.
=cut
*/
void init() {
SUPER();
/* pre-fill 11 slots with PMCNULL */
DYNSELF.set_integer_native(11);
}
/*
=item C<STRING *get_string_keyed(PMC *key)>
Returns the Parrot string value for C<*key>. The only current recognized
C<key> is "_message".
=item C<STRING *get_string()>
Return the exception message.
=cut
*/
STRING *get_string_keyed(PMC *key) {
STRING *s = key_string(INTERP, key);
if (!string_compare(INTERP, s, CONST_STRING(INTERP, "_message")))
return DYNSELF.get_string_keyed_int(0);
return 0;
}
STRING *get_string() {
return DYNSELF.get_string_keyed_int(0);
}
/*
=item C<INTVAL get_integer_keyed(PMC *key)>
Returns the integer value for C<*key>.
=cut
*/
INTVAL get_integer_keyed(PMC *key) {
STRING *s = key_string(INTERP, key);
if (!string_compare(INTERP, s, CONST_STRING(INTERP, "_type")))
return DYNSELF.get_integer_keyed_int(1);
if (!string_compare(INTERP, s, CONST_STRING(INTERP, "_severity")))
return DYNSELF.get_integer_keyed_int(2);
return 0;
}
/*
=item C<PMC *get_pmc_keyed(PMC *key)>
Returns the PMC value for C<*key>.
=cut
*/
PMC *get_pmc_keyed(PMC *key) {
STRING *s = key_string(INTERP, key);
return DYNSELF.getprop(s);
}
/*
=item C<PMC *get_pmc_keyed_int(INTVAL key)>
Returns the PMC value of the element at index C<key>, but ignores too
big negative keys.
=cut
*/
PMC *get_pmc_keyed_int(INTVAL key) {
if (key <= -PMC_int_val(SELF))
return PMCNULL;
return SUPER(key);
}
/*
=item C<void set_string_keyed(PMC *key, STRING *value)>
Sets the Parrot string value for C<*key>.
=cut
*/
void set_string_keyed(PMC *key, STRING *value) {
STRING *s = key_string(INTERP, key);
if (!string_compare(INTERP, s, CONST_STRING(INTERP, "_message")))
DYNSELF.set_string_keyed_int(0, value);
}
/*
=item C<void set_integer_keyed(PMC *key, INTVAL value) >
Sets the integer value for C<*key>.
=cut
*/
void set_integer_keyed(PMC *key, INTVAL value) {
STRING *s = key_string(INTERP, key);
if (!string_compare(INTERP, s, CONST_STRING(INTERP, "_type")))
DYNSELF.set_integer_keyed_int(1, value);
if (!string_compare(INTERP, s, CONST_STRING(INTERP, "_severity")))
DYNSELF.set_integer_keyed_int(2, value);
}
/*
=item C<void set_pmc_keyed(PMC *key, PMC *value)>
Sets the PMC value for C<*key>.
=cut
*/
void set_pmc_keyed(PMC *key, PMC *value) {
STRING *s = key_string(INTERP, key);
DYNSELF.setprop(s, value);
}
/*
=item C<INTVAL is_equal(PMC *value)>
Compare the passed in Exception with SELF. Returns True if C<SELF> isa C<value>
=cut
*/
INTVAL is_equal(PMC *value) {
if (value->vtable->base_type == enum_class_Exception ||
VTABLE_isa(INTERP, value, const_string(INTERP, "Exception"))) {
/* RT#46689 check parents */
return 1;
}
return 0;
}
/*
=item C<get_attr_str>
Retrieve an attribute value for the exception object.
=cut
*/
PMC *get_attr_str(STRING *name) {
INTVAL index = get_attrib_index(interp, SELF, name);
/* If lookup failed, exception. */
if (index == -1)
real_exception(interp, NULL, ATTRIB_NOT_FOUND,
"No such attribute '%S'", name);
return DYNSELF.get_pmc_keyed_int(index);
}
/*
=item C<set_attr_str>
Set an attribute value for the exception object.
=cut
*/
void set_attr_str(STRING *name, PMC *value) {
INTVAL index = get_attrib_index(interp, SELF, name);
/* If lookup failed, exception. */
if (index == -1)
real_exception(interp, NULL, ATTRIB_NOT_FOUND,
"No such attribute '%S'", name);
DYNSELF.set_pmc_keyed_int(index, value);
}
/*
=item C<shift_*>, C<unshift_*>, C<pop_*>, C<push_*>
These methods are silently ignored.
=cut
*/
PMC *shift_pmc() {
/* fprintf(stderr, "don't do that then\n"); RT#46691 */
return PMCNULL;
}
FLOATVAL shift_float() {
(void) SELF.shift_pmc();
return 0.0;
}
INTVAL shift_integer() {
(void) SELF.shift_pmc();
return 0;
}
STRING *shift_string() {
(void) SELF.shift_pmc();
return NULL;
}
void unshift_pmc(PMC *value) {
/* fprintf(stderr, "don't do that then\n"); RT#46691 */
}
void unshift_float(FLOATVAL value) {
SELF.unshift_pmc(NULL);
}
void unshift_integer(INTVAL value) {
SELF.unshift_pmc(NULL);
}
void unshift_string(STRING *value) {
SELF.unshift_pmc(NULL);
}
void push_pmc(PMC *value) {
/* fprintf(stderr, "don't do that then\n"); RT#46691 */
}
void push_float(FLOATVAL value) {
SELF.push_pmc(PMCNULL);
}
void push_integer(INTVAL value) {
SELF.push_pmc(PMCNULL);
}
void push_string(STRING *value) {
SELF.push_pmc(PMCNULL);
}
PMC *pop_pmc() {
/* fprintf(stderr, "don't do that then\n"); RT#46691 */
return PMCNULL;
}
FLOATVAL pop_float() {
(void) SELF.pop_pmc();
return 0.0;
}
INTVAL pop_integer() {
(void) SELF.pop_pmc();
return 0;
}
STRING *pop_string() {
(void) SELF.pop_pmc();
return NULL;
}
}
/*
=back
=head1 HISTORY
Initial revision by leo 2003.07.10.
=cut
*/
/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4:
*/
Jump to Line
Something went wrong with that request. Please try again.