aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Germain <bnt.germain@gmail.com>2021-06-23 12:38:01 +0200
committerBenoit Germain <bnt.germain@gmail.com>2021-06-23 12:38:01 +0200
commitd1ef9b97e356805c622e4832ec76289bae391a6e (patch)
treee00a1a4b1c16bcc02d0e6c75d664d93e76f8d606
parent5875fe44ba7a240dd101f954c7dc83337a0c2cef (diff)
downloadlanes-d1ef9b97e356805c622e4832ec76289bae391a6e.tar.gz
lanes-d1ef9b97e356805c622e4832ec76289bae391a6e.tar.bz2
lanes-d1ef9b97e356805c622e4832ec76289bae391a6e.zip
__lanesclone now receives the original as light userdata the first time it is called
-rw-r--r--CHANGES5
-rw-r--r--deep_test/deep_test.c12
-rw-r--r--docs/index.html25
-rw-r--r--src/tools.c10
4 files changed, 35 insertions, 17 deletions
diff --git a/CHANGES b/CHANGES
index c3893d0..792a52b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,7 +1,10 @@
1CHANGES: 1CHANGES:
2 2
3CHANGE 148: BGe 23-Jun-21
4 * __lanesclone now receives the original as light userdata the first time it is called -> BREAKS CUSTOM DEEP USERDATA API
5
3CHANGE 147: BGe 16-Jun-21 6CHANGE 147: BGe 16-Jun-21
4 * changed lanes.threads() output so that several lanes with the same name don't clobber each other in the result table 7 * changed lanes.threads() output so that several lanes with the same name don't clobber each other in the result table -> BREAKS API
5 * bumped version to 3.15 because of the API change 8 * bumped version to 3.15 because of the API change
6 9
7CHANGE 146: BGe 26-Apr-19 10CHANGE 146: BGe 26-Apr-19
diff --git a/deep_test/deep_test.c b/deep_test/deep_test.c
index 9585a3c..61c81c5 100644
--- a/deep_test/deep_test.c
+++ b/deep_test/deep_test.c
@@ -166,8 +166,12 @@ static int clonable_lanesclone( lua_State* L)
166{ 166{
167 switch( lua_gettop( L)) 167 switch( lua_gettop( L))
168 { 168 {
169 case 0: 169 case 1:
170 lua_pushinteger( L, sizeof( struct s_MyClonableUserdata)); 170 {
171 // in case we need it to compute the amount of memory we need
172 struct s_MyClonableUserdata* self = lua_touserdata( L, 1);
173 lua_pushinteger( L, sizeof( struct s_MyClonableUserdata));
174 }
171 return 1; 175 return 1;
172 176
173 case 2: 177 case 2:
@@ -175,8 +179,8 @@ static int clonable_lanesclone( lua_State* L)
175 struct s_MyClonableUserdata* self = lua_touserdata( L, 1); 179 struct s_MyClonableUserdata* self = lua_touserdata( L, 1);
176 struct s_MyClonableUserdata* from = lua_touserdata( L, 2); 180 struct s_MyClonableUserdata* from = lua_touserdata( L, 2);
177 *self = *from; 181 *self = *from;
178 return 0;
179 } 182 }
183 return 0;
180 184
181 default: 185 default:
182 (void) luaL_error( L, "Lanes called clonable_lanesclone with unexpected parameters"); 186 (void) luaL_error( L, "Lanes called clonable_lanesclone with unexpected parameters");
@@ -223,7 +227,7 @@ extern int __declspec(dllexport) luaopen_deep_test(lua_State* L)
223{ 227{
224 luaL_newlib( L, deep_module); // M 228 luaL_newlib( L, deep_module); // M
225 229
226 // preregister the metatables for the types we can instanciate so that Lanes can know about them 230 // preregister the metatables for the types we can instantiate so that Lanes can know about them
227 if( luaL_newmetatable( L, "clonable")) // M mt 231 if( luaL_newmetatable( L, "clonable")) // M mt
228 { 232 {
229 luaL_setfuncs( L, clonable_mt, 0); 233 luaL_setfuncs( L, clonable_mt, 0);
diff --git a/docs/index.html b/docs/index.html
index 49b862f..e9a313e 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -64,13 +64,13 @@
64 <font size="-1"> 64 <font size="-1">
65 <p> 65 <p>
66 <br/> 66 <br/>
67 <i>Copyright &copy; 2007-19 Asko Kauppi, Benoit Germain. All rights reserved.</i> 67 <i>Copyright &copy; 2007-21 Asko Kauppi, Benoit Germain. All rights reserved.</i>
68 <br/> 68 <br/>
69 Lua Lanes is published under the same <a href="http://en.wikipedia.org/wiki/MIT_License">MIT license</a> as Lua 5.1, 5.2, 5.3 and 5.4. 69 Lua Lanes is published under the same <a href="http://en.wikipedia.org/wiki/MIT_License">MIT license</a> as Lua 5.1, 5.2, 5.3 and 5.4.
70 </p> 70 </p>
71 71
72 <p> 72 <p>
73 This document was revised on 26-Apr-19, and applies to version <tt>3.14.0</tt>. 73 This document was revised on 23-Jun-21, and applies to version <tt>3.15.0</tt>.
74 </p> 74 </p>
75 </font> 75 </font>
76 </center> 76 </center>
@@ -1548,23 +1548,31 @@ events to a common Linda, but... :).</font>
1548 1548
1549<h3 id="clonable_userdata">Clonable full userdata in your own apps</h3> 1549<h3 id="clonable_userdata">Clonable full userdata in your own apps</h3>
1550<p> 1550<p>
1551 Starting with version 3.13.0, a new way of passing full userdata across lanes uses a new <tt>__lanesclone</tt> metamethod. A typical implementation would look like: 1551 Starting with version 3.13.0, a new way of passing full userdata across lanes uses a new <tt>__lanesclone</tt> metamethod.
1552 When a deep userdata is cloned, Lanes calls <tt>__lanesclone</tt> twice, in the context of the source lane.</br>
1553 The first call receives the original as light userdata, as in <tt>ud:__lanesclone()</tt>, and should return the amount of memory used to create the cloned full userdata.</br>
1554 The second call receives the clone and original as light userdata, as in <tt>clone:__lanesclone(original)</tt>, and should perform the actual cloning.</br>
1555 A typical implementation would look like:
1552<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> 1556<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
1553static int clonable_lanesclone( lua_State* L) 1557static int clonable_lanesclone( lua_State* L)
1554{ 1558{
1555 switch( lua_gettop( L)) 1559 switch( lua_gettop( L))
1556 { 1560 {
1557 case 0: 1561 case 1: // original:__lanesclone()
1558 lua_pushinteger( L, sizeof( struct s_MyClonableUserdata)); 1562 {
1563 // the original (as light userdata), in case you need it to compute the size of the clone
1564 struct s_MyClonableUserdata* self = lua_touserdata( L, 1);
1565 lua_pushinteger( L, sizeof( struct s_MyClonableUserdata));
1566 }
1559 return 1; 1567 return 1;
1560 1568
1561 case 2: 1569 case 2: // clone:__lanesclone(original)
1562 { 1570 {
1563 struct s_MyClonableUserdata* self = lua_touserdata( L, 1); 1571 struct s_MyClonableUserdata* self = lua_touserdata( L, 1);
1564 struct s_MyClonableUserdata* from = lua_touserdata( L, 2); 1572 struct s_MyClonableUserdata* from = lua_touserdata( L, 2);
1565 *self = *from; 1573 *self = *from;
1566 return 0;
1567 } 1574 }
1575 return 0;
1568 1576
1569 default: 1577 default:
1570 (void) luaL_error( L, "Lanes called clonable_lanesclone with unexpected parameters"); 1578 (void) luaL_error( L, "Lanes called clonable_lanesclone with unexpected parameters");
@@ -1605,7 +1613,7 @@ int luaopen_deep_test(lua_State* L)
1605</p> 1613</p>
1606 1614
1607<p> 1615<p>
1608 Then a new clonable userdata instance can just do like any non-Lanes aware userdata, as long as its metatable contains the aforementionned <tt>__lanesclone</tt> method. Note that the current implementation doesn't support uservalues on such userdata. 1616 Then a new clonable userdata instance can just do like any non-Lanes aware userdata, as long as its metatable contains the aforementionned <tt>__lanesclone</tt> method.
1609<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> 1617<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
1610int luaD_new_clonable( lua_State* L) 1618int luaD_new_clonable( lua_State* L)
1611{ 1619{
@@ -1746,3 +1754,4 @@ int luaD_new_clonable( lua_State* L)
1746 1754
1747</body> 1755</body>
1748</html> 1756</html>
1757</pre></pre></pre></pre></pre></pre></pre> \ No newline at end of file
diff --git a/src/tools.c b/src/tools.c
index 02d51ae..f3ac236 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -1760,8 +1760,9 @@ static bool_t copyclone( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_Stat
1760 void* const source = lua_touserdata( L, i); 1760 void* const source = lua_touserdata( L, i);
1761 void* clone = NULL; 1761 void* clone = NULL;
1762 lua_pushvalue( L, -1); // ... mt __lanesclone __lanesclone 1762 lua_pushvalue( L, -1); // ... mt __lanesclone __lanesclone
1763 // call the cloning function with 0 arguments, should return the number of bytes to allocate for the clone 1763 // call the cloning function with 1 argument, should return the number of bytes to allocate for the clone
1764 lua_call( L, 0, 1); // ... mt __lanesclone size 1764 lua_pushlightuserdata( L, source); // ... mt __lanesclone __lanesclone source
1765 lua_call( L, 1, 1); // ... mt __lanesclone size
1765 STACK_MID( L, 3); 1766 STACK_MID( L, 3);
1766 userdata_size = (size_t) lua_tointeger( L, -1); // ... mt __lanesclone size 1767 userdata_size = (size_t) lua_tointeger( L, -1); // ... mt __lanesclone size
1767 lua_pop( L, 1); // ... mt __lanesclone 1768 lua_pop( L, 1); // ... mt __lanesclone
@@ -1899,8 +1900,9 @@ static bool_t inter_copy_function( Universe* U, lua_State* L2, uint_t L2_cache_i
1899 // __lanesclone should always exist because we wouldn't be restoring data from a userdata_clone_sentinel closure to begin with 1900 // __lanesclone should always exist because we wouldn't be restoring data from a userdata_clone_sentinel closure to begin with
1900 lua_getfield( L2, -1, "__lanesclone"); // ... mt __lanesclone 1901 lua_getfield( L2, -1, "__lanesclone"); // ... mt __lanesclone
1901 lua_pushvalue( L2, -1); // ... mt __lanesclone __lanesclone 1902 lua_pushvalue( L2, -1); // ... mt __lanesclone __lanesclone
1902 // call the cloning function with 0 arguments, should return the number of bytes to allocate for the clone 1903 // call the cloning function with 1 argument, should return the number of bytes to allocate for the clone
1903 lua_call( L2, 0, 1); // ... mt __lanesclone size 1904 lua_pushlightuserdata( L2, source); // ... mt __lanesclone __lanesclone source
1905 lua_call( L2, 1, 1); // ... mt __lanesclone size
1904 userdata_size = (size_t) lua_tointeger( L2, -1); // ... mt __lanesclone size 1906 userdata_size = (size_t) lua_tointeger( L2, -1); // ... mt __lanesclone size
1905 lua_pop( L2, 1); // ... mt __lanesclone 1907 lua_pop( L2, 1); // ... mt __lanesclone
1906 lua_pushnil( L2); // ... mt __lanesclone nil 1908 lua_pushnil( L2); // ... mt __lanesclone nil