blob: 89030152770198331e1fc07d0acee0c73eb14e5d [file] [log] [blame]
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +00001/*
mark.lam@apple.com17ae4902021-02-19 15:51:15 +00002 * Copyright (C) 2017-2021 Apple Inc. All rights reserved.
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +00003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#if ENABLE(WEBASSEMBLY)
29
30#include "WasmFormat.h"
31#include "WasmLimits.h"
justin_michaud@apple.com1f3b5212019-06-06 03:14:47 +000032#include "WriteBarrier.h"
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +000033#include <wtf/MallocPtr.h>
34#include <wtf/Optional.h>
35#include <wtf/Ref.h>
36#include <wtf/ThreadSafeRefCounted.h>
37
jfbastien@apple.com89177d32017-10-26 15:33:55 +000038namespace JSC { namespace Wasm {
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +000039
jfbastien@apple.com89177d32017-10-26 15:33:55 +000040class Instance;
justin_michaud@apple.com1f3b5212019-06-06 03:14:47 +000041class FuncRefTable;
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +000042
43class Table : public ThreadSafeRefCounted<Table> {
justin_michaud@apple.com1f3b5212019-06-06 03:14:47 +000044 WTF_MAKE_NONCOPYABLE(Table);
45 WTF_MAKE_FAST_ALLOCATED(Table);
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +000046public:
justin_michaud@apple.com1f3b5212019-06-06 03:14:47 +000047 static RefPtr<Table> tryCreate(uint32_t initial, Optional<uint32_t> maximum, TableElementType);
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +000048
justin_michaud@apple.com1f3b5212019-06-06 03:14:47 +000049 JS_EXPORT_PRIVATE ~Table() = default;
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +000050
cdumez@apple.com8b7a0222018-12-20 04:41:11 +000051 Optional<uint32_t> maximum() const { return m_maximum; }
jfbastien@apple.comc384fff2018-01-09 07:10:36 +000052 uint32_t length() const { return m_length; }
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +000053
jfbastien@apple.comc384fff2018-01-09 07:10:36 +000054 static ptrdiff_t offsetOfLength() { return OBJECT_OFFSETOF(Table, m_length); }
55 static ptrdiff_t offsetOfMask() { return OBJECT_OFFSETOF(Table, m_mask); }
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +000056
jfbastien@apple.comc384fff2018-01-09 07:10:36 +000057 static uint32_t allocatedLength(uint32_t length);
58 uint32_t mask() const { return m_mask; }
justin_michaud@apple.com1f3b5212019-06-06 03:14:47 +000059
justin_michaud@apple.com6cae9352019-06-18 22:01:02 +000060 template<typename T> T* owner() const { return reinterpret_cast<T*>(m_owner); }
justin_michaud@apple.com1f3b5212019-06-06 03:14:47 +000061 void setOwner(JSObject* owner)
62 {
63 ASSERT(!m_owner);
64 ASSERT(owner);
65 m_owner = owner;
66 }
67
68 TableElementType type() const { return m_type; }
commit-queue@webkit.orgc53450d2020-11-07 01:10:50 +000069 bool isExternrefTable() const { return m_type == TableElementType::Externref; }
commit-queue@webkit.org91d305a2021-01-08 18:18:06 +000070 bool isFuncrefTable() const { return m_type == TableElementType::Funcref; }
commit-queue@webkit.org2b24f922021-01-29 19:26:36 +000071 Type wasmType() const;
justin_michaud@apple.com1f3b5212019-06-06 03:14:47 +000072 FuncRefTable* asFuncrefTable();
73
jfbastien@apple.comc384fff2018-01-09 07:10:36 +000074 static bool isValidLength(uint32_t length) { return length < maxTableEntries; }
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +000075
justin_michaud@apple.com1f3b5212019-06-06 03:14:47 +000076 void clear(uint32_t);
77 void set(uint32_t, JSValue);
78 JSValue get(uint32_t) const;
79
commit-queue@webkit.org91d305a2021-01-08 18:18:06 +000080 Optional<uint32_t> grow(uint32_t delta, JSValue defaultValue);
commit-queue@webkit.org0198ce72020-12-07 22:26:48 +000081 void copy(const Table* srcTable, uint32_t dstIndex, uint32_t srcIndex);
justin_michaud@apple.com1f3b5212019-06-06 03:14:47 +000082
mark.lam@apple.com17ae4902021-02-19 15:51:15 +000083 DECLARE_VISIT_AGGREGATE;
justin_michaud@apple.com1f3b5212019-06-06 03:14:47 +000084
85protected:
commit-queue@webkit.orgc53450d2020-11-07 01:10:50 +000086 Table(uint32_t initial, Optional<uint32_t> maximum, TableElementType = TableElementType::Externref);
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +000087
jfbastien@apple.comc384fff2018-01-09 07:10:36 +000088 void setLength(uint32_t);
89
justin_michaud@apple.com1f3b5212019-06-06 03:14:47 +000090 uint32_t m_length;
91 uint32_t m_mask;
92 const TableElementType m_type;
93 const Optional<uint32_t> m_maximum;
94
ysuzuki@apple.com4642e112020-01-03 02:36:43 +000095 MallocPtr<WriteBarrier<Unknown>, VMMalloc> m_jsValues;
justin_michaud@apple.com1f3b5212019-06-06 03:14:47 +000096 JSObject* m_owner;
97};
98
99class FuncRefTable : public Table {
100public:
101 JS_EXPORT_PRIVATE ~FuncRefTable() = default;
102
103 void setFunction(uint32_t, JSObject*, WasmToWasmImportableFunction, Instance*);
tzagallo@apple.combf01be22019-10-31 22:32:52 +0000104 const WasmToWasmImportableFunction& function(uint32_t) const;
105 Instance* instance(uint32_t) const;
justin_michaud@apple.com1f3b5212019-06-06 03:14:47 +0000106
commit-queue@webkit.org0198ce72020-12-07 22:26:48 +0000107 void copyFunction(const FuncRefTable* srcTable, uint32_t dstIndex, uint32_t srcIndex);
108
justin_michaud@apple.com1f3b5212019-06-06 03:14:47 +0000109 static ptrdiff_t offsetOfFunctions() { return OBJECT_OFFSETOF(FuncRefTable, m_importableFunctions); }
110 static ptrdiff_t offsetOfInstances() { return OBJECT_OFFSETOF(FuncRefTable, m_instances); }
111
112private:
113 FuncRefTable(uint32_t initial, Optional<uint32_t> maximum);
114
ysuzuki@apple.com4642e112020-01-03 02:36:43 +0000115 MallocPtr<WasmToWasmImportableFunction, VMMalloc> m_importableFunctions;
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +0000116 // call_indirect needs to do an Instance check to potentially context switch when calling a function to another instance. We can hold raw pointers to Instance here because the embedder ensures that Table keeps all the instances alive. We couldn't hold a Ref here because it would cause cycles.
ysuzuki@apple.com4642e112020-01-03 02:36:43 +0000117 MallocPtr<Instance*, VMMalloc> m_instances;
justin_michaud@apple.com1f3b5212019-06-06 03:14:47 +0000118
119 friend class Table;
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +0000120};
121
122} } // namespace JSC::Wasm
123
124#endif // ENABLE(WEBASSEMBLY)