# New Ticket Created by  Cory Spencer 
# Please include the string:  [perl #34970]
# in the subject line of all future correspondence about this issue. 
# <URL: https://rt.perl.org/rt3/Ticket/Display.html?id=34970 >



The getattribute opcode previously threw an internal exception when an 
attribute wasn't found in a class.  This type of exception is uncatchable 
with Parrot exception handlers.  The included patch allows a real, 
catchable exception to be thrown in these cases.
diff -ur parrot-from/include/parrot/exceptions.h 
parrot-to/include/parrot/exceptions.h

--- parrot-from/include/parrot/exceptions.h     2005-04-13 17:08:08.000000000 
-0700

+++ parrot-to/include/parrot/exceptions.h       2005-04-13 17:09:17.000000000 
-0700

@@ -115,6 +115,7 @@

         NO_CLASS,

         LEX_NOT_FOUND,

         PAD_NOT_FOUND,

+        ATTRIB_NOT_FOUND,

         GLOBAL_NOT_FOUND,

         METH_NOT_FOUND,

         WRITE_TO_CONSTCLASS,

diff -ur parrot-from/src/objects.c parrot-to/src/objects.c

--- parrot-from/src/objects.c   2005-04-13 17:08:08.000000000 -0700

+++ parrot-to/src/objects.c     2005-04-13 17:08:48.000000000 -0700

@@ -1,6 +1,6 @@

 /*

 Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.

-$Id: objects.c 7826 2005-04-13 23:38:16Z chromatic $

+$Id: objects.c 7785 2005-04-06 11:50:59Z leo $

 

 =head1 NAME

 

@@ -52,7 +52,7 @@

     return new_array;

 }

 

-/* Take the class and completely rebuild the attribute stuff for

+/* Take the class and completely rebuild the atttribute stuff for

    it. Horribly destructive, and definitely not a good thing to do if

    there are instantiated objects for the class */

 static void

@@ -173,7 +173,7 @@

 

 Create a vtable that dispatches either to the contained PMC in the first

 attribute (deleg_pmc) or to an overridden method (delegate), depending

-on the existence of the method for this class.

+on the existance of the method for this class.

 

 =cut

 

@@ -446,7 +446,7 @@

 parrot_class_register(Interp* interpreter, STRING *class_name,

         PMC *new_class, PMC *mro)>

 

-This is the way to register a new Parrot class as an instantiable

+This is the way to register a new Parrot class as an instantiatable

 type. Doing this involves putting it in the class hash, setting its

 vtable so that the C<init> method initializes objects of the class rather than

 the class itself, and adding it to the interpreter's base type table so

@@ -1192,7 +1192,7 @@

 

 */

 

-/* Life is ever so much easier if a class keeps its attributes at the

+/* Life is ever so much easiser if a class keeps its attributes at the

    end of the attribute array, since we don't have to insert and

    reorder attributes. Inserting's no big deal, especially since we're

    going to break horribly if you insert into a class that's been

@@ -1281,8 +1281,12 @@

     attrib_array = PMC_data(object);

     attrib_count = ATTRIB_COUNT(object);

     if (attrib >= attrib_count || attrib < POD_FIRST_ATTRIB) {

+        real_exception(interpreter, NULL, ATTRIB_NOT_FOUND,

+                       "Attribute '%d' not found", attrib);

+        /*

         internal_exception(OUT_OF_BOUNDS,

                 "No such attribute #%d", (int)attrib);

+        */

     }

     return get_attrib_num(attrib_array, attrib);

 }

@@ -1294,7 +1298,9 @@

     PMC *attr_hash;

     SLOTTYPE *class_array;

     HashBucket *b;

-    char *cattr, *cobj;

+    STRING *delimit;

+    STRING *attr_name;

+    int index, length;

 

     if (!PObj_is_object_TEST(object))

         internal_exception(INTERNAL_NOT_IMPLEMENTED,

@@ -1307,12 +1313,21 @@

                 (Hash*) PMC_struct_val(attr_hash), attr);

     if (b)

         return VTABLE_get_integer(interpreter, (PMC*)b->value);

-    /* escape the NUL char */

-    cobj = string_to_cstring(interpreter, attr);

-    cattr = cobj + strlen(cobj) + 1;

-    internal_exception(1, "No such attribute '%s\\0%s'",

-            cobj, cattr);

-    string_cstring_free(cattr);

+

+    /* Create a delimiter for splitting up the Class\0attribute syntax. */

+    delimit = string_from_cstring(interpreter, "\0", 1);

+

+    /* Calculate the offset and the length of the attribute string. */

+    index  = string_str_index(interpreter, attr, delimit, 0) + 1;

+    length = string_length(interpreter, attr) - index;

+

+    /* Extract the attribute name and throw the exception. */

+    attr_name = string_from_cstring(interpreter, "", 0);

+    attr_name = string_substr(interpreter, attr, index, length, attr_name, 0);

+

+    real_exception(interpreter, NULL, ATTRIB_NOT_FOUND,

+                   "Attribute '%Ss' not found", attr_name);

+

     return 0;

 }

 

Reply via email to