mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1243633 - Baldr: add call/call_import (r=bbouvier)
This commit is contained in:
parent
c35dacbaec
commit
6d10e98724
@ -161,6 +161,46 @@ DecodeExprType(JSContext* cx, Decoder& d, ExprType *type)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
DecodeCall(FunctionDecoder& f, ExprType expected)
|
||||
{
|
||||
uint32_t funcIndex;
|
||||
if (!f.d().readU32(&funcIndex))
|
||||
return f.fail("unable to read import index");
|
||||
|
||||
if (funcIndex >= f.mg().numFuncSigs())
|
||||
return f.fail("callee index out of range");
|
||||
|
||||
const DeclaredSig& sig = f.mg().funcSig(funcIndex);
|
||||
|
||||
for (ValType argType : sig.args()) {
|
||||
if (!DecodeExpr(f, ToExprType(argType)))
|
||||
return false;
|
||||
}
|
||||
|
||||
return CheckType(f, sig.ret(), expected);
|
||||
}
|
||||
|
||||
static bool
|
||||
DecodeCallImport(FunctionDecoder& f, ExprType expected)
|
||||
{
|
||||
uint32_t importIndex;
|
||||
if (!f.d().readU32(&importIndex))
|
||||
return f.fail("unable to read import index");
|
||||
|
||||
if (importIndex >= f.mg().numImports())
|
||||
return f.fail("import index out of range");
|
||||
|
||||
const DeclaredSig& sig = *f.mg().import(importIndex).sig;
|
||||
|
||||
for (ValType argType : sig.args()) {
|
||||
if (!DecodeExpr(f, ToExprType(argType)))
|
||||
return false;
|
||||
}
|
||||
|
||||
return CheckType(f, sig.ret(), expected);
|
||||
}
|
||||
|
||||
static bool
|
||||
DecodeConst(FunctionDecoder& f, ExprType expected)
|
||||
{
|
||||
@ -233,6 +273,10 @@ DecodeExpr(FunctionDecoder& f, ExprType expected)
|
||||
switch (expr) {
|
||||
case Expr::Nop:
|
||||
return CheckType(f, ExprType::Void, expected);
|
||||
case Expr::Call:
|
||||
return DecodeCall(f, expected);
|
||||
case Expr::CallImport:
|
||||
return DecodeCallImport(f, expected);
|
||||
case Expr::I32Const:
|
||||
return DecodeConst(f, expected);
|
||||
case Expr::GetLocal:
|
||||
|
@ -91,6 +91,7 @@ class WasmAstSig : public WasmAstBase
|
||||
enum class WasmAstKind
|
||||
{
|
||||
Block,
|
||||
Call,
|
||||
Const,
|
||||
Export,
|
||||
Func,
|
||||
@ -196,6 +197,23 @@ class WasmAstBlock : public WasmAstExpr
|
||||
const WasmAstExprVector& exprs() const { return exprs_; }
|
||||
};
|
||||
|
||||
class WasmAstCall : public WasmAstExpr
|
||||
{
|
||||
Expr expr_;
|
||||
uint32_t index_;
|
||||
WasmAstExprVector args_;
|
||||
|
||||
public:
|
||||
static const WasmAstKind Kind = WasmAstKind::Call;
|
||||
WasmAstCall(Expr expr, uint32_t index, WasmAstExprVector&& args)
|
||||
: WasmAstExpr(Kind), expr_(expr), index_(index), args_(Move(args))
|
||||
{}
|
||||
|
||||
Expr expr() const { return expr_; }
|
||||
uint32_t index() const { return index_; }
|
||||
const WasmAstExprVector& args() const { return args_; }
|
||||
};
|
||||
|
||||
class WasmAstFunc : public WasmAstNode
|
||||
{
|
||||
const uint32_t sigIndex_;
|
||||
@ -312,6 +330,8 @@ class WasmToken
|
||||
enum Kind
|
||||
{
|
||||
Block,
|
||||
Call,
|
||||
CallImport,
|
||||
CloseParen,
|
||||
Const,
|
||||
EndOfFile,
|
||||
@ -511,6 +531,14 @@ class WasmTokenStream
|
||||
return WasmToken(WasmToken::Block, begin, cur_);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
if (consume(end_, MOZ_UTF16("all"))) {
|
||||
if (consume(end_, MOZ_UTF16("_import")))
|
||||
return WasmToken(WasmToken::CallImport, begin, cur_);
|
||||
return WasmToken(WasmToken::Call, begin, cur_);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
if (consume(end_, MOZ_UTF16("xport")))
|
||||
return WasmToken(WasmToken::Export, begin, cur_);
|
||||
@ -699,6 +727,25 @@ ParseBlock(WasmParseContext& c)
|
||||
return new(c.lifo) WasmAstBlock(Move(exprs));
|
||||
}
|
||||
|
||||
static WasmAstCall*
|
||||
ParseCall(WasmParseContext& c, Expr expr)
|
||||
{
|
||||
WasmToken index;
|
||||
if (!c.ts.match(WasmToken::Integer, &index, c.error))
|
||||
return nullptr;
|
||||
|
||||
WasmAstExprVector args(c.lifo);
|
||||
while (c.ts.getIf(WasmToken::OpenParen)) {
|
||||
WasmAstExpr* arg = ParseExprInsideParens(c);
|
||||
if (!arg || !args.append(arg))
|
||||
return nullptr;
|
||||
if (!c.ts.match(WasmToken::CloseParen, c.error))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new(c.lifo) WasmAstCall(expr, index.integer(), Move(args));
|
||||
}
|
||||
|
||||
static WasmAstConst*
|
||||
ParseConst(WasmParseContext& c, WasmToken constToken)
|
||||
{
|
||||
@ -749,6 +796,10 @@ ParseExprInsideParens(WasmParseContext& c)
|
||||
return new(c.lifo) WasmAstNop;
|
||||
case WasmToken::Block:
|
||||
return ParseBlock(c);
|
||||
case WasmToken::Call:
|
||||
return ParseCall(c, Expr::Call);
|
||||
case WasmToken::CallImport:
|
||||
return ParseCall(c, Expr::CallImport);
|
||||
case WasmToken::Const:
|
||||
return ParseConst(c, expr);
|
||||
case WasmToken::GetLocal:
|
||||
@ -957,6 +1008,23 @@ EncodeBlock(Encoder& e, WasmAstBlock& b)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
EncodeCall(Encoder& e, WasmAstCall& c)
|
||||
{
|
||||
if (!e.writeExpr(c.expr()))
|
||||
return false;
|
||||
|
||||
if (!e.writeU32(c.index()))
|
||||
return false;
|
||||
|
||||
for (WasmAstExpr* arg : c.args()) {
|
||||
if (!EncodeExpr(e, *arg))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
EncodeConst(Encoder& e, WasmAstConst& c)
|
||||
{
|
||||
@ -993,6 +1061,8 @@ EncodeExpr(Encoder& e, WasmAstExpr& expr)
|
||||
return e.writeExpr(Expr::Nop);
|
||||
case WasmAstKind::Block:
|
||||
return EncodeBlock(e, expr.as<WasmAstBlock>());
|
||||
case WasmAstKind::Call:
|
||||
return EncodeCall(e, expr.as<WasmAstCall>());
|
||||
case WasmAstKind::Const:
|
||||
return EncodeConst(e, expr.as<WasmAstConst>());
|
||||
case WasmAstKind::GetLocal:
|
||||
|
@ -28,13 +28,10 @@ assertEq(stack.functionDisplayName, "tester");
|
||||
|
||||
assertEq(stack.parent.functionDisplayName, "doTest");
|
||||
assertEq(stack.parent.line, 6);
|
||||
assertEq(stack.parent.column, 5);
|
||||
|
||||
assertEq(stack.parent.parent.functionDisplayName, "test");
|
||||
assertEq(stack.parent.parent.line, 10);
|
||||
assertEq(stack.parent.parent.column, 5);
|
||||
|
||||
assertEq(stack.parent.parent.parent.line, 24);
|
||||
assertEq(stack.parent.parent.parent.column, 1);
|
||||
|
||||
assertEq(stack.parent.parent.parent.parent, null);
|
||||
|
@ -175,3 +175,44 @@ assertErrorMessage(() => wasmEvalText('(module (func (result f32) (block (i32.co
|
||||
assertEq(wasmEvalText('(module (func (result i32) (block (i32.const 13) (block (i32.const 42)))) (export "" 0))')(), 42);
|
||||
assertErrorMessage(() => wasmEvalText('(module (func (result f32) (param f32) (block (get_local 0) (i32.const 0))))'), TypeError, mismatchError("i32", "f32"));
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// calls
|
||||
|
||||
assertThrowsInstanceOf(() => wasmEvalText('(module (func (nop)) (func (call 0 (i32.const 0))))'), TypeError);
|
||||
assertThrowsInstanceOf(() => wasmEvalText('(module (func (param i32) (nop)) (func (call 0)))'), TypeError);
|
||||
assertThrowsInstanceOf(() => wasmEvalText('(module (func (param f32) (nop)) (func (call 0 (i32.const 0))))'), TypeError);
|
||||
assertErrorMessage(() => wasmEvalText('(module (func (nop)) (func (call 3)))'), TypeError, /callee index out of range/);
|
||||
wasmEvalText('(module (func (nop)) (func (call 0)))');
|
||||
wasmEvalText('(module (func (param i32) (nop)) (func (call 0 (i32.const 0))))');
|
||||
assertEq(wasmEvalText('(module (func (result i32) (i32.const 42)) (func (result i32) (call 0)) (export "" 1))')(), 42);
|
||||
assertThrowsInstanceOf(() => wasmEvalText('(module (func (call 0)) (export "" 0))')(), InternalError);
|
||||
assertThrowsInstanceOf(() => wasmEvalText('(module (func (call 1)) (func (call 0)) (export "" 0))')(), InternalError);
|
||||
|
||||
assertThrowsInstanceOf(() => wasmEvalText('(module (import "a" "") (func (call_import 0 (i32.const 0))))', {a:()=>{}}), TypeError);
|
||||
assertThrowsInstanceOf(() => wasmEvalText('(module (import "a" "" (param i32)) (func (call_import 0)))', {a:()=>{}}), TypeError);
|
||||
assertThrowsInstanceOf(() => wasmEvalText('(module (import "a" "" (param f32)) (func (call_import 0 (i32.const 0))))', {a:()=>{}}), TypeError);
|
||||
assertErrorMessage(() => wasmEvalText('(module (import "a" "") (func (call_import 1)))'), TypeError, /import index out of range/);
|
||||
wasmEvalText('(module (import "a" "") (func (call_import 0)))', {a:()=>{}});
|
||||
wasmEvalText('(module (import "a" "" (param i32)) (func (call_import 0 (i32.const 0))))', {a:()=>{}});
|
||||
|
||||
var f = wasmEvalText('(module (import "inc" "") (func (call_import 0)) (export "" 0))', {inc:()=>counter++});
|
||||
var g = wasmEvalText('(module (import "f" "") (func (block (call_import 0) (call_import 0))) (export "" 0))', {f});
|
||||
var counter = 0;
|
||||
f();
|
||||
assertEq(counter, 1);
|
||||
g();
|
||||
assertEq(counter, 3);
|
||||
|
||||
var f = wasmEvalText('(module (import "callf" "") (func (call_import 0)) (export "" 0))', {callf:()=>f()});
|
||||
assertThrowsInstanceOf(() => f(), InternalError);
|
||||
|
||||
var f = wasmEvalText('(module (import "callg" "") (func (call_import 0)) (export "" 0))', {callg:()=>g()});
|
||||
var g = wasmEvalText('(module (import "callf" "") (func (call_import 0)) (export "" 0))', {callf:()=>f()});
|
||||
assertThrowsInstanceOf(() => f(), InternalError);
|
||||
|
||||
var code = '(module (import "one" "" (result i32)) (import "two" "" (result i32)) (func (result i32) (i32.const 3)) (func (result i32) (i32.const 4)) (func (result i32) BODY) (export "" 2))';
|
||||
var imports = {one:()=>1, two:()=>2};
|
||||
assertEq(wasmEvalText(code.replace('BODY', '(call_import 0)'), imports)(), 1);
|
||||
assertEq(wasmEvalText(code.replace('BODY', '(call_import 1)'), imports)(), 2);
|
||||
assertEq(wasmEvalText(code.replace('BODY', '(call 0)'), imports)(), 3);
|
||||
assertEq(wasmEvalText(code.replace('BODY', '(call 1)'), imports)(), 4);
|
||||
|
Loading…
Reference in New Issue
Block a user