emscripten_sleep_with_yield() 期间的非 emterpreted 调用
Non-emterpreted calls during emscripten_sleep_with_yield()
我有一个 C 例程通过 Emscripten emterpreter, that calls emscripten_sleep_with_yield()
转译为 Javascript。当它产生时,我想 运行 一些 non-emterpreted 异步回调中的 C 代码。当我尝试时,出现一条错误消息:
"This error happened during an emterpreter-async save or load of the stack. Was there non-emterpreted code on the stack during save (which is unallowed)?"
从抽象意义上讲,我不确定为什么在加载或保存堆栈时调用非 empterpreted 代码会出现问题——它实际上不是 on 要求保留的堆栈。
这个非 emterpreted 代码的动机是更新一些对产生的例程可见的结构。我发现回调中的普通 JavaScript 技术上 可能通过对 emscripten 堆执行 setValue()
来实现影响。但是通过 JavaScript 进行 C 操作是很尴尬的,特别是因为许多例程,如 AllocateUTF8()
在幕后调用 _malloc()
......并且那些有同样的问题。
这是一个说明问题的简单示例。有什么办法解决这个......例如在进行非 emterpreted 调用时将 load/save 状态变量存储在某处,然后将它们放回去??
test.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>
test.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']"
在 html 中注释掉对 not_emterpreted()
的调用将导致它执行人们期望的睡眠循环。就像我说的那样,那时你可以改为将 C 影响作为针对 emterpreter 堆的原始 JavaScript 指令。但是...这不是非 emterpreted emscripten C 吗? :-/
这是 emscripten 中过于保守的错误机制。针对这个问题,现在已经取消了限制:
我有一个 C 例程通过 Emscripten emterpreter, that calls emscripten_sleep_with_yield()
转译为 Javascript。当它产生时,我想 运行 一些 non-emterpreted 异步回调中的 C 代码。当我尝试时,出现一条错误消息:
"This error happened during an emterpreter-async save or load of the stack. Was there non-emterpreted code on the stack during save (which is unallowed)?"
从抽象意义上讲,我不确定为什么在加载或保存堆栈时调用非 empterpreted 代码会出现问题——它实际上不是 on 要求保留的堆栈。
这个非 emterpreted 代码的动机是更新一些对产生的例程可见的结构。我发现回调中的普通 JavaScript 技术上 可能通过对 emscripten 堆执行 setValue()
来实现影响。但是通过 JavaScript 进行 C 操作是很尴尬的,特别是因为许多例程,如 AllocateUTF8()
在幕后调用 _malloc()
......并且那些有同样的问题。
这是一个说明问题的简单示例。有什么办法解决这个......例如在进行非 emterpreted 调用时将 load/save 状态变量存储在某处,然后将它们放回去??
test.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>
test.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']"
在 html 中注释掉对 not_emterpreted()
的调用将导致它执行人们期望的睡眠循环。就像我说的那样,那时你可以改为将 C 影响作为针对 emterpreter 堆的原始 JavaScript 指令。但是...这不是非 emterpreted emscripten C 吗? :-/
这是 emscripten 中过于保守的错误机制。针对这个问题,现在已经取消了限制: