飞万达吊运机-600261股份股吧

2023年9月26日发(作者:武光汤)
WebAssembly编程实践(1.3)胶⽔代码初探
说明:本系列⽂章转载⾃《C/C++⾯向wasm编程——Emscripten⼯程实践》系列教程(名字太长,转载以《WebAssembly编程实践》
为题)。
作者:丁尔男,Github @3dgen
作者:柴树杉,Github @chai2010,Twitter @chaishushan
-----------------------------------------------------------------------------------------
1.3 胶⽔代码初探
打开上⼀节(1.2)中由Emscripten⽣成的JavaScript胶⽔代码,我们可以发现,⼤多数的操作,都围绕全局对象Module展开,⽽
该对象正是Emscripten程序运⾏时的核⼼所在。
tips 跳过1.3.1以及1.3.2不会影响后续章节的阅读。但如果您对Emscripten模块载⼊等细节感兴趣,本节内容将有助于理解胶⽔代
码的结构。随着Emscripten的版本升级,其⽣成的胶⽔代码有可能发⽣变化,本节展⽰的代码均基于Emscripten 1.38.11。
1.3.1 WebAssembly汇编模块载⼊
WebAssembly汇编模块(既.wasm⽂件)的载⼊是在doNativeWasm函数中完成的。其核⼼部分如下:
function instantiateArrayBuffer(receiver) {
getBinaryPromise().then(function(binary) {
return tiate(binary, info);
}).then(receiver).catch(function(reason) {
err('failed to asynchronously prepare wasm: ' + reason);
abort(reason);
});
}
// Prefer streaming instantiation if available.
if (!Module['wasmBinary'] &&
typeof tiateStreaming === 'function' &&
!isDataURI(wasmBinaryFile) &&
typeof fetch === 'function') {
function receiveInstance(instance, module) {
exports = s;
if () mergeMemory();
Module['asm'] = exports;
Module["usingWasm"] = true;
removeRunDependency('wasm-instantiate');
}
......
function receiveInstantiatedSource(output) {
// 'output' is a WebAssemblyInstantiatedSource object which has both the module and instance.
// receiveInstance() will swap in the exports (to ) so they can be called
assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?');
... ...
var _main = Module["_main"] = function() {
assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');
assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');
return Module["asm"]["_main"].apply(null, arguments) };
var _malloc = Module["_malloc"] = function() {
assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');
assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');
return Module["asm"]["_malloc"].apply(null, arguments) };
... ...
在Emscripten中,C函数导出时,函数名前会添加下划线“_”,由此可知上述代码分别提供了main()以及malloc()函数的封装;⽽var
_main以及Module._main对应的,都是中的main()函数。我们可以在浏览器控制台中⼿动执⾏_main()以及Module._main()对此进⾏
检验:
不出所料,⼆者都执⾏了C代码中的main()函数,输出了“你好,世界!”。
1.3.3 异步加载
WebAssembly实例是通过tiateStreaming()/tiate()⽅法创建的,⽽这两个⽅法均为异步调⽤,这
意味着.js⽂件加载完成时Emscripten的Runtime并未准备就绪。倘若我们修改,载⼊.js后⽴即执⾏Module._main():
Module._main();
控制台将输出以下错误信息:
Assertion failed: you need to wait for the runtime to be ready
(e.g. wait for main() to be called)
解决这⼀问题需要建⽴⼀种Runtime准备就绪时的通知机制,为此Emscripten提供了多种解决⽅案,最简单的⽅法是在main()函数中发出通知,但是对多数纯功能性的
Module = {};
imeInitialized = function() { //do sth.
Module._main();
}
其基本思路是在Module初始化前,向Module中注⼊⼀个名为onRuntimeInitialized的⽅法,Emscripten的Runtime就绪后,将会回调该⽅
法。在中,我们可以观察到该回调的调⽤过程:
function run(args) {
... ...
ensureInitRuntime();
新型防盗窗-株洲飞鹿高新材料技术股份有限公司

更多推荐
406胶
发布评论