diff options
Diffstat (limited to 'js/src/wasm/WasmJS.h')
-rw-r--r-- | js/src/wasm/WasmJS.h | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/js/src/wasm/WasmJS.h b/js/src/wasm/WasmJS.h new file mode 100644 index 000000000..5480797c5 --- /dev/null +++ b/js/src/wasm/WasmJS.h @@ -0,0 +1,267 @@ +/* -*- 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 |