Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 19 additions & 48 deletions src/wasm2js.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,10 @@ class Wasm2JSBuilder {

// The second pass on an expression: process it fully, generating
// JS
Ref processFunctionBody(Module* m, Function* func, bool standalone);
Ref processExpression(Expression* curr,
Module* m,
Function* func = nullptr,
bool standalone = false);

Index getDataIndex(Name segment) {
auto it = dataIndices.find(segment);
Expand Down Expand Up @@ -323,7 +326,7 @@ class Wasm2JSBuilder {
void addTable(Ref ast, Module* wasm);
void addStart(Ref ast, Module* wasm);
void addExports(Ref ast, Module* wasm);
void addGlobal(Ref ast, Global* global);
void addGlobal(Ref ast, Global* global, Module* module);
void addMemoryFuncs(Ref ast, Module* wasm);
void addMemoryGrowFunc(Ref ast, Module* wasm);

Expand Down Expand Up @@ -503,7 +506,7 @@ Ref Wasm2JSBuilder::processWasm(Module* wasm, Name funcName) {
// globals
bool generateFetchHighBits = false;
ModuleUtils::iterDefinedGlobals(*wasm, [&](Global* global) {
addGlobal(asmFunc[3], global);
addGlobal(asmFunc[3], global, wasm);
if (flags.allowAsserts && global->name == INT64_TO_32_HIGH_BITS) {
generateFetchHighBits = true;
}
Expand Down Expand Up @@ -845,46 +848,12 @@ void Wasm2JSBuilder::addExports(Ref ast, Module* wasm) {
ValueBuilder::makeStatement(ValueBuilder::makeReturn(exports)));
}

void Wasm2JSBuilder::addGlobal(Ref ast, Global* global) {
void Wasm2JSBuilder::addGlobal(Ref ast, Global* global, Module* module) {
Ref theVar = ValueBuilder::makeVar();
ast->push_back(theVar);

auto* init = global->init;
Ref value;

if (auto* const_ = init->dynCast<Const>()) {
TODO_SINGLE_COMPOUND(const_->type);
switch (const_->type.getBasic()) {
case Type::i32: {
value = ValueBuilder::makeInt(const_->value.geti32());
break;
}
case Type::f32: {
value = ValueBuilder::makeCall(
MATH_FROUND,
makeJsCoercion(ValueBuilder::makeDouble(const_->value.getf32()),
JS_DOUBLE));
break;
}
case Type::f64: {
value = makeJsCoercion(ValueBuilder::makeDouble(const_->value.getf64()),
JS_DOUBLE);
break;
}
default: {
assert(false && "Top const type not supported");
}
}
} else if (auto* get = init->dynCast<GlobalGet>()) {
value = ValueBuilder::makeName(fromName(get->name, NameScope::Top));
} else if (init->is<RefNull>()) {
value = ValueBuilder::makeName(NULL_);
} else {
assert(false && "Top init type not supported");
}

Ref init = processExpression(global->init, module);
ValueBuilder::appendToVar(
theVar, fromName(global->name, NameScope::Top), value);
theVar, fromName(global->name, NameScope::Top), init);
}

Ref Wasm2JSBuilder::processFunction(Module* m,
Expand Down Expand Up @@ -934,7 +903,8 @@ Ref Wasm2JSBuilder::processFunction(Module* m,
size_t theVarIndex = ret[3]->size();
ret[3]->push_back(theVar);
// body
flattenAppend(ret, processFunctionBody(m, func, standaloneFunction));
flattenAppend(ret,
processExpression(func->body, m, func, standaloneFunction));
// vars, including new temp vars
for (Index i = func->getVarIndexBase(); i < func->getNumLocals(); i++) {
ValueBuilder::appendToVar(
Expand All @@ -952,9 +922,10 @@ Ref Wasm2JSBuilder::processFunction(Module* m,
return ret;
}

Ref Wasm2JSBuilder::processFunctionBody(Module* m,
Function* func,
bool standaloneFunction) {
Ref Wasm2JSBuilder::processExpression(Expression* curr,
Module* m,
Function* func,
bool standaloneFunction) {
// Switches are tricky to handle - in wasm they often come with
// massively-nested "towers" of blocks, which if naively translated
// to JS may exceed parse recursion limits of VMs. Therefore even when
Expand Down Expand Up @@ -1092,9 +1063,9 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m,
: parent(parent), func(func), module(m),
standaloneFunction(standaloneFunction) {}

Ref process() {
switchProcessor.walk(func->body);
return visit(func->body, NO_RESULT);
Ref process(Expression* curr) {
switchProcessor.walk(curr);
return visit(curr, NO_RESULT);
}

// A scoped temporary variable.
Expand Down Expand Up @@ -2460,7 +2431,7 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m,
}
};

return ExpressionProcessor(this, m, func, standaloneFunction).process();
return ExpressionProcessor(this, m, func, standaloneFunction).process(curr);
}

void Wasm2JSBuilder::addMemoryFuncs(Ref ast, Module* wasm) {
Expand Down
12 changes: 11 additions & 1 deletion test/wasm2js/refs.2asm.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ function asmFunc(imports) {
var Math_trunc = Math.trunc;
var Math_sqrt = Math.sqrt;
var global = null;
var global_ref = use_global_ref;
function null_() {
return null;
}
Expand Down Expand Up @@ -42,13 +43,21 @@ function asmFunc(imports) {
return temp;
}

function use_global_ref(x) {
var temp = null;
temp = global_ref;
global_ref = x;
return temp;
}

return {
"null_": null_,
"is_null": is_null,
"ref_func": ref_func,
"ref_eq": ref_eq,
"ref_as": ref_as,
"use_global": use_global
"use_global": use_global,
"use_global_ref": use_global_ref
};
}

Expand All @@ -60,3 +69,4 @@ export var ref_func = retasmFunc.ref_func;
export var ref_eq = retasmFunc.ref_eq;
export var ref_as = retasmFunc.ref_as;
export var use_global = retasmFunc.use_global;
export var use_global_ref = retasmFunc.use_global_ref;
12 changes: 11 additions & 1 deletion test/wasm2js/refs.2asm.js.opt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ function asmFunc(imports) {
var Math_trunc = Math.trunc;
var Math_sqrt = Math.sqrt;
var global = null;
var global_ref = use_global_ref;
function null_() {
return null;
}
Expand Down Expand Up @@ -40,13 +41,21 @@ function asmFunc(imports) {
return $1;
}

function use_global_ref($0) {
var $1 = null;
$1 = global_ref;
global_ref = $0;
return $1;
}

return {
"null_": null_,
"is_null": is_null,
"ref_func": ref_func,
"ref_eq": ref_eq,
"ref_as": ref_as,
"use_global": use_global
"use_global": use_global,
"use_global_ref": use_global_ref
};
}

Expand All @@ -58,3 +67,4 @@ export var ref_func = retasmFunc.ref_func;
export var ref_eq = retasmFunc.ref_eq;
export var ref_as = retasmFunc.ref_as;
export var use_global = retasmFunc.use_global;
export var use_global_ref = retasmFunc.use_global_ref;
13 changes: 13 additions & 0 deletions test/wasm2js/refs.wast
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
(module
(global $global (mut anyref) (ref.null any))

(global $global-ref (mut funcref) (ref.func $use-global-ref))

(func $null (export "null") (result anyref)
(ref.null any)
)
Expand Down Expand Up @@ -49,4 +51,15 @@
)
(local.get $temp)
)

(func $use-global-ref (export "use-global-ref") (param $x funcref) (result funcref)
(local $temp funcref)
(local.set $temp
(global.get $global-ref)
)
(global.set $global-ref
(local.get $x)
)
(local.get $temp)
)
)