Skip to content

Commit 3468619

Browse files
authored
wasm2js: Fix null handling and RefAsNonNull (#6656)
1 parent 0e11876 commit 3468619

File tree

5 files changed

+88
-29
lines changed

5 files changed

+88
-29
lines changed

src/emscripten-optimizer/optimizer-shared.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <limits>
1818

1919
#include "optimizer.h"
20+
#include "shared-constants.h"
2021
#include "support/safe_integer.h"
2122

2223
using namespace cashew;
@@ -33,30 +34,25 @@ Ref makeJsCoercedZero(JsType type) {
3334
switch (type) {
3435
case JS_INT:
3536
return ValueBuilder::makeNum(0);
36-
break;
3737
case JS_DOUBLE:
3838
return ValueBuilder::makeUnary(PLUS, ValueBuilder::makeNum(0));
39-
break;
4039
case JS_FLOAT: {
4140
if (!JS_FLOAT_ZERO.isNull()) {
4241
return ValueBuilder::makeName(JS_FLOAT_ZERO);
4342
} else {
4443
return ValueBuilder::makeCall(MATH_FROUND, ValueBuilder::makeNum(0));
4544
}
46-
break;
4745
}
4846
case JS_FLOAT32X4: {
4947
return ValueBuilder::makeCall(SIMD_FLOAT32X4,
5048
ValueBuilder::makeNum(0),
5149
ValueBuilder::makeNum(0),
5250
ValueBuilder::makeNum(0),
5351
ValueBuilder::makeNum(0));
54-
break;
5552
}
5653
case JS_FLOAT64X2: {
5754
return ValueBuilder::makeCall(
5855
SIMD_FLOAT64X2, ValueBuilder::makeNum(0), ValueBuilder::makeNum(0));
59-
break;
6056
}
6157
case JS_INT8X16: {
6258
return ValueBuilder::makeCall(SIMD_INT8X16,
@@ -76,7 +72,6 @@ Ref makeJsCoercedZero(JsType type) {
7672
ValueBuilder::makeNum(0),
7773
ValueBuilder::makeNum(0),
7874
ValueBuilder::makeNum(0));
79-
break;
8075
}
8176
case JS_INT16X8: {
8277
return ValueBuilder::makeCall(SIMD_INT16X8,
@@ -88,15 +83,16 @@ Ref makeJsCoercedZero(JsType type) {
8883
ValueBuilder::makeNum(0),
8984
ValueBuilder::makeNum(0),
9085
ValueBuilder::makeNum(0));
91-
break;
9286
}
9387
case JS_INT32X4: {
9488
return ValueBuilder::makeCall(SIMD_INT32X4,
9589
ValueBuilder::makeNum(0),
9690
ValueBuilder::makeNum(0),
9791
ValueBuilder::makeNum(0),
9892
ValueBuilder::makeNum(0));
99-
break;
93+
}
94+
case JS_REF: {
95+
return ValueBuilder::makeName(wasm::NULL_);
10096
}
10197
default:
10298
assert(0);

src/wasm2js.h

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -846,44 +846,45 @@ void Wasm2JSBuilder::addExports(Ref ast, Module* wasm) {
846846
}
847847

848848
void Wasm2JSBuilder::addGlobal(Ref ast, Global* global) {
849-
if (auto* const_ = global->init->dynCast<Const>()) {
850-
Ref theValue;
849+
Ref theVar = ValueBuilder::makeVar();
850+
ast->push_back(theVar);
851+
852+
auto* init = global->init;
853+
Ref value;
854+
855+
if (auto* const_ = init->dynCast<Const>()) {
851856
TODO_SINGLE_COMPOUND(const_->type);
852857
switch (const_->type.getBasic()) {
853858
case Type::i32: {
854-
theValue = ValueBuilder::makeInt(const_->value.geti32());
859+
value = ValueBuilder::makeInt(const_->value.geti32());
855860
break;
856861
}
857862
case Type::f32: {
858-
theValue = ValueBuilder::makeCall(
863+
value = ValueBuilder::makeCall(
859864
MATH_FROUND,
860865
makeJsCoercion(ValueBuilder::makeDouble(const_->value.getf32()),
861866
JS_DOUBLE));
862867
break;
863868
}
864869
case Type::f64: {
865-
theValue = makeJsCoercion(
866-
ValueBuilder::makeDouble(const_->value.getf64()), JS_DOUBLE);
870+
value = makeJsCoercion(ValueBuilder::makeDouble(const_->value.getf64()),
871+
JS_DOUBLE);
867872
break;
868873
}
869874
default: {
870875
assert(false && "Top const type not supported");
871876
}
872877
}
873-
Ref theVar = ValueBuilder::makeVar();
874-
ast->push_back(theVar);
875-
ValueBuilder::appendToVar(
876-
theVar, fromName(global->name, NameScope::Top), theValue);
877-
} else if (auto* get = global->init->dynCast<GlobalGet>()) {
878-
Ref theVar = ValueBuilder::makeVar();
879-
ast->push_back(theVar);
880-
ValueBuilder::appendToVar(
881-
theVar,
882-
fromName(global->name, NameScope::Top),
883-
ValueBuilder::makeName(fromName(get->name, NameScope::Top)));
878+
} else if (auto* get = init->dynCast<GlobalGet>()) {
879+
value = ValueBuilder::makeName(fromName(get->name, NameScope::Top));
880+
} else if (init->is<RefNull>()) {
881+
value = ValueBuilder::makeName(NULL_);
884882
} else {
885883
assert(false && "Top init type not supported");
886884
}
885+
886+
ValueBuilder::appendToVar(
887+
theVar, fromName(global->name, NameScope::Top), value);
887888
}
888889

889890
Ref Wasm2JSBuilder::processFunction(Module* m,
@@ -2415,8 +2416,15 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m,
24152416
WASM_UNREACHABLE("unimp");
24162417
}
24172418
Ref visitRefAs(RefAs* curr) {
2418-
unimplemented(curr);
2419-
WASM_UNREACHABLE("unimp");
2419+
// TODO: support others
2420+
assert(curr->op == RefAsNonNull);
2421+
2422+
// value || trap()
2423+
ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TRAP);
2424+
return ValueBuilder::makeBinary(
2425+
visit(curr->value, EXPRESSION_RESULT),
2426+
IString("||"),
2427+
ValueBuilder::makeCall(ABI::wasm2js::TRAP));
24202428
}
24212429

24222430
Ref visitContBind(ContBind* curr) {

test/wasm2js/refs.2asm.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11

2+
function wasm2js_trap() { throw new Error('abort'); }
3+
24
function asmFunc(imports) {
35
var Math_imul = Math.imul;
46
var Math_fround = Math.fround;
@@ -10,6 +12,7 @@ function asmFunc(imports) {
1012
var Math_ceil = Math.ceil;
1113
var Math_trunc = Math.trunc;
1214
var Math_sqrt = Math.sqrt;
15+
var global = null;
1316
function null_() {
1417
return null;
1518
}
@@ -28,11 +31,24 @@ function asmFunc(imports) {
2831
return x == y | 0;
2932
}
3033

34+
function ref_as(x) {
35+
return x || wasm2js_trap();
36+
}
37+
38+
function use_global(x) {
39+
var temp = null;
40+
temp = global;
41+
global = x;
42+
return temp;
43+
}
44+
3145
return {
3246
"null_": null_,
3347
"is_null": is_null,
3448
"ref_func": ref_func,
35-
"ref_eq": ref_eq
49+
"ref_eq": ref_eq,
50+
"ref_as": ref_as,
51+
"use_global": use_global
3652
};
3753
}
3854

@@ -42,3 +58,5 @@ export var null_ = retasmFunc.null_;
4258
export var is_null = retasmFunc.is_null;
4359
export var ref_func = retasmFunc.ref_func;
4460
export var ref_eq = retasmFunc.ref_eq;
61+
export var ref_as = retasmFunc.ref_as;
62+
export var use_global = retasmFunc.use_global;

test/wasm2js/refs.2asm.js.opt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11

2+
function wasm2js_trap() { throw new Error('abort'); }
3+
24
function asmFunc(imports) {
35
var Math_imul = Math.imul;
46
var Math_fround = Math.fround;
@@ -10,6 +12,7 @@ function asmFunc(imports) {
1012
var Math_ceil = Math.ceil;
1113
var Math_trunc = Math.trunc;
1214
var Math_sqrt = Math.sqrt;
15+
var global = null;
1316
function null_() {
1417
return null;
1518
}
@@ -26,11 +29,24 @@ function asmFunc(imports) {
2629
return $0 == $1 | 0;
2730
}
2831

32+
function ref_as($0) {
33+
return $0 || wasm2js_trap();
34+
}
35+
36+
function use_global($0) {
37+
var $1 = null;
38+
$1 = global;
39+
global = $0;
40+
return $1;
41+
}
42+
2943
return {
3044
"null_": null_,
3145
"is_null": is_null,
3246
"ref_func": ref_func,
33-
"ref_eq": ref_eq
47+
"ref_eq": ref_eq,
48+
"ref_as": ref_as,
49+
"use_global": use_global
3450
};
3551
}
3652

@@ -40,3 +56,5 @@ export var null_ = retasmFunc.null_;
4056
export var is_null = retasmFunc.is_null;
4157
export var ref_func = retasmFunc.ref_func;
4258
export var ref_eq = retasmFunc.ref_eq;
59+
export var ref_as = retasmFunc.ref_as;
60+
export var use_global = retasmFunc.use_global;

test/wasm2js/refs.wast

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
(module
2+
(global $global (mut anyref) (ref.null any))
3+
24
(func $null (export "null") (result anyref)
35
(ref.null any)
46
)
@@ -30,4 +32,21 @@
3032
(local.get $y)
3133
)
3234
)
35+
36+
(func $ref.as (export "ref.as") (param $x anyref) (result anyref)
37+
(ref.as_non_null
38+
(local.get $x)
39+
)
40+
)
41+
42+
(func $use-global (export "use-global") (param $x anyref) (result anyref)
43+
(local $temp anyref)
44+
(local.set $temp
45+
(global.get $global)
46+
)
47+
(global.set $global
48+
(local.get $x)
49+
)
50+
(local.get $temp)
51+
)
3352
)

0 commit comments

Comments
 (0)