{
  "schemaVersion": "0.11.0",
  "canonical": "https://www.pystone.net/notes/webgl-logic-runtime-js-wasm/",
  "atlas": "https://www.pystone.net/?node=webgl-logic-runtime-js-wasm#knowledge-atlas",
  "markdown": "https://www.pystone.net/notes/webgl-logic-runtime-js-wasm.md",
  "context": "https://www.pystone.net/notes/webgl-logic-runtime-js-wasm.context.json",
  "knowledgeVersion": "224c990773de.5fa8af6e39fa",
  "build": {
    "siteCommit": "224c990773de166d23a886306577dd90379529ce",
    "notesCommit": "5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a",
    "builtAt": "1970-01-01T00:00:00.000Z",
    "version": "224c990773de.5fa8af6e39fa"
  },
  "id": "note:webgl-logic-runtime-js-wasm",
  "slug": "webgl-logic-runtime-js-wasm",
  "title": "底层深入-WebGL应用逻辑运行时（JavaScript与WebAssembly）",
  "type": "note",
  "visibility": "public",
  "idStability": "rename-stable",
  "author": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "publisher": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "aliases": [],
  "summary": "底层深入 WebGL应用逻辑运行时（JavaScript与WebAssembly）",
  "contentRole": "unspecified",
  "isMoc": false,
  "mocRecognition": "none",
  "generated": false,
  "attribution": "unspecified",
  "domain": "10-计算机、信息技术与工程",
  "tags": [],
  "mocs": [],
  "contentHash": "d1538cd47995f3df50dffd836872ed1c76978d1c1a37e1958e0ea211637437bf",
  "assets": [],
  "headings": [
    {
      "depth": 1,
      "text": "底层深入-WebGL应用逻辑运行时（JavaScript与WebAssembly）",
      "anchor": "底层深入-webgl应用逻辑运行时javascript与webassembly",
      "citation": "https://www.pystone.net/notes/webgl-logic-runtime-js-wasm/#%E5%BA%95%E5%B1%82%E6%B7%B1%E5%85%A5-webgl%E5%BA%94%E7%94%A8%E9%80%BB%E8%BE%91%E8%BF%90%E8%A1%8C%E6%97%B6javascript%E4%B8%8Ewebassembly"
    },
    {
      "depth": 2,
      "text": "什么是 “JavaScript 运行时”？",
      "anchor": "什么是-javascript-运行时",
      "citation": "https://www.pystone.net/notes/webgl-logic-runtime-js-wasm/#%E4%BB%80%E4%B9%88%E6%98%AF-javascript-%E8%BF%90%E8%A1%8C%E6%97%B6"
    },
    {
      "depth": 2,
      "text": "JS 代码到机器码的流水线（以 V8 为例）",
      "anchor": "js-代码到机器码的流水线以-v8-为例",
      "citation": "https://www.pystone.net/notes/webgl-logic-runtime-js-wasm/#js-%E4%BB%A3%E7%A0%81%E5%88%B0%E6%9C%BA%E5%99%A8%E7%A0%81%E7%9A%84%E6%B5%81%E6%B0%B4%E7%BA%BF%E4%BB%A5-v8-%E4%B8%BA%E4%BE%8B"
    },
    {
      "depth": 2,
      "text": "WebAssembly 与 JavaScript 的关系",
      "anchor": "webassembly-与-javascript-的关系",
      "citation": "https://www.pystone.net/notes/webgl-logic-runtime-js-wasm/#webassembly-%E4%B8%8E-javascript-%E7%9A%84%E5%85%B3%E7%B3%BB"
    },
    {
      "depth": 3,
      "text": "差异部分",
      "anchor": "差异部分",
      "citation": "https://www.pystone.net/notes/webgl-logic-runtime-js-wasm/#%E5%B7%AE%E5%BC%82%E9%83%A8%E5%88%86"
    },
    {
      "depth": 3,
      "text": "示例：同一个 add 函数的两种形态",
      "anchor": "示例同一个-add-函数的两种形态",
      "citation": "https://www.pystone.net/notes/webgl-logic-runtime-js-wasm/#%E7%A4%BA%E4%BE%8B%E5%90%8C%E4%B8%80%E4%B8%AA-add-%E5%87%BD%E6%95%B0%E7%9A%84%E4%B8%A4%E7%A7%8D%E5%BD%A2%E6%80%81"
    },
    {
      "depth": 3,
      "text": "编译流水线（以 V8 为例）",
      "anchor": "编译流水线以-v8-为例",
      "citation": "https://www.pystone.net/notes/webgl-logic-runtime-js-wasm/#%E7%BC%96%E8%AF%91%E6%B5%81%E6%B0%B4%E7%BA%BF%E4%BB%A5-v8-%E4%B8%BA%E4%BE%8B"
    },
    {
      "depth": 3,
      "text": "共用的部分 = “引擎 + 事件循环 + 宿主 API”",
      "anchor": "共用的部分-引擎-事件循环-宿主-api",
      "citation": "https://www.pystone.net/notes/webgl-logic-runtime-js-wasm/#%E5%85%B1%E7%94%A8%E7%9A%84%E9%83%A8%E5%88%86-%E5%BC%95%E6%93%8E-%E4%BA%8B%E4%BB%B6%E5%BE%AA%E7%8E%AF-%E5%AE%BF%E4%B8%BB-api"
    },
    {
      "depth": 3,
      "text": "调用栈与内存的实际交错",
      "anchor": "调用栈与内存的实际交错",
      "citation": "https://www.pystone.net/notes/webgl-logic-runtime-js-wasm/#%E8%B0%83%E7%94%A8%E6%A0%88%E4%B8%8E%E5%86%85%E5%AD%98%E7%9A%84%E5%AE%9E%E9%99%85%E4%BA%A4%E9%94%99"
    },
    {
      "depth": 2,
      "text": "在微信小游戏 / WebGL 场景中的落地",
      "anchor": "在微信小游戏-webgl-场景中的落地",
      "citation": "https://www.pystone.net/notes/webgl-logic-runtime-js-wasm/#%E5%9C%A8%E5%BE%AE%E4%BF%A1%E5%B0%8F%E6%B8%B8%E6%88%8F-webgl-%E5%9C%BA%E6%99%AF%E4%B8%AD%E7%9A%84%E8%90%BD%E5%9C%B0"
    }
  ],
  "claims": [],
  "outgoing": [],
  "incoming": [
    {
      "id": "note:game-graphics-and-runtime",
      "title": "游戏图形与运行时",
      "url": "https://www.pystone.net/notes/game-graphics-and-runtime/",
      "atlas": "https://www.pystone.net/?node=game-graphics-and-runtime#knowledge-atlas",
      "label": "游戏图形与运行时",
      "origin": "explicit",
      "humanReviewed": true,
      "context": "WebGL中的“底层深入-WebGL应用逻辑运行时（JavaScript与WebAssembly）”导航项",
      "citation": "https://www.pystone.net/notes/game-graphics-and-runtime/#webgl"
    }
  ],
  "contentMarkdown": "# 底层深入-WebGL应用逻辑运行时（JavaScript与WebAssembly）\n\n﻿# 底层深入-WebGL应用逻辑运行时（JavaScript与WebAssembly）\n\n## 什么是 “JavaScript 运行时”？\n\n> **运行时（runtime）= JS 引擎 + 事件循环 + 宿主 API**\n> 引擎执行脚本；事件循环调度任务；宿主提供 “外界能力”（网络、文件、WebGL 等）。\n\n**在 Web / 小程序里的两层结构**\n\n```text\n┌─────────────  宿主层  ──────────────┐\n│  setTimeout / requestAnimationFrame│\n│  wx.request / canvas / WebGL       │\n└────────────────────────────────────┘\n┌───────────  JS 引擎层  ────────────┐\n│  解析(Parser) → 字节码(Interpreter)│\n│  → JIT 编译(Hot code) → 机器码     │\n│  GC / 隐式类型系统 / PromiseJobs   │\n└────────────────────────────────────┘\n```\n\n* **Android 微信小游戏**：引擎是 **V8**；\n* **iOS 微信小游戏**：引擎是 **JavaScriptCore (JSC)**；二者都 **没 DOM**、只暴露 `wx.*` API。\n* 小游戏容器在 C++/Java 层维护事件循环，把宿主回调排进 **宏任务队列**，V8 / JSC 执行完一轮微任务后再取宏任务。\n\n---\n\n## JS 代码到机器码的流水线（以 V8 为例）\n\n1. **解析**：生成 AST。\n2. **Ignition** 把 AST 编译成 *字节码* 并立即解释执行。\n3. **Profiling**：热点函数被标记为 *warm/hot*。\n4. **Sparkplug / TurboFan** JIT 把热点字节码优化为本机指令；还能随时 **反优化**。\n\n最终机器码直接跑在 ARM64 / x86-64 CPU 上；GC 维护堆对象与类型反馈。\n\n---\n\n## WebAssembly 与 JavaScript 的关系\n\n* 它们“共用同一个（物理）运行时”，因为引擎、事件循环、宿主线程都完全重合；\n* 它们各自拥有“独立的语言 runtime”，因为字节码格式、内存模型和首段编译器彼此不同。\n\n### 差异部分\n\n物理上共用同一 runtime，但逻辑上独立。\n\n| 项          | JavaScript                            | WebAssembly                          |\n| ---------- | ------------------------------------- | ------------------------------------ |\n| **模块格式**   | `.js` 源文本/ESM                         | `.wasm` 二进制、`.wat` 文本                |\n| **类型系统**   | 动态、可变对象                               | 静态, 固定位宽的 `i32/f64` 等                |\n| **内存模型**   | GC 堆（对象可移动）                           | 线性内存 `WebAssembly.Memory`（连续字节）      |\n| **首段编译器**  | _Ignition_ 解释器 / _Sparkplug_ baseline | _Liftoff_ baseline 编译器               |\n| **互调桥**    | `WebAssembly.Instance.exports.fn()`   | `import \"js\" \"log\"` 直接调 JS 函数        |\n| **加载 API** | `<script>`、`eval`                     | `WebAssembly.instantiateStreaming()` |\n\n### 示例：同一个 `add` 函数的两种形态\n\n```js\n// JavaScript\nexport function add(a, b) { return a + b }\n```\n\n```wat\n;; WebAssembly Text Format\n(module\n  (func $add (export \"add\") (param i32 i32) (result i32)\n    local.get 0\n    local.get 1\n    i32.add))\n```\n\n加载并互调：\n```js\nconst { add } = await WebAssembly\n      .instantiateStreaming(fetch('add.wasm'))\n      .then(m => m.instance.exports);\n\nconsole.log(add(40, 2));  // 42\n```\n\n### 编译流水线（以 V8 为例）\n\n```text\nJavaScript             WebAssembly\n--------               ------------\nsource .js             binary .wasm\n   │ parse               │ decode\n   ▼                     ▼\n Ignition bytecode      Liftoff machine code   ← 首帧快速启动\n   │ (解释执行 & 收集热度)  │\n   ├───────┐             ├───────┐\n   ▼       │             ▼       │\nTurboFan JIT ───────────┴─► TurboFan JIT       ← 热点函数重编译\n  (优化、内联、SIMD…)             (相同优化管线)\n```\n\n两条支流最后都汇入 **同一个机器码调度器**，在同一线程栈上运行。\n\n### 共用的部分 = “引擎 + 事件循环 + 宿主 API”\n两者 **共用同一个引擎内核与事件循环**：Wasm 模块只是 JS 引擎中的另一类 “代码对象”。当 Wasm 函数被调用时，执行栈可跨语言跳转。\n\n| 层级                                   | 共享？ | 说明                                                               |\n| ------------------------------------ | --- | ---------------------------------------------------------------- |\n| **宿主事件循环**                           | ✅   | 浏览器/小游戏的宏任务队列只维护一份；JS 代码、Wasm 代码都要“让出栈”才能让 UI 与 I/O 事件继续跑。       |\n| **引擎核心 (V8/JSC)**                    | ✅   | V8 官方定义自己是 “JavaScript **and WebAssembly** engine”；同一个堆、同一套线程模型。 |\n| **优化 JIT (TurboFan / DFG)**          | ✅   | 优化器既能接收 JS 字节码也能接收 Wasm IR，再生成本机指令。                              |\n| **Host APIs** (`wx.request`, WebGL…) | ✅   | 这部分暴露给 JS，全靠 JS 调用把参数塞进 Wasm 内存后再供 Wasm 代码使用。                    |\n\n### 调用栈与内存的实际交错\n\n```text\nJS (app.js)\n  └─ calls wasmAdd() ─► Wasm (add.wasm)\n                         └─ calls console.log          (回到 JS)\n```\n\n- “JS→Wasm” 时，引擎生成 **TRAMPOLINE**：把 JS 数值装箱/拆箱成 `i32` 写进线性内存；\n- “Wasm→JS” 时走 `import` 表，返回点仍在同一执行栈帧；\n- GC 线程若移动 JS 对象，只需更新托管句柄；Wasm 线性内存地址永远不变，因而无需移动补丁。\n\n\n## 在微信小游戏 / WebGL 场景中的落地\n\n* **逻辑线程只有一个**：JS 执行、Wasm 执行、WebGL API 调用全在同一 V8/JSC 线程完成。\n* **WebGL** 本质是宿主（GameRuntime）暴露的 C++ API：\n\n  ```js\n  const id = gl.createShader(gl.VERTEX_SHADER); // JS 调 => C++ => GPU\n  ```\n* **Unity WebGL**：IL2CPP 先把 C# 编译成 Wasm；运行时模板在 `Module.onRuntimeInitialized` 里用 JS 把渲染循环排进宿主事件循环。\n* **同源崩溃上报**：`wx.onError`（JS）+ `Module.onAbort`（Wasm）监听到异常后，共用 `sendCrash()` API 把数据发往服务器——JS 和 Wasm 层面虽然触发点不同，但最终走的是同一个 JS 发送函数。\n"
}
