# 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;
}