1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "jit/MacroAssembler.h"
10 #include "jsapi-tests/tests.h"
11 #include "jsapi-tests/testsJit.h"
13 #include "wasm/WasmConstants.h"
14 #include "wasm/WasmFeatures.h" // AnyCompilerAvailable
15 #include "wasm/WasmGenerator.h"
16 #include "wasm/WasmSignalHandlers.h" // EnsureFullSignalHandlers
17 #include "wasm/WasmValType.h"
20 using namespace js::jit
;
21 using namespace js::wasm
;
23 static bool TestTruncFn(JSContext
* cx
, unsigned argc
, Value
* vp
) {
24 CallArgs args
= CallArgsFromVp(argc
, vp
);
25 double d
= args
[0].toDouble();
26 args
.rval().setInt32((int)d
);
30 // Check if wasm modules can be encoded in C++ and run.
31 BEGIN_TEST(testWasmEncodeBasic
) {
32 if (!AnyCompilerAvailable(cx
)) {
37 EnsureFullSignalHandlers(cx
);
39 FeatureOptions options
;
40 ScriptedCaller scriptedCaller
;
41 SharedCompileArgs compileArgs
=
42 CompileArgs::buildAndReport(cx
, std::move(scriptedCaller
), options
);
44 ModuleEnvironment
moduleEnv(compileArgs
->features
);
45 CompilerEnvironment
compilerEnv(CompileMode::Once
, Tier::Optimized
,
47 compilerEnv
.computeParameters();
48 MOZ_ALWAYS_TRUE(moduleEnv
.init());
50 ValTypeVector paramsImp
, resultsImp
;
51 MOZ_ALWAYS_TRUE(paramsImp
.emplaceBack(ValType::F64
) &&
52 resultsImp
.emplaceBack(ValType::I32
));
55 CacheableName impName
;
56 MOZ_ALWAYS_TRUE(CacheableName::fromUTF8Chars("t", &impName
));
57 MOZ_ALWAYS_TRUE(moduleEnv
.addImportedFunc(std::move(paramsImp
),
58 std::move(resultsImp
),
59 std::move(ns
), std::move(impName
)));
61 ValTypeVector params
, results
;
62 MOZ_ALWAYS_TRUE(results
.emplaceBack(ValType::I32
));
63 CacheableName expName
;
64 MOZ_ALWAYS_TRUE(CacheableName::fromUTF8Chars("r", &expName
));
65 MOZ_ALWAYS_TRUE(moduleEnv
.addDefinedFunc(std::move(params
),
66 std::move(results
), true,
67 mozilla::Some(std::move(expName
))));
69 ModuleGenerator
mg(*compileArgs
, &moduleEnv
, &compilerEnv
, nullptr, nullptr,
71 MOZ_ALWAYS_TRUE(mg
.init(nullptr));
73 // Build function and keep bytecode around until the end.
76 Encoder
encoder(bytecode
);
77 MOZ_ALWAYS_TRUE(EncodeLocalEntries(encoder
, ValTypeVector()));
78 MOZ_ALWAYS_TRUE(encoder
.writeOp(Op::F64Const
) &&
79 encoder
.writeFixedF64(42.3));
80 MOZ_ALWAYS_TRUE(encoder
.writeOp(Op::Call
) && encoder
.writeVarU32(0));
81 MOZ_ALWAYS_TRUE(encoder
.writeOp(Op::End
));
83 MOZ_ALWAYS_TRUE(mg
.compileFuncDef(1, 0, bytecode
.begin(),
84 bytecode
.begin() + bytecode
.length()));
85 MOZ_ALWAYS_TRUE(mg
.finishFuncDefs());
87 SharedBytes shareableBytes
= js_new
<ShareableBytes
>();
88 MOZ_ALWAYS_TRUE(shareableBytes
);
89 SharedModule module
= mg
.finishModule(*shareableBytes
);
90 MOZ_ALWAYS_TRUE(module
);
92 MOZ_ASSERT(module
->imports().length() == 1);
93 MOZ_ASSERT(module
->exports().length() == 1);
95 // Instantiate and run.
97 Rooted
<ImportValues
> imports(cx
);
98 RootedFunction
func(cx
, NewNativeFunction(cx
, TestTruncFn
, 0, nullptr));
99 MOZ_ALWAYS_TRUE(func
);
100 MOZ_ALWAYS_TRUE(imports
.get().funcs
.append(func
));
102 Rooted
<WasmInstanceObject
*> instance(cx
);
103 MOZ_ALWAYS_TRUE(module
->instantiate(cx
, imports
.get(), nullptr, &instance
));
104 RootedFunction
wasmFunc(cx
);
106 WasmInstanceObject::getExportedFunction(cx
, instance
, 1, &wasmFunc
));
108 JSAutoRealm
ar(cx
, wasmFunc
);
109 RootedValue
rval(cx
);
110 RootedValue
fval(cx
);
112 JS::Call(cx
, fval
, wasmFunc
, JS::HandleValueArray::empty(), &rval
));
113 MOZ_RELEASE_ASSERT(rval
.toInt32() == 42);
117 END_TEST(testWasmEncodeBasic
)