diff options
author | Benoit Germain <bnt.germain@gmail.com> | 2012-11-18 16:22:49 +0100 |
---|---|---|
committer | Benoit Germain <bnt.germain@gmail.com> | 2012-11-18 16:22:49 +0100 |
commit | 2ff1905501d19199ddbb7d035f36ca7a41705a6a (patch) | |
tree | d52f9eeebf6317a66cdf529273c6a0860366b9c6 /docs/index.html | |
parent | 518d7ba7bf9ff18fb60e9f304465164c9b068a99 (diff) | |
download | lanes-2ff1905501d19199ddbb7d035f36ca7a41705a6a.tar.gz lanes-2ff1905501d19199ddbb7d035f36ca7a41705a6a.tar.bz2 lanes-2ff1905501d19199ddbb7d035f36ca7a41705a6a.zip |
Separated public "deep" API declarations in a dedicated header.
Diffstat (limited to 'docs/index.html')
-rw-r--r-- | docs/index.html | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/docs/index.html b/docs/index.html index bb64ba2..f7aa2d4 100644 --- a/docs/index.html +++ b/docs/index.html | |||
@@ -69,7 +69,7 @@ | |||
69 | </p> | 69 | </p> |
70 | 70 | ||
71 | <p> | 71 | <p> |
72 | This document was revised on 25-Sep-12, and applies to version <tt>3.4.0</tt>. | 72 | This document was revised on 25-Oct-12, and applies to version <tt>3.4.0</tt>. |
73 | </p> | 73 | </p> |
74 | </font> | 74 | </font> |
75 | </center> | 75 | </center> |
@@ -488,7 +488,7 @@ | |||
488 | 488 | ||
489 | <p> | 489 | <p> |
490 | If a lane body pulls a C function imported by a module required before Lanes itself (thus not through a hooked <tt>require</tt>), the lane generator creation will raise an error. | 490 | If a lane body pulls a C function imported by a module required before Lanes itself (thus not through a hooked <tt>require</tt>), the lane generator creation will raise an error. |
491 | The function name it shows is a path where it was found by scanning _G. As a utility, the name guessing functionality is exposed as such: | 491 | The function name it shows is a path where it was found by scanning <tt>_G</tt>. As a utility, the name guessing functionality is exposed as such: |
492 | 492 | ||
493 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"> | 493 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"> |
494 | <tr> | 494 | <tr> |
@@ -1098,14 +1098,14 @@ events to a common Linda, but... :).</font> | |||
1098 | // extract C function pointer from source | 1098 | // extract C function pointer from source |
1099 | lua_CFunction func = lua_tocfunction( source, -1); | 1099 | lua_CFunction func = lua_tocfunction( source, -1); |
1100 | // transfer upvalues | 1100 | // transfer upvalues |
1101 | int nup = trasnfer_upvalues( dest, source); | 1101 | int nup = transfer_upvalues( dest, source); |
1102 | // dest Lua stack contains a copy of all upvalues | 1102 | // dest Lua stack contains a copy of all upvalues |
1103 | lua_pushcfunction( dest, func, nup); | 1103 | lua_pushcfunction( dest, func, nup); |
1104 | } | 1104 | } |
1105 | </pre></td></tr></table> | 1105 | </pre></td></tr></table> |
1106 | 1106 | ||
1107 | <p> | 1107 | <p> |
1108 | This has the main drawback of not being LuaJIT-compatible, because some functions registered by LuaJIT are not regular C functions, but specially optimized implementations. As a result, <tt>lua_tocfunction()</tt> returns NULL for them. | 1108 | This has the main drawback of not being LuaJIT-compatible, because some functions registered by LuaJIT are not regular C functions, but specially optimized implementations. As a result, <tt>lua_tocfunction()</tt> returns <tt>NULL</tt> for them. |
1109 | <br> | 1109 | <br> |
1110 | Therefore, Lanes no longer transfers functions that way. Instead, functions are transfered as follows (more or less): | 1110 | Therefore, Lanes no longer transfers functions that way. Instead, functions are transfered as follows (more or less): |
1111 | </p> | 1111 | </p> |
@@ -1136,11 +1136,11 @@ events to a common Linda, but... :).</font> | |||
1136 | <br> | 1136 | <br> |
1137 | Then when a function is transfered from one state to another, all we have to do is retrieve the name associated to a function in the source Lua state, then with that name retrieve the equivalent function that already exists in the destination state. | 1137 | Then when a function is transfered from one state to another, all we have to do is retrieve the name associated to a function in the source Lua state, then with that name retrieve the equivalent function that already exists in the destination state. |
1138 | <br> | 1138 | <br> |
1139 | Note that there is no need to transfer upvalues, as they are already bound to the function registered in the destination state. (And in any event, it is not possible to create a closure from a C function pushed on the stack, it can only be created with a lua_CFunction pointer). | 1139 | Note that there is no need to transfer upvalues, as they are already bound to the function registered in the destination state. (And in any event, it is not possible to create a closure from a C function pushed on the stack, it can only be created with a <tt>lua_CFunction</tt> pointer). |
1140 | </p> | 1140 | </p> |
1141 | 1141 | ||
1142 | <p> | 1142 | <p> |
1143 | There are two issues here: | 1143 | There are several issues here: |
1144 | <ul> | 1144 | <ul> |
1145 | <li>Some base libraries register some C functions in the global environment. Because of that, Lanes must scan the global namespace to find all C functions (such as <tt>error</tt>, <tt>print</tt>, etc.).</li> | 1145 | <li>Some base libraries register some C functions in the global environment. Because of that, Lanes must scan the global namespace to find all C functions (such as <tt>error</tt>, <tt>print</tt>, etc.).</li> |
1146 | <li> | 1146 | <li> |
@@ -1151,10 +1151,19 @@ events to a common Linda, but... :).</font> | |||
1151 | When iterating over all keys of the global table, Lanes has no guarantee that it will hit <tt>"string"</tt> before or after <tt>"string2"</tt>. However, the values associated to <tt>string.match</tt> and <tt>string2.match</tt> are the same C function. | 1151 | When iterating over all keys of the global table, Lanes has no guarantee that it will hit <tt>"string"</tt> before or after <tt>"string2"</tt>. However, the values associated to <tt>string.match</tt> and <tt>string2.match</tt> are the same C function. |
1152 | Lanes doesn't expect a C function value to be encountered more than once. In the event it occurs, when the lookup table is populated with a [function, name] pair, an existing pair won't be updated if it is already found. In other words, the first name that was computed is retained. | 1152 | Lanes doesn't expect a C function value to be encountered more than once. In the event it occurs, when the lookup table is populated with a [function, name] pair, an existing pair won't be updated if it is already found. In other words, the first name that was computed is retained. |
1153 | If Lanes processed <tt>"string2"</tt> first, it means that if the Lua state that contains the <tt>"string2"</tt> global name sends function <tt>string.match</tt>, <tt>lookup_func_name</tt> would return name <tt>"string2.match"</tt>, with the obvious effect that <tt>push_resolved_func</tt> | 1153 | If Lanes processed <tt>"string2"</tt> first, it means that if the Lua state that contains the <tt>"string2"</tt> global name sends function <tt>string.match</tt>, <tt>lookup_func_name</tt> would return name <tt>"string2.match"</tt>, with the obvious effect that <tt>push_resolved_func</tt> |
1154 | won't find <tt>"string2.match"</tt> in the destination lookup database, thus failing the transfer (even though this function is referenced under name <tt>"string.match"</tt>). | 1154 | won't find <tt>"string2.match"</tt> in the destination lookup database, thus failing the transfer (even though this function exists, but is referenced under name <tt>"string.match"</tt>). |
1155 | </li> | ||
1156 | <li> | ||
1157 | Lua 5.2 introduced a hash randomizer seed which causes table iteration to yield a different key order on different VMs even when the tables are populated the exact same way. | ||
1158 | When Lua is built with compatibility options (such as LUA_COMPAT_ALL), this causes several base libraries to register functions under multiple names. | ||
1159 | This, with the randomizer, can cause the first name of a function to be different on different VMs, which breaks function transfer. | ||
1160 | <b>This means that Lua 5.2 must be built WITHOUT compatibility options to be able to use Lanes.</b> | ||
1161 | Even under Lua 5.1, this may cause trouble (even if this would be much less frequent). | ||
1162 | Unfortunately, this fails with <tt>string.gfind</tt>/<tt>string.gmatch</tt> when Lua 5.1 is built with <tt>LUA_COMPAT_GFIND</tt> (which is the case of LuaBinaries), | ||
1163 | so for the time being, Lanes fails only for Lua 5.2 as the randomizer is the real show breaker here. | ||
1155 | </li> | 1164 | </li> |
1156 | </ul> | 1165 | </ul> |
1157 | Another more direct reason of failed transfer is that the destination state doesn't know about the C function that has to be transferred. This occurs if a function is tranferred in a lane before it had a chance to scan the module. | 1166 | Another more direct reason of failed transfer is that the destination state doesn't know about the C function that has to be transferred. This occurs if a function is transferred in a lane before it had a chance to scan the module. |
1158 | If the C function is sent through a linda, it is enough for the destination lane body to have required the module before the function is sent. | 1167 | If the C function is sent through a linda, it is enough for the destination lane body to have required the module before the function is sent. |
1159 | But if the lane body provided to the generator has a C function as upvalue, the transfer itself must succeed, therefore the module that imported that C function must be required in the destination lane before the lane body starts executing. This is where the <a href = "#.required"><tt>.required</tt></a> options play their role. | 1168 | But if the lane body provided to the generator has a C function as upvalue, the transfer itself must succeed, therefore the module that imported that C function must be required in the destination lane before the lane body starts executing. This is where the <a href = "#.required"><tt>.required</tt></a> options play their role. |
1160 | </p> | 1169 | </p> |
@@ -1186,7 +1195,7 @@ events to a common Linda, but... :).</font> | |||
1186 | </pre></td></tr></table> | 1195 | </pre></td></tr></table> |
1187 | 1196 | ||
1188 | 1197 | ||
1189 | <h3 id="shared_userdata">Deep userdata in your own apps</h3> | 1198 | <h3 id="deep_userdata">Deep userdata in your own apps</h3> |
1190 | 1199 | ||
1191 | <p> | 1200 | <p> |
1192 | The mechanism Lanes uses for sharing Linda handles between separate Lua states can be used for custom userdata as well. Here's what to do. | 1201 | The mechanism Lanes uses for sharing Linda handles between separate Lua states can be used for custom userdata as well. Here's what to do. |
@@ -1195,9 +1204,7 @@ events to a common Linda, but... :).</font> | |||
1195 | <ol> | 1204 | <ol> |
1196 | <li> | 1205 | <li> |
1197 | Provide an <i>identity function</i> for your userdata, in C. This function is used for creation and deletion of your deep userdata (the shared resource), and for making metatables for the state-specific proxies for accessing it. The prototype is | 1206 | Provide an <i>identity function</i> for your userdata, in C. This function is used for creation and deletion of your deep userdata (the shared resource), and for making metatables for the state-specific proxies for accessing it. The prototype is |
1198 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1207 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> void idfunc( lua_State *L, char const * const which);</pre></td></tr></table> |
1199 | void idfunc( lua_State *L, char const * const which); | ||
1200 | </pre></td></tr></table> | ||
1201 | <tt>which</tt> can be one of: | 1208 | <tt>which</tt> can be one of: |
1202 | <ul> | 1209 | <ul> |
1203 | <li><tt>"new"</tt>: requests the creation of a new object, whose pointer is pushed on the stack as a light userdata.</li> | 1210 | <li><tt>"new"</tt>: requests the creation of a new object, whose pointer is pushed on the stack as a light userdata.</li> |
@@ -1207,6 +1214,7 @@ events to a common Linda, but... :).</font> | |||
1207 | </ul> | 1214 | </ul> |
1208 | Take a look at <tt>linda_id</tt> in <tt>lanes.c</tt>. | 1215 | Take a look at <tt>linda_id</tt> in <tt>lanes.c</tt>. |
1209 | </li> | 1216 | </li> |
1217 | <li>Include <tt>"deep.h"</tt> and link against Lanes. | ||
1210 | <li>Instanciate your userdata using <tt>luaG_deep_userdata()</tt>, instead of the regular <tt>lua_newuserdata()</tt>. Given an <tt>idfunc</tt>, it sets up the support structures and returns a state-specific proxy userdata for accessing your data. This proxy can also be copied over to other lanes.</li> | 1218 | <li>Instanciate your userdata using <tt>luaG_deep_userdata()</tt>, instead of the regular <tt>lua_newuserdata()</tt>. Given an <tt>idfunc</tt>, it sets up the support structures and returns a state-specific proxy userdata for accessing your data. This proxy can also be copied over to other lanes.</li> |
1211 | <li>Accessing the deep userdata from your C code, use <tt>luaG_todeep()</tt> instead of the regular <tt>lua_touserdata()</tt>.</li> | 1219 | <li>Accessing the deep userdata from your C code, use <tt>luaG_todeep()</tt> instead of the regular <tt>lua_touserdata()</tt>.</li> |
1212 | </ol> | 1220 | </ol> |