1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * 4 * Copyright 2016 Mozilla Foundation 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 #ifndef wasm_table_h 20 #define wasm_table_h 21 22 #include "gc/Policy.h" 23 #include "wasm/WasmCode.h" 24 25 namespace js { 26 namespace wasm { 27 28 // A Table is an indexable array of opaque values. Tables are first-class 29 // stateful objects exposed to WebAssembly. asm.js also uses Tables to represent 30 // its homogeneous function-pointer tables. 31 // 32 // A table of FuncRef holds FunctionTableElems, which are (code*,tls*) pairs, 33 // where the tls must be traced. 34 // 35 // A table of AnyRef holds JSObject pointers, which must be traced. 36 37 // TODO/AnyRef-boxing: With boxed immediates and strings, JSObject* is no longer 38 // the most appropriate representation for Cell::anyref. 39 STATIC_ASSERT_ANYREF_IS_JSOBJECT; 40 41 using TableAnyRefVector = GCVector<HeapPtr<JSObject*>, 0, SystemAllocPolicy>; 42 43 class Table : public ShareableBase<Table> { 44 using InstanceSet = 45 JS::WeakCache<GCHashSet<WeakHeapPtrWasmInstanceObject, 46 MovableCellHasher<WeakHeapPtrWasmInstanceObject>, 47 SystemAllocPolicy>>; 48 using UniqueFuncRefArray = UniquePtr<FunctionTableElem[], JS::FreePolicy>; 49 50 WeakHeapPtrWasmTableObject maybeObject_; 51 InstanceSet observers_; 52 UniqueFuncRefArray functions_; // either functions_ has data 53 TableAnyRefVector objects_; // or objects_, but not both 54 const RefType elemType_; 55 const bool isAsmJS_; 56 uint32_t length_; 57 const Maybe<uint32_t> maximum_; 58 59 template <class> 60 friend struct js::MallocProvider; 61 Table(JSContext* cx, const TableDesc& desc, HandleWasmTableObject maybeObject, 62 UniqueFuncRefArray functions); 63 Table(JSContext* cx, const TableDesc& desc, HandleWasmTableObject maybeObject, 64 TableAnyRefVector&& objects); 65 66 void tracePrivate(JSTracer* trc); 67 friend class js::WasmTableObject; 68 69 public: 70 static RefPtr<Table> create(JSContext* cx, const TableDesc& desc, 71 HandleWasmTableObject maybeObject); 72 void trace(JSTracer* trc); 73 elemType()74 RefType elemType() const { return elemType_; } repr()75 TableRepr repr() const { return elemType_.tableRepr(); } 76 isAsmJS()77 bool isAsmJS() const { 78 MOZ_ASSERT(elemType_.isFunc()); 79 return isAsmJS_; 80 } isFunction()81 bool isFunction() const { return elemType().isFunc(); } length()82 uint32_t length() const { return length_; } maximum()83 Maybe<uint32_t> maximum() const { return maximum_; } 84 85 // Only for function values. Raw pointer to the table. 86 uint8_t* functionBase() const; 87 88 // set/get/fillFuncRef is allowed only on table-of-funcref. 89 // get/fillAnyRef is allowed only on table-of-anyref. 90 // setNull is allowed on either. 91 92 const FunctionTableElem& getFuncRef(uint32_t index) const; 93 bool getFuncRef(JSContext* cx, uint32_t index, 94 MutableHandleFunction fun) const; 95 void setFuncRef(uint32_t index, void* code, const Instance* instance); 96 void fillFuncRef(uint32_t index, uint32_t fillCount, FuncRef ref, 97 JSContext* cx); 98 99 AnyRef getAnyRef(uint32_t index) const; 100 void fillAnyRef(uint32_t index, uint32_t fillCount, AnyRef ref); 101 102 void setNull(uint32_t index); 103 104 // Copy entry from |srcTable| at |srcIndex| to this table at |dstIndex|. Used 105 // by table.copy. May OOM if it needs to box up a function during an upcast. 106 bool copy(const Table& srcTable, uint32_t dstIndex, uint32_t srcIndex); 107 108 // grow() returns (uint32_t)-1 if it could not grow. 109 uint32_t grow(uint32_t delta); 110 bool movingGrowable() const; 111 bool addMovingGrowObserver(JSContext* cx, WasmInstanceObject* instance); 112 113 // about:memory reporting: 114 115 size_t sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const; 116 117 size_t gcMallocBytes() const; 118 }; 119 120 using SharedTable = RefPtr<Table>; 121 using SharedTableVector = Vector<SharedTable, 0, SystemAllocPolicy>; 122 123 } // namespace wasm 124 } // namespace js 125 126 #endif // wasm_table_h 127