网页汇编接口
标准库宿主之务 闲块数 受有值之参,返豫言核之服务四十五之空闲物理块数,每块二兆;原生与节点宿主无此核池则返负一。执行器映带型导入于原语一百九十四,再询共用底层平台。
网一:唯一之目标
编译器唯一目标:WasmGC。用引擎引用、类型数组、结构及 Wasm 调用栈,不赖任何“裸指针之约”。本篇节号恒定,以便引述;原第二节随旧目标而删。
网三:GC 值
表达式皆返 (ref null eq),实际如下。
| 值 | 表示 |
|---|---|
| 单位、擦除类 | ref.null eq |
| -2^30…2^30-1 整 | 有符号 ref.i31 |
| 其余 i64 | $big=struct(field i64) |
| 爻 | i31 0/1 |
| 小数 | $float=struct(field f64) |
| 元组、引用、闭包、数组 | $tuple=array(mut (ref null eq)) |
| 串、字节、字节缓冲 | $bytes=array(mut i8),不附隐藏之末零;字节缓冲可改,惟以类别于字节串 |
| 构造实例 | 专用之结构 $变形=struct (field i32) (field 诸字段):形者构造器诸显式字段之表:声为整数之字段为“整”(i64),余(含声为小数者与类变量之字段)为“任”((ref null eq));“小”(f64)为小数之字段所留,今不生;一实一物;首为标(类内之序,自一始),第 i 字段居 i+1 号;字段皆不可改,型终而无超型 |
| 资源(接口之文无构造器之类) | $外=struct(field (ref null extern)),字段不可改,藏宿主所授之物;可空者,惟令原型全局得以 struct.new_default 造之 |
| 代码 | i31 函数表索引 |
闭包首代码,余捕获;普通源函数保擦后逐参链,内部多参数型不由源箭头数臆定。代码 ref.cast i31、i31.get_u 后按参数数目 call_indirect,不填宿主之址。
同形之构造器(无论属何类)共一结构,同类而同形者以标别之。匹配构造器,依此匹配诸构造器之支之形次第 ref.test(字段多者居前),中则转之而取其标;皆不中则得零,落于默认之支或报错之支。既入一支,所匹配者惟转一次,存于带型之局,取字段皆读此局。
网四:调用、模块、异常
本基线恒生 t0 至 t16;模块之函数或动态调用参数逾十六者,依所用最大参数之数 N 续生 t17 至 tN。参数皆 eqref,结果亦然,self 入参数数。尾调用 return_call_indirect,普通合流用结果块与 br,不设续延之帧。
确知之函(见《函数应用形状分析》“去装箱”)别有快体 $m号(纯整之函为 $n号):其参依确知签名为 i64、f64、(ref $tuple) 或 (ref null eq),其果为 i64、f64 或 (ref null eq),型内书,不入函数之表。公门 $f号 守上之 $tN 之约:解参而调快体,果非 eqref 则装之。编译器径调确知之函者,径调其快体。函之局部,通用之外,可有 i64、i32、f64 之局部,以存未装之整、爻、小;至元组、闭包、全局诸通用之处乃装。
函数索引依闭包树组之序,全局键 路径#定义名,不含定义序号;常模之顶层为不变之全局,初值为常令(struct.new、array.new_fixed、ref.i31 等,数处所共之物别设不变之全局 $常号),试、脚本之程序之体所书之全局可变、初为空引;输出合并一模块,非可任意拼接之约。替单函数须保表号、类型、全局,或桥接。
导出 _start,于承 $error 之 try_table 中先自 data 拷逾一万字节之串常,次依序调试、脚本、金样之程序之体并弃果,终呼入口之函。顶层数据所用之字面书为常全局,函中所用者初行时自 data 造之。漏网之 $error 至 _start,以其串调 $exception 全局所存之顶层未承之术(闭包);术返则 unreachable,术空则转型败而陷。字面按 \hh,不假有效文本而改字节。
串异用 $error 标签,载其串一 eqref。抛即 throw $error,模式缺支亦然。尝试调模块内之 $try(操作, 处理):于 (try_table (catch $error …)) 中以元调操作之闭包,常终径返其果;承之则出 try_table,以异串尾调处理之闭包。二闭包皆依公约间调(型 $t2,首参为闭包自身)。$exception 可变全局唯存顶层未承之术,标准库以 豫言_设置当前异常处理器 登之。
提前返用 $escape 标签,载标识与值两个 eqref。每入动态之域新造空 $tuple 为标识,以 ref.eq 较之,无次数之限;捕获比标,不同重抛,越动态范围不支持。二标皆模块自定;$error 以 yy_错误 之名出,宿主之导入术可以之抛尝试所能承之异,载本模之 $bytes 为辞(JS 宿主书 new WebAssembly.Exception(exports.yy_错误, [辞之字节]));$escape 唯用于模内。算术、索引、cast trap 非自动可捕字符串异常。
网五:宿主之界
客经带型之导入调宿主,宿主经导出调客。
带型之导入
。接口。豫 之无体之声(构建时未为适配所代者)编为带型之 Wasm 函数导入。模块名为所在包之短名,字段名为声名,皆不带版本;(模块,字段)一模唯一,同导再见,签名须同。导入于函数编号先于自定之函,其序编译器定之、每次同,宿主依(模块,字段)绑之。接口之模既链入,其所声诸函皆成导入;宿主所未实者,给桩,调之乃报“接口函数未绑定:模块.字段”。
标准库之宿主之务,声于 库/豫章/东道。接口。豫 与 宿主带列。接口。豫(用列之八函别为一文,免模成环),导入模块皆曰“标准库”,凡六十八函;构建基础之工之务,声于 库/营造/营东道。接口。豫,导入模块曰“构建基础”,六函(存包上下文、问面板可用、绘面板、今程序与指定文 SHA-256、字节串之页散列)。标准库之公函改调于此,公名与参次不易。故编译器与豫构惟导此二模,不复导 call,凡行编译器之宿主皆当供之;Node 工具之宿主尽供之,惟读取终端按键、出入终端原始输入之式、二拼音之转与绘监视面板为桩。
类型检查依参果之类算边界签名,书作“参形,参形→果形”。参之元不书,故签名之参与 Wasm 之参一一相当。形之文法见汉语稿。
| 豫言之类 | 形 | 顶层参果之 Wasm 类 | 嵌于元组之表 |
|---|---|---|---|
| 整数 | 整 | i64 | 规整之 i31 或 $big |
| 小数 | 小 | f64 | $float |
| 爻 | 爻 | i32,惟零一 | i31 零一 |
| 字符串、字节串、字节缓冲 | 串 | (ref $bytes) |
$bytes |
| 有 | 元 | 参省,果无 | 空引 |
| 接口之文无构造器之类(资源) | 资 | (ref extern) |
$外 |
| 元组、命名元组(依字段之序) | 组〔…〕 | (ref $tuple) |
$tuple |
| 列于甲 | 列〔甲〕 | (ref $tuple),诸元依甲之嵌表 |
$tuple |
| 有构造器之类 | 变〔支|…〕 | (ref $tuple):首为支序(构造器于类声之次,自零始)之 i31,次为载荷诸项 |
$tuple |
异步返回 于 甲(惟为果之最外) |
异〔甲之形〕 | 同甲 | — |
顶层之引皆非空,惟元组之元可空。果类为 异步返回 于 甲 之导入(诺 声于标准库 语言核心/异步原语。豫),签名之果记为“异〔甲之形〕”,其 Wasm 类与转换同甲;“异”惟为果之最外,见于参或果之里者类型检查报误。宿主可于此类导入挂起:JS 胶水惟于签名带“异”而实标“异步”者套 JSPI 之 WebAssembly.Suspending,签名带“异”而实同步者照常同步调之,签名无“异”之导入还 Promise 则报误;原生执行器与 Node 工具宿主照常阻塞而成。客以「坐待」取值,「即得」「既而」于客内相合;三者于运行时皆去之(「即得」「坐待」为转类,「既而」为一调)。应用接口暂不受异步返回。诸转换皆在客内:整拆装,小取装,爻转 i31,资拆装 $外(参拆后先断其非空)。列、变及含列变之组,以编译器依形去重所生之转换函处之;惟含整、小、爻、串、元、资之组径传,宿主惟读之,不改客所授之元组,惟写引于己所新造者。变体诸支于客中之专用结构之形,类型检查算之,惟书于内导入名(签名之变〔…〕后接 客〔形|形…〕,皆“任”则省之),转换之函据之装整、小之字段为界上之整、小,归则解之;自定之段「豫言边界」之签名不带之。不可过界之类,类型检查时报误:函数(回调宜用应用接口)、泛型之函与类变量、列外之递归类、引用与数组引用等非接口之文无构造器之类、动态分类值。
自定之段「豫言边界」
提案 00002 第四步开发稿验列之身份:内建列之施依物类得列界形;旧多态列核主“豫言”、包名“标准库”及包内 数据结构/多态列。豫 之列声明。包目虽徙,身份存。此稿方验,标准库别名之迁与内建列运行时转换犹未毕。
凡 WasmGC 之模皆带名 豫言边界 之自定之段,内为 UTF-8 文,一行一项,行尾换行,字段以制表符隔之:导入⇥模块⇥字段⇥签名,每带型导入恰一行,序同导入段;导出⇥导出名⇥签名,每应用接口之出恰一行,签名已去类为“有”之参。无带型之导入与导出则其内为空。读者遇不识之首字段,略其行。JS 宿主据此识豫言之程,依签名转值;原生执行器可不读之,依 Wasm 类校之。
应用接口之出
入口之模(编译之序之末)或链入程序之任一常模定义某 。应用接口。豫 模所声之同名顶层之函(先察入口,乃自后而前察余模),编译器编为导出;故库亦得供应用接口之函(如云工东道库之回调入口「行云工回音」)。出名为 包名/函数名:源中定「理来书」,出名为 豫寓坐堂/理来书。导出之函,参为诸非“有”之参之顶层 Wasm 类,果为果形之顶层类(“有”则无果)。包之函转参为客值(“有”参补空引用),有顶层直调之工函则径调之,否则自全局槽取闭包逐参调之,乃转果为边界之表;未承之 $error 交与 _start 同之顶层处理(书“未捕捉的豫言异常”而以一退)。无模实之而程序调之之应用接口(豫言径调应用接口之声亦然),运行时抛可承之豫言之异“应用接口函数没有由应用实现:包名/函数名”。
宿主先调 _start,须则乃调应用接口之出。_start 既行程序之体,即召入口之函,宿主不另召之。
入口之函(提案 00006):入口之文非 。测试。豫、。脚本。豫 与金样 名其编号。豫 者,须于本文定义入口之函(默名「入口」,类 化「有」而「有」;包描述「类型」之「入口函数」或编译器之项 --入口函数 名 可另指其名)。_start 先依所依之序行诸模之静态初置,书标准库「常处祸」之全局槽于 $exception,乃呼入口之函。其包 $入口调用 同应用接口导出之包,不导出。无入口之函或其元数非一,则编译报错。试、脚本与金样之顶层即程序之体,_start 依次行之,不呼入口之函。JS 宿主经胶水之 读边界导出、造边界导出(JS 值依形转为 Wasm 值,果转回 JS 值;异步者经 WebAssembly.promising)调应用接口之出。
原型全局与值桥
模示宿主以不可变之类原型全局 yy_bytes、yy_tuple、yy_big、yy_float、yy_extern,另出异常之标 yy_错误(见网四)。宿主取实际引擎类型造返回值,不能另造同形而不兼容之型。原型与宿主所用之引擎同配置,跨版本另验。
JS 宿主经值桥之模(与编译器同代所生,类型定义与客运行时全同)读写嵌于元组之值:kind 辨其类(空〇、小整一、字节二、元组三、大整四、小数五、资源六),int/new_int、float/new_float、ext_get/new_ext、tuple_len/tuple_get/tuple_set/new_tuple、bytes_len/bytes_out/bytes_in 读写诸值,字节经值桥之线性内存相换。三家 JS 宿主共用胶水 豫言操作系统/宿主/网页汇编/边界.mjs:读「豫言边界」之段,依签名互转 Wasm 值与 JS 值,无实者给桩;惟标“异步”之实乃套 JSPI。诸 JS 宿主各供标准库、构建基础之何函,及退出、误流、小数之文等同一之义,见仓中 豫言操作系统/宿主/标准库宿主.文言.md。
编译器就地所生之原语
外部调用唯无体之声合之:宿主之务皆编为带型之导入(见上),原语则编译器就地生令,或调客内运行时之术;生码遇未登或无生码之则之内建原语则报“未实现的内建原语”。
guest 已含引用及数组、抛异与尝试、登顶层未承之术、不安全恒等、整数加减乘除及相等、串字节拼接与比较、长度、取字节、截字节串,字节缓冲之造、一字与小端四字之读写、填、抄、转字节串,及若干 UTF-8/JSON 操作,并字节转字符串(惟受一至二百五十五)、字节串单字节(受零至二百五十五;逾则皆陷)、字节串空与字符串转整数(其义见执行与编译之编四)。形参次序仍须守。诸名亦为「。内建。豫」内建之声所可用之原语(见类型与模块类六)。
小数之加减乘除与整转小、小转整亦成于 guest:编译器按名就地生 f64.add、f64.sub、f64.mul、f64.div、f64.convert_i64_s、i64.trunc_f64_s,参自 $float 或整数去其装,果复装之,其义见执行与编译之编四。宿主犹存此六名之实,以待旧编译器所出之产物。逾 i31 之整数字面与小数字面,各登为一可变 eq 引用之全局 $n号,_start 于字符串全局既立之后各装之一次而存焉,用者取全局;字面径为上述运算或整数运算之参者,书为 i64.const、f64.const,不装。
数值原语之第二批,编译器依生码之原语登记表就地生之,其声名与粗形之签列于原语之表:整数取余(i64.rem_s);整数位与、位或、位异或(i64.and/or/xor)与位非(与 −1 异或);整数左移、右移、无符号右移、循环左移、循环右移(i64.shl/shr_s/shr_u/rotl/rotr);整数前导零数、末尾零数、置位数(i64.clz/ctz/popcnt);整数小等、大等、无符号小于、无符号大于(i64.le_s/ge_s/lt_u/gt_u);整数无符号除与无符号余(i64.div_u/rem_u);小数等、不等、小于、大于、小等、大等(f64.eq/ne/lt/gt/le/ge);小数最小、最大、复号(f64.min/max/copysign);小数绝对值、取负、向上取整、向下取整、截断、就近取整、开方(f64.abs/neg/ceil/floor/trunc/nearest/sqrt);小数饱和转整数(i64.trunc_sat_f64_s)、无符号整数转小数(f64.convert_i64_u)、小数位与位转小数(i64.reinterpret_f64、f64.reinterpret_i64)。参依其类自整数或 $float 去装,字面径书其常;果依其类复装(整数调 $box,小数 struct.new $float,爻 ref.i31);较之果居 i32 之局,为条件则不装。其义见执行与编译之编四。此批惟经「。内建。豫」之声而用,宿主无其实。
网六:所验之界
本篇依网页后端源码述其约。全实现尚须数界、尾递归、异常范围、嵌零、宿主失败及 GC 压力之验。