summaryrefslogtreecommitdiffstats
path: root/js/src/wasm/cranelift/baldrapi.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/wasm/cranelift/baldrapi.h')
-rw-r--r--js/src/wasm/cranelift/baldrapi.h283
1 files changed, 283 insertions, 0 deletions
diff --git a/js/src/wasm/cranelift/baldrapi.h b/js/src/wasm/cranelift/baldrapi.h
new file mode 100644
index 0000000000..58a999785b
--- /dev/null
+++ b/js/src/wasm/cranelift/baldrapi.h
@@ -0,0 +1,283 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ *
+ * Copyright 2018 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// This is an ADT-style C API to the WebAssembly per-function compilation state,
+// allowing Rust to access constant metadata and produce output.
+//
+// This file is input to Rust's bindgen, so as to create primitive APIs for the
+// Cranelift pipeline to access compilation metadata. The actual Rust API then
+// wraps these primitive APIs. See src/bindings/mod.rs.
+//
+// This file can be included in SpiderMonkey's C++ code, where all the prefixes
+// must be obeyed. The purpose of the prefixes is to avoid type confusion. See
+// js/src/wasm/WasmCraneliftCompile.cpp.
+
+#ifndef wasm_cranelift_baldrapi_h
+#define wasm_cranelift_baldrapi_h
+
+// DO NOT INCLUDE SPIDERMONKEY HEADER FILES INTO THIS FILE.
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+#include "wasm/WasmConstants.h"
+
+// wasm/*.{cpp,h}, class and struct types that are opaque to us here
+namespace js {
+namespace wasm {
+// wasm/WasmGenerator.h
+struct FuncCompileInput;
+// wasm/WasmTypes.h
+class GlobalDesc;
+class FuncType;
+class TypeIdDesc;
+struct TableDesc;
+// wasm/WasmValidate.h
+struct ModuleEnvironment;
+} // namespace wasm
+} // namespace js
+
+// This struct contains all the information that can be computed once for the
+// entire process and then should never change. It contains a mix of CPU
+// feature detection flags, and static information the C++ compile has access
+// to, but which can't be automatically provided to Rust.
+
+struct CraneliftStaticEnvironment {
+ bool has_sse2;
+ bool has_sse3;
+ bool has_sse41;
+ bool has_sse42;
+ bool has_popcnt;
+ bool has_avx;
+ bool has_bmi1;
+ bool has_bmi2;
+ bool has_lzcnt;
+ bool platform_is_windows;
+ bool ref_types_enabled;
+ bool threads_enabled;
+ bool v128_enabled;
+ size_t static_memory_bound;
+ size_t memory_guard_size;
+ size_t memory_base_tls_offset;
+ size_t instance_tls_offset;
+ size_t interrupt_tls_offset;
+ size_t cx_tls_offset;
+ size_t realm_cx_offset;
+ size_t realm_tls_offset;
+ size_t realm_func_import_tls_offset;
+ size_t size_of_wasm_frame;
+
+ // Not bindgen'd because it's inlined.
+ inline CraneliftStaticEnvironment();
+};
+
+// This structure proxies the C++ ModuleEnvironment and the information it
+// contains.
+
+struct CraneliftModuleEnvironment {
+ // This is a pointer and not a reference to work-around a bug in bindgen.
+ const js::wasm::ModuleEnvironment* env;
+ uint32_t min_memory_length;
+
+ // Not bindgen'd because it's inlined.
+ explicit inline CraneliftModuleEnvironment(
+ const js::wasm::ModuleEnvironment& env);
+};
+
+struct BD_Stackmaps;
+
+// Data for a single wasm function to be compiled by Cranelift.
+// This information is all from the corresponding `js::wasm::FuncCompileInput`
+// struct, but formatted in a Rust-friendly way.
+
+struct CraneliftFuncCompileInput {
+ const uint8_t* bytecode;
+ size_t bytecode_size;
+ uint32_t index;
+ uint32_t offset_in_module;
+
+ // The stackmaps sink to use when compiling this function.
+ BD_Stackmaps* stackmaps;
+
+ // Not bindgen'd because it's inlined.
+ explicit inline CraneliftFuncCompileInput(const js::wasm::FuncCompileInput&);
+};
+
+// A single entry in all the metadata array provided after the compilation of a
+// single wasm function. The meaning of the field extra depends on the enum
+// value.
+//
+// XXX should we use a union for this instead? bindgen seems to be able to
+// handle them, with a lot of unsafe'ing.
+
+struct CraneliftMetadataEntry {
+ enum Which { DirectCall, IndirectCall, Trap, SymbolicAccess } which;
+ uint32_t code_offset;
+ uint32_t module_bytecode_offset;
+ size_t extra;
+};
+
+// The result of a single function compilation, containing the machine code
+// generated by Cranelift, as well as some useful metadata to generate the
+// prologue/epilogue etc.
+
+struct CraneliftCompiledFunc {
+ size_t num_metadata;
+ const CraneliftMetadataEntry* metadatas;
+
+ size_t frame_pushed;
+ bool contains_calls;
+
+ // The compiled code comprises machine code, relocatable jump tables, and
+ // copyable read-only data, concatenated without padding. The "...Size"
+ // members give the sizes of the individual sections. The code starts at
+ // offsets 0; the other offsets can be derived from the sizes.
+ const uint8_t* code;
+ size_t code_size;
+ size_t jumptables_size;
+ size_t rodata_size;
+ size_t total_size;
+
+ // Relocation information for instructions that reference into the jump tables
+ // and read-only data segments. The relocation information is
+ // machine-specific.
+ size_t num_rodata_relocs;
+ const uint32_t* rodata_relocs;
+};
+
+// Possible constant values for initializing globals.
+
+struct BD_ConstantValue {
+ js::wasm::TypeCode t;
+ union {
+ int32_t i32;
+ int64_t i64;
+ float f32;
+ double f64;
+ void* r;
+ uint8_t v128[16]; // Little-endian
+ } u;
+};
+
+struct BD_ValType {
+ uint32_t packed;
+};
+
+// A subset of the wasm SymbolicAddress enum. This is converted to wasm using
+// ToSymbolicAddress in WasmCraneliftCompile.
+
+enum class BD_SymbolicAddress : uint32_t {
+ MemoryGrow = 0,
+ MemorySize,
+ MemoryCopy,
+ MemoryCopyShared,
+ DataDrop,
+ MemoryFill,
+ MemoryFillShared,
+ MemoryInit,
+ TableSize,
+ TableGrow,
+ TableGet,
+ TableSet,
+ TableCopy,
+ TableFill,
+ TableInit,
+ ElemDrop,
+ RefFunc,
+ FloorF32,
+ FloorF64,
+ CeilF32,
+ CeilF64,
+ NearestF32,
+ NearestF64,
+ TruncF32,
+ TruncF64,
+ PreBarrier,
+ PostBarrier,
+ WaitI32,
+ WaitI64,
+ Wake,
+ Limit
+};
+
+extern "C" {
+js::wasm::TypeCode env_unpack(BD_ValType type);
+
+size_t env_num_tables(const CraneliftModuleEnvironment* env);
+size_t env_num_globals(const CraneliftModuleEnvironment* env);
+size_t env_num_types(const CraneliftModuleEnvironment* env);
+size_t env_num_funcs(const CraneliftModuleEnvironment* env);
+size_t env_num_elems(const CraneliftModuleEnvironment* env);
+size_t env_num_datas(const CraneliftModuleEnvironment* env);
+js::wasm::TypeCode env_elem_typecode(const CraneliftModuleEnvironment* env,
+ uint32_t index);
+bool env_is_func_valid_for_ref(const CraneliftModuleEnvironment* env,
+ uint32_t index);
+/// Returns the maximum memory size as an uint32, or UINT32_MAX if not defined.
+uint32_t env_max_memory(const CraneliftModuleEnvironment* env);
+
+bool env_uses_shared_memory(const CraneliftModuleEnvironment* env);
+bool env_has_memory(const CraneliftModuleEnvironment* env);
+const js::wasm::FuncType* env_type(const CraneliftModuleEnvironment* env,
+ size_t typeIndex);
+const js::wasm::FuncType* env_func_sig(const CraneliftModuleEnvironment* env,
+ size_t funcIndex);
+const js::wasm::TypeIdDesc* env_func_sig_id(
+ const CraneliftModuleEnvironment* env, size_t funcIndex);
+size_t env_func_sig_index(const CraneliftModuleEnvironment* env,
+ size_t funcIndex);
+size_t env_func_import_tls_offset(const CraneliftModuleEnvironment* env,
+ size_t funcIndex);
+bool env_func_is_import(const CraneliftModuleEnvironment* env,
+ size_t funcIndex);
+const js::wasm::FuncType* env_signature(const CraneliftModuleEnvironment* env,
+ size_t sigIndex);
+const js::wasm::TypeIdDesc* env_signature_id(
+ const CraneliftModuleEnvironment* env, size_t sigIndex);
+const js::wasm::TableDesc* env_table(const CraneliftModuleEnvironment* env,
+ size_t tableIndex);
+const js::wasm::GlobalDesc* env_global(const CraneliftModuleEnvironment* env,
+ size_t globalIndex);
+
+bool global_isConstant(const js::wasm::GlobalDesc*);
+bool global_isIndirect(const js::wasm::GlobalDesc*);
+BD_ConstantValue global_constantValue(const js::wasm::GlobalDesc*);
+js::wasm::TypeCode global_type(const js::wasm::GlobalDesc*);
+size_t global_tlsOffset(const js::wasm::GlobalDesc*);
+
+size_t table_tlsOffset(const js::wasm::TableDesc*);
+uint32_t table_initialLimit(const js::wasm::TableDesc*);
+// Returns the maximum limit as an uint32, or UINT32_MAX if not defined.
+uint32_t table_maximumLimit(const js::wasm::TableDesc*);
+js::wasm::TypeCode table_elementTypeCode(const js::wasm::TableDesc*);
+
+size_t funcType_numArgs(const js::wasm::FuncType*);
+const BD_ValType* funcType_args(const js::wasm::FuncType*);
+size_t funcType_numResults(const js::wasm::FuncType*);
+const BD_ValType* funcType_results(const js::wasm::FuncType*);
+
+js::wasm::TypeIdDescKind funcType_idKind(const js::wasm::TypeIdDesc*);
+size_t funcType_idImmediate(const js::wasm::TypeIdDesc*);
+size_t funcType_idTlsOffset(const js::wasm::TypeIdDesc*);
+
+void stackmaps_add(BD_Stackmaps* sink, const uint32_t* bitMap,
+ size_t mappedWords, size_t argsSize, size_t codeOffset);
+
+} // extern "C"
+
+#endif // wasm_cranelift_baldrapi_h