emscripten - emscripten_sleep_with_yield() 期间的非解释调用
问题描述
我有一个通过Emscripten emterpreter转换为 Javascript 的 C 例程,它调用emscripten_sleep_with_yield()
. 虽然它正在产生,但我想在异步回调中运行一些非解释的 C 代码。当我尝试时,有一条错误消息显示:
“此错误发生在 emterpreter-async 保存或加载堆栈期间。保存期间堆栈上是否有非 emterpreted 代码(这是不允许的)?”
从抽象的意义上说,我不确定为什么在堆栈加载或保存时调用非空解析代码会有任何问题——它实际上并不在被要求保留的堆栈上。
这个非解释代码的动机是更新一些对产生的例程可见的结构。我发现回调中的纯 JavaScript 在技术上可以通过setValue()
进入 emscripten 堆来实现影响。但是通过 JavaScript 进行 C 操作是很尴尬的,特别是因为许多例程,比如底层AllocateUTF8()
调用_malloc()
……而且这些例程都有同样的问题。
这是一个显示问题的简单示例。有没有办法解决这个问题......例如,在进行非解释调用时将加载/保存状态变量存储在某处,然后将它们放回去?
测试.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Plain call during Emterpreter Stack Load</title>
<script src="test.o.js"></script>
<script>
Module.onRuntimeInitialized = function() {
setTimeout(function () {
console.log("calling not_emterpreted()");
_not_emterpreted();
}, 0);
_emterpreted_yielder();
console.log("yielding...");
}
</script>
</head>
<body></body>
</html>
测试.c
#include <stdio.h>
#include <emscripten.h>
EMSCRIPTEN_KEEPALIVE void emterpreted_yielder() {
while (1) {
printf("emterpreted_yielder() sleeping...\n");
emscripten_sleep_with_yield(1000);
}
}
EMSCRIPTEN_KEEPALIVE void not_emterpreted() {
printf("Entering not_emterpreted()\n");
}
构建:
emcc test.c -o test.o.js -s EMTERPRETIFY=1 -s EMTERPRETIFY_ASYNC=1 -s EMTERPRETIFY_BLACKLIST="['_not_emterpreted']"
注释掉not_emterpreted()
html 中的调用将导致它执行预期的睡眠循环。就像我说的那样,那时您可以将 C 影响作为针对 emterpreter 堆的原始 JavaScript 指令。但是......这不是非解释的emscripten C吗?:-/
解决方案
这是 emscripten 中过于保守的错误机制。针对这个问题,现在已经取消了限制:
推荐阅读
- c# - 用 Modal 替换 ASP.NET 身份登录和注册页面,但收到 InvalidOperationException
- python - 绘制不平衡的数据集
- ios - 在 iOS 应用程序和 Webview 中使用 MSAL 进行单点登录
- r - 德国引号在 tinytex/rmarkdown 中损坏 - 即使使用包 `csquotes`
- json - 具有基于问题的分数的问答游戏的数据结构
- ruby-on-rails - 如何在不创建实例组的情况下管理 GCE VM 实例中的多个请求?
- javascript - 当它应该未定义时,JavaScript 绑定将第二个参数设置为等于第一个参数?
- javascript - 如何知道浏览器是否支持 webSQL?
- c - C编程,为什么我的代码有溢出?
- java - 10 分钟后重复 TextSwitcher 文本