简体   繁体   English

在 Zig 中,如何判断一个帧是否代表完全执行的 function?

[英]In Zig, how do you tell if a frame represents a fully executed function?

In Zig (currently using 0.7.1), suppose for some reason you don't have any good way to design code which always has exactly one resume for every suspend .在 Zig(当前使用 0.7.1)中,假设由于某种原因您没有任何好的方法来设计每次suspend总是只有一个resume的代码。 Is there any supported way to detect at runtime that a given frame has or has not been executed to completion?是否有任何受支持的方法可以在运行时检测给定帧是否已执行完成?

// overly simplistic example designed to illustrate the problem
pub fn main() void {
    var frame = async amain(2);
    resume frame;
    resume frame;

    // panic/UB -- resume async function which already returned
    // 
    // we would prefer to have some kind of check which could allow
    // us to detect at runtime that the following resumption is illegal
    resume frame;
}

fn amain(ubound: i32) void {
    var i: i32 = 0;
    while (i < ubound) : (i += 1) {
        suspend;
    }
}

If I log the raw bytes of those frame structs (which as far as I can tell are opaque and don't support field access? I'm a little new to Zig), then it seems pretty obvious that a portion of the frame is dedicated to marking whether it has returned:如果我记录那些框架结构的原始字节(据我所知,它们是不透明的并且不支持字段访问?我对 Zig 有点陌生),那么很明显框架的一部分是专用于标记是否返回:

[70, 3a, 23, 00, 00, 00, 00, 00, 02, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 02, 00, 00, 00, 00, 00, 00, 00]
[70, 3a, 23, 00, 00, 00, 00, 00, 02, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 02, 00, 00, 00, 01, 00, 00, 00]
[70, 3a, 23, 00, 00, 00, 00, 00, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, 02, 00, 00, 00, 02, 00, 00, 00]

Blindly reading that data seems a little reckless however, and I'd feel a lot more comfortable if I knew the struct layout were guaranteed or that there were some builtin way to uncover that information.然而,盲目阅读这些数据似乎有点鲁莽,如果我知道结构布局是有保证的或者有一些内置的方法来发现这些信息,我会感觉舒服得多。

Edit::编辑::

In particular, the problem that I'm trying to solve is that when designing an event loop (eg when interfacing between JS and Zig/WASM) you seem to have to marry the implementation of an async function to the API of the event loop itself.特别是,我试图解决的问题是,在设计事件循环时(例如,在 JS 和 Zig/WASM 之间进行接口时),您似乎必须将异步 function 的实现与事件循环本身的 API 结合起来.

The built-in event loop, for example, has a yield() function precisely so that it can do the necessary bookkeeping to ensure that code has one resume per suspend, but as far as I can tell that's an unnecessary restriction since whether a frame has returned seems to be stored and readily accessible.例如,内置的事件循环有一个yield() function,这样它就可以进行必要的簿记,以确保代码每次暂停都有一个恢复,但据我所知,这是一个不必要的限制,因为一个框架是否已返回似乎已存储且易于访问。

It's certainly possible that I'm misunderstanding the purpose of Zig's async/await, but I don't see any fundamental reason why a general purpose event loop capable of handling any async function (not just those adhering to a particular loop API) couldn't be written, but I'm struggling to see how that's possible without a little more runtime introspection than the docs indicate is available.我当然有可能误解了 Zig 的 async/await 的目的,但我看不出有任何根本原因可以处理任何异步 function 的通用事件循环(不仅仅是那些遵循特定循环 API 的)不能'没有写出来,但我正在努力看看如果没有比文档指示可用的更多的运行时自省,那是如何可能的。

As of April 2022 there's an open proposal for implementing this feature in the language.截至 2022 年 4 月,有一项关于在该语言中实现此功能的公开提案 A workaround till then might still be manually reading the async frame header.到那时为止的解决方法可能仍然是手动读取异步帧 header。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM