146 lines
5.7 KiB
C++
146 lines
5.7 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
|
*
|
|
* Copyright 2016 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.
|
|
*/
|
|
|
|
#ifndef wasm_instance_h
|
|
#define wasm_instance_h
|
|
|
|
#include "gc/Barrier.h"
|
|
#include "wasm/WasmCode.h"
|
|
#include "wasm/WasmTable.h"
|
|
|
|
namespace js {
|
|
namespace wasm {
|
|
|
|
// Instance represents a wasm instance and provides all the support for runtime
|
|
// execution of code in the instance. Instances share various immutable data
|
|
// structures with the Module from which they were instantiated and other
|
|
// instances instantiated from the same Module. However, an Instance has no
|
|
// direct reference to its source Module which allows a Module to be destroyed
|
|
// while it still has live Instances.
|
|
|
|
class Instance
|
|
{
|
|
JSCompartment* const compartment_;
|
|
ReadBarrieredWasmInstanceObject object_;
|
|
const UniqueCode code_;
|
|
GCPtrWasmMemoryObject memory_;
|
|
SharedTableVector tables_;
|
|
TlsData tlsData_;
|
|
|
|
// Internal helpers:
|
|
const void** addressOfSigId(const SigIdDesc& sigId) const;
|
|
FuncImportTls& funcImportTls(const FuncImport& fi);
|
|
TableTls& tableTls(const TableDesc& td) const;
|
|
|
|
// Import call slow paths which are called directly from wasm code.
|
|
friend void* AddressOf(SymbolicAddress, ExclusiveContext*);
|
|
static int32_t callImport_void(Instance*, int32_t, int32_t, uint64_t*);
|
|
static int32_t callImport_i32(Instance*, int32_t, int32_t, uint64_t*);
|
|
static int32_t callImport_i64(Instance*, int32_t, int32_t, uint64_t*);
|
|
static int32_t callImport_f64(Instance*, int32_t, int32_t, uint64_t*);
|
|
static uint32_t growMemory_i32(Instance* instance, uint32_t delta);
|
|
static uint32_t currentMemory_i32(Instance* instance);
|
|
bool callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc, const uint64_t* argv,
|
|
MutableHandleValue rval);
|
|
|
|
// Only WasmInstanceObject can call the private trace function.
|
|
friend class js::WasmInstanceObject;
|
|
void tracePrivate(JSTracer* trc);
|
|
|
|
public:
|
|
Instance(JSContext* cx,
|
|
HandleWasmInstanceObject object,
|
|
UniqueCode code,
|
|
HandleWasmMemoryObject memory,
|
|
SharedTableVector&& tables,
|
|
Handle<FunctionVector> funcImports,
|
|
const ValVector& globalImports);
|
|
~Instance();
|
|
bool init(JSContext* cx);
|
|
void trace(JSTracer* trc);
|
|
|
|
JSContext* cx() const { return tlsData_.cx; }
|
|
JSCompartment* compartment() const { return compartment_; }
|
|
Code& code() { return *code_; }
|
|
const Code& code() const { return *code_; }
|
|
const CodeSegment& codeSegment() const { return code_->segment(); }
|
|
uint8_t* codeBase() const { return code_->segment().base(); }
|
|
const Metadata& metadata() const { return code_->metadata(); }
|
|
bool isAsmJS() const { return metadata().isAsmJS(); }
|
|
const SharedTableVector& tables() const { return tables_; }
|
|
SharedMem<uint8_t*> memoryBase() const;
|
|
size_t memoryLength() const;
|
|
size_t memoryMappedSize() const;
|
|
bool memoryAccessInGuardRegion(uint8_t* addr, unsigned numBytes) const;
|
|
TlsData& tlsData() { return tlsData_; }
|
|
|
|
// This method returns a pointer to the GC object that owns this Instance.
|
|
// Instances may be reached via weak edges (e.g., Compartment::instances_)
|
|
// so this perform a read-barrier on the returned object unless the barrier
|
|
// is explicitly waived.
|
|
|
|
WasmInstanceObject* object() const;
|
|
WasmInstanceObject* objectUnbarriered() const;
|
|
|
|
// Execute the given export given the JS call arguments, storing the return
|
|
// value in args.rval.
|
|
|
|
MOZ_MUST_USE bool callExport(JSContext* cx, uint32_t funcIndex, CallArgs args);
|
|
|
|
// Initially, calls to imports in wasm code call out through the generic
|
|
// callImport method. If the imported callee gets JIT compiled and the types
|
|
// match up, callImport will patch the code to instead call through a thunk
|
|
// directly into the JIT code. If the JIT code is released, the Instance must
|
|
// be notified so it can go back to the generic callImport.
|
|
|
|
void deoptimizeImportExit(uint32_t funcImportIndex);
|
|
|
|
// Called by simulators to check whether accessing 'numBytes' starting at
|
|
// 'addr' would trigger a fault and be safely handled by signal handlers.
|
|
|
|
bool memoryAccessWouldFault(uint8_t* addr, unsigned numBytes);
|
|
|
|
// Called by Wasm(Memory|Table)Object when a moving resize occurs:
|
|
|
|
void onMovingGrowMemory(uint8_t* prevMemoryBase);
|
|
void onMovingGrowTable();
|
|
|
|
// See Code::ensureProfilingState comment.
|
|
|
|
MOZ_MUST_USE bool ensureProfilingState(JSContext* cx, bool enabled);
|
|
|
|
// about:memory reporting:
|
|
|
|
void addSizeOfMisc(MallocSizeOf mallocSizeOf,
|
|
Metadata::SeenSet* seenMetadata,
|
|
ShareableBytes::SeenSet* seenBytes,
|
|
Table::SeenSet* seenTables,
|
|
size_t* code,
|
|
size_t* data) const;
|
|
};
|
|
|
|
typedef UniquePtr<Instance> UniqueInstance;
|
|
|
|
bool InitInstanceStaticData();
|
|
void ShutDownInstanceStaticData();
|
|
|
|
} // namespace wasm
|
|
} // namespace js
|
|
|
|
#endif // wasm_instance_h
|