Mypal/js/src/wasm/WasmJS.h

268 lines
9.5 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_js_h
#define wasm_js_h
#include "gc/Policy.h"
#include "vm/NativeObject.h"
#include "wasm/WasmTypes.h"
namespace js {
class TypedArrayObject;
namespace wasm {
// Creates a testing-only NaN JS object with fields as described above, for
// T=float or T=double.
template<typename T>
JSObject*
CreateCustomNaNObject(JSContext* cx, T* addr);
// Converts a testing-only NaN JS object with a nan_low field to a float32 NaN
// with nan_low as the payload.
bool
ReadCustomFloat32NaNObject(JSContext* cx, HandleValue v, uint32_t* ret);
// Converts a testing-only NaN JS object with nan_{low,high} components to a
// double NaN with nan_low|(nan_high)>>32 as the payload.
bool
ReadCustomDoubleNaNObject(JSContext* cx, HandleValue v, uint64_t* ret);
// Creates a JS object containing two fields (low: low 32 bits; high: high 32
// bits) of a given Int64 value. For testing purposes only.
JSObject*
CreateI64Object(JSContext* cx, int64_t i64);
// Reads an int64 from a JS object with the same shape as described in the
// comment above. For testing purposes only.
bool
ReadI64Object(JSContext* cx, HandleValue v, int64_t* i64);
// Return whether WebAssembly can be compiled on this platform.
// This must be checked and must be true to call any of the top-level wasm
// eval/compile methods.
bool
HasCompilerSupport(ExclusiveContext* cx);
// Return whether WebAssembly is enabled on this platform.
bool
HasSupport(ExclusiveContext* cx);
// Compiles the given binary wasm module given the ArrayBufferObject
// and links the module's imports with the given import object.
MOZ_MUST_USE bool
Eval(JSContext* cx, Handle<TypedArrayObject*> code, HandleObject importObj,
MutableHandleWasmInstanceObject instanceObj);
// The field name of the export object on the instance object.
extern const char InstanceExportField[];
// These accessors can be used to probe JS values for being an exported wasm
// function.
extern bool
IsExportedFunction(JSFunction* fun);
extern bool
IsExportedWasmFunction(JSFunction* fun);
extern bool
IsExportedFunction(const Value& v, MutableHandleFunction f);
extern Instance&
ExportedFunctionToInstance(JSFunction* fun);
extern WasmInstanceObject*
ExportedFunctionToInstanceObject(JSFunction* fun);
extern uint32_t
ExportedFunctionToFuncIndex(JSFunction* fun);
} // namespace wasm
// The class of the WebAssembly global namespace object.
extern const Class WebAssemblyClass;
JSObject*
InitWebAssemblyClass(JSContext* cx, HandleObject global);
// The class of WebAssembly.Module. Each WasmModuleObject owns a
// wasm::Module. These objects are used both as content-facing JS objects and as
// internal implementation details of asm.js.
class WasmModuleObject : public NativeObject
{
static const unsigned MODULE_SLOT = 0;
static const ClassOps classOps_;
static void finalize(FreeOp* fop, JSObject* obj);
static bool imports(JSContext* cx, unsigned argc, Value* vp);
static bool exports(JSContext* cx, unsigned argc, Value* vp);
public:
static const unsigned RESERVED_SLOTS = 1;
static const Class class_;
static const JSPropertySpec properties[];
static const JSFunctionSpec methods[];
static const JSFunctionSpec static_methods[];
static bool construct(JSContext*, unsigned, Value*);
static WasmModuleObject* create(ExclusiveContext* cx,
wasm::Module& module,
HandleObject proto = nullptr);
wasm::Module& module() const;
};
// The class of WebAssembly.Instance. Each WasmInstanceObject owns a
// wasm::Instance. These objects are used both as content-facing JS objects and
// as internal implementation details of asm.js.
class WasmInstanceObject : public NativeObject
{
static const unsigned INSTANCE_SLOT = 0;
static const unsigned EXPORTS_SLOT = 1;
static const ClassOps classOps_;
bool isNewborn() const;
static void finalize(FreeOp* fop, JSObject* obj);
static void trace(JSTracer* trc, JSObject* obj);
// ExportMap maps from function definition index to exported function
// object. This map is weak to avoid holding objects alive; the point is
// just to ensure a unique object identity for any given function object.
using ExportMap = GCHashMap<uint32_t,
ReadBarrieredFunction,
DefaultHasher<uint32_t>,
SystemAllocPolicy>;
using WeakExportMap = JS::WeakCache<ExportMap>;
WeakExportMap& exports() const;
public:
static const unsigned RESERVED_SLOTS = 2;
static const Class class_;
static const JSPropertySpec properties[];
static const JSFunctionSpec methods[];
static const JSFunctionSpec static_methods[];
static bool construct(JSContext*, unsigned, Value*);
static WasmInstanceObject* create(JSContext* cx,
UniquePtr<wasm::Code> code,
HandleWasmMemoryObject memory,
Vector<RefPtr<wasm::Table>, 0, SystemAllocPolicy>&& tables,
Handle<FunctionVector> funcImports,
const wasm::ValVector& globalImports,
HandleObject proto);
wasm::Instance& instance() const;
static bool getExportedFunction(JSContext* cx,
HandleWasmInstanceObject instanceObj,
uint32_t funcIndex,
MutableHandleFunction fun);
const wasm::CodeRange& getExportedFunctionCodeRange(HandleFunction fun);
};
// The class of WebAssembly.Memory. A WasmMemoryObject references an ArrayBuffer
// or SharedArrayBuffer object which owns the actual memory.
class WasmMemoryObject : public NativeObject
{
static const unsigned BUFFER_SLOT = 0;
static const unsigned OBSERVERS_SLOT = 1;
static const ClassOps classOps_;
static void finalize(FreeOp* fop, JSObject* obj);
static bool bufferGetterImpl(JSContext* cx, const CallArgs& args);
static bool bufferGetter(JSContext* cx, unsigned argc, Value* vp);
static bool growImpl(JSContext* cx, const CallArgs& args);
static bool grow(JSContext* cx, unsigned argc, Value* vp);
using InstanceSet = GCHashSet<ReadBarrieredWasmInstanceObject,
MovableCellHasher<ReadBarrieredWasmInstanceObject>,
SystemAllocPolicy>;
using WeakInstanceSet = JS::WeakCache<InstanceSet>;
bool hasObservers() const;
WeakInstanceSet& observers() const;
WeakInstanceSet* getOrCreateObservers(JSContext* cx);
public:
static const unsigned RESERVED_SLOTS = 2;
static const Class class_;
static const JSPropertySpec properties[];
static const JSFunctionSpec methods[];
static const JSFunctionSpec static_methods[];
static bool construct(JSContext*, unsigned, Value*);
static WasmMemoryObject* create(ExclusiveContext* cx,
Handle<ArrayBufferObjectMaybeShared*> buffer,
HandleObject proto);
ArrayBufferObjectMaybeShared& buffer() const;
bool movingGrowable() const;
bool addMovingGrowObserver(JSContext* cx, WasmInstanceObject* instance);
static uint32_t grow(HandleWasmMemoryObject memory, uint32_t delta, JSContext* cx);
};
// The class of WebAssembly.Table. A WasmTableObject holds a refcount on a
// wasm::Table, allowing a Table to be shared between multiple Instances
// (eventually between multiple threads).
class WasmTableObject : public NativeObject
{
static const unsigned TABLE_SLOT = 0;
static const ClassOps classOps_;
bool isNewborn() const;
static void finalize(FreeOp* fop, JSObject* obj);
static void trace(JSTracer* trc, JSObject* obj);
static bool lengthGetterImpl(JSContext* cx, const CallArgs& args);
static bool lengthGetter(JSContext* cx, unsigned argc, Value* vp);
static bool getImpl(JSContext* cx, const CallArgs& args);
static bool get(JSContext* cx, unsigned argc, Value* vp);
static bool setImpl(JSContext* cx, const CallArgs& args);
static bool set(JSContext* cx, unsigned argc, Value* vp);
static bool growImpl(JSContext* cx, const CallArgs& args);
static bool grow(JSContext* cx, unsigned argc, Value* vp);
public:
static const unsigned RESERVED_SLOTS = 1;
static const Class class_;
static const JSPropertySpec properties[];
static const JSFunctionSpec methods[];
static const JSFunctionSpec static_methods[];
static bool construct(JSContext*, unsigned, Value*);
// Note that, after creation, a WasmTableObject's table() is not initialized
// and must be initialized before use.
static WasmTableObject* create(JSContext* cx, wasm::Limits limits);
wasm::Table& table() const;
};
} // namespace js
#endif // wasm_js_h