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);