范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

WebAssembly初识

  1. 前言
  WebAssembly 是 W3C 标准化组织制定的一个可移植、体积小、加载快并且兼容 Web 的全新格式。利用 WebAssembly 技术可以方便地将非 JavaScript 代码快速地"运行"在浏览器中,从而为前端场景提供了无限可能;此外,随着 WebAssembly 在开发者社区中越来越流行,也正在成为服务端以及云计算平台上的新锐。
  作为本课程的开篇,本文首先介绍 WebAssembly 的发展历程,正所谓 "以史为镜,可以知兴替",从其历史演变中我们可以深入了解 WebAssembly 技术的来龙去脉,以及它的核心诉求和价值;接下来,我们会梳理和总结 WebAssembly 的使命和优势;最后,我们通过一个简单的 WebAssembly 浏览器应用示例,带领读者一起身临其境地感受下 WebAssembly 在 Web 环境中的真实使用体验。 2. WebAssembly 历史演变
  WebAssembly 技术源于浏览器,其发展历程可以说是一部浏览器性能优化史。在 Web 前端领域,JavaScript 语言是编写运行在浏览器上的 Web 应用的首选;与此同时,Node.js 等非浏览器 JavaScript 运行时环境的出现, JavaScript 变得越来越流行;然而,各类应用随着功能逐渐复杂化,对性能的要求越来越高;而由于 JavaScript 语言本身的一些特性,已经很难满足日益增长的应用性能需求。
  为了满足应用日益增长的性能需求,针对 JavaScript 语言本身缺陷带来的瓶颈优化,逐步形成了三个阶段性优化产物,他们分别是 asm.js、NaCl/PNaCl 以及 WebAssembly,正是这三个阶段的优化逐步推动了 WebAssembly 技术的发展。接下来,我们将逐一从这三个阶段来阐述其各自的诉求及其价值,从而了解 WebAssembly 起源及其目标和优势。 2.1 asm.js 阶段
  JavaScript 是前端开发的首选语言,由于 JavaScript 本身是一种动态、弱类型编程语言;因此,只有在程序运行时才能确定执行上下文中对象具体数据类型;不仅如此,JavaScript 语言还允许同一个变量在不同时刻可以绑定不同类型的对象。JavaScript 的弱类型导致虚拟机只能在执行时刻进行类型推断,同时,其动态性又进一步导致当前的执行结果无法被复用,因为代码所执行的对象类型和逻辑都可能随时改变。
  为了解决 JavaScript 语言自身带来的上述弊端,asm.js 便应运而生。asm.js 设计的出发点直指 JavaScript 语言的设计缺陷,asm.js 可以在 JavaScript 代码运行之前便确定程序中变量的具体类型;与此同时,它还进一步保证程序中变量的类型不会在程序运行的过程中发生改变。基于 asm.js 对弱类型和动态性的约束,虚拟机在执行过程中可以利用确定性的类型进行编译优化,并且编译结果可以复用而不需要重复执行相同源代码的编译优化过程,从而使得 Web 应用的运行效率有巨大的提升。
  asm.js 标准始于 2013 年 8 月,它是 JavaScript 的一个严格子集, 是一种可用于编译器的低层级的、高效的目标语言。相较 JavaScript 而言,asm.js 使用了一 种名为 Annotation 的类型声明方式来对变量类型进行约束,其中 Annotation 的形式采用  | T   表示。如下述 asm.js 模块代码所示,赋值语句 n = n | 0   通过对变量与 0 进行使用"按位或"操作的声明方式,可以让虚拟机在解析 asm.js 代码时强制将该变量 n   视为一个 32 位的整数,并且该变量所能够存储的数据类型在运行过程中无法被更改。function fast_fib_module(stdlib, foreign, heap) {     "use asm";     function fib(n) {         n = n|0;         if (n >>> 0 < 3) {             return 1|0;         }         return (fib((n-1)|0) + fib((n-2)|0))|0;     }     return fib; }
  从整体上看,asm.js 模块是一个标准的 JavaScript 函数。在 asm.js 的模块语法规则中,不仅需要对函数所传入的参数进行类型声明,而且这些是必需且强制的;此外,asm.js 标准中只定义了对数值类型的 Annotation 声明方式,这使得 asm.js 的应用场景很大程度上集中在数值计算密集型 Web 应用的优化处理上;再加上各大浏览器厂商对 asm.js 标准的支持程度和实现方式也不尽相同。
  asm.js 技术本身存在的问题和局限性,大大阻碍了 asm.js 的发展,从而也推动了 Web 应用优化进入了 NaCl 和 PNaCl 阶段。 2.2 NaCl 和 PNaCl 阶段
  NaCl(Google Native Client) 是 2011 Google Chrome 团队意在把基于原生 C/C++ 语言编写的本地应用安全、高效地运行在 Web 浏览器端的一项技术。该技术主要方式是将原生 C/C++ 语言编写的本地应用编译为标准的 NaCl 模块,每个 NaCl 模块是一个以 ".nexe" 为后缀的 ELF 格式二进制文件,该文件可以直接在 Chrome 中加载并运行。基于 NaCl 技术开发出来的应用可以以接近原生 C/C++ 应用的效率在浏览器端稳定地运行,但在实际项目使用时,需要为每种不同的处理器架构分别单独编译对应版本的 NaCl 二进制模块文件;这种方式既不方便也不符合开源软件的便携特性;不仅如此,NaCl 模块这种直接存储针对底层处理器架构机器码的方式也使得模块本身失去了可移植性。
  为了解决由于 NaCl 模块的平台依赖性导致的互联网上自由地分发的问题,又推出了新的 PNaCl (Chrome Portable Native Client) 技术。PNaCl 并不会直接将应用的 C/C++ 源代码编译成依赖特定处理器架构的底层机器码,PNaCl 首先会将应用的 C/C++ 源代码编译成一种基于 LLVM 生成的抽象中间二进制模块 ,以 ".pexe" 为后缀。这种模块不依赖具体的处理器架构,因此可以在互联网上被随意地分发。在浏览器中运行 PNaCl 应用时,浏览器会首先将 pexe 二进制模块加载到内存中,并根据当前处理器架构通过内置的 AOT 编译器将 pexe 二进制模块编译为特定处理器架构的机器码,随后被浏览器直接执行。
  NaCl 和 PNaCl 技术没有被除 Chrome 以外的任何其他浏览器支持;此外,基于 C/C++ 语言也大大增加了 NaCl 和 PNaCl 应用的开发难度和开发成本,使得 NaCl 和 PNaCl 基本脱离了技术快速迭代的前端开发领域。
  NaCl 和 PNaCl 技术本身存在的问题和局限性,阻碍了它成为浏览器的事实标准,从而也推动了 Web 应用优化进入到了当前的 WebAssembly 阶段。 2.3 WebAssembly 阶段
  基于前两个阶段的探索,为了提升 Web 应用的性能,2015 年 Mozilla 在 asm.js 的基础上发布了一种新型的二进制代码格式 "WebAssembly"。这种二进制文件可以用类似 JavaScript 模块加载的方式被浏览器快速、 高效地执行;不仅如此,WebAssembly 并不像 NaCl 那样需要区分浏览器所运行的处理器架构,这使得它可以自由地在互联网上分发,具有很好的浏览器兼容性和用户体验。鉴于 WebAssembly 的优势,2017 年,Firefox、Chrome、Edge 和 Webkit 四大浏览器厂商在 WebAssembly MVP (最小可用版本) 标准的设计上达成共识;同年,WebAssembly Working Group (以下简称 WWG) 成立,标志着 WebAssembly 成为 W3C 标准技术体系的一部分;2019 年 12 月,宣布 WebAssembly 成为第 4 种 Web 语言,同时 WebAssembly 1.0 标准正式落地。
  随着 WebAssembly 在开发者社区中越来越流行,WebAssembly 的潜在价值从 Web 逐渐开始向其他领域,比如云原生、AI 以及区块链等;2019 年 12 月,Bytecode Alliance 字节码联盟宣布正式成立,联盟旨在通过协作的方式,来共同实现 WebAssembly 及 WASI 相关标准,并通过提出新标准的方式来共同打造 WebAssembly 在浏览器之外的未来生态。
  在最近的 2022 年, WebAssembly 2.0 草案正式发布,相比 WebAssembly 1.0,WebAssembly 2.0 草案中加入了很多值得关注的新特性,比如引用类型(Reference Types)、固定宽度的 SIMD(Fixed-width SIMD)、批量内存操作(Bulk Memory Operations)等等。 3. WebAssembly 目标及其优势
  我们在上一节中介绍了 WebAssembly 发展历程,其设计的主要目标也是其核心优势主要体现在如下几个方面: 性能 : WebAssembly 是静态强类型低级语言,通过利用常见的硬件能力,WebAssembly 代码在不同平台上能够以接近本地速度运行。此外,WebAssembly 是一个轻量的二进制格式,提供了友好的高效冷启动,轻量部署能力。 跨平台、可移植 : WebAssembly 是一个可移植、体积小、语言和平台无关的二进制格式,开发者可以使用各种自身熟悉的语言开发,生成的 WebAssembly 作为平台无关的应用发布形式;发布的 WebAssembly 模块可以在众多平台上运行,例如浏览器、后端、终端设备、移动设备、IoT 等都有广阔的应用场景。 沙箱环境 : WebAssembly 运行在一个独立的沙箱中,一方面可以避免了数据的泄露和侧信道攻击,另一方面恶意代码只能影响自身沙箱环境而不会影响应用本身。 标准化 : W3C WebAssembly Working Group 制定相关的标准,可以保证标准的通用性和各厂商的兼容性。 网络安全 : WebAssembly 的设计原则是与其他网络技术和谐共处并保持向后兼容,WebAssembly 被限制运行在一个安全的沙箱执行环境中,像其他网络代码一样,它遵循浏览器的同源策略和授权策略。 灵活的开发模式 : WebAssembly 制定了标准化的中间指令格式,开发者可以使用多种不同的开发语言,如 C/C++,Java/Kotlin, TypeScript, Rust 等,利用工具链可以转化为统一的 WebAssembly 的中间指令格式。
  图 1. 传统应用开发、运行模式
  传统开发模式一般如图 1 所示,通过特定的语言生态开发、发布和运行应用。这种模式在大型系统中不可避免的暴露出其劣势: 首先,对于开发者来说,为了满足项目中不同部分的需求,需要采用不同的语言来开发,开发者需要掌握多种不同类型的语言,技术栈负担重。 其次,大型软件需要解决不同开发语言的协作问题(交互和集成),不同语言的交互一般需要语言特定的 FFI,而没有统一的集成方式和接口(组合爆炸 问题);交互过程中会引入额外的损耗(内存和性能) 再次,不同的语言发布的程序采用各自的方式部署和运行,对安全性,隔离性,跨平台等方面都会各自面临相同的问题,而没有统一的机制解决。 最后,不同的语言是为解决特定的问题,会在其他方面做妥协(例如,脚本语言 JavaScript, Ruby 开发者门槛低,但性能也低),对于已有模块的复用和迁移代价较大,无论是语言间相互转换 (transcompile) 还是重写都需要付出极大的代价。
  WebAssembly 为应用开发者提供了不一样的技术架构选型的可能性。WebAssembly 作为一个可安全隔离,高效,体积小、跨平台,多语言支持的可移植二进制中间形式,为解决上述问题提供了可实施的路径,不同的开发者可以利用 WebAssembly 的特性来满足业务需求。
  对于 JavaScript、Python 等脚本语言来说,为了追求更高的性能,可以将性能热点模块通过 WebAssembly 来实现,从而获取高性能执行的收益。对于 Rust 开发者来说,利用语言的特性可以获取高性能和高安全性,但为了让开发者获得更低的开发门槛,可以编译为 WebAssembly 模块提供给类似 JavaScript、Python 等脚本语言使用,降低开发者门槛;对于 C++ 开发者来说,可以获得高性能,但 C++ 不完备的安全性机制可能会使应用存在安全隐患,可以将其编译为 WebAssembly 在轻量级安全沙箱中运行,从而使得安全机制做到开箱即用(安全性保障需要安全领域的专业支持,门槛很高),如图 2 所示。
  图 2. WebAssembly 多语言使用场景示例 4. WebAssembly Web 应用体验
  在前面各小节中,我们已经一起了解了 WebAssembly 技术及其特点,为了更直观地了解 WebAssembly 的优势,本小节将搭建 Mandelbrot Web 应用来展示 WebAssembly 是如何与 JavaScript 语言结合,以及如何无缝的在 Web 环境中运行。其中,Mandelbrot [8] 是在复平面上组成分形的点的集合,其图形绘制过程需要进行大量的复平面数值计算,通过 WebAssembly 实现可以有效的提高计算和绘制性能。Mandelbrot 图形绘制算法将采用 AssemblyScript [9] 来编写,并通过 AssemblyScript 编译器生成 WebAssembly 二进制模块。
  本小节的剩余部分,我们将详解介绍 Mandelbrot Web 应用的创建过程和运行效果。 为了能够将 AssemblyScript 编译为 WebAssembly 二进制模块,需要通过如下命令创建项目工程,并预先安装 AssemblyScript 编译器。 npm init npm install --save-dev assemblyscript Mandelbrot 图形绘制函数 computeLine 保存为 Mandelbrot.ts,当完成工程创建后,通过如下命令行可以将 Mandelbrot.ts 编译为 WebAssembly 二进制文件 Mandelbrot.wasm。 npx asc Mandelbrot.ts --target release -o Mandelbrot.wasm // file: Mandelbrot.ts  /** Number of discrete color values on the JS side. */ const NUM_COLORS = 2048;  /** Computes a single line in the rectangle `width` x `height`. */ export function computeLine(y: u32, width: u32, height: u32, limit: u32): void {     var translateX = width * (1.0 / 1.6);     var translateY = height * (1.0 / 2.0);     var scale = 10.0 / min(3 * width, 4 * height);     var imaginary = (y - translateY) * scale;     var realOffset = translateX * scale;     var stride = (y * width) << 1;     var invLimit = 1.0 / limit;      var minIterations = min(8, limit);      for (let x: u32 = 0; x < width; ++x) {         let real = x * scale - realOffset;          // Iterate until either the escape radius or iteration limit is exceeded         let ix = 0.0, iy = 0.0, ixSq: f64, iySq: f64;         let iteration: u32 = 0;         while ((ixSq = ix * ix) + (iySq = iy * iy) <= 4.0) {             iy = 2.0 * ix * iy + imaginary;             ix = ixSq - iySq + real;             if (iteration >= limit) break;             ++iteration;         }          // Do a few extra iterations for quick escapes to reduce error margin         while (iteration < minIterations) {             let ixNew = ix * ix - iy * iy + real;             iy = 2.0 * ix * iy + imaginary;             ix = ixNew;             ++iteration;         }          // Iteration count is a discrete value in the range [0, limit] here, but we"d like it to be         // normalized in the range [0, 2047] so it maps to the gradient computed in JS.         // see also: http://linas.org/art-gallery/escape/escape.html         let col = NUM_COLORS - 1;         let sqd = ix * ix + iy * iy;          if (sqd > 1.0) {             let frac = Math.log2(0.5 * Math.log(sqd));             col = ((NUM_COLORS - 1) * clamp((iteration + 1 - frac) * invLimit, 0.0, 1.0));         }         store(stride + (x << 1), col);     } }  /** Clamps a value between the given minimum and maximum. */ @inline function clamp(value: T, minValue: T, maxValue: T): T {     return min(max(value, minValue), maxValue); } 为了展示 Mandelbrot 效果,可以通过在 Web 页面[11] 中来加载 Mandelbrot.wasm,并调用 computeLine 函数来计算 Mandelbrot 集来完成图形绘制。 // file: index.html  // Set up the canvas with a 2D rendering context var cnv = document.getElementsByTagName("canvas")[0]; var ctx = cnv.getContext("2d"); var bcr = cnv.getBoundingClientRect();  // Compute the size of the viewport // var width = bcr.width | 0; // var height = bcr.height | 0; // var ratio = window.devicePixelRatio || 1 // ... // ctx.scale(ratio, ratio);  // Compute the size of and instantiate the module"s memory const memory = new WebAssembly.Memory({     initial: ((byteSize + 0xffff) & ~0xffff) >>> 16 }); const mem = new Uint16Array(memory.buffer); const imageData = ctx.createImageData(width, height); const argb = new Uint32Array(imageData.data.buffer);  // Fetch and instantiate the module fetch("build/Mandelbrot.wasm") .then(response => response.arrayBuffer()) .then(buffer => WebAssembly.instantiate(buffer, {     env: {         memory,         "Math.log": Math.log,         "Math.log2": Math.log2     }, })) .then(module => {     const exports = module.instance.exports;     const computeLine = exports.computeLine;     const updateLine = function (y) {         var yx = y * width;         for (let x = 0; x < width; ++x) {             argb[yx + x] = colors[mem[yx + x]];         }     };      // Compute an initial balanced version of the set.     const limit = 40;     for (let y = 0; y < height; ++y) {         computeLine(y, width, height, limit);         updateLine(y);     }      // Keep rendering the image buffer.     (function render() {         if (animate) requestAnimationFrame(render);         ctx.putImageData(imageData, 0, 0);     })();     // ... }).catch(err => {     alert("Failed to load WASM: " + err.message + " (ad blocker, maybe?)");     console.log(err.stack); }); 按上述步骤,我们已经生成 Mandelbrot.wasm 二进制模块,并在 index.html 中完成模块加载和图形绘制的逻辑实现,最后,我们可以在本地建立 http 服务来加载和展示 Mandelbrot 图形效果,如图 3 所示。 cd $webassembly_tech/samples/mandelbrot npx serve  >   >    Serving!                                  >                                              >     - Local:    http://localhost:3000        >                                              >     Copied local address to clipboard!       >                                              >
  图 3. Mandelbrot 集图形效果
  虽然上述步骤中,我们已经详细描述了 Mandelbrot Web 应用中 WebAssembly 的生成和 Web 页面集成的各个步骤;但为了方便读者构建原型,webassembly_tech [11] 提供了源代码的下载,并提供了 Mandelbrot 项目使用文档快速构建和查看效果。 5. 总结
  至此,我们已经完整地介绍了 WebAssembly 技术的来龙去脉以及它的核心价值,并通过 Mandelbrot 示例带领读者一起身临其境地感受了 WebAssembly 在 Web 环境中的真实使用体验。然而,随着 WebAssembly 技术的不断发展,其应用领域和应用场景也越来越广阔,为了更好的了解 WebAssembly 的价值及其应用生态,在接下来的第二章中,我们将会对 WebAssembly 使用场景和未来发展趋势做进一步的介绍和探索。 6. 参考文献
  [1]. "asm.js" Working Draft:  http://asmjs.org/spec/latest/
  [2]. Native Client (NaCl & PNaCl): https://www.chromium.org/nativeclient/
  [3]. WebAssembly: https://webassembly.org/specs/
  [4]. Bringing WebAssembly outside the web with WASI by Lin Clark: https://www.youtube.com/watch?v=fh9WXPu0hw8
  [5]. Mandelbrot set: https://en.wikipedia.org/wiki/Mandelbrot_set
  [6]. Local Web Server: https://github.com/yaozhongxiao/cli/tree/master/server
  [7]. webassembly_tech: https://github.com/yaozhongxiao/webassembly_tech/tree/master/samples
  [8]. Mandelbrot set: https://en.wikipedia.org/wiki/Mandelbrot_set
  [9]. AssemblyScript: https://www.assemblyscript.org/
  [10]. Mandelbrot Set:https://github.com/yaozhongxiao/webassembly_tech/tree/master/samples/mandelbrot/index.html
  [11]. webassembly_tech: https://github.com/yaozhongxiao/webassembly_tech/tree/master/samples/mandelbrot/README.md
  作者:姚忠孝
  来源:微信公众号:字节前端 ByteFE
  出处:https://mp.weixin.qq.com/s/xvhQxqF5pWUVleL_P3tqgA

世界首善超越了比尔盖茨巴菲特,累计捐出6700亿元人民币近日,2021胡润全球世纪慈善家正式发布,报告列出最近一百多年中全球捐赠价值最高的慈善家,中国三人上榜,英国有六人,美国人数最多有三十余人登上该榜。下面主要介绍全球前十大慈善家的基远程组网高效办公!有蒲公英x5异地办公也不怕路由器作为企业组建网络的核心设备,选购是比较关键的。不过不少企业采购人员缺乏专业知识,所以只能选择了家用路由器。实际上,企业路由器无论是稳定性和安全性都要有所保障,有时候如果你还需早报比尔盖茨称全球变暖需控制vivoT1降至冰点价手机中国早报随着社会逐渐工业化,全球的平均气温越来越高,这影响到了在地球上生存的所有生物,所以控制全球变暖在当下一直是人们十分重视的问题。双十一电商大促,在众多活动商品中,手机可谓带10万人民币去缅甸,能舒舒服服炫富吗?来听当地姑娘怎么说准备十万元人民币去缅甸旅行,算不算当地的土豪呢?下面就听听缅甸的女老板怎么说的吧?(此处已添加小程序,请到今日头条客户端查看)大家都知道,缅甸是我国的邻国,虽然经济发展缓慢,但是当双十一单日销售榜基本是谁降价多,选择谁?k40无敌?双十一市场手机销售竞争很激烈,11月5日上午的销量看,能看出一个思路,谁有活动,谁的销量就不错?第一名是红米k40,当然看销量不错,仔细看,有一个最高优惠550元的活动,这个手机本还在用原声为视频配音吗?学会这一招,一键将文本生成语音在日常生活中,我们经常会用到语音转文字,比如朋友给我们发送的语音消息不方便听,我们就可以将语音转成文字。对于文字转语音,相信很多人也不陌生,尤其是一些自媒体的小伙伴,往往在录制视频江西一座军工厂,规模很大还有电影院,曾被很多人羡慕如今很荒凉江西一座军工厂,规模很大还有电影院,曾被很多人羡慕如今很荒凉说到江西这座自古以来有着千岳之地称号的城市,想必大家都有所耳闻吧,凭借着其优越的区位优势和城市境内极其便利的交通,使得这文莱王子吴尊的幻灭史,欺骗粉丝15年,心机太重了10月10日,吴尊在微博晒出了一家人的生日祝福照。有细心的网友发现,吴尊一家四口的生日仅仅相差一天,让人不禁羡慕缘分如此奇妙。殊不知这背后吴尊的妻子,为此付出了多少惨痛代价。经历过为什么说火锅变甜是门好生意?火锅变甜了?其实是火锅开启了甜品模式,将甜品和茶饮作为重要的品类,引入到火锅店的运营中。那么为什么说火锅变甜是门好生意呢?下文就将为你阐明这一点。甜和辣互补用户需求是王道一提起川菜天津优化城市体系,将建5个副中心城市,宝坻武清成功入围天津位于我国北部,华北平原东北部,东临渤海,北依燕山,西靠首都北京。自从我国的首都确定为北京之后,天津就一直是拱卫京畿的要地。除此之外,天津还是我国一带一路交汇点亚欧大陆桥最近的东冬奥会主题曲确定,曾唱北京欢迎你的100位明星,现状如何?不良的习惯会随时阻碍你走向成名获利和享乐的路上去。莎士比亚2021年渐近尾声,北京也即将拉开第24届冬季奥运的帷幕。而随着圣火顺利抵达,此次盛会的主题曲也被正式公布。这就是由17岁
透明壳也优雅,NothingPhone1图赏近日,Nothing发布了旗下首款新机NothingPhone1,起售价为469欧元(约合人民币3200元)。综合来看,NothingPhone1给人耳目一新的感觉,整体设计新颖而欧洲正式出台两项重要法案,矛头对准美国科技巨头,欧洲摆脱美国控制的抗争开始了董少鹏证券日报副总编辑人大重阳金融研究院高级研究员近日,欧洲议会通过了数字服务法和数字市场法,旨在规范数字市场秩序,维护用户合法权益,限制数字科技巨头过度垄断和不正当竞争行为,但其何止损失376亿元?警告正式传来,拆华为5G恶果出现自从5G网络被提出以后,就受到了世界各国的重视,作为最新一代的移动互联网通信技术,5G网络的到来,也将会让全球的科技市场迎来大洗牌,而且5G网络还将会让物联网车联网都成为现实,到时关于元宇宙的伦理之思1992年,尼尔斯蒂芬森在其科幻小说雪崩中,构造了一个与现实世界相平行的虚拟世界,即元宇宙(Metaverse)。此后,元宇宙这一概念虽未离开大众的视野,但却并没有被人们所广泛关注7月共67款国产网络游戏获批,腾讯网易均未在列7月12日,国家新闻出版署发布2022年7月份国产网络游戏审批信息,共67款游戏获批。头部游戏公司腾讯和网易游戏均未拿到版号。此次获批版号的游戏包括游族的战火与永恒西山居的双相创梦问界M7华为智选车的积分赛时隔半年,余承东又一次把问界搬上了华为的新品发布会,又一次压轴出场。新能源车产业对于制裁下的华为来说不是可有可无的试水,而是赖以生存的救命稻草。华为公布的财务数据显示,2020年华1亿元餐饮消费券,助餐饮企业走出困境新京报社论发放1亿元消费券,从消费端挖掘餐饮业复苏潜力,在当下无疑是雪中送炭之举。6月6日,北京恢复堂食首日,海淀区融科资讯中心,贵州味道餐厅,两位市民在点餐。新京报记者浦峰摄新京报社论近日吃鸡新款荣耀宣章军需!历经5个月,最可爱的皮肤终于来了务实不浮夸!我是你们的情报小能手,微笑十倍镜。吃鸡手游和平精英近期虽然一直在出新皮肤,但是都以小裙子为主,这也让许多玩家忍耐到了极点,过于女性化的皮肤急需一个新的设计来换换口味!众警惕!微信出现这两个界面,马上停手很多人经常会用到微信转账在用微信转账时如果你的手机出现这两个界面一定要提高警惕说明你当前支付存在巨大风险这15分钟,非常关键风险提醒一定要注意冷静下来别上当为了阻止诈骗行为对被害人这些小朋友写的诗,真的是可爱又惊艳,好多大人都自愧不如啊往往小朋友说的话写的句子,才是最纯真可爱又惊艳绝绝下面这些小朋友写的短诗,你看到过几首?这样的句子,以你的才能能否比得过?哈哈哈第一首古诗我把刚写的一首诗,放在太阳底下晒想把它晒黄张靓颖是白出了一个新色号吗,穿着简单的黑裙子,就像合影杀手哈喽,大家好,我是biu时尚,很高兴又和大家分享明星时尚与搭配技巧!希望我的文章让你对时尚更加的感兴趣,让本身就好看的你,更加的有魅力!抹胸的时尚搭配造型是很多礼服的选择当中比较常