Author: fperrad
Date: Sun Jan 15 22:59:02 2006
New Revision: 11206
Modified:
trunk/languages/lua/classes/luatable.pmc
Log:
Lua :
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)
Courtesy of Klaas-Jan Stol.
Modified: trunk/languages/lua/classes/luatable.pmc
==============================================================================
--- trunk/languages/lua/classes/luatable.pmc (original)
+++ trunk/languages/lua/classes/luatable.pmc Sun Jan 15 22:59:02 2006
@@ -71,6 +71,25 @@ Return the string "table".
/*
+=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()>
In Lua, both C<nil> and C<false> make a condition false; any other values
@@ -91,16 +110,25 @@ So return always true.
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
*/
PMC* get_pmc_keyed (PMC* key) {
+ PMC *newcopy;
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;
+ newcopy = retval->vtable->clone(INTERP, retval);
+ return newcopy;
}
/*
@@ -109,17 +137,29 @@ C<table> accessor.
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) {
+
+ /* 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);
}
}
@@ -152,6 +192,8 @@ Return always false.
return (PMC*)0;
}
+ /* TODO: Implement the Metamethod mechanism, see the Lua ref.man. */
+
PMC* subtract (PMC* value, PMC* dest) {
return (PMC*)0;
}