tagged release 0.6.4
[parrot.git] / src / pmc / exception.pmc
bloba92d6a6351379dd07fd296bee508c800c99d77be
1 /*
2 Copyright (C) 2001-2008, The Perl Foundation.
3 $Id$
5 =head1 NAME
7 src/pmc/exception.pmc - Exception PMC
9 =head1 DESCRIPTION
11 This is the exception base class.
13 For now, this class is based on C<ResziablePMCArray>. This will change when the
14 full PMC PDD is implemented.
16 An exception object has these attributes:
18 =over 4
20 =item 0 C<_message>
22 Textual representation of the exception.
24 =item 1 C<_type>
26 The exception type, (see F<include/parrot/exceptions.h>, F<except_type.pasm>).
28 =item 2 C<_severity>
30 The severity of the exception, (see F<src/exceptions.h>,
31 F<except_severity.pasm>).
33 =item 3 C<payload>
35 Additional data for the exception.
37 =item 4 C<unused>
39 =back
41 Optional:
43 =over 4
45 =item 5 C<_C_file>
47 The C code file in which the exception was raised.
49 =item 6 C<_C_line>
51 The line of C code on which the exception was raised.
53 =item 7 C<_P_file>
55 The PASM/PIR/Perl file in which the exception was raised.
57 =item 8 C<_P_line>
59 The line of PASM/PIR/Perl code on which the exception was raised.
61 =item 9, 10 C<unused>
63 Any information attached by the HL. This shouldn't start with an
64 underscore (that is reserved for Parrot's internal usage. These are
65 stored as properties.
67 Note: currently, HLL information must be indexed by number. Slots 9 and 10
68 are available for the HLL - This is subject to change.
70 =back
72 When an exception handler is called, the exception object is passed as
73 as the first argument, the message as the second argument of the call.
74 These arguments can be retrieved with the C<get_results> opcode.
76 =cut
80 #include "parrot/parrot.h"
82 /* This finds the index of an attribute in an object's attribute store and
83  * returns it. Returns -1 if the attribute does not exist. */
84 static INTVAL
85 get_attrib_index(PARROT_INTERP, PMC *self, STRING *name)
87         if (!string_compare(interp, name, CONST_STRING(interp, "message")))
88             return 0;
90         if (!string_compare(interp, name, CONST_STRING(interp, "type")))
91             return 1;
93         if (!string_compare(interp, name, CONST_STRING(interp, "severity")))
94             return 2;
96         if (!string_compare(interp, name, CONST_STRING(interp, "payload")))
97             return 3;
99             return -1;
104 =head2 Methods
106 =over 4
108 =cut
112 pmclass Exception extends ResizablePMCArray need_ext {
116 =item C<void init()>
118 Initializes the exception with default values.
120 =cut
124     VTABLE void init() {
125         SUPER();
126         /* pre-fill 11 slots with PMCNULL */
127         SELF.set_integer_native(11);
128     }
132 =item C<STRING *get_string_keyed(PMC *key)>
134 Returns the Parrot string value for C<*key>. The only current recognized
135 C<key> is "_message".
137 =item C<STRING *get_string()>
139 Return the exception message.
141 =cut
145     VTABLE STRING *get_string_keyed(PMC *key) {
146         STRING *s = key_string(INTERP, key);
148         if (!string_compare(INTERP, s, CONST_STRING(INTERP, "_message")))
149             return SELF.get_string_keyed_int(0);
151         return 0;
152     }
154     VTABLE STRING *get_string() {
155         return SELF.get_string_keyed_int(0);
156     }
160 =item C<INTVAL get_integer_keyed(PMC *key)>
162 Returns the integer value for C<*key>.
164 =cut
168     VTABLE INTVAL get_integer_keyed(PMC *key) {
169         STRING *s = key_string(INTERP, key);
171         if (!string_compare(INTERP, s, CONST_STRING(INTERP, "_type")))
172             return SELF.get_integer_keyed_int(1);
174         if (!string_compare(INTERP, s, CONST_STRING(INTERP, "_severity")))
175             return SELF.get_integer_keyed_int(2);
177         return 0;
178     }
182 =item C<PMC *get_pmc_keyed(PMC *key)>
184 Returns the PMC value for C<*key>.
186 =cut
190     VTABLE PMC *get_pmc_keyed(PMC *key) {
191         STRING *s = key_string(INTERP, key);
192         return SELF.getprop(s);
193     }
197 =item C<PMC *get_pmc_keyed_int(INTVAL key)>
199 Returns the PMC value of the element at index C<key>, but ignores too
200 big negative keys.
202 =cut
206     VTABLE PMC *get_pmc_keyed_int(INTVAL key) {
207         if (key <= -PMC_int_val(SELF))
208             return PMCNULL;
210         return SUPER(key);
211     }
215 =item C<void set_string_keyed(PMC *key, STRING *value)>
217 Sets the Parrot string value for C<*key>.
219 =cut
223     VTABLE void set_string_keyed(PMC *key, STRING *value) {
224         STRING *s = key_string(INTERP, key);
226         if (!string_compare(INTERP, s, CONST_STRING(INTERP, "_message")))
227             SELF.set_string_keyed_int(0, value);
228     }
232 =item C<void set_integer_keyed(PMC *key, INTVAL value) >
234 Sets the integer value for C<*key>.
236 =cut
240     VTABLE void set_integer_keyed(PMC *key, INTVAL value) {
241         STRING *s = key_string(INTERP, key);
243         if (!string_compare(INTERP, s, CONST_STRING(INTERP, "_type")))
244             SELF.set_integer_keyed_int(1, value);
246         if (!string_compare(INTERP, s, CONST_STRING(INTERP, "_severity")))
247             SELF.set_integer_keyed_int(2, value);
248     }
252 =item C<void set_pmc_keyed(PMC *key, PMC *value)>
254 Sets the PMC value for C<*key>.
256 =cut
260     VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
261         STRING *s = key_string(INTERP, key);
262         SELF.setprop(s, value);
263     }
266 =item C<INTVAL is_equal(PMC *value)>
268 Compare the passed in Exception with SELF. Returns True if C<SELF> isa C<value>
270 =cut
273     VTABLE INTVAL is_equal(PMC *value) {
274         /* RT#46689 check parents */
275         if (value->vtable->base_type == enum_class_Exception
276         ||  VTABLE_isa(INTERP, value, CONST_STRING(INTERP, "Exception")))
277             return 1;
279         return 0;
280     }
284 =item C<get_attr_str>
286 Retrieve an attribute value for the exception object.
288 =cut
291     VTABLE PMC *get_attr_str(STRING *name) {
292         INTVAL index = get_attrib_index(interp, SELF, name);
294         /* If lookup failed, exception. */
295         if (index == -1)
296             real_exception(interp, NULL, ATTRIB_NOT_FOUND,
297                 "No such attribute '%S'", name);
299        return SELF.get_pmc_keyed_int(index);
300     }
304 =item C<set_attr_str>
306 Set an attribute value for the exception object.
308 =cut
311     VTABLE void set_attr_str(STRING *name, PMC *value) {
312         INTVAL index = get_attrib_index(interp, SELF, name);
314         /* If lookup failed, exception. */
315         if (index == -1)
316             real_exception(interp, NULL, ATTRIB_NOT_FOUND,
317                 "No such attribute '%S'", name);
319         SELF.set_pmc_keyed_int(index, value);
320     }
324 =item C<shift_*>, C<unshift_*>, C<pop_*>, C<push_*>
326 These methods are silently ignored.
328 =cut
331     VTABLE PMC *shift_pmc() {
332         /* fprintf(stderr, "don't do that then\n"); RT#46691 */
333         return PMCNULL;
334     }
336     VTABLE FLOATVAL shift_float() {
337         (void) SELF.shift_pmc();
338         return 0.0;
339     }
341     VTABLE INTVAL shift_integer() {
342         (void) SELF.shift_pmc();
343         return 0;
344     }
346     VTABLE STRING *shift_string() {
347         (void) SELF.shift_pmc();
348         return NULL;
349     }
351     void unshift_pmc(PMC *value) {
352         /* fprintf(stderr, "don't do that then\n"); RT#46691 */
353     }
355     VTABLE void unshift_float(FLOATVAL value) {
356         SELF.unshift_pmc(NULL);
357     }
359     VTABLE void unshift_integer(INTVAL value) {
360         SELF.unshift_pmc(NULL);
361     }
363     VTABLE void unshift_string(STRING *value) {
364         SELF.unshift_pmc(NULL);
365     }
367     void push_pmc(PMC *value) {
368         /* fprintf(stderr, "don't do that then\n"); RT#46691 */
369     }
371     VTABLE void push_float(FLOATVAL value) {
372         SELF.push_pmc(PMCNULL);
373     }
375     VTABLE void push_integer(INTVAL value) {
376         SELF.push_pmc(PMCNULL);
377     }
379     VTABLE void push_string(STRING *value) {
380         SELF.push_pmc(PMCNULL);
381     }
383     VTABLE PMC *pop_pmc() {
384         /* fprintf(stderr, "don't do that then\n"); RT#46691 */
385         return PMCNULL;
386     }
388     VTABLE FLOATVAL pop_float() {
389         (void) SELF.pop_pmc();
390         return 0.0;
391     }
393     VTABLE INTVAL pop_integer() {
394         (void) SELF.pop_pmc();
395         return 0;
396     }
398     VTABLE STRING *pop_string() {
399         (void) SELF.pop_pmc();
400         return NULL;
401     }
406 =back
408 =head1 HISTORY
410 Initial revision by leo 2003.07.10.
412 =cut
417  * Local variables:
418  *   c-file-style: "parrot"
419  * End:
420  * vim: expandtab shiftwidth=4:
421  */