Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce Value type for operands #419

Merged
merged 6 commits into from
Jul 30, 2020
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Change element type in OperandStack to Value
chfast committed Jul 30, 2020
commit 34e0f94d988b12fa7cab988c5d8b1a386a6fa7f5
3 changes: 2 additions & 1 deletion lib/fizzy/execute.cpp
Original file line number Diff line number Diff line change
@@ -270,7 +270,8 @@ bool invoke_function(
{
const auto num_args = func_type.inputs.size();
assert(stack.size() >= num_args);
span<const uint64_t> call_args{stack.rend() - num_args, num_args};
const auto* first_arg = stack.rend() - num_args;
span<const uint64_t> call_args{&first_arg->i64, num_args}; // FIXME: hack!
stack.drop(num_args);

const auto ret = func(instance, call_args, depth + 1);
21 changes: 11 additions & 10 deletions lib/fizzy/stack.hpp
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@

#pragma once

#include "value.hpp"
#include <cassert>
#include <cstdint>
#include <memory>
@@ -59,24 +60,24 @@ class Stack : public std::vector<T>
class OperandStack
{
/// The size of the pre-allocated internal storage: 128 bytes.
static constexpr auto small_storage_size = 128 / sizeof(uint64_t);
static constexpr auto small_storage_size = 128 / sizeof(Value);

/// The pointer to the top item, or below the stack bottom if stack is empty.
///
/// This pointer always alias m_storage, but it is kept as the first field
/// because it is accessed the most. Therefore, it must be initialized
/// in the constructor after the m_storage.
uint64_t* m_top;
Value* m_top;

/// The pre-allocated internal storage.
uint64_t m_small_storage[small_storage_size];
Value m_small_storage[small_storage_size];

/// The unbounded storage for items.
std::unique_ptr<uint64_t[]> m_large_storage;
std::unique_ptr<Value[]> m_large_storage;

uint64_t* bottom() { return m_large_storage ? m_large_storage.get() : m_small_storage; }
Value* bottom() { return m_large_storage ? m_large_storage.get() : m_small_storage; }

const uint64_t* bottom() const
const Value* bottom() const
{
return m_large_storage ? m_large_storage.get() : m_small_storage;
}
@@ -90,7 +91,7 @@ class OperandStack
explicit OperandStack(size_t max_stack_height)
{
if (max_stack_height > small_storage_size)
m_large_storage = std::make_unique<uint64_t[]>(max_stack_height);
m_large_storage = std::make_unique<Value[]>(max_stack_height);
m_top = bottom() - 1;
}

@@ -118,7 +119,7 @@ class OperandStack

/// Pushes an item on the stack.
/// The stack max height limit is not checked.
void push(uint64_t item) noexcept { *++m_top = item; }
void push(Value item) noexcept { *++m_top = item; }

/// Returns an item popped from the top of the stack.
/// Requires non-empty stack.
@@ -146,9 +147,9 @@ class OperandStack
}

/// Returns iterator to the bottom of the stack.
const uint64_t* rbegin() const noexcept { return bottom(); }
const Value* rbegin() const noexcept { return bottom(); }

/// Returns end iterator counting from the bottom of the stack.
const uint64_t* rend() const noexcept { return m_top + 1; }
const Value* rend() const noexcept { return m_top + 1; }
};
} // namespace fizzy
2 changes: 1 addition & 1 deletion test/unittests/span_test.cpp
Original file line number Diff line number Diff line change
@@ -57,7 +57,7 @@ TEST(span, stack)
stack.push(13);

constexpr auto num_items = 2;
span<const uint64_t> s(stack.rend() - num_items, num_items);
span<const Value> s(stack.rend() - num_items, num_items);
EXPECT_EQ(s.size(), 2);
EXPECT_EQ(s[0], 12);
EXPECT_EQ(s[1], 13);