aboutsummaryrefslogtreecommitdiff
path: root/deep_test/deeptest.lua
diff options
context:
space:
mode:
authorBenoit Germain <bnt.germain@gmail.com>2021-06-26 18:25:53 +0200
committerBenoit Germain <bnt.germain@gmail.com>2021-06-26 18:25:53 +0200
commit909470be9f7ec1dd2d09ae1a371d69c9c652e957 (patch)
treecd16d9976e90c1d8a61d8ee3423d4af1671bafc0 /deep_test/deeptest.lua
parent050e14dd7fa04e2262ae6b1cc984d76c4149b664 (diff)
downloadlanes-909470be9f7ec1dd2d09ae1a371d69c9c652e957.tar.gz
lanes-909470be9f7ec1dd2d09ae1a371d69c9c652e957.tar.bz2
lanes-909470be9f7ec1dd2d09ae1a371d69c9c652e957.zip
fix stack overflow when transfering a clonable userdata referencing itself through a uservalue
Diffstat (limited to 'deep_test/deeptest.lua')
-rw-r--r--deep_test/deeptest.lua47
1 files changed, 33 insertions, 14 deletions
diff --git a/deep_test/deeptest.lua b/deep_test/deeptest.lua
index 92cd372..3c89c3d 100644
--- a/deep_test/deeptest.lua
+++ b/deep_test/deeptest.lua
@@ -5,8 +5,8 @@ local l = lanes.linda "my linda"
5local dt = lanes.require "deep_test" 5local dt = lanes.require "deep_test"
6 6
7local test_deep = true 7local test_deep = true
8local test_clonable = false 8local test_clonable = true
9local test_uvtype = "string" 9local test_uvtype = "function"
10 10
11local makeUserValue = function( obj_) 11local makeUserValue = function( obj_)
12 if test_uvtype == "string" then 12 if test_uvtype == "string" then
@@ -14,12 +14,23 @@ local makeUserValue = function( obj_)
14 elseif test_uvtype == "function" then 14 elseif test_uvtype == "function" then
15 -- a function that pull the userdata as upvalue 15 -- a function that pull the userdata as upvalue
16 local f = function() 16 local f = function()
17 print( obj_) 17 return tostring( obj_)
18 end 18 end
19 return f 19 return f
20 end 20 end
21end 21end
22 22
23local printDeep = function( prefix_, obj_, t_)
24 local uservalue = obj_:getuv( 1)
25 print( prefix_)
26 print ( obj_, uservalue, type( uservalue) == "function" and uservalue() or "")
27 if t_ then
28 for k, v in pairs( t_) do
29 print( k, v)
30 end
31 end
32end
33
23local performTest = function( obj_) 34local performTest = function( obj_)
24 -- setup the userdata with some value and a uservalue 35 -- setup the userdata with some value and a uservalue
25 obj_:set( 666) 36 obj_:set( 666)
@@ -29,15 +40,20 @@ local performTest = function( obj_)
29 -- lua 5.4 supports multiple uservalues of arbitrary types 40 -- lua 5.4 supports multiple uservalues of arbitrary types
30 -- obj_:setuv( 2, "ENDUV") 41 -- obj_:setuv( 2, "ENDUV")
31 42
43 local t =
44 {
45 ["key"] = obj_,
46 -- [obj_] = "val"
47 }
48
32 -- read back the contents of the object 49 -- read back the contents of the object
33 print( "immediate:", obj_, obj_:getuv( 1)) 50 printDeep( "immediate:", obj_, t)
34 51
35 -- send the object in a linda, get it back out, read the contents 52 -- send the object in a linda, get it back out, read the contents
36 l:set( "key", obj_) 53 l:set( "key", obj_, t)
37 -- when obj_ is a deep userdata, out is the same userdata as obj_ (not another one pointing on the same deep memory block) because of an internal cache table [deep*] -> proxy) 54 -- when obj_ is a deep userdata, out is the same userdata as obj_ (not another one pointing on the same deep memory block) because of an internal cache table [deep*] -> proxy)
38 -- when obj_ is a clonable userdata, we get a different clone everytime we cross a linda or lane barrier 55 -- when obj_ is a clonable userdata, we get a different clone everytime we cross a linda or lane barrier
39 local out = l:get( "key") 56 printDeep( "out of linda:", l:get( "key", 2))
40 print( "out of linda:", out, out:getuv( 1))
41 57
42 -- send the object in a lane through parameter passing, the lane body returns it as return value, read the contents 58 -- send the object in a lane through parameter passing, the lane body returns it as return value, read the contents
43 local g = lanes.gen( 59 local g = lanes.gen(
@@ -45,23 +61,26 @@ local performTest = function( obj_)
45 , { 61 , {
46 required = { "deep_test"} -- we will transfer userdata created by this module, so we need to make this lane aware of it 62 required = { "deep_test"} -- we will transfer userdata created by this module, so we need to make this lane aware of it
47 } 63 }
48 , function( param_) 64 , function( arg_, t_)
49 -- read contents inside lane 65 -- read contents inside lane: arg_ and t_ by argument
50 print( "in lane:", param_, param_:getuv( 1)) 66 printDeep( "in lane, as arguments:", arg_, t_)
51 return param_ 67 -- read contents inside lane: obj_ and t by upvalue
68 printDeep( "in lane, as upvalues:", obj_, t)
69 return arg_, t_
52 end 70 end
53 ) 71 )
54 h = g( obj_) 72 h = g( obj_, t)
55 -- when obj_ is a deep userdata, from_lane is the same userdata as obj_ (not another one pointing on the same deep memory block) because of an internal cache table [deep*] -> proxy) 73 -- when obj_ is a deep userdata, from_lane is the same userdata as obj_ (not another one pointing on the same deep memory block) because of an internal cache table [deep*] -> proxy)
56 -- when obj_ is a clonable userdata, we get a different clone everytime we cross a linda or lane barrier 74 -- when obj_ is a clonable userdata, we get a different clone everytime we cross a linda or lane barrier
57 local from_lane = h[1] 75 printDeep( "from lane:", h[1], h[2])
58 print( "from lane:", from_lane, from_lane:getuv( 1))
59end 76end
60 77
61if test_deep then 78if test_deep then
79 print "DEEP"
62 performTest( dt.new_deep()) 80 performTest( dt.new_deep())
63end 81end
64 82
65if test_clonable then 83if test_clonable then
84 print "CLONABLE"
66 performTest( dt.new_clonable()) 85 performTest( dt.new_clonable())
67end 86end