this patch changes the behaviour of the LuaTable PMC.
changes have to do with the reference semantics that PMCs have, and
LuaTables should not have.
Setting and getting a value now will set (and get) a copy of the value.
Clone() returns a reference to itself, as clone() should be used for
register to register copying (due to the by-value semantics of Lua values)
regards,
klaas-jan
--- languages/lua/classes/luatable.pmc 2006-01-13 16:34:42.000000000 +0100
+++ languages/lua/classes/newluatable.pmc 2006-01-13 16:37:42.000000000
+0100
@@ -68,6 +68,31 @@
return Parrot_sprintf_c(INTERP, "table: %08X", SELF);
}
+
+/*
+
+=item C<PMC* clone()>
+
+PMCs are always handled by-reference in Parrot. So, copying register contents
only copies
+the reference to the PMC. For LuaString, LuaNumber, LuaBoolean, this is not
correct,
+as Lua has by-value semantics for these types. In order to be able to handle
register
+"move" instructions, this should be implemented using clone(). However,
LuaTable and LuaFunction
+do have by-reference semantics. As you don't know the type during compile-time
of an object,
+just always use clone() to copy register contents. LuaTable and LuaFunction
should therefore
+only clone the reference to themselves, not make a deep copy.
+
+=cut
+
+*/
+
+ PMC* clone() {
+ return SELF;
+ }
+
+
+
+
+
/*
=item C<INTVAL get_bool()>
@@ -90,6 +115,13 @@
C<table> accessor.
+A copy of the value is retrieved, otherwise, this could happen:
+
+ temp = table[key]
+ temp = <some other value>
+ temp2 = table[key]
+ # temp2 is now <some other value> due to the by-reference semantics of
PMCs
+
=cut
*/
@@ -97,9 +129,10 @@
PMC *retval = SUPER(key);
if (enum_class_None == retval->vtable->base_type) {
- return Lua_Nil;
+ return Lua_Nil; /* should we create a New LuaNil object every
time? Or is returning the same LuaNil over and over again ok? */
}
- return retval;
+ PMC *newcopy = retval->vtable->clone(INTERP, retval);
+ return newcopy;
}
/*
@@ -108,22 +141,36 @@
C<table> mutator.
+A copy of the value is stored, otherwise, this could happen:
+
+ table[key] = value
+ value = <some other value>
+ temp = table[key]
+ # temp is now <some other value> due to the by-reference semantics of
PMCs
+
=cut
*/
void set_pmc_keyed (PMC* key, PMC* value) {
- if (key == Lua_Nil) {
+
+ /* XXX should check for "isa", not equality with "==", since LuaNil is
no singular anymore */
+
+ if (key == Lua_Nil) {
real_exception(INTERP, NULL, 1, "table index is nil");
}
+
if (value == Lua_Nil) {
Hash.SELF.delete_keyed(key);
- } else {
- SUPER(key, value);
+ }
+ else {
+
+ PMC *newcopy = value->vtable->clone(INTERP, value);
+ SUPER(key, newcopy);
}
}
/*
-
+0
=item C<PMC logical_not(PMC *dest)>
Return always false.
@@ -150,6 +197,8 @@
return (PMC*)0;
}
+ /* TODO: Implement the Metamethod mechanism, see the Lua ref.man. */
+
PMC* subtract (PMC* value, PMC* dest) {
return (PMC*)0;
}