Skip to content

[RFC] 1-layout+2-runtime: 函数调用形参一层引用+显式解引用(删命名参数 Ptr 双层穿透,参数名编译期绑定帧槽,* 解引用) #286

Description

@miaobyte

背景

& 数据指针(#285)与函数调用形参解析的语义冲突,暴露了当前函数调用参数是两层指针这一历史冗余。

现状:两层穿透

rwfunc foo(a:int64) -> () { b = a + 1 } 的形参解析链:

frameRoot/a        → "[0,-1]"         名字 → 槽坐标(/lib 指令树 extindex 透出的只读命名 Ptr)
frameRoot/[0,-1]   → 实参 key 路径    槽 → 实参地址(调用点在帧根新建的帧本地 Ptr)
读该路径           → 值              解引用

a → [0,-1] → 实参 穿透两次。第二跳(a → [0,-1])是历史实现的冗余:/lib/foo/a 这个静态 Ptr 承担了它不该承担的运行时解析职责——它本应是纯类型声明位。

为什么 **int32 是错的

langtype 永不累积 ref 层数——* 前缀是源码标注 ref 的语法糖,layout 剥离后独立落成 head 的 ref 字节,wire 层 langtype 串永久不含 *。这条链三层全是 langtype=int32,差异只在 refbody。ref 层数是寻址路径,不是类型。

正确设计:一层引用 + 显式解引用(C 指针统一)

函数参数的本质是「函数体里名字 a 绑定到实参的引用」,这是一层引用。layout 在编译期把函数体内的参数名直接绑定到帧槽坐标,删掉 /lib/foo/a 的运行时 Ptr 层;读取参数值改用显式解引用 *,与 C 指针三件套统一:

layout 编译 foo 函数体:参数名 a → 替换为帧槽坐标的显式解引用 *[0,-1]
   rwfunc foo(a:int64) -> () { b = a + 1 }
→ rwfunc foo([0,-1]:*int64) -> () { b = *[0,-1] + 1 }
runtime 执行:读 *[0,-1] = 读帧槽 [0,-1](ref=1, body=实参地址)→ 解引用到实参

运行期只剩一层:[0,-1] → /vthread/1/x1* 显式解引用。

  • 帧槽 [0,-1](读参)/[0,+1](写参):ref=1,langtype=参数类型,body=实参地址,调用时 runtime 写入。
  • /lib/foo/a 降级为纯签名元数据(dump / 类型检查用),不参与运行解析。
  • 三件套对齐 C:&x 取地址、p(读 ref=1 变量)得地址值本身、*p 解引用。成员访问 p·f 经指针自动解引用;*p 取整值。

连带收益

数据指针(#285)与软链接的语义冲突随之化解:函数调用不再依赖「/lib 里的命名 Ptr 双层穿透」,& 的地址值指针与软链接在「读 Ptr = 地址值、* 显式解引用」的同一 ref=1 语义下统一。

落地范围(spec 先行,再实现)

spec 需改:16-ptr(三件套 + 显式解引用语义)、附录/05-表达式(prefix_unary 加 *)、04-函数写槽与布局、12-rwfunc布局、09-调用extindex、05-函数调用、03-函数(形参引用升级为 *[0,-k])。

实现:layout 参数名→帧槽坐标编译期绑定 + * 解引用运算符;runtime 形参解析简化为单层穿透 + * 解引用。

关联:#285#199

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    RFC需要讨论与决策的设计提案(含裁决记录)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions