diff options
author | Benoit Germain <bnt.germain@gmail.com> | 2021-06-26 18:25:53 +0200 |
---|---|---|
committer | Benoit Germain <bnt.germain@gmail.com> | 2021-06-26 18:25:53 +0200 |
commit | 909470be9f7ec1dd2d09ae1a371d69c9c652e957 (patch) | |
tree | cd16d9976e90c1d8a61d8ee3423d4af1671bafc0 /deep_test/deeptest.lua | |
parent | 050e14dd7fa04e2262ae6b1cc984d76c4149b664 (diff) | |
download | lanes-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.lua | 47 |
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" | |||
5 | local dt = lanes.require "deep_test" | 5 | local dt = lanes.require "deep_test" |
6 | 6 | ||
7 | local test_deep = true | 7 | local test_deep = true |
8 | local test_clonable = false | 8 | local test_clonable = true |
9 | local test_uvtype = "string" | 9 | local test_uvtype = "function" |
10 | 10 | ||
11 | local makeUserValue = function( obj_) | 11 | local 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 |
21 | end | 21 | end |
22 | 22 | ||
23 | local 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 | ||
32 | end | ||
33 | |||
23 | local performTest = function( obj_) | 34 | local 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)) | ||
59 | end | 76 | end |
60 | 77 | ||
61 | if test_deep then | 78 | if test_deep then |
79 | print "DEEP" | ||
62 | performTest( dt.new_deep()) | 80 | performTest( dt.new_deep()) |
63 | end | 81 | end |
64 | 82 | ||
65 | if test_clonable then | 83 | if test_clonable then |
84 | print "CLONABLE" | ||
66 | performTest( dt.new_clonable()) | 85 | performTest( dt.new_clonable()) |
67 | end | 86 | end |