-
Notifications
You must be signed in to change notification settings - Fork 883
Expand file tree
/
Copy pathjs-utils.h
More file actions
137 lines (128 loc) · 4.08 KB
/
Copy pathjs-utils.h
File metadata and controls
137 lines (128 loc) · 4.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
* Copyright 2026 WebAssembly Community Group participants
*
* 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_ir_js_utils_h
#define wasm_ir_js_utils_h
#include "ir/intrinsics.h"
#include "wasm-type.h"
#include "wasm.h"
namespace wasm::JSUtils {
// Whether a field is immutable and a reference to a subtype of externref that
// could hold a JS prototype.
inline bool isPossibleJSPrototypeField(const Field& field) {
if (field.mutable_ != Immutable) {
return false;
}
if (!field.type.isRef()) {
return false;
}
return field.type.getHeapType().isMaybeShared(HeapType::ext);
}
// Whether this is a descriptor struct type whose first field is immutable and a
// subtype of externref.
inline bool hasPossibleJSPrototypeField(HeapType type) {
if (!type.getDescribedType()) {
return false;
}
assert(type.isStruct());
const auto& fields = type.getStruct().fields;
if (fields.empty()) {
return false;
}
return isPossibleJSPrototypeField(fields[0]);
}
// Calls flowIn and flowOut on all types that may flow in from or out to JS.
template<typename In, typename Out>
void iterJSInterface(const Module& wasm, In flowIn, Out flowOut) {
// @binaryen.js.called functions are called from JS. Their parameters flow
// in from JS and their results flow back out.
for (auto f : Intrinsics(wasm).getJSCalledFunctions()) {
auto* func = wasm.getFunction(f);
for (auto type : func->getParams()) {
flowIn(type);
}
for (auto type : func->getResults()) {
flowOut(type);
}
}
for (auto& ex : wasm.exports) {
switch (ex->kind) {
case ExternalKindImpl::Function: {
// Exported functions are also called from JS. Their parameters flow
// in from JS and their result flow back out.
auto* func = wasm.getFunction(*ex->getInternalName());
for (auto type : func->getParams()) {
flowIn(type);
}
for (auto type : func->getResults()) {
flowOut(type);
}
break;
}
case ExternalKindImpl::Table: {
// Exported tables let values flow in and out.
auto* table = wasm.getTable(*ex->getInternalName());
flowOut(table->type);
flowIn(table->type);
break;
}
case ExternalKindImpl::Global: {
// Exported globals let values flow out. Iff they are mutable, they
// also let values flow back in.
auto* global = wasm.getGlobal(*ex->getInternalName());
flowOut(global->type);
if (global->mutable_) {
flowIn(global->type);
}
break;
}
case ExternalKindImpl::Memory:
case ExternalKindImpl::Tag:
case ExternalKindImpl::Invalid:
break;
}
}
for (auto& func : wasm.functions) {
// Imported functions are the opposite of exported functions. Their
// parameters flow out and their results flow in.
if (func->imported()) {
for (auto type : func->getParams()) {
flowOut(type);
}
for (auto type : func->getResults()) {
flowIn(type);
}
}
}
for (auto& table : wasm.tables) {
// Imported tables, like exported tables, let values flow in and out.
if (table->imported()) {
flowOut(table->type);
flowIn(table->type);
}
}
for (auto& global : wasm.globals) {
// Imported mutable globals let values flow in and out. Imported immutable
// globals imply that values will flow in.
if (global->imported()) {
flowIn(global->type);
if (global->mutable_) {
flowOut(global->type);
}
}
}
}
} // namespace wasm::JSUtils
#endif // wasm_ir_js_utils_h