зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1863794 - wasm: Generalize builtin module function support. r=yury
- Add optional result to builtin module functions - Allow RefType params to builtin module functions - Don't require linear memory to be available These are required for expressing the kinds of functions that we want for js-string-builtins. Depends on D193110 Differential Revision: https://phabricator.services.mozilla.com/D193111
This commit is contained in:
Родитель
7aa6f07799
Коммит
343cd58824
|
@ -2120,7 +2120,8 @@ static bool WasmBuiltinI8VecMul(JSContext* cx, unsigned argc, Value* vp) {
|
|||
|
||||
wasm::BuiltinModuleFuncId ids[] = {wasm::BuiltinModuleFuncId::I8VecMul};
|
||||
Rooted<WasmModuleObject*> module(cx);
|
||||
if (!wasm::CompileBuiltinModule(cx, ids, wasm::Shareable::False, &module)) {
|
||||
if (!wasm::CompileBuiltinModule(cx, ids, Some(wasm::Shareable::False),
|
||||
&module)) {
|
||||
return false;
|
||||
}
|
||||
args.rval().set(ObjectValue(*module.get()));
|
||||
|
|
|
@ -56,6 +56,12 @@ def load_yaml(yaml_path):
|
|||
return yaml.load(contents, OrderedLoader)
|
||||
|
||||
|
||||
def cppBool(v):
|
||||
if v:
|
||||
return "true"
|
||||
return "false"
|
||||
|
||||
|
||||
def main(c_out, yaml_path):
|
||||
data = load_yaml(yaml_path)
|
||||
|
||||
|
@ -66,21 +72,41 @@ def main(c_out, yaml_path):
|
|||
sa = op["symbolic_address"]
|
||||
contents += (
|
||||
f" M({op['op']}, \"{op['export']}\", "
|
||||
f"{sa['name']}, {sa['type']}, {op['entry']}, {i})\\\n"
|
||||
f"{sa['name']}, {sa['type']}, {op['entry']}, {cppBool(op['uses_memory'])}, {i})\\\n"
|
||||
)
|
||||
contents += "\n"
|
||||
|
||||
for op in data:
|
||||
# Define DECLARE_BUILTIN_MODULE_FUNC_SAS_PARAM_VALTYPES_<op> as:
|
||||
# Define DECLARE_BUILTIN_MODULE_FUNC_PARAM_VALTYPES_<op> as:
|
||||
# `{ValType::I32, ValType::I32, ...}`.
|
||||
contents += (
|
||||
f"#define DECLARE_BUILTIN_MODULE_FUNC_SAS_PARAM_VALTYPES_{op['op']} "
|
||||
f"{{ValType::{', ValType::'.join(op['params'])}}}\n"
|
||||
f"#define DECLARE_BUILTIN_MODULE_FUNC_PARAM_VALTYPES_{op['op']} "
|
||||
f"{{{', '.join(op['params'])}}}\n"
|
||||
)
|
||||
# Define DECLARE_BUILTIN_MODULE_FUNC_PARAM_TYPES_<op> as:
|
||||
|
||||
# Define DECLARE_BUILTIN_MODULE_FUNC_PARAM_SASTYPES_<op> as:
|
||||
# `<num_types>, {_PTR, _I32, ..., _PTR, _END}`.
|
||||
sas_types = f"{{_PTR{''.join(', _' + p for p in op['params'])}, _PTR, _END}}"
|
||||
num_types = len(op["params"]) + 2
|
||||
contents += f"#define DECLARE_BUILTIN_MODULE_FUNC_PARAM_TYPES_{op['op']} {num_types}, {sas_types}\n"
|
||||
num_types = len(op["params"]) + 1
|
||||
sas_types = (
|
||||
f"{{_PTR{''.join(', ' + (p + '.toMIRType()') for p in op['params'])}"
|
||||
)
|
||||
if op["uses_memory"]:
|
||||
sas_types += ", _PTR"
|
||||
num_types += 1
|
||||
sas_types += ", _END}"
|
||||
|
||||
contents += f"#define DECLARE_BUILTIN_MODULE_FUNC_PARAM_SASTYPES_{op['op']} {num_types}, {sas_types}\n"
|
||||
|
||||
result_valtype = ""
|
||||
result_sastype = ""
|
||||
if "result" in op:
|
||||
result_valtype = f"Some({op['result']})\n"
|
||||
result_sastype = f"{op['result']}.toMIRType()\n"
|
||||
else:
|
||||
result_valtype = "Nothing()"
|
||||
result_sastype = "_VOID"
|
||||
contents += f"#define DECLARE_BUILTIN_MODULE_FUNC_RESULT_VALTYPE_{op['op']} {result_valtype}\n"
|
||||
contents += f"#define DECLARE_BUILTIN_MODULE_FUNC_RESULT_SASTYPE_{op['op']} {result_sastype}\n"
|
||||
contents += f"#define DECLARE_BUILTIN_MODULE_FUNC_FAILMODE_{op['op']} _{op['fail_mode']}\n"
|
||||
|
||||
generate_header(c_out, "wasm_WasmBuiltinModuleGenerated_h", contents)
|
||||
|
|
|
@ -9415,8 +9415,10 @@ bool BaseCompiler::emitCallBuiltinModuleFunc() {
|
|||
return true;
|
||||
}
|
||||
|
||||
// The final parameter of an builtinModuleFunc is implicitly the heap base
|
||||
pushHeapBase(0);
|
||||
if (builtinModuleFunc->usesMemory) {
|
||||
// The final parameter of an builtinModuleFunc is implicitly the heap base
|
||||
pushHeapBase(0);
|
||||
}
|
||||
|
||||
// Call the builtinModuleFunc
|
||||
return emitInstanceCall(builtinModuleFunc->signature);
|
||||
|
|
|
@ -32,14 +32,17 @@
|
|||
using namespace js;
|
||||
using namespace js::wasm;
|
||||
|
||||
#define VISIT_BUILTIN_FUNC(op, export, sa_name, abitype, entry, idx) \
|
||||
static const ValType BuiltinModuleFunc##op##_Params[] = \
|
||||
DECLARE_BUILTIN_MODULE_FUNC_SAS_PARAM_VALTYPES_##op; \
|
||||
\
|
||||
const BuiltinModuleFunc BuiltinModuleFunc##op = { \
|
||||
export, \
|
||||
mozilla::Span<const ValType>(BuiltinModuleFunc##op##_Params), \
|
||||
SASig##sa_name, \
|
||||
#define VISIT_BUILTIN_FUNC(op, export, sa_name, abitype, entry, uses_memory, \
|
||||
idx) \
|
||||
static const ValType BuiltinModuleFunc##op##_Params[] = \
|
||||
DECLARE_BUILTIN_MODULE_FUNC_PARAM_VALTYPES_##op; \
|
||||
\
|
||||
const BuiltinModuleFunc BuiltinModuleFunc##op = { \
|
||||
export, \
|
||||
mozilla::Span<const ValType>(BuiltinModuleFunc##op##_Params), \
|
||||
DECLARE_BUILTIN_MODULE_FUNC_RESULT_VALTYPE_##op, \
|
||||
SASig##sa_name, \
|
||||
uses_memory, \
|
||||
};
|
||||
|
||||
FOR_EACH_BUILTIN_MODULE_FUNC(VISIT_BUILTIN_FUNC)
|
||||
|
@ -50,15 +53,19 @@ bool BuiltinModuleFunc::funcType(FuncType* type) const {
|
|||
if (!paramVec.append(params.data(), params.data() + params.size())) {
|
||||
return false;
|
||||
}
|
||||
*type = FuncType(std::move(paramVec), ValTypeVector());
|
||||
ValTypeVector resultVec;
|
||||
if (result.isSome() && !resultVec.append(*result)) {
|
||||
return false;
|
||||
}
|
||||
*type = FuncType(std::move(paramVec), std::move(resultVec));
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */
|
||||
const BuiltinModuleFunc& BuiltinModuleFunc::getFromId(BuiltinModuleFuncId id) {
|
||||
switch (id) {
|
||||
#define VISIT_BUILTIN_FUNC(op, export, sa_name, abitype, entry, idx) \
|
||||
case BuiltinModuleFuncId::op: \
|
||||
#define VISIT_BUILTIN_FUNC(op, ...) \
|
||||
case BuiltinModuleFuncId::op: \
|
||||
return BuiltinModuleFunc##op;
|
||||
FOR_EACH_BUILTIN_MODULE_FUNC(VISIT_BUILTIN_FUNC)
|
||||
#undef VISIT_BUILTIN_FUNC
|
||||
|
@ -89,7 +96,7 @@ bool EncodeFuncBody(const BuiltinModuleFunc& builtinModuleFunc,
|
|||
|
||||
bool wasm::CompileBuiltinModule(JSContext* cx,
|
||||
const mozilla::Span<BuiltinModuleFuncId> ids,
|
||||
Shareable sharedMemory,
|
||||
mozilla::Maybe<Shareable> memory,
|
||||
MutableHandle<WasmModuleObject*> result) {
|
||||
// Create the options manually, enabling intrinsics
|
||||
FeatureOptions featureOptions;
|
||||
|
@ -113,23 +120,24 @@ bool wasm::CompileBuiltinModule(JSContext* cx,
|
|||
return false;
|
||||
}
|
||||
|
||||
// Add (import (memory 0))
|
||||
CacheableName emptyString;
|
||||
CacheableName memoryString;
|
||||
if (!CacheableName::fromUTF8Chars("memory", &memoryString)) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
if (!moduleEnv.imports.append(Import(std::move(emptyString),
|
||||
std::move(memoryString),
|
||||
DefinitionKind::Memory))) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
if (!moduleEnv.memories.append(
|
||||
MemoryDesc(Limits(0, Nothing(), sharedMemory)))) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
if (memory.isSome()) {
|
||||
// Add (import (memory 0))
|
||||
CacheableName emptyString;
|
||||
CacheableName memoryString;
|
||||
if (!CacheableName::fromUTF8Chars("memory", &memoryString)) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
if (!moduleEnv.imports.append(Import(std::move(emptyString),
|
||||
std::move(memoryString),
|
||||
DefinitionKind::Memory))) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
if (!moduleEnv.memories.append(MemoryDesc(Limits(0, Nothing(), *memory)))) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Add (type (func (params ...))) for each func. The function types will
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#ifndef wasm_builtin_module_h
|
||||
#define wasm_builtin_module_h
|
||||
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/Span.h"
|
||||
|
||||
#include "wasm/WasmBuiltins.h"
|
||||
|
@ -36,11 +37,15 @@ namespace wasm {
|
|||
struct BuiltinModuleFunc {
|
||||
// The name of the func as it is exported
|
||||
const char* exportName;
|
||||
// The params taken by the func. No results are required for these funcs
|
||||
// at this time, so we omit them
|
||||
// The params taken by the func.
|
||||
mozilla::Span<const ValType> params;
|
||||
// The optional result returned by the func.
|
||||
mozilla::Maybe<const ValType> result;
|
||||
// The signature of the builtin that implements the func
|
||||
const SymbolicAddressSignature& signature;
|
||||
// Whether this function takes a pointer to the memory base as a hidden final
|
||||
// parameter.
|
||||
bool usesMemory;
|
||||
|
||||
// Allocate a FuncType for this func, returning false for OOM
|
||||
bool funcType(FuncType* type) const;
|
||||
|
@ -53,7 +58,7 @@ struct BuiltinModuleFunc {
|
|||
// Compile and return the builtin module for a given set of operations.
|
||||
bool CompileBuiltinModule(JSContext* cx,
|
||||
const mozilla::Span<BuiltinModuleFuncId> ids,
|
||||
Shareable sharedMemory,
|
||||
mozilla::Maybe<Shareable> memory,
|
||||
MutableHandle<WasmModuleObject*> result);
|
||||
|
||||
} // namespace wasm
|
||||
|
|
|
@ -12,10 +12,12 @@
|
|||
entry: Instance::intrI8VecMul
|
||||
export: i8vecmul
|
||||
params:
|
||||
- I32
|
||||
- I32
|
||||
- I32
|
||||
- I32
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
fail_mode: FailOnNegI32
|
||||
uses_memory: true
|
||||
|
||||
#if defined(ENABLE_WASM_MOZ_INTGEMM)
|
||||
|
||||
|
@ -38,12 +40,14 @@
|
|||
entry: intgemm::IntrI8PrepareB
|
||||
export: int8_prepare_b
|
||||
params:
|
||||
- I32
|
||||
- F32
|
||||
- F32
|
||||
- I32
|
||||
- I32
|
||||
- I32
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::f32()'
|
||||
- 'ValType::f32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
fail_mode: FailOnNegI32
|
||||
uses_memory: true
|
||||
|
||||
|
||||
# Prepare B for the Matrix Multiply intrinsic from transposed version of Input matrix B.
|
||||
|
@ -61,12 +65,14 @@
|
|||
entry: intgemm::IntrI8PrepareBFromTransposed
|
||||
export: int8_prepare_b_from_transposed
|
||||
params:
|
||||
- I32
|
||||
- F32
|
||||
- F32
|
||||
- I32
|
||||
- I32
|
||||
- I32
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::f32()'
|
||||
- 'ValType::f32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
fail_mode: FailOnNegI32
|
||||
uses_memory: true
|
||||
|
||||
|
||||
# Prepare B for the Matrix Multiply intrinsic from a quantized and transposed version of Input
|
||||
|
@ -84,10 +90,12 @@
|
|||
entry: intgemm::IntrI8PrepareBFromQuantizedTransposed
|
||||
export: int8_prepare_b_from_quantized_transposed
|
||||
params:
|
||||
- I32
|
||||
- I32
|
||||
- I32
|
||||
- I32
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
fail_mode: FailOnNegI32
|
||||
uses_memory: true
|
||||
|
||||
|
||||
# Prepare A for the Matrix Multiply intrinsic from Input matrix A.
|
||||
|
@ -108,12 +116,14 @@
|
|||
entry: intgemm::IntrI8PrepareA
|
||||
export: int8_prepare_a
|
||||
params:
|
||||
- I32
|
||||
- F32
|
||||
- F32
|
||||
- I32
|
||||
- I32
|
||||
- I32
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::f32()'
|
||||
- 'ValType::f32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
fail_mode: FailOnNegI32
|
||||
uses_memory: true
|
||||
|
||||
|
||||
# Prepares bias for the Matrix Multiply intrinsic.
|
||||
|
@ -132,15 +142,17 @@
|
|||
entry: intgemm::IntrI8PrepareBias
|
||||
export: int8_prepare_bias
|
||||
params:
|
||||
- I32
|
||||
- F32
|
||||
- F32
|
||||
- F32
|
||||
- F32
|
||||
- I32
|
||||
- I32
|
||||
- I32
|
||||
- I32
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::f32()'
|
||||
- 'ValType::f32()'
|
||||
- 'ValType::f32()'
|
||||
- 'ValType::f32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
fail_mode: FailOnNegI32
|
||||
uses_memory: true
|
||||
|
||||
|
||||
# Perform multiplication of 2 matrices followed by adding a bias.
|
||||
|
@ -165,18 +177,20 @@
|
|||
entry: intgemm::IntrI8MultiplyAndAddBias
|
||||
export: int8_multiply_and_add_bias
|
||||
params:
|
||||
- I32
|
||||
- F32
|
||||
- F32
|
||||
- I32
|
||||
- F32
|
||||
- F32
|
||||
- I32
|
||||
- F32
|
||||
- I32
|
||||
- I32
|
||||
- I32
|
||||
- I32
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::f32()'
|
||||
- 'ValType::f32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::f32()'
|
||||
- 'ValType::f32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::f32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
fail_mode: FailOnNegI32
|
||||
uses_memory: true
|
||||
|
||||
|
||||
# Select a subset of columns of prepared B.
|
||||
|
@ -192,11 +206,13 @@
|
|||
entry: intgemm::IntrI8SelectColumnsOfB
|
||||
export: int8_select_columns_of_b
|
||||
params:
|
||||
- I32
|
||||
- I32
|
||||
- I32
|
||||
- I32
|
||||
- I32
|
||||
- I32
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
- 'ValType::i32()'
|
||||
fail_mode: FailOnNegI32
|
||||
uses_memory: true
|
||||
|
||||
#endif // ENABLE_WASM_MOZ_INTGEMM
|
||||
|
|
|
@ -393,10 +393,12 @@ const SymbolicAddressSignature SASigArrayCopy = {
|
|||
7,
|
||||
{_PTR, _RoN, _I32, _RoN, _I32, _I32, _I32, _END}};
|
||||
|
||||
#define VISIT_BUILTIN_FUNC(op, export, sa_name, abitype, entry, idx) \
|
||||
const SymbolicAddressSignature SASig##sa_name = { \
|
||||
SymbolicAddress::sa_name, _VOID, _FailOnNegI32, \
|
||||
DECLARE_BUILTIN_MODULE_FUNC_PARAM_TYPES_##op};
|
||||
#define VISIT_BUILTIN_FUNC(op, export, sa_name, ...) \
|
||||
const SymbolicAddressSignature SASig##sa_name = { \
|
||||
SymbolicAddress::sa_name, \
|
||||
DECLARE_BUILTIN_MODULE_FUNC_RESULT_SASTYPE_##op, \
|
||||
DECLARE_BUILTIN_MODULE_FUNC_FAILMODE_##op, \
|
||||
DECLARE_BUILTIN_MODULE_FUNC_PARAM_SASTYPES_##op};
|
||||
|
||||
FOR_EACH_BUILTIN_MODULE_FUNC(VISIT_BUILTIN_FUNC)
|
||||
#undef VISIT_BUILTIN_FUNC
|
||||
|
@ -1455,7 +1457,7 @@ void* wasm::AddressOf(SymbolicAddress imm, ABIFunctionType* abiType) {
|
|||
*abiType = Args_General1;
|
||||
return FuncCast(PrintText, *abiType);
|
||||
#endif
|
||||
#define VISIT_BUILTIN_FUNC(op, export, sa_name, abitype, entry, idx) \
|
||||
#define VISIT_BUILTIN_FUNC(op, export, sa_name, abitype, entry, ...) \
|
||||
case SymbolicAddress::sa_name: \
|
||||
*abiType = abitype; \
|
||||
return FuncCast(entry, *abiType);
|
||||
|
@ -1617,7 +1619,7 @@ bool wasm::NeedsBuiltinThunk(SymbolicAddress sym) {
|
|||
case SymbolicAddress::ArrayInitData:
|
||||
case SymbolicAddress::ArrayInitElem:
|
||||
case SymbolicAddress::ArrayCopy:
|
||||
#define VISIT_BUILTIN_FUNC(op, export, sa_name, abitype, entry, idx) \
|
||||
#define VISIT_BUILTIN_FUNC(op, export, sa_name, ...) \
|
||||
case SymbolicAddress::sa_name:
|
||||
FOR_EACH_BUILTIN_MODULE_FUNC(VISIT_BUILTIN_FUNC)
|
||||
#undef VISIT_BUILTIN_FUNC
|
||||
|
|
|
@ -142,7 +142,7 @@ enum class SymbolicAddress {
|
|||
ArrayInitData,
|
||||
ArrayInitElem,
|
||||
ArrayCopy,
|
||||
#define VISIT_BUILTIN_FUNC(op, export, sa_name, abitype, entry, idx) sa_name,
|
||||
#define VISIT_BUILTIN_FUNC(op, export, sa_name, ...) sa_name,
|
||||
FOR_EACH_BUILTIN_MODULE_FUNC(VISIT_BUILTIN_FUNC)
|
||||
#undef VISIT_BUILTIN_FUNC
|
||||
#ifdef WASM_CODEGEN_DEBUG
|
||||
|
@ -278,7 +278,7 @@ extern const SymbolicAddressSignature SASigArrayNewElem;
|
|||
extern const SymbolicAddressSignature SASigArrayInitData;
|
||||
extern const SymbolicAddressSignature SASigArrayInitElem;
|
||||
extern const SymbolicAddressSignature SASigArrayCopy;
|
||||
#define VISIT_BUILTIN_FUNC(op, export, sa_name, abitype, entry, idx) \
|
||||
#define VISIT_BUILTIN_FUNC(op, export, sa_name, ...) \
|
||||
extern const SymbolicAddressSignature SASig##sa_name;
|
||||
FOR_EACH_BUILTIN_MODULE_FUNC(VISIT_BUILTIN_FUNC)
|
||||
#undef VISIT_BUILTIN_FUNC
|
||||
|
|
|
@ -956,7 +956,8 @@ enum class BuiltinModuleFuncId {
|
|||
// emitted internally when compiling intrinsic modules and are rejected by wasm
|
||||
// validation.
|
||||
// See wasm/WasmBuiltinModule.yaml for the list.
|
||||
#define VISIT_BUILTIN_FUNC(op, export, sa_name, abitype, entry, idx) \
|
||||
#define VISIT_BUILTIN_FUNC(op, export, sa_name, abitype, entry, has_memory, \
|
||||
idx) \
|
||||
op = idx, // NOLINT
|
||||
FOR_EACH_BUILTIN_MODULE_FUNC(VISIT_BUILTIN_FUNC)
|
||||
#undef VISIT_BUILTIN_FUNC
|
||||
|
|
|
@ -1794,8 +1794,8 @@ static const char* ThunkedNativeToDescription(SymbolicAddress func) {
|
|||
return "call to native array.init_elem function";
|
||||
case SymbolicAddress::ArrayCopy:
|
||||
return "call to native array.copy function";
|
||||
#define VISIT_BUILTIN_FUNC(op, export, sa_name, abitype, entry, idx) \
|
||||
case SymbolicAddress::sa_name: \
|
||||
#define VISIT_BUILTIN_FUNC(op, export, sa_name, ...) \
|
||||
case SymbolicAddress::sa_name: \
|
||||
return "call to native " #op " builtin (in wasm)";
|
||||
FOR_EACH_BUILTIN_MODULE_FUNC(VISIT_BUILTIN_FUNC)
|
||||
#undef VISIT_BUILTIN_FUNC
|
||||
|
|
|
@ -7708,16 +7708,29 @@ static bool EmitCallBuiltinModuleFunc(FunctionCompiler& f) {
|
|||
return false;
|
||||
}
|
||||
|
||||
MDefinition* memoryBase = f.memoryBase(0);
|
||||
if (!f.passArg(memoryBase, MIRType::Pointer, &args)) {
|
||||
return false;
|
||||
if (builtinModuleFunc->usesMemory) {
|
||||
MDefinition* memoryBase = f.memoryBase(0);
|
||||
if (!f.passArg(memoryBase, MIRType::Pointer, &args)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!f.finishCall(&args)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return f.builtinInstanceMethodCall(callee, bytecodeOffset, args);
|
||||
bool hasResult = builtinModuleFunc->result.isSome();
|
||||
MDefinition* result = nullptr;
|
||||
MDefinition** resultOutParam = hasResult ? &result : nullptr;
|
||||
if (!f.builtinInstanceMethodCall(callee, bytecodeOffset, args,
|
||||
resultOutParam)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hasResult) {
|
||||
f.iter().setResult(result);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool EmitBodyExprs(FunctionCompiler& f) {
|
||||
|
|
|
@ -5158,7 +5158,7 @@ static bool WebAssembly_mozIntGemm(JSContext* cx, unsigned argc, Value* vp) {
|
|||
wasm::BuiltinModuleFuncId::I8PrepareBias,
|
||||
wasm::BuiltinModuleFuncId::I8MultiplyAndAddBias,
|
||||
wasm::BuiltinModuleFuncId::I8SelectColumnsOfB};
|
||||
if (!wasm::CompileBuiltinModule(cx, ids, Shareable::False, &module)) {
|
||||
if (!wasm::CompileBuiltinModule(cx, ids, Some(Shareable::False), &module)) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -4097,10 +4097,16 @@ inline bool OpIter<Policy>::readCallBuiltinModuleFunc(
|
|||
|
||||
*builtinModuleFunc = &BuiltinModuleFunc::getFromId(BuiltinModuleFuncId(id));
|
||||
|
||||
if (env_.numMemories() == 0) {
|
||||
if ((*builtinModuleFunc)->usesMemory && env_.numMemories() == 0) {
|
||||
return fail("can't touch memory without memory");
|
||||
}
|
||||
return popWithTypes((*builtinModuleFunc)->params, params);
|
||||
if (!popWithTypes((*builtinModuleFunc)->params, params)) {
|
||||
return false;
|
||||
}
|
||||
if ((*builtinModuleFunc)->result.isNothing()) {
|
||||
return true;
|
||||
}
|
||||
return push(*(*builtinModuleFunc)->result);
|
||||
}
|
||||
|
||||
} // namespace wasm
|
||||
|
|
|
@ -112,11 +112,11 @@ union PackedTypeCode {
|
|||
|
||||
static PackedTypeCode pack(TypeCode tc) { return pack(tc, nullptr, false); }
|
||||
|
||||
bool isValid() const { return typeCode_ != NoTypeCode; }
|
||||
constexpr bool isValid() const { return typeCode_ != NoTypeCode; }
|
||||
|
||||
PackedRepr bits() const { return bits_; }
|
||||
|
||||
TypeCode typeCode() const {
|
||||
constexpr TypeCode typeCode() const {
|
||||
MOZ_ASSERT(isValid());
|
||||
return TypeCode(typeCode_);
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ union PackedTypeCode {
|
|||
// what ValType needs, so that this decoding step is not necessary, but that
|
||||
// moves complexity elsewhere, and the perf gain here would be only about 1%
|
||||
// for baseline compilation throughput.
|
||||
TypeCode typeCodeAbstracted() const {
|
||||
constexpr TypeCode typeCodeAbstracted() const {
|
||||
TypeCode tc = typeCode();
|
||||
return tc < LowestPrimitiveTypeCode ? AbstractReferenceTypeCode : tc;
|
||||
}
|
||||
|
@ -634,6 +634,11 @@ class PackedType : public T {
|
|||
inline void AddRef() const;
|
||||
inline void Release() const;
|
||||
|
||||
static constexpr PackedType i32() { return PackedType(PackedType::I32); }
|
||||
static constexpr PackedType f32() { return PackedType(PackedType::F32); }
|
||||
static constexpr PackedType i64() { return PackedType(PackedType::I64); }
|
||||
static constexpr PackedType f64() { return PackedType(PackedType::F64); }
|
||||
|
||||
static PackedType fromMIRType(jit::MIRType mty) {
|
||||
switch (mty) {
|
||||
case jit::MIRType::Int32:
|
||||
|
@ -830,7 +835,7 @@ class PackedType : public T {
|
|||
// as a pointer. At the JS/wasm boundary, an AnyRef can be represented as a
|
||||
// JS::Value, and the type translation may have to be handled specially and on
|
||||
// a case-by-case basis.
|
||||
jit::MIRType toMIRType() const {
|
||||
constexpr jit::MIRType toMIRType() const {
|
||||
switch (tc_.typeCodeAbstracted()) {
|
||||
case TypeCode::I32:
|
||||
return jit::MIRType::Int32;
|
||||
|
|
Загрузка…
Ссылка в новой задаче