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

Reply via email to