Skip to content

Commit 6d92ba9

Browse files
authored
LiteralList => Literals (WebAssembly#4451)
LiteralList overlaps with Literals, but is less efficient as it is not a SmallVector. Add reserve/capacity methods to SmallVector which are now necessary to compile.
1 parent 3168fa2 commit 6d92ba9

7 files changed

Lines changed: 46 additions & 31 deletions

File tree

src/shell-interface.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ struct ShellExternalInterface : ModuleInstance::ExternalInterface {
133133
});
134134
}
135135

136-
Literals callImport(Function* import, LiteralList& arguments) override {
136+
Literals callImport(Function* import, Literals& arguments) override {
137137
if (import->module == SPECTEST && import->base.startsWith(PRINT)) {
138138
for (auto argument : arguments) {
139139
std::cout << argument << " : " << argument.type << '\n';
@@ -153,7 +153,7 @@ struct ShellExternalInterface : ModuleInstance::ExternalInterface {
153153
Literals callTable(Name tableName,
154154
Index index,
155155
HeapType sig,
156-
LiteralList& arguments,
156+
Literals& arguments,
157157
Type results,
158158
ModuleInstance& instance) override {
159159

src/support/small_vector.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,14 @@ template<typename T, size_t N> class SmallVector {
119119
}
120120
}
121121

122+
void reserve(size_t reservedSize) {
123+
if (reservedSize > N) {
124+
flexible.reserve(reservedSize - N);
125+
}
126+
}
127+
128+
size_t capacity() const { return N + flexible.capacity(); }
129+
122130
bool operator==(const SmallVector<T, N>& other) const {
123131
if (usedFixed != other.usedFixed) {
124132
return false;

src/tools/execution-results.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ struct LoggingExternalInterface : public ShellExternalInterface {
3939

4040
LoggingExternalInterface(Loggings& loggings) : loggings(loggings) {}
4141

42-
Literals callImport(Function* import, LiteralList& arguments) override {
42+
Literals callImport(Function* import, Literals& arguments) override {
4343
if (import->module == "fuzzing-support") {
4444
std::cout << "[LoggingExternalInterface logging";
4545
loggings.push_back(Literal()); // buffer with a None between calls
@@ -239,7 +239,7 @@ struct ExecutionResults {
239239

240240
FunctionResult run(Function* func, Module& wasm, ModuleInstance& instance) {
241241
try {
242-
LiteralList arguments;
242+
Literals arguments;
243243
// init hang support, if present
244244
if (auto* ex = wasm.getExportOrNull("hangLimitInitializer")) {
245245
instance.callFunction(ex->value, arguments);

src/tools/wasm-ctor-eval.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ struct CtorEvalExternalInterface : EvallingModuleInstance::ExternalInterface {
256256
});
257257
}
258258

259-
Literals callImport(Function* import, LiteralList& arguments) override {
259+
Literals callImport(Function* import, Literals& arguments) override {
260260
Name WASI("wasi_snapshot_preview1");
261261

262262
if (ignoreExternalInput) {
@@ -324,7 +324,7 @@ struct CtorEvalExternalInterface : EvallingModuleInstance::ExternalInterface {
324324
Literals callTable(Name tableName,
325325
Index index,
326326
HeapType sig,
327-
LiteralList& arguments,
327+
Literals& arguments,
328328
Type result,
329329
EvallingModuleInstance& instance) override {
330330

@@ -524,7 +524,7 @@ EvalCtorOutcome evalCtor(EvallingModuleInstance& instance,
524524
// 1. Statically or dynamically stop evalling when a param is actually
525525
// used, or
526526
// 2. Split out --ignore-external-input into separate flags.
527-
LiteralList params;
527+
Literals params;
528528
for (Index i = 0; i < func->getNumParams(); i++) {
529529
auto type = func->getLocalType(i);
530530
if (!LiteralUtils::canMakeZero(type)) {

src/tools/wasm-shell.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ class Shell {
179179
Name base = s[i++]->str();
180180

181181
if (s[0]->str() == INVOKE) {
182-
LiteralList args;
182+
Literals args;
183183
while (i < s.size()) {
184184
Expression* argument = builders[moduleName]->parseExpression(*s[i++]);
185185
args.push_back(getLiteralFromConstExpression(argument));

src/wasm-interpreter.h

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,6 @@ class Flow {
9898
}
9999
};
100100

101-
// A list of literals, for function calls
102-
typedef std::vector<Literal> LiteralList;
103-
104101
// Debugging helpers
105102
#ifdef WASM_INTERPRETER_DEBUG
106103
class Indenter {
@@ -165,8 +162,7 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
165162
// Maximum iterations before giving up on a loop.
166163
Index maxLoopIterations;
167164

168-
Flow generateArguments(const ExpressionList& operands,
169-
LiteralList& arguments) {
165+
Flow generateArguments(const ExpressionList& operands, Literals& arguments) {
170166
NOTE_ENTER_("generateArguments");
171167
arguments.reserve(operands.size());
172168
for (auto expression : operands) {
@@ -1284,7 +1280,7 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
12841280
}
12851281
Flow visitTupleMake(TupleMake* curr) {
12861282
NOTE_ENTER("tuple.make");
1287-
LiteralList arguments;
1283+
Literals arguments;
12881284
Flow flow = generateArguments(curr->operands, arguments);
12891285
if (flow.breaking()) {
12901286
return flow;
@@ -1384,7 +1380,7 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
13841380
Flow visitTry(Try* curr) { WASM_UNREACHABLE("unimp"); }
13851381
Flow visitThrow(Throw* curr) {
13861382
NOTE_ENTER("Throw");
1387-
LiteralList arguments;
1383+
Literals arguments;
13881384
Flow flow = generateArguments(curr->operands, arguments);
13891385
if (flow.breaking()) {
13901386
return flow;
@@ -2306,11 +2302,11 @@ template<typename GlobalManager, typename SubType> class ModuleInstanceBase {
23062302
virtual ~ExternalInterface() = default;
23072303
virtual void init(Module& wasm, SubType& instance) {}
23082304
virtual void importGlobals(GlobalManager& globals, Module& wasm) = 0;
2309-
virtual Literals callImport(Function* import, LiteralList& arguments) = 0;
2305+
virtual Literals callImport(Function* import, Literals& arguments) = 0;
23102306
virtual Literals callTable(Name tableName,
23112307
Index index,
23122308
HeapType sig,
2313-
LiteralList& arguments,
2309+
Literals& arguments,
23142310
Type result,
23152311
SubType& instance) = 0;
23162312
virtual bool growMemory(Address oldSize, Address newSize) = 0;
@@ -2510,21 +2506,21 @@ template<typename GlobalManager, typename SubType> class ModuleInstanceBase {
25102506

25112507
// run start, if present
25122508
if (wasm.start.is()) {
2513-
LiteralList arguments;
2509+
Literals arguments;
25142510
callFunction(wasm.start, arguments);
25152511
}
25162512
}
25172513

25182514
// call an exported function
2519-
Literals callExport(Name name, const LiteralList& arguments) {
2515+
Literals callExport(Name name, const Literals& arguments) {
25202516
Export* export_ = wasm.getExportOrNull(name);
25212517
if (!export_) {
25222518
externalInterface->trap("callExport not found");
25232519
}
25242520
return callFunction(export_->value, arguments);
25252521
}
25262522

2527-
Literals callExport(Name name) { return callExport(name, LiteralList()); }
2523+
Literals callExport(Name name) { return callExport(name, Literals()); }
25282524

25292525
// get an exported global
25302526
Literals getExport(Name name) {
@@ -2659,7 +2655,7 @@ template<typename GlobalManager, typename SubType> class ModuleInstanceBase {
26592655
std::vector<Literals> locals;
26602656
Function* function;
26612657

2662-
FunctionScope(Function* function, const LiteralList& arguments)
2658+
FunctionScope(Function* function, const Literals& arguments)
26632659
: function(function) {
26642660
if (function->getParams().size() != arguments.size()) {
26652661
std::cerr << "Function `" << function->name << "` expects "
@@ -2731,7 +2727,7 @@ template<typename GlobalManager, typename SubType> class ModuleInstanceBase {
27312727
Flow visitCall(Call* curr) {
27322728
NOTE_ENTER("Call");
27332729
NOTE_NAME(curr->target);
2734-
LiteralList arguments;
2730+
Literals arguments;
27352731
Flow flow = this->generateArguments(curr->operands, arguments);
27362732
if (flow.breaking()) {
27372733
return flow;
@@ -2755,7 +2751,7 @@ template<typename GlobalManager, typename SubType> class ModuleInstanceBase {
27552751

27562752
Flow visitCallIndirect(CallIndirect* curr) {
27572753
NOTE_ENTER("CallIndirect");
2758-
LiteralList arguments;
2754+
Literals arguments;
27592755
Flow flow = this->generateArguments(curr->operands, arguments);
27602756
if (flow.breaking()) {
27612757
return flow;
@@ -2780,7 +2776,7 @@ template<typename GlobalManager, typename SubType> class ModuleInstanceBase {
27802776
}
27812777
Flow visitCallRef(CallRef* curr) {
27822778
NOTE_ENTER("CallRef");
2783-
LiteralList arguments;
2779+
Literals arguments;
27842780
Flow flow = this->generateArguments(curr->operands, arguments);
27852781
if (flow.breaking()) {
27862782
return flow;
@@ -3555,7 +3551,7 @@ template<typename GlobalManager, typename SubType> class ModuleInstanceBase {
35553551
};
35563552

35573553
// Call a function, starting an invocation.
3558-
Literals callFunction(Name name, const LiteralList& arguments) {
3554+
Literals callFunction(Name name, const Literals& arguments) {
35593555
// if the last call ended in a jump up the stack, it might have left stuff
35603556
// for us to clean up here
35613557
callDepth = 0;
@@ -3565,7 +3561,7 @@ template<typename GlobalManager, typename SubType> class ModuleInstanceBase {
35653561

35663562
// Internal function call. Must be public so that callTable implementations
35673563
// can use it (refactor?)
3568-
Literals callFunctionInternal(Name name, const LiteralList& arguments) {
3564+
Literals callFunctionInternal(Name name, const Literals& arguments) {
35693565
if (callDepth > maxDepth) {
35703566
externalInterface->trap("stack limit");
35713567
}

test/example/small_vector.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
using namespace wasm;
77

8-
template<typename T> void test() {
8+
template<typename T> void test(size_t N) {
99
{
1010
T t;
1111
// build up
@@ -55,12 +55,23 @@ template<typename T> void test() {
5555
u.push_back(2);
5656
assert(t != u);
5757
}
58+
{
59+
// Test reserve/capacity.
60+
T t;
61+
62+
// Capacity begins at the size of the fixed storage.
63+
assert(t.capacity() == N);
64+
65+
// Reserving more increases the capacity (but how much is impl-defined).
66+
t.reserve(t.capacity() + 100);
67+
assert(t.capacity() >= N + 100);
68+
}
5869
}
5970

6071
int main() {
61-
test<SmallVector<int, 0>>();
62-
test<SmallVector<int, 1>>();
63-
test<SmallVector<int, 2>>();
64-
test<SmallVector<int, 10>>();
72+
test<SmallVector<int, 0>>(0);
73+
test<SmallVector<int, 1>>(1);
74+
test<SmallVector<int, 2>>(2);
75+
test<SmallVector<int, 10>>(10);
6576
std::cout << "ok.\n";
6677
}

0 commit comments

Comments
 (0)