WebAssembly核心编程[1]:wasm模块实例化的N种方式

news2024/10/6 12:22:46

当我们在一个Web应用中使用WebAssembly,最终的目的要么是执行wasm模块的入口程序(通过start指令指定的函数),要么是调用其导出的函数,这一切的前提需要创建一个通过WebAssembly.Instance对象表示的wasm模块实例(源代码)。

一、wasm模块实例化总体流程

虽然编程模式多种多样,但是wasm模块的实例化总体采用如下的流程:

  • 步骤一:下载wasm模块文件;

  • 步骤二:解析文件并创建通过WebAssembly.Module类型表示的wasm模块;

  • 步骤三:根据wasm模块,结合提供的导入对象,创建通过WebAssembly.Instance类型表示的模块实例。

二、利用WebAssembly.Module创建实例

我们照例通过一个简单的实例来演示针对wasm模块加载和模块实例创建的各种编程模式。我们首先利用WebAssembly Text Format(WAT)形式定义如下一个wasm程序,定义的文件名为app.wat。如代码所示,我们定义了一个用于输出指定浮点数(i64)绝对值的导出函数absolute。绝对值通过f64.abs指令计算,具体得输出则通过导入的print函数完成。

(module
   (func $print (import "imports" "print") (param $op f64) (param $result f64))
   (func (export "absolute") (param $op f64)
      (local.get $op)
      (f64.abs (local.get $op))
      (call $print)
   )
)

我们通过指定wat2wasm (源代码压缩包种提供了对应的.exe)命令(wat2wasm app.wat –o app.wasm)编译app.wat并生成app.wasm后,定义如下这个index.html页面,作为宿主程序的JavaScript脚本完全按照上面所示的步骤完成了针对wasm模块实例的创建。

<html>
    <head></head>
    <body>
        <div id="container"></div>
        <script>
            var print = (op, result) => document.getElementById("container").innerText = `abs(${op}) = ${result}`;
           fetch("app.wasm")
                .then((response) => response.arrayBuffer())
                .then(bytes => {
                    var module = new WebAssembly.Module(bytes);
                    var instance = new WebAssembly.Instance(module, {"imports":{"print": print}});
                    instance.exports.absolute(-3.14);
                })
        </script>
    </body>
</html>

具体来说,我们调用fetch函数将app.wasm文件下载下来后,我们将获得的字节内容作为参数调用构建函数创建了一个WebAssembly.Module对象。然后将这个Module对象和创建的导入对象({"imports":{"print": print}})作为参数调用构造函数创建了一个WebAssembly.Instance对象,该对象正是我们需要的wasm模块实例。我们从模块实例中提取并执行导出的absolute函数。导入的print函数会将绝对值计算表达式以如下的形式输出到页面中。

image

除了调用构造函数以同步(阻塞)的方式根据WebAssembly.Module对象创建WebAssembly.Instance对象外,我们还可以调用WebAssembly.instantiate静态方法以异步的方式“激活”wasm模块实例,它返回一个Promise<WebAssembly.Instance>对象。

var print = (op, result) => document.getElementById("container").innerText = `abs(${op}) = ${result}`;
fetch("app.wasm")
    .then((response) => response.arrayBuffer())
    .then(bytes => {
        var module = new WebAssembly.Module(bytes);
        return WebAssembly.instantiate(module, { "imports": { "print": print } });
    })
    .then(instance => instance.exports.absolute(-3.14));

三、通过字节内容创建创建实例

静态方法WebAssembly.instantiate还提供了另一个重载,我们可以直接指定下载wasm模块文件得到的字节内容作为参数。这个重载返回一个Promise<WebAssembly.WebAssemblyInstantiatedSource>对象,WebAssemblyInstantiatedSource对象的instance属性返回的正是我们需要的wasm模块实例。

var print = (op, result) => document.getElementById("container").innerText = `abs(${op}) = ${result}`;
fetch("app.wasm")
    .then((response) => response.arrayBuffer())
    .then(bytes => WebAssembly.instantiate(bytes, {"imports":{"print": print}}))
    .then(result =>result.instance.exports.absolute(-3.14));

四、利用XMLHttpRequest加载wasm模块

fetch函数是我们推荐的用于下载wasm模块文件的方式,不过我们一定义要使用传统的XMLHttpRequest对象也未尝不可。上面的三种激活wasm模块实例的方式可以采用如下的形式来实现。

var print = (op, result) => document.getElementById("container").innerText = `abs(${op}) = ${result}`;
const request = new XMLHttpRequest();
request.open("GET", "app.wasm");
request.responseType = "arraybuffer";
request.send();

request.onload = () => {
    var bytes = request.response;
    var module = new WebAssembly.Module(bytes);
    var instance = new WebAssembly.Instance(module, {"imports":{"print": print}});
    instance.exports.absolute(-3.14);
};

上面演示的利用创建的WebAssembly.Module对象和导入对象调用构造函数创建WebAssembly.Instance的同步形式。下面则是将二者作为参数调用静态方式WebAssembly.instantiate以异步方式激活wasm模块实例的方式。

var print = (op, result) => document.getElementById("container").innerText = `abs(${op}) = ${result}`;
const request = new XMLHttpRequest();
request.open("GET", "app.wasm");
request.responseType = "arraybuffer";
request.send();

request.onload = () => {
    var bytes = request.response;
    WebAssembly
        .instantiate(request.response, {"imports":{"print": print}})
        .then(result => result.instance.exports.absolute(-3.14));
};

下面演示WebAssembly.instantiate静态方法的另一个重载。

var print = (op, result) => document.getElementById("container").innerText = `abs(${op}) = ${result}`;
const request = new XMLHttpRequest();
request.open("GET", "app.wasm");
request.responseType = "arraybuffer";
request.send();

request.onload = () => {
    var bytes = request.response;
    WebAssembly
        .instantiate(request.response, {"imports":{"print": print}})
        .then(result => result.instance.exports.absolute(-3.14));
};

五、极简编程方式

其实我们有“一步到位”的方式,那就是按照如下的形式执行静态方法WebAssembly.instantiateStreaming。该方法的第一个参数用于提供下载.wasm模块文件的PromiseLike<Response>对象,第二个参数则用于指定导入对象。该方法同样返回一个Promise<WebAssembly.WebAssemblyInstantiatedSource>对象,WebAssemblyInstantiatedSource的instance属性返回的正是我们所需的wasm模块实例。

var print = (op, result) => document.getElementById("container").innerText = `abs(${op}) = ${result}`;
WebAssembly
    .instantiateStreaming(fetch("app.wasm"), {"imports":{"print": print}})
    .then(result => result.instance.exports.absolute(-3.14))

文章转载自:Artech

原文链接:https://www.cnblogs.com/artech/p/17994560/wasm_loading

体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1423860.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

京东广告算法架构体系建设--高性能计算方案最佳实践 | 京东零售广告技术团队

1、前言 推荐领域算法模型的在线推理是一个对高并发、高实时有较强要求的场景。算法最初是基于Wide & Deep相对简单的网络结构进行建模&#xff0c;容易满足高实时、高并发的推理性能要求。但随着广告模型效果优化进入深水区&#xff0c;基于Transformer用户行为序列和Att…

springboot137欢迪迈手机商城设计与开发

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

HBase介绍

一、HBase简介 1.1、HBase是什么 Google在200-2006发表了GFS、MapReduce、BigTable三篇 论文 &#xff0c;号称“三驾马车”&#xff0c;开启了大数据的时代。 GFS是Google File System&#xff0c;开源实现是HDFS&#xff08;Hadoop File System&#xff09;。 MapReduce…

全流程机器视觉工程开发(三)任务前瞻 - 从opencv的安装编译说起,到图像增强和分割

前言 最近开始做这个裂缝识别的任务了&#xff0c;大大小小的问题我已经摸得差不多了&#xff0c;然后关于识别任务和分割任务我现在也弄的差不多了。 现在开始做正式的业务&#xff0c;也就是我们说的裂缝识别的任务。作为前言&#xff0c;先来说说场景&#xff1a; 现在相…

初识webpack(一)概念、入口配置、输出配置、loader等

目录 (一)概念 webpack的依赖图 (二)webpack的基本使用 (三)webpack的配置文件 1.入口(entry)配置 2.输出(output)配置 (三)loader 1.css文件处理 (1)安装css-loader和style-loader (2)在webpack.config.js中配置loader 2.less文件处理 3.postcss的使用 (1)安装…

相片修复框架-GFPGAN

一 GFPGAN 介绍 GFPGAN 是一个由腾讯 ARC 团队开发的用于人脸图像生成和优化的 GAN 模型。在github可以找到开源的代码&#xff0c;它由两个主要模块组成&#xff1a; 退化移除模块 (U-Net)&#xff1a;用于从低分辨率、低质量的人脸图像中恢复出高质量的人脸图像。 生成式脸部…

软件工程知识梳理6-运行和维护

软件维护需要的工作量很大&#xff0c;大型软件的维护成本高达开发成本的4倍左右。所以&#xff0c;软件工程的主要目的就是要提高软件的可维护性&#xff0c;减少软件维护所需要的工作量&#xff0c;降低软件系统的总成本。 定义&#xff1a;软件已经交付使用之后&#xff0c;…

【爬虫专区】批量下载PDF (无反爬)

天命&#xff1a;只要没反爬&#xff0c;一切都简单 这次爬取的是绿盟的威胁情报的PDF 先看一下结构&#xff0c;很明显就是一个for循环渲染 burp抓包会发现第二次接口请求 接口请求一次就能获取到了所有的数据 然后一个循环批量下载数据即可&#xff0c;其实没啥难度的 imp…

腾讯云幻兽帕鲁Palworld服务器价格表,2024年2月最新

腾讯云幻兽帕鲁服务器价格32元起&#xff0c;4核16G12M配置32元1个月、96元3个月、156元6个月、312元一年&#xff0c;支持4-8个玩家&#xff1b;8核32G22M幻兽帕鲁服务器115元1个月、345元3个月&#xff0c;支持10到20人在线开黑。腾讯云百科txybk.com分享更多4核8G12M、16核6…

PVE 7.4-17 中开启vGPU显卡虚拟化

要为VM提供图形引擎&#xff0c;一般分为3种&#xff1a; 1、软件模拟图形-性能差 2、显卡直通-性能最好&#xff0c;一个虚拟机独享一个显卡 3、vGPU-性能好&#xff0c;多个虚拟机共享一个显卡 目前市面上的主流GPU厂家有intel、amd、nvidia&#xff0c;本篇文章主要介绍nvi…

Intercom与HelpLook:搭建知识库哪个更符合你的需求?

在当今信息化日益发展的时代&#xff0c;知识库作为一种集中存储和管理企业信息的重要工具&#xff0c;已经被越来越多的公司所采用。它有助于企业提升效率&#xff0c;改进服务质量&#xff0c;更好地与客户进行沟通。Intercom和HelpLook近两年在这个领域的讨论度不断变高&…

网络层 IP协议(1)

前置知识 主机:配有IP地址,但是不进行路由控制的设备 路由器:既配置了IP地址,又能进行路由控制的设备 节点:主机和路由器的总称 IP协议主要完成的任务就是 地址管理和路由选择 地址管理:使用一套地址体系,将网络设备的地址描述出来 路由选择:一个数据报如何从源地址到目的地址 …

摄影分享|基于Springboot的摄影分享网站设计与实现(源码+数据库+文档)

摄影分享网站目录 目录 基于Springboot的摄影分享网站设计与实现 一、前言 二、系统功能设计 三、系统实现 1、用户信息管理 2、图片素材管理 3、视频素材管理 4、公告信息管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐…

excel 选中指定区域

问题 excel 选中指定区域 详细问题 笔者有一个excel数据集&#xff0c;数据量较大&#xff0c;如何快速选中指定区域 解决方案 步骤1、 点击起始单元格 确定单元格坐标&#xff08;建议直接CtrlC复制至剪贴板&#xff09; 具体操作入下图所示 步骤2、 点击结束单元格 …

数与抽象之自然数

自然数 “自然数的抽象与内在属性&#xff1a;图7中的纯粹五性” “自然”是数学家对我们所熟悉的1&#xff0c;2&#xff0c;3&#xff0c;4这样的数字所赋予的称呼。自然数是最基本的数学对象&#xff0c;但它们似乎并没有引导我们去抽象地思考。毕竟&#xff0c;单单一个数…

【Linux网络编程一】网络基础(网络框架)

【Linux网络编程一】网络基础&#xff08;网络框架&#xff09; 一.什么是协议1.通信问题2.协议本质3.网络协议标准 二.协议分层1.为什么协议要分层2.如何具体的分层 三.操作系统OS与网络协议栈的关系1.核心点&#xff1a;网络通信贯穿协议栈 四.局域网中通信的基本原理1.封装&…

【教学类-34-01】20240130纸尺1.0 (A4横版5条,刻度25*5=125CM)

作品展示&#xff1a; 背景需求&#xff1a; 大3班一位孩子用“骰子统计纸”制作了一个身高刻度表 【教学类-40-01】A4骰子纸模制作1.0&#xff08;飞机形 5.5CM纸盒骰子1个记录纸1条&#xff09;&#xff08;点数是不同的符号图案&#xff09;-CSDN博客文章浏览阅读160次。【…

查看阿里云maven仓中某个库有哪些版本

起因 最近项目上有做视频业务&#xff0c;方案是使用阿里云的短视频服务&#xff0c;其中也有使用到阿里云的上传SDK&#xff0c;过程中有遇一个上传SDK的内部崩溃&#xff0c;崩溃栈如下&#xff1a; Back traces starts. java.lang.NullPointerException: Attempt to invok…

【Qt】—— Qt Creator界⾯认识

目录 &#xff08;一&#xff09;左边栏 &#xff08;二&#xff09;代码编辑区 &#xff08;三&#xff09;UI设计界⾯ &#xff08;四&#xff09;构建区 &#xff08;一&#xff09;左边栏 在编辑模式下&#xff0c;左边竖排的两个窗⼝叫做"边栏"。 ①是项⽬…

指针的深入理解(三)

这一节主要使用复习回调函数&#xff0c; 利用冒泡模拟实现qsort函数。 qsort 排序使用冒泡排序&#xff0c;主要难点在于运用元素个数和字节数以及基地址控制元素的比较&#xff1a; if里面使用了一个判断函数&#xff0c;qsort可以排序任意的数据&#xff0c;原因就是因为可…