Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
迂街过巷
minigame-unity-webgl-transform
提交
5ed7b96b
M
minigame-unity-webgl-transform
项目概览
迂街过巷
/
minigame-unity-webgl-transform
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
minigame-unity-webgl-transform
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
5ed7b96b
编写于
12月 16, 2021
作者:
S
skyler
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
update wasm split: add incremental build
上级
ce514810
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
302 addition
and
0 deletion
+302
-0
Design/WasmSplit.md
Design/WasmSplit.md
+27
-0
image/wasmsplit/incremental-split.png
image/wasmsplit/incremental-split.png
+0
-0
tools/rewrite_exception_symbol.js
tools/rewrite_exception_symbol.js
+275
-0
未找到文件。
Design/WasmSplit.md
浏览文件 @
5ed7b96b
...
...
@@ -85,3 +85,30 @@ unity导出小游戏项目后,代码是在一个wasm文件里,经过brotli
### 关闭分包
如果想回退到未分包的版本,点击插件页的关闭代码分包按钮即可
### 增量分包
从unity每一次导出后的小游戏,都需要重新分包,对于小版本改动会产生比较烦人的工作量
因此我们支持了增量分包,可以在二次导出时,通过选择之前已经进行过分包的版本,在之前分包的基础上进行增量分包
<image
src=
"../image/wasmsplit/incremental-split.png"
>
这里主要是通过symbol文件,按函数签名识别相同函数来实现的,因此需要导出时有symbol文件
**注意**
由于unity 2021目前导出symbol的流程有问题,在unity修复之前,需要先手动执行下工具来导出symbol,具体见导出后的unity console信息。
### FAQ
*
iOS上进不去游戏
iOS由于加载子包的实现不同,所以最开始的收集会比较卡,这个时候可以观察分包插件面板,如果能看到有新增函数个数的变化,一般就是没问题的。如果新增函数较多(超过1000),可以先继续往下生成分包,再进行收集,这样可以加速已收集部分的运行。
*
没有看到增量分包的界面
由于增量分包是新增的功能,因此之前的项目不能被用来增量更新。更新分包插件后,第二次导出的版本开始才可以使用
另外对于unity 2021的版本,注意检查下minigame目录下有没有webgl.wasm.symbols.unityweb这个文件,没有的话注意按照导出时unity console的指引执行工具生成这个文件。
\ No newline at end of file
image/wasmsplit/incremental-split.png
0 → 100755
浏览文件 @
5ed7b96b
64.1 KB
tools/rewrite_exception_symbol.js
0 → 100644
浏览文件 @
5ed7b96b
var
fs
=
require
(
"
fs
"
);
var
process
=
require
(
"
process
"
);
function
demangle
(
func
)
{
// var hasLibcxxabi = !!Module["___cxa_demangle"];
var
hasLibcxxabi
=
false
;
// if (hasLibcxxabi) {
// try {
// var buf = _malloc(func.length);
// writeStringToMemory(func.substr(1), buf);
// var status = _malloc(4);
// var ret = Module["___cxa_demangle"](buf, 0, 0, status);
// if (getValue(status, "i32") === 0 && ret) {
// return Pointer_stringify(ret);
// }
// } catch (e) {
// } finally {
// if (buf) _free(buf);
// if (status) _free(status);
// if (ret) _free(ret);
// }
// }
var
i
=
3
;
var
basicTypes
=
{
v
:
"
void
"
,
b
:
"
bool
"
,
c
:
"
char
"
,
s
:
"
short
"
,
i
:
"
int
"
,
l
:
"
long
"
,
f
:
"
float
"
,
d
:
"
double
"
,
w
:
"
wchar_t
"
,
a
:
"
signed char
"
,
h
:
"
unsigned char
"
,
t
:
"
unsigned short
"
,
j
:
"
unsigned int
"
,
m
:
"
unsigned long
"
,
x
:
"
long long
"
,
y
:
"
unsigned long long
"
,
z
:
"
...
"
,
};
var
subs
=
[];
var
first
=
true
;
function
dump
(
x
)
{
if
(
x
)
Module
.
print
(
x
);
Module
.
print
(
func
);
var
pre
=
""
;
for
(
var
a
=
0
;
a
<
i
;
a
++
)
pre
+=
"
"
;
Module
.
print
(
pre
+
"
^
"
);
}
function
parseNested
()
{
i
++
;
if
(
func
[
i
]
===
"
K
"
)
i
++
;
var
parts
=
[];
while
(
func
[
i
]
!==
"
E
"
)
{
if
(
func
[
i
]
===
"
S
"
)
{
i
++
;
var
next
=
func
.
indexOf
(
"
_
"
,
i
);
var
num
=
func
.
substring
(
i
,
next
)
||
0
;
parts
.
push
(
subs
[
num
]
||
"
?
"
);
i
=
next
+
1
;
continue
;
}
if
(
func
[
i
]
===
"
C
"
)
{
parts
.
push
(
parts
[
parts
.
length
-
1
]);
i
+=
2
;
continue
;
}
var
size
=
parseInt
(
func
.
substr
(
i
));
var
pre
=
size
.
toString
().
length
;
if
(
!
size
||
!
pre
)
{
i
--
;
break
;
}
var
curr
=
func
.
substr
(
i
+
pre
,
size
);
parts
.
push
(
curr
);
subs
.
push
(
curr
);
i
+=
pre
+
size
;
}
i
++
;
return
parts
;
}
function
parse
(
rawList
,
limit
,
allowVoid
)
{
limit
=
limit
||
Infinity
;
var
ret
=
""
,
list
=
[];
function
flushList
()
{
return
"
(
"
+
list
.
join
(
"
,
"
)
+
"
)
"
;
}
var
name
;
if
(
func
[
i
]
===
"
N
"
)
{
name
=
parseNested
().
join
(
"
::
"
);
limit
--
;
if
(
limit
===
0
)
return
rawList
?
[
name
]
:
name
;
}
else
{
if
(
func
[
i
]
===
"
K
"
||
(
first
&&
func
[
i
]
===
"
L
"
))
i
++
;
var
size
=
parseInt
(
func
.
substr
(
i
));
if
(
size
)
{
var
pre
=
size
.
toString
().
length
;
name
=
func
.
substr
(
i
+
pre
,
size
);
i
+=
pre
+
size
;
}
}
first
=
false
;
if
(
func
[
i
]
===
"
I
"
)
{
i
++
;
var
iList
=
parse
(
true
);
var
iRet
=
parse
(
true
,
1
,
true
);
ret
+=
iRet
[
0
]
+
"
"
+
name
+
"
<
"
+
iList
.
join
(
"
,
"
)
+
"
>
"
;
}
else
{
ret
=
name
;
}
paramLoop
:
while
(
i
<
func
.
length
&&
limit
--
>
0
)
{
var
c
=
func
[
i
++
];
if
(
c
in
basicTypes
)
{
list
.
push
(
basicTypes
[
c
]);
}
else
{
switch
(
c
)
{
case
"
P
"
:
list
.
push
(
parse
(
true
,
1
,
true
)[
0
]
+
"
*
"
);
break
;
case
"
R
"
:
list
.
push
(
parse
(
true
,
1
,
true
)[
0
]
+
"
&
"
);
break
;
case
"
L
"
:
{
i
++
;
var
end
=
func
.
indexOf
(
"
E
"
,
i
);
var
size
=
end
-
i
;
list
.
push
(
func
.
substr
(
i
,
size
));
i
+=
size
+
2
;
break
;
}
case
"
A
"
:
{
var
size
=
parseInt
(
func
.
substr
(
i
));
i
+=
size
.
toString
().
length
;
if
(
func
[
i
]
!==
"
_
"
)
throw
"
?
"
;
i
++
;
list
.
push
(
parse
(
true
,
1
,
true
)[
0
]
+
"
[
"
+
size
+
"
]
"
);
break
;
}
case
"
E
"
:
break
paramLoop
;
default
:
ret
+=
"
?
"
+
c
;
break
paramLoop
;
}
}
}
if
(
!
allowVoid
&&
list
.
length
===
1
&&
list
[
0
]
===
"
void
"
)
list
=
[];
if
(
rawList
)
{
if
(
ret
)
{
list
.
push
(
ret
+
"
?
"
);
}
return
list
;
}
else
{
return
ret
+
flushList
();
}
}
var
parsed
=
func
;
try
{
if
(
func
==
"
Object._main
"
||
func
==
"
_main
"
)
{
return
"
main()
"
;
}
// if (typeof func === "number") func = Pointer_stringify(func);
if
(
func
[
0
]
!==
"
_
"
)
return
func
;
if
(
func
[
1
]
!==
"
_
"
)
return
func
;
if
(
func
[
2
]
!==
"
Z
"
)
return
func
;
switch
(
func
[
3
])
{
case
"
n
"
:
return
"
operator new()
"
;
case
"
d
"
:
return
"
operator delete()
"
;
}
parsed
=
parse
();
}
catch
(
e
)
{
parsed
+=
"
?
"
;
}
if
(
parsed
.
indexOf
(
"
?
"
)
>=
0
&&
!
hasLibcxxabi
)
{
// Runtime.warnOnce(
// "warning: a problem occurred in builtin C++ name demangling; build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling"
// );
return
func
;
}
return
parsed
;
}
function
printHelp
()
{
console
.
log
(
"
Usage: node rewrite_exception_symbol.js <exception_file> <symbol_file>
\n
"
);
}
if
(
process
.
argv
.
length
<
4
)
{
printHelp
();
process
.
exit
(
0
);
}
var
exceptionText
=
fs
.
readFileSync
(
process
.
argv
[
2
],
{
encoding
:
"
utf8
"
});
var
symbolText
=
fs
.
readFileSync
(
process
.
argv
[
3
],
{
encoding
:
"
utf8
"
});
function
parseSymbol
(
symbolText
)
{
var
symbolMap
=
new
Map
();
var
startLine
=
"
var debugSymbols = {
"
;
var
start
=
symbolText
.
indexOf
(
startLine
);
start
+=
startLine
.
length
;
for
(;;)
{
var
next
=
symbolText
.
indexOf
(
"
,
"
,
start
);
var
s
=
symbolText
.
substr
(
start
,
next
-
start
).
trim
();
// console.log("symbol line:", s);
var
b
=
s
.
length
>
0
?
s
.
charCodeAt
(
0
)
:
0
;
if
(
b
<
48
||
b
>
57
)
{
// not in [0-9]
break
;
}
var
mid
=
s
.
indexOf
(
"
:
"
);
if
(
mid
<
0
)
{
break
;
}
var
left
=
s
.
substr
(
0
,
mid
);
var
right
=
s
.
substr
(
mid
+
1
,
s
.
length
-
mid
-
1
);
if
(
right
[
0
]
===
"
'
"
&&
right
[
right
.
length
-
1
]
===
"
'
"
)
{
right
=
right
.
substr
(
1
,
right
.
length
-
2
);
}
// console.log("symbol:", left, right);
right
=
demangle
(
right
);
// console.log("after demangle:", right);
// console.log("symbol:", start, mid, left, right);
symbolMap
.
set
(
left
,
right
);
start
=
next
+
1
;
}
return
symbolMap
;
}
var
symbolMap
=
parseSymbol
(
symbolText
);
function
replaceWithSymbol
(
src
,
symbolMap
,
regex
)
{
var
res
=
src
.
matchAll
(
regex
);
// console.log("to replace symbol:", src, regex);
var
output
=
""
;
var
start
=
0
;
for
(;;)
{
var
d
=
res
.
next
();
if
(
d
.
value
)
{
var
s
=
symbolMap
.
get
(
d
.
value
[
1
]);
// console.log("to replace:", d.value, s, start);
if
(
s
)
{
output
+=
src
.
substr
(
start
,
d
.
value
.
index
-
start
);
output
+=
s
+
"
:wasm-function[
"
+
d
.
value
[
1
]
+
"
]
"
;
}
else
{
output
+=
src
.
substr
(
start
,
d
.
value
.
index
-
start
);
output
+=
d
.
value
[
0
];
}
start
=
d
.
value
.
index
+
d
.
value
[
0
].
length
;
}
if
(
d
.
done
)
{
output
+=
src
.
substr
(
start
);
break
;
}
}
return
output
;
}
var
output
=
replaceWithSymbol
(
exceptionText
,
symbolMap
,
/j
(\d
+
)
:wasm-function
\[\d
+]/g
);
output
=
replaceWithSymbol
(
output
,
symbolMap
,
/<anonymous>:wasm-function
\[(\d
+
)\]
/g
);
console
.
log
(
output
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录