惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Fortinet All Blogs
宝玉的分享
宝玉的分享
酷 壳 – CoolShell
酷 壳 – CoolShell
T
The Exploit Database - CXSecurity.com
Help Net Security
Help Net Security
腾讯CDC
Project Zero
Project Zero
C
CXSECURITY Database RSS Feed - CXSecurity.com
IT之家
IT之家
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Tailwind CSS Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
D
Darknet – Hacking Tools, Hacker News & Cyber Security
L
LINUX DO - 最新话题
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
T
Threatpost
N
News | PayPal Newsroom
C
Cybersecurity and Infrastructure Security Agency CISA
Hacker News - Newest:
Hacker News - Newest: "LLM"
S
SegmentFault 最新的问题
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
P
Proofpoint News Feed
A
Arctic Wolf
B
Blog RSS Feed
Forbes - Security
Forbes - Security
P
Privacy & Cybersecurity Law Blog
Attack and Defense Labs
Attack and Defense Labs
V2EX - 技术
V2EX - 技术
P
Proofpoint News Feed
I
Intezer
Application and Cybersecurity Blog
Application and Cybersecurity Blog
阮一峰的网络日志
阮一峰的网络日志
aimingoo的专栏
aimingoo的专栏
T
Tenable Blog
MyScale Blog
MyScale Blog
U
Unit 42
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
WordPress大学
WordPress大学
W
WeLiveSecurity
D
DataBreaches.Net
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
G
GRAHAM CLULEY
有赞技术团队
有赞技术团队
Martin Fowler
Martin Fowler
罗磊的独立博客
The Last Watchdog
The Last Watchdog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
V
Vulnerabilities – Threatpost
美团技术团队
Microsoft Security Blog
Microsoft Security Blog

V2EX

我用 AI 写代码,但终端管理反而成了累赘——于是我做了 codux - V2EX [调研] 各位在公司都用什么 ide 和 agent 写代码? 老运维 share 一个运维平台 新电脑 brew install node 之后,一个小设置可以提升对供应链投毒的防御 - V2EX GLM-Coding 调用持续报错: z.ai 的 Lite 套餐几乎无法使用,官方 Pro/Max 是否稳定? - V2EX 上海漕河泾内推,本组有 2 个 hc,一个后端,一个前端,预算都是 20k 左右,不打卡,氛围好 如果 V2EX 上有一组不永久保存聊天记录(比如只保存 7 天或者 24 小时)的聊天室,那么会开启哪些有用或者有趣的可能? - V2EX gemini cli 貌似挂了,一直返回 403 - V2EX 第一次在自媒体上赚到钱 收集了最近在使用的低价 GPT, Gemini,邮箱等 AI 会员的小店合集 讨论个大实话:现在企业还在说 AI 编程提效 20%, 30%的,真的太落后,没用懂 AI。因为包括很多前沿公司,已经狂奔到提效 200%-500%的情况 [招聘][远程][币安] 前端/后端/QA/iOS/Android 至少 3 年以上经验 目前有大量 HC 欢迎投递 Chatgpt Pro 用量用不完的可以开这些设置 面试的时候好像遇到钓鱼了,给各位避个坑 cursor 年续费 22 号到期, 自动续费是否还是老的计次套餐呢 - V2EX 被两件破事毁掉的一下午,琐碎的内耗消磨人的精力 使用 Planet 存储 Codex 的会话或者重要信息 - V2EX 如果业务部门领导不要你开发功能,而是要求你教会它用 claude code 开发功能,你会怎么做? 分享一个 MacOS 接绿联 CM818 USB 转 DP 转接器使用感受 - V2EX 我的 HR 朋友 10 年老 Java ,非全大专,大家帮忙看看简历 开源了一个 AI 口语练习工具,音素级发音评分,完全免费可自部署 V2EX 上有哪些你觉得很有趣、印象深刻的妹纸? 字节为啥不出个国内版 Vercel? 有在大马的朋友吗? 问个运营商问题 你们在有领导的公司大群发过的最大胆的消息是什么 公司裁员,目前没有工作。想试试摆摊,做一个移动鲜啤打酒车 我的硬盘 Memblaze Pblaze 5 Linux 下不识别,给 Linux 内核提交了补丁, AI 说有望被合并 - V2EX 只有我一个人觉得 codex 不好用? 做了个 AI + 真人专家监督的广告投放平台 Auxora, 7 个品牌跑出 6x ROAS 如何走出至亲的离世 Claude Web 端貌似 claude-opus-4-7 偷偷上了? 现在 Apple 开发者帳號應該是用哪个地区会更好? - V2EX 用回测筛选因子的一点经验分享 给女儿 vibe 了一个故事类的 app,做完发现,这类应用似乎上线难度极大? - V2EX 手机格式化 bitget 钱包没了,里面开通的银行卡还有机会拿到吗 - V2EX [送码] TransVoice - 我的第一款 App 上架啦!实时转写+翻译+字幕,会议听课好助手! PictureHub 高清摄影作品的画廊 Planet 的第一个使用 macOS 26 SDK 构建的 Insider 版本 20260416-1 - V2EX 成都二手房是不是在涨价,有点坐不住了 - V2EX claude 生态(skill mcp plugin)等 Studio Display XDR VESA 适配器脱落 有在用印度区 applestore 的大哥嘛,请教一下礼品卡去哪里买呢 - V2EX 我好像知道京东家政爆火的原因了 - V2EX 薅了公司的 a 家 api key,用机场 ip 做代理容易被封吗 如何在初期就识别 HR 在刷 KPI,没打算招你? [分享]精心打造一个 AI 编程知识库(算法/设计模式/提示词/Skills),助力程序员转型 港版 iPhone 在国内支持联通 5GA 吗?在广东用 想办港卡 AI 对 it 行业影响太大了 我做了个把照片变成 iOS 小组件贴纸的 App ChatGPT Pro 5x 套餐 量真的很足! I have found a method to directly generate advertising video materials using scripts 在小城市开个店,给人写软件,有前途吗 chrome 最新的 147 版直接卡爆炸了 - V2EX 为什么厂家不在 skill/mcp 这类的工具中塞广告呢?这样不是可以大赚嘛? minimax 真是脸都不要了,工作日下午 14:00 定时开启 529,脸都不要了。训练模型居然占用用户使用时间 外资非核心部门 vs 另一家外资的核心部门,该跳吗? iTad 标签 扩展 加小动作 ? - V2EX 去年 H200 能买,不让买是代替快出来了? - V2EX AI 赛事通 - 2026 年 4 月中国区新增 AI 竞赛和黑客松汇总 - V2EX V2EX › 登录 现在安卓开发都在做啥 - V2EX 浏览器插件 沉浸式翻译 是不支持自定义模型了吗? - V2EX Codex 里的 GPT5.4 也能降智?上午让它改两个问题,改了一个小时了, plus 额度用了一半了还是没改好,和前几天用的体感完全不一样。要它改的问题也不复杂。服了。 目前有使用 claude code 的收到人脸认证的吗 - V2EX 分享一个自己做的 Nginx 管理工具,实时请求动态预览!(无奈市面上实在找不到好用的,自己撸了个) - V2EX claude code 崩了么? 今天在反重力上用 claude 一点都不丝滑,有同样的感受吗? opencode 消息周知插件 今天 claude opus 和前两天比,质的飞跃 - V2EX 999 包月价? - V2EX 一个版本, 50 项更新:我们几乎重做了整个播放页 本地大模型多大显存够用? GOGDNS 一款简易的私人 DNS 服务器 - V2EX API key (GLM) 怎么使用 claude code desktop ? Claude 这样订阅有问题吗 - V2EX 帮我爸找回了一篇赛博兰亭集序 求推荐稳定、高性价比使用 Claude Opus 4.6 的渠道/平台 搞个云端 claude code 防止 封号 - V2EX 用 Claude 要实名了,内地用户怎么办? OpenAI Plus 和 Team 都缩水了吗 海外 Android 手机有什么好用的国内第三方应用市场推荐吗 - V2EX 把电脑伪装成电视,用 DLNA 投屏拿到视频号直播流地址 - V2EX claude 认证莫慌 北京互联网法院有什么攻略么?起诉北京智谱华章科技股份有限公司退款可行么? - V2EX Claude 开始引入身份验证 求 vscode 做笔记软件的插件推荐 - V2EX 讯飞星辰的 Coding Plan 如何? Anthropic 宣布在 Claude 平台推行身份验证机制 科普一下低价 gpt 是怎么来的 有没有长期关注 Claude 的朋友,我建了一个 Channel 自动抓取 Claude Team 的推文 啃了那篇 54 页的 Agent Harness 综述, 给大伙讲个省流版 现在那家的 coding plan 还能买到 是不是最近会有什么更聪明的大模型要发布了呀? 用多了 AI 后,有没有觉得 AI 生成的文章有很强的既视感? 如何 实践 Harness 工程? 今日份 GPT 5.4 笑话 如何建一个自己的号池,让 cursor 真正实现 token 自由 写了三个月 Agent Harness,我终于敢让 Claude Code 全自动写代码了
Nature 编程语言集成 WebView
weiwenhao · 2026-01-22 · via V2EX

一位开发者尝试在 nature 编程语言 中集成 WebView (项目地址:https://github.com/wzzc-dev/nature-webview),采用类似 Rust Tauri 的集成方式,最终打包完成后可以得到体积小巧、轻量化的可执行桌面程序。

这个简单的桌面程序就是由 nature + webview 打包而来,在 macos arm64 上只有 680KB 的大小,下面是一个更加简单的 hello world 代码示例

import webview as w
import webview.{webview_t}
import libc.{cstr, to_cfn}
import co.{sleep}
import co
import runtime

fn interval_callback() {
    co.yield() // Yield coroutine every 10ms to allow GC to run
}

fn other() {
    for true {
        println('other co')
        sleep(1000)
    }
}

fn main() {
    println("Hello, Nature Webview!")

    @async(other(), co.SAME)

    var window = w.create(1, null)
    w.set_title(window, "Hello World".to_cstr())
    w.bind(window, "interval_callback".to_cstr(), to_cfn(interval_callback as anyptr), 0)

    var html = `
      <html>
          <body>
              <script>setInterval(() => {window.interval_callback();}, 10);</script>
              <h1>Hello, Nature!</h1>
          </body>
      </html>`

    w.set_html(window, html.to_cstr())

    w.run(window) // blocking coroutine!
    w.destroy(window)
}

nature 是一款基于全局协程模型的编程语言,它与 WebView 的兼容性并不理想。起初该方案完全无法运行,nature-webview 的作者与我进行了沟通, 我认为这是一项非常有意义的工作,是 nature 核心 GUI 特性的重要环节,因此我着手排查并解决导致运行失败的问题,经过一个周末努力,主要问题都被解决,我迫不及待的将其分享出来!

WebView 必须运行在 t0 系统栈 + 系统线程中

在 macOS 系统上,编译完成后程序虽能正常启动,但通过 JS 回调 nature 时却发生了崩溃,且这个崩溃的调用栈非常深,难以追溯。即便通过 Debug 方式构建 WebView ,依旧无法获取完整的调用栈。

最终发现这是因为 WebView 动态依赖 WebKit 库,而 WebKit 库无法追踪调用栈。经过多次尝试后偶然发现了 macos 的崩溃报告,我发现其中包含了完整的堆栈追踪日志!原来我一直忽略了如此重要的信息。

命令行执行程序崩溃时,也可以通过 ~/Library/Logs/DiagnosticReports/ 直接查看堆栈追踪日志

Crashed Thread:        0  Dispatch queue: com.apple.main-thread
Exception Type:        EXC_BREAKPOINT (SIGTRAP)

Termination Reason:    Namespace SIGNAL, Code 5 Trace/BPT trap: 5
Terminating Process:   exc handler [37708]

Thread 0 Crashed::  Dispatch queue: com.apple.main-thread
0   JavaScriptCore                	    0x7ff828e4b7d1 JSC::LocalAllocator::allocate(JSC::Heap&, JSC::GCDeferralContext*, JSC::AllocationFailureMode)::'lambda'()::operator()() const + 6801
1   JavaScriptCore                	    0x7ff829574b24 JSC::VM::VM(JSC::VM::VMType, JSC::HeapType, WTF::RunLoop*, bool*) + 24452

根据日志可以判断这是一个通过类似 assert 抛出来的断点类型的异常,并且发生在内存分配中,说明这极有可能和运行环境相关。

于是我尝试使用 C + WebView 进行对比测试并复现问题,nature 是运行在协程和协程栈中,所以通过 c 库的 mcontext + mmap stack 模拟 nature 的运行模式,果然重现了错误。到这里已经大概猜测是 WebKit 会进行运行时栈检测,并且是通过 pthread_get_stackaddr_np 的方式直接读取线程默认栈。

这是一个棘手的问题,如果需要兼容 WebView 需要对 nature 的基础架构进行一定改动。到目前为止都还只是猜测,为了证实测测我去下载了一个多 G 的 WebKit 代码定位堆栈追踪中的函数。最终定位到了下面的关键逻辑

ALWAYS_INLINE void* LocalAllocator::allocate(JSC::Heap& heap, size_t cellSize, GCDeferralContext* deferralContext, AllocationFailureMode failureMode)
{
    VM& vm = heap.vm();
    if constexpr (validateDFGDoesGC)
        vm.verifyCanGC();
    return m_freeList.allocateWithCellSize(
        [&]() ALWAYS_INLINE_LAMBDA {
            sanitizeStackForVM(vm);
            return static_cast<HeapCell*>(allocateSlowCase(heap, cellSize, deferralContext, failureMode));
        }, cellSize);
}

这个函数的结构和堆栈追踪中显示的一致,虽然有版本变动带来的影响,但是大概率就是该函数导致了崩溃,进一步追踪发现其中的 sanitizeStackForVM 函数果然使用了 pthread_get_stackaddr_np 来获取栈信息并进行 assert 判断。

问题到这里基本已经确定,可以尝试解决该问题。过去我知道 UI 必须在系统默认线程上渲染,但是没想到有些 UI 库对栈的要求也如此严格。由于 nature 的协程运行在共享栈中,所以解决起来也比较简单,直接拿系统栈作为共享栈使用即可,不过系统栈还需要驱动 procesor 运行,所以我暂时拿其中一半系统栈来作为协程的共享栈。

当然这是一个临时解决方案,在较新的 macos 26.2 系统中并不会发生类似的崩溃,以后也许可以继续使用 mmap 进行栈分配。

WebView 必须使用 glibc

由于 macos 系统发行版本单一,并且强制要求使用动态库链接,所以 nature 在 macos 上没有遇到编译问题,但是在 linux 上则出现了该问题。

nature 在 linux 系统上基于 musl 进行纯静态编译,libruntime.a + libuv.a + libc.a 是 nature 依赖的核心,这三件套都是 musl libc 纯静态编译的,所以跨平台性很好,一次编译到处运行。

WebView 在 linux 上依赖的 webkit 和 gtk 必须基于 glibc 动态编译,这和 nature 现在的编译理念产生了严重的冲突。动态编译的 webkit 和 gtk 在不同的 linux 发行版本上也有着兼容问题。难道这无法解决么?还真不行,Rust 的 tarui 在 linux 系统上也同样有着这样的兼容困扰。

既然现在 webkit 和 gtk 直接打破了静态编译的幻想,必须动态编译,必须依赖 glibc ,牺牲一定的跨平台性,那 nature 索性直接放弃静态编译和交叉编译的思路,直接使用 glibc 进行动态编译好了。

使用系统自带的链接器 ld 将 nature 依赖的静态库代码和 webkit 相关库进行动静态库混合链接后,终于在 ubuntu 22.04 desktop 上运行成功。

nature 手写的链接器只实现了静态编译部分,所以动态编译时需要通过 --ld /usr/local/ld 指定系统链接器。

为了更好的兼容性 nature build 的 --ldflags 参数还需要进行调整,在识别到传递 -lc 参数后,会自动去掉 libc.a 的依赖。有一个比较神奇的地方在于 musl libc 工具链编译的 libruntime.a 和 libuv.a 能够和 glibc 库直接混合链接使用。

最终得到的令人眼花缭乱的编译参数 😄,nature 并不依赖于 gcc 工具链,所以需要在 ldflags 中处理 crtendS 这样的初始化文件。

nature build --ld '/usr/bin/ld' --ldflags "/usr/lib/gcc/x86_64-linux-gnu/11/crtbeginS.o /usr/lib/gcc/x86_64-linux-gnu/11/crtendS.o --dynamic-linker=/lib64/ld-linux-x86-64.so.2 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/11 --whole-archive /usr/local/lib/libwebview.a --no-whole-archive -lwebkit2gtk-4.1 -lgtk-3 -lgdk-3 -lz -lpangocairo-1.0 -lcairo-gobject -lgdk_pixbuf-2.0 -latk-1.0 -lpango-1.0 -lcairo -lharfbuzz -lsoup-3.0 -lgio-2.0 -lgmodule-2.0 -ljavascriptcoregtk-4.1 -lgobject-2.0 -lglib-2.0 -lstdc++ -lgcc_s -lpthread -lc" test.n --verbose

w.run 阻塞 runtime

现在解决所有的问题了么?注意看这一行代码,它直接指向了一个 c++ 函数 webview_run ,并且这个函数永远不会返回。这会发生什么?

w.run(window) // blocking coroutine!

经过上面的适配,webview 成功在协程中运行,如果你足够了解协程的运行原理,你就会知道这一行阻塞操作会占用核心线程都控制权,这导致在该核心线程上的协程调度器和其他协程永远都不会运行。但这还不够致命,nature 可以轻易的通过创建新的线程来解决这个问题。真正的问题是阻塞系统调用会导致该线程无法进入 STW 状态,从而阻塞整个 GC ,这才是真正无解且致命的问题。

nature 采用了协作式的调度方案,意味着更多的控制权交在了开发者手上,为了更友好的 GUI 体验,也许应该尝试一些不同的方案。于是最终使用了一个比较 hack 的方式解决了该问题。

w.bind(window, "interval_callback".to_cstr(), to_cfn(co.yield as anyptr), 0)

var html = `
  <html>
	  <body>
		  <script>setInterval(() => {window.interval_callback();}, 10);</script>
		  <h1>Hello, Nature!</h1>
	  </body>
  </html>`

我们在 js 代码中创建了一个定时器,每 10ms 调用一次 nature 函数绑定,该函数绑定会 yield 当前协程将控制权交还给协程调度器。 通过这种方式不需要调整任何的 nature 编译器让整个协程调度器能够正常运转,代价大概就是需要 10ms 的延迟,而不是按需调度罢了。但是至少不会产生 GC 问题。

C/C++ 回调 nature fn

C/C++ 是不安全非托管的函数能够回调 nature 函数吗?原则上不行,比如 golang 不允许,因为 golang 的 C 代码和 go 代码运行在了不同的栈中,所以无法直接调用。

nature 和 C 代码在同一个共享栈中运行,所以回调能够正常触发。但在当前的设计中,nature 没有考虑过作为回调被 C 代码调用,所以 GC 不能正确的识别该混合调用模式。但这还算好解决,我们可以通过追溯栈帧获取整个栈上的函数调用链条并进行 GC root mark, C 在大多数情况下同样遵循该栈帧规则。

另外一个问题是闭包问题

fn foo() {}

fn main() {
	int a = 1
	fn() f = foo
	f = fn() {
		var b = a // Reference to external var
	}
	
	f()
	foo()

}

在高级编程语言中通常会区分闭包和全局函数,在上面的代码示例中,面对一个 fn 类型的变量 f ,编译器无法追踪其是全局函数还是闭包。所以通常会采取妥协的策略将 fn 类型变量统一按照闭包进行存储和使用。如图,fn 并不是一个单独的指针指向函数的地址,而是一个 16byte 的 pair 结构。

所以如果直接将 nature 中的 global fn 通过参数进行传递时,该参数是一个 16byte 的奇怪数据,C 并不知道 fn 的地址是什么,所以还需要从闭包中提取 fn 地址传递给 C 。这里的 libc.to_cfn 做了一个简单的工作,就是直接抛弃 env ptr(全局函数的 env ptr 总是为 null)并从中提取 fn ptr 传递给 C 函数。

w.bind(window, "interval_callback".to_cstr(), libc.to_cfn(interval_callback as anyptr), 0)

总结

到这里已知的问题都得到了解决,虽然方案上比较妥协,但是最终还是让 nature 编程语言成功集成了 WebView ,并且能够达到和 C + webview 一样的原生性能体验,同时也能够享受 GC 编程语言带来的安全性和协程的便利性。而 WebView 是一个典型的 C/C++ UI 库的示例,可以采用同样的方式集成类似 sokol/ImGui 等 UI 库。

https://nature-lang.cn/news/20260115 就如上一篇文章最后提到的,可控内存分配器和 unsafe 裸函数支持是原本的 GUI 支持策略基础,但是未料到共享栈模式的协程和 C/C++ 的兼容性如此优秀,直接就完成了适配。不过这种妥协不会是最终的解决方案,unsafe 裸函数和可控内存分配模式的工作会继续推动。到时候 nautre 的 main 函数可以选择独立于协程调度系统采取单独的线程和栈运行,让 nature 更加适应原生的 GUI 开发。

当然图形化操作系统 windows 同样是 GUI 支持重要一个环节,我将会进行看进行支持,由于调整了 nature 的源码,所以需要等到 0.7.3 版本发布时才能体验 nature-webview ,在这期间我会使用 nature 结合 webview 开发一个小项目进一步测试可用性。