Author: jrieks
Date: Thu Apr 14 05:57:22 2005
New Revision: 7830

Modified:
   trunk/include/parrot/exceptions.h
   trunk/src/objects.c
Log:
[perl #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.

Committed with some tweaks to not break t/pmc/objects.t.

Courtesy of Cory Spencer


Modified: trunk/include/parrot/exceptions.h
==============================================================================
--- trunk/include/parrot/exceptions.h   (original)
+++ trunk/include/parrot/exceptions.h   Thu Apr 14 05:57:22 2005
@@ -115,6 +115,7 @@
         NO_CLASS,
         LEX_NOT_FOUND,
         PAD_NOT_FOUND,
+        ATTRIB_NOT_FOUND,
         GLOBAL_NOT_FOUND,
         METH_NOT_FOUND,
         WRITE_TO_CONSTCLASS,

Modified: trunk/src/objects.c
==============================================================================
--- trunk/src/objects.c (original)
+++ trunk/src/objects.c Thu Apr 14 05:57:22 2005
@@ -1281,7 +1281,7 @@
     attrib_array = PMC_data(object);
     attrib_count = ATTRIB_COUNT(object);
     if (attrib >= attrib_count || attrib < POD_FIRST_ATTRIB) {
-        internal_exception(OUT_OF_BOUNDS,
+        real_exception(interpreter, NULL, ATTRIB_NOT_FOUND,
                 "No such attribute #%d", (int)attrib);
     }
     return get_attrib_num(attrib_array, attrib);
@@ -1294,7 +1294,10 @@
     PMC *attr_hash;
     SLOTTYPE *class_array;
     HashBucket *b;
-    char *cattr, *cobj;
+    STRING *delimit;
+    STRING *attr_name;
+    STRING *obj_name;
+    int index, length;
 
     if (!PObj_is_object_TEST(object))
         internal_exception(INTERNAL_NOT_IMPLEMENTED,
@@ -1307,12 +1310,22 @@
                 (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 and object name. */
+    attr_name = string_substr(interpreter, attr, index, length, 0, 0);
+    obj_name = string_substr(interpreter, attr, 0, index-1, 0, 0);
+
+    real_exception(interpreter, NULL, ATTRIB_NOT_FOUND,
+           "No such attribute '%Ss\\0%Ss'",
+           obj_name, attr_name);
+
     return 0;
 }
 
@@ -1353,7 +1366,7 @@
     attrib_array = PMC_data(object);
     attrib_count = ATTRIB_COUNT(object);
     if (attrib >= attrib_count || attrib < POD_FIRST_ATTRIB) {
-        internal_exception(OUT_OF_BOUNDS,
+        real_exception(interpreter, NULL, ATTRIB_NOT_FOUND,
                 "No such attribute #%d", (int)attrib);
     }
     set_attrib_num(object, attrib_array, attrib, value);

Reply via email to