Skip to content

Commit 6e65de2

Browse files
committed
Use thread context space
1 parent 3dd80fb commit 6e65de2

File tree

5 files changed

+98
-17
lines changed

5 files changed

+98
-17
lines changed

lib/fizzy/execute.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -463,15 +463,20 @@ __attribute__((no_sanitize("float-cast-overflow"))) inline constexpr float demot
463463
class ThreadContextGuard
464464
{
465465
ThreadContext& m_thread_context;
466+
Value* const m_free_space;
466467

467468
public:
468469
explicit ThreadContextGuard(ThreadContext& thread_context) noexcept
469-
: m_thread_context{thread_context}
470+
: m_thread_context{thread_context}, m_free_space{m_thread_context.free_space}
470471
{
471472
m_thread_context.lock();
472473
}
473474

474-
~ThreadContextGuard() noexcept { m_thread_context.unlock(); }
475+
~ThreadContextGuard() noexcept
476+
{
477+
m_thread_context.unlock();
478+
m_thread_context.free_space = m_free_space;
479+
}
475480
};
476481

477482
} // namespace
@@ -493,10 +498,14 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, span<const Value>
493498
const auto& code = instance.module.get_code(func_idx);
494499
auto* const memory = instance.memory.get();
495500

496-
constexpr auto stack_space_size = 128 / sizeof(Value);
497-
Value stack_space[stack_space_size];
501+
auto* current_thread_context = &thread_context;
502+
498503
OperandStack stack(args, code.local_count, static_cast<size_t>(code.max_stack_height),
499-
stack_space, std::size(stack_space));
504+
current_thread_context->free_space, current_thread_context->space_left());
505+
const auto storage_size_required =
506+
args.size() + code.local_count + static_cast<size_t>(code.max_stack_height);
507+
if (storage_size_required <= current_thread_context->space_left())
508+
current_thread_context->free_space += storage_size_required;
500509

501510
const Instr* pc = code.instructions.data();
502511
const uint8_t* immediates = code.immediates.data();
@@ -581,7 +590,8 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, span<const Value>
581590
const auto called_func_idx = read<uint32_t>(immediates);
582591
const auto& called_func_type = instance.module.get_function_type(called_func_idx);
583592

584-
if (!invoke_function(called_func_type, called_func_idx, instance, stack, thread_context))
593+
if (!invoke_function(
594+
called_func_type, called_func_idx, instance, stack, *current_thread_context))
585595
goto trap;
586596
break;
587597
}
@@ -607,7 +617,7 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, span<const Value>
607617
goto trap;
608618

609619
if (!invoke_function(
610-
actual_type, called_func->function, instance, stack, thread_context))
620+
actual_type, called_func->function, instance, stack, *current_thread_context))
611621
goto trap;
612622
break;
613623
}

lib/fizzy/instantiate.hpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,16 @@ struct Instance;
2525
class ThreadContext
2626
{
2727
public:
28-
Value stack_space[512];
28+
static constexpr size_t N = 128;
2929

30-
size_t space_left = 512;
30+
Value stack_space[N];
31+
32+
Value* free_space = stack_space;
33+
34+
size_t space_left() const noexcept
35+
{
36+
return static_cast<size_t>((stack_space + N) - free_space);
37+
}
3138

3239
int depth = 0;
3340

lib/fizzy/stack.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,10 @@ class OperandStack
106106
}
107107

108108
m_bottom = m_locals + num_args + num_local_variables;
109+
#pragma GCC diagnostic push
110+
#pragma GCC diagnostic ignored "-Warray-bounds"
109111
m_top = m_bottom - 1;
112+
#pragma GCC diagnostic pop
110113

111114
std::copy(std::begin(args), std::end(args), m_locals);
112115
std::fill_n(m_locals + num_args, num_local_variables, 0);

test/unittests/execute_call_test.cpp

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,34 @@ TEST(execute_call, call_with_arguments)
5858
EXPECT_THAT(execute(parse(wasm), 1, {}), Result(4));
5959
}
6060

61+
TEST(execute_call, call_shared_stack_space)
62+
{
63+
/* wat2wasm
64+
(module
65+
(func $double (param i32) (result i64)
66+
local.get 0
67+
i64.extend_i32_u
68+
local.get 0
69+
i64.extend_i32_u
70+
i64.add
71+
)
72+
73+
(func $main (param i32) (param i32) (result i64)
74+
local.get 1
75+
local.get 0
76+
i32.add
77+
call $double
78+
)
79+
)
80+
*/
81+
const auto wasm = from_hex(
82+
"0061736d01000000010c0260017f017e60027f7f017e03030200010a150209002000ad2000ad7c0b0900200120"
83+
"006a10000b");
84+
85+
auto instance = instantiate(parse(wasm));
86+
EXPECT_THAT(execute(*instance, 1, {2, 3}), Result(10)); // double(2+3)
87+
}
88+
6189
TEST(execute_call, call_indirect)
6290
{
6391
/* wat2wasm
@@ -205,6 +233,36 @@ TEST(execute_call, call_indirect_uninited_table)
205233
EXPECT_THAT(execute(module, 3, {4}), Traps());
206234
}
207235

236+
TEST(execute_call, call_indirect_shared_stack_space)
237+
{
238+
/* wat2wasm
239+
(module
240+
(type $ft (func (param i32) (result i64)))
241+
(func $double (param i32) (result i64)
242+
local.get 0
243+
i64.extend_i32_u
244+
local.get 0
245+
i64.extend_i32_u
246+
i64.add
247+
)
248+
249+
(func $main (param i32) (param i32) (result i64)
250+
local.get 1
251+
local.get 0
252+
call_indirect (type $ft)
253+
)
254+
255+
(table anyfunc (elem $double))
256+
)
257+
*/
258+
const auto wasm = from_hex(
259+
"0061736d01000000010c0260017f017e60027f7f017e0303020001040501700101010907010041000b01000a15"
260+
"0209002000ad2000ad7c0b0900200120001100000b");
261+
262+
auto instance = instantiate(parse(wasm));
263+
EXPECT_THAT(execute(*instance, 1, {0, 10}), Result(20)); // double(10)
264+
}
265+
208266
TEST(execute_call, imported_function_call)
209267
{
210268
/* wat2wasm
@@ -263,16 +321,16 @@ TEST(execute_call, imported_functions_call_indirect)
263321
(func $sqr (import "env" "sqr") (param i32) (result i64))
264322
(func $isqrt (import "env" "isqrt") (param i32) (result i64))
265323
(func $double (param i32) (result i64)
266-
get_local 0
267-
i64.extend_u/i32
268-
get_local 0
269-
i64.extend_u/i32
324+
local.get 0
325+
i64.extend_i32_u
326+
local.get 0
327+
i64.extend_i32_u
270328
i64.add
271329
)
272330
273331
(func $main (param i32) (param i32) (result i64)
274-
get_local 1
275-
get_local 0
332+
local.get 1
333+
local.get 0
276334
call_indirect (type $ft)
277335
)
278336
@@ -529,6 +587,7 @@ TEST(execute_call, call_imported_infinite_recursion)
529587
auto instance = instantiate(module, {{host_foo, host_foo_type}});
530588

531589
EXPECT_THAT(execute(*instance, 0, {}), Traps());
590+
EXPECT_THAT(execute(*instance, 1, {}), Traps());
532591
}
533592

534593
TEST(execute_call, call_indirect_imported_table_infinite_recursion)

test/unittests/stack_test.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ using namespace testing;
1010

1111
namespace
1212
{
13-
intptr_t address_diff(const void* a, const void* b) noexcept
13+
/// Computes absolute difference of two addresses.
14+
/*[[clang::no_sanitize("address")]]*/ intptr_t address_diff(const void* a, const void* b) noexcept
1415
{
15-
return std::abs(reinterpret_cast<intptr_t>(a) - reinterpret_cast<intptr_t>(b));
16+
const auto diff = reinterpret_cast<intptr_t>(a) - reinterpret_cast<intptr_t>(b);
17+
return std::abs(diff);
1618
}
1719
} // namespace
1820

0 commit comments

Comments
 (0)