Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

请教一下第10章 关于upvalue的问题 #29

Open
Yiklek opened this issue Jul 2, 2021 · 1 comment
Open

请教一下第10章 关于upvalue的问题 #29

Yiklek opened this issue Jul 2, 2021 · 1 comment

Comments

@Yiklek
Copy link

Yiklek commented Jul 2, 2021

您好,首先十分感谢作者,这本书对帮助我理解虚拟机底层运行机制帮助很大。目前看到第10章,也参考了这个仓库自己实现了一个Rust版本。
在实现好第10章的内容后对upvalue的一些情况做了测试,但是发现有一种情况不能通过,debug后觉得可能是对于upvalue的引用问题。
用例代码如下:

local step = 1
local start = 0
local function assert(v)
    if not v then
        fail()
    end
end
function newCounter()
    local count = start
    return function()
        count = count + step
        return count
    end
end

c1 = newCounter()
assert(c1() == 1)
assert(c1() == 2)

c2 = newCounter()
assert(c2() == 1)   -- 3
assert(c1() == 3)   -- 4
assert(c2() == 2)  -- 5

似乎是因为newCounter获取到startcount之后,后续对count的更改都会同时反馈在最外层的start上。
我想请教一下,lua对于这种情况闭包获取到的upvalue的生命周期是不是还有其他的处理呢?如果有的话是如何实现的呢,在官方c实现的版本里应该去了解哪部分的代码?

如果您方便的话请您帮忙解答一下,非常感谢!

编译器版本:
Lua 5.3.5 Copyright (C) 1994-2018 Lua.org, PUC-Rio
操作系统:
macOS 11.3.1
附编译后的指令:

main <tests/upvalue.lua:0,0> (52 instructions at 0x7f8d3a406590)
0+ params, 5 slots, 1 upvalue, 3 locals, 7 constants, 2 functions
        1       [1]     LOADK           0 -1    ; 1
        2       [2]     LOADK           1 -2    ; 0
        3       [7]     CLOSURE         2 0     ; 0x7f8d3a406700
        4       [14]    CLOSURE         3 1     ; 0x7f8d3a406b40
        5       [8]     SETTABUP        0 -3 3  ; _ENV "newCounter"
        6       [16]    GETTABUP        3 0 -3  ; _ENV "newCounter"
        7       [16]    CALL            3 1 2
        8       [16]    SETTABUP        0 -4 3  ; _ENV "c1"
        9       [17]    MOVE            3 2
        10      [17]    GETTABUP        4 0 -4  ; _ENV "c1"
        11      [17]    CALL            4 1 2
        12      [17]    EQ              1 4 -1  ; - 1
        13      [17]    JMP             0 1     ; to 15
        14      [17]    LOADBOOL        4 0 1
        15      [17]    LOADBOOL        4 1 0
        16      [17]    CALL            3 2 1
        17      [18]    MOVE            3 2
        18      [18]    GETTABUP        4 0 -4  ; _ENV "c1"
        19      [18]    CALL            4 1 2
        20      [18]    EQ              1 4 -5  ; - 2
        21      [18]    JMP             0 1     ; to 23
        22      [18]    LOADBOOL        4 0 1
        23      [18]    LOADBOOL        4 1 0
        24      [18]    CALL            3 2 1
        25      [20]    GETTABUP        3 0 -3  ; _ENV "newCounter"
        26      [20]    CALL            3 1 2
        27      [20]    SETTABUP        0 -6 3  ; _ENV "c2"
        28      [21]    MOVE            3 2
        29      [21]    GETTABUP        4 0 -6  ; _ENV "c2"
        30      [21]    CALL            4 1 2
        31      [21]    EQ              1 4 -1  ; - 1
        32      [21]    JMP             0 1     ; to 34
        33      [21]    LOADBOOL        4 0 1
        34      [21]    LOADBOOL        4 1 0
        35      [21]    CALL            3 2 1
        36      [22]    MOVE            3 2
        37      [22]    GETTABUP        4 0 -4  ; _ENV "c1"
        38      [22]    CALL            4 1 2
        39      [22]    EQ              1 4 -7  ; - 3
        40      [22]    JMP             0 1     ; to 42
        41      [22]    LOADBOOL        4 0 1
        42      [22]    LOADBOOL        4 1 0
        43      [22]    CALL            3 2 1
        44      [23]    MOVE            3 2
        45      [23]    GETTABUP        4 0 -6  ; _ENV "c2"
        46      [23]    CALL            4 1 2
        47      [23]    EQ              1 4 -5  ; - 2
        48      [23]    JMP             0 1     ; to 50
        49      [23]    LOADBOOL        4 0 1
        50      [23]    LOADBOOL        4 1 0
        51      [23]    CALL            3 2 1
        52      [23]    RETURN          0 1
constants (7) for 0x7f8d3a406590:
        1       1
        2       0
        3       "newCounter"
        4       "c1"
        5       2
        6       "c2"
        7       3
locals (3) for 0x7f8d3a406590:
        0       step    2       53
        1       start   3       53
        2       assert  4       53
upvalues (1) for 0x7f8d3a406590:
        0       _ENV    1       0

function <tests/upvalue.lua:3,7> (5 instructions at 0x7f8d3a406700)
1 param, 2 slots, 1 upvalue, 1 local, 1 constant, 0 functions
        1       [4]     TEST            0 1
        2       [4]     JMP             0 2     ; to 5
        3       [5]     GETTABUP        1 0 -1  ; _ENV "fail"
        4       [5]     CALL            1 1 1
        5       [7]     RETURN          0 1
constants (1) for 0x7f8d3a406700:
        1       "fail"
locals (1) for 0x7f8d3a406700:
        0       v       1       6
upvalues (1) for 0x7f8d3a406700:
        0       _ENV    0       0

function <tests/upvalue.lua:8,14> (4 instructions at 0x7f8d3a406b40)
0 params, 2 slots, 2 upvalues, 1 local, 0 constants, 1 function
        1       [9]     GETUPVAL        0 0     ; start
        2       [13]    CLOSURE         1 0     ; 0x7f8d3a406c40
        3       [13]    RETURN          1 2
        4       [14]    RETURN          0 1
constants (0) for 0x7f8d3a406b40:
locals (1) for 0x7f8d3a406b40:
        0       count   2       5
upvalues (2) for 0x7f8d3a406b40:
        0       start   1       1
        1       step    1       0

function <tests/upvalue.lua:10,13> (7 instructions at 0x7f8d3a406c40)
0 params, 2 slots, 2 upvalues, 0 locals, 0 constants, 0 functions
        1       [11]    GETUPVAL        0 0     ; count
        2       [11]    GETUPVAL        1 1     ; step
        3       [11]    ADD             0 0 1
        4       [11]    SETUPVAL        0 0     ; count
        5       [12]    GETUPVAL        0 0     ; count
        6       [12]    RETURN          0 2
        7       [13]    RETURN          0 1
constants (0) for 0x7f8d3a406c40:
locals (0) for 0x7f8d3a406c40:
upvalues (2) for 0x7f8d3a406c40:
        0       count   1       0
        1       step    0       1
@zxh0
Copy link
Owner

zxh0 commented Jul 6, 2021

请问一下具体的问题是什么?是说这个测试用书中的代码执行结果和CLua不一致吗?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants