Skip to content

Commit

Permalink
LibWasm+Everywhere: Make the instruction count limit configurable
Browse files Browse the repository at this point in the history
...and enable it for LibWeb and test-wasm.
Note that `wasm` will not be limited by this.
  • Loading branch information
alimpfard committed Jul 16, 2021
1 parent 70b94f5 commit 65cd552
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 3 deletions.
1 change: 1 addition & 0 deletions Tests/LibWasm/test-wasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class WebAssemblyModule final : public JS::Object {
explicit WebAssemblyModule(JS::Object& prototype)
: JS::Object(prototype)
{
m_machine.enable_instruction_count_limit();
}

static Wasm::AbstractMachine& machine() { return m_machine; }
Expand Down
10 changes: 10 additions & 0 deletions Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ InstantiationResult AbstractMachine::instantiate(Module const& module, Vector<Ex
module.for_each_section_of_type<GlobalSection>([&](auto& global_section) {
for (auto& entry : global_section.entries()) {
Configuration config { m_store };
if (m_should_limit_instruction_count)
config.enable_instruction_count_limit();
config.set_frame(Frame {
auxiliary_instance,
Vector<Value> {},
Expand All @@ -153,6 +155,8 @@ InstantiationResult AbstractMachine::instantiate(Module const& module, Vector<Ex
Vector<Reference> references;
for (auto& entry : segment.init) {
Configuration config { m_store };
if (m_should_limit_instruction_count)
config.enable_instruction_count_limit();
config.set_frame(Frame {
main_module_instance,
Vector<Value> {},
Expand Down Expand Up @@ -204,6 +208,8 @@ InstantiationResult AbstractMachine::instantiate(Module const& module, Vector<Ex
return IterationDecision::Break;
}
Configuration config { m_store };
if (m_should_limit_instruction_count)
config.enable_instruction_count_limit();
config.set_frame(Frame {
main_module_instance,
Vector<Value> {},
Expand Down Expand Up @@ -262,6 +268,8 @@ InstantiationResult AbstractMachine::instantiate(Module const& module, Vector<Ex
segment.value().visit(
[&](DataSection::Data::Active const& data) {
Configuration config { m_store };
if (m_should_limit_instruction_count)
config.enable_instruction_count_limit();
config.set_frame(Frame {
main_module_instance,
Vector<Value> {},
Expand Down Expand Up @@ -439,6 +447,8 @@ Result AbstractMachine::invoke(FunctionAddress address, Vector<Value> arguments)
Result AbstractMachine::invoke(Interpreter& interpreter, FunctionAddress address, Vector<Value> arguments)
{
Configuration configuration { m_store };
if (m_should_limit_instruction_count)
configuration.enable_instruction_count_limit();
return configuration.call(interpreter, address, move(arguments));
}

Expand Down
3 changes: 3 additions & 0 deletions Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -505,10 +505,13 @@ class AbstractMachine {
auto& store() const { return m_store; }
auto& store() { return m_store; }

void enable_instruction_count_limit() { m_should_limit_instruction_count = true; }

private:
Optional<InstantiationError> allocate_all_initial_phase(Module const&, ModuleInstance&, Vector<ExternValue>&, Vector<Value>& global_values);
Optional<InstantiationError> allocate_all_final_phase(Module const&, ModuleInstance&, Vector<Vector<Reference>>& elements);
Store m_store;
bool m_should_limit_instruction_count { false };
};

class Linker {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,15 @@ void BytecodeInterpreter::interpret(Configuration& configuration)
auto& instructions = configuration.frame().expression().instructions();
auto max_ip_value = InstructionPointer { instructions.size() };
auto& current_ip_value = configuration.ip();
auto const should_limit_instruction_count = configuration.should_limit_instruction_count();
u64 executed_instructions = 0;

while (current_ip_value < max_ip_value) {
if (executed_instructions++ >= Constants::max_allowed_executed_instructions_per_call) [[unlikely]] {
m_trap = Trap { "Exceeded maximum allowed number of instructions" };
return;
if (should_limit_instruction_count) {
if (executed_instructions++ >= Constants::max_allowed_executed_instructions_per_call) [[unlikely]] {
m_trap = Trap { "Exceeded maximum allowed number of instructions" };
return;
}
}
auto& instruction = instructions[current_ip_value.value()];
auto old_ip = current_ip_value;
Expand Down
4 changes: 4 additions & 0 deletions Userland/Libraries/LibWasm/AbstractMachine/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ class Configuration {
Result call(Interpreter&, FunctionAddress, Vector<Value> arguments);
Result execute(Interpreter&);

void enable_instruction_count_limit() { m_should_limit_instruction_count = true; }
bool should_limit_instruction_count() const { return m_should_limit_instruction_count; }

void dump_stack();

private:
Expand All @@ -69,6 +72,7 @@ class Configuration {
Stack m_stack;
size_t m_depth { 0 };
InstructionPointer m_ip;
bool m_should_limit_instruction_count { false };
};

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namespace Web::Bindings {
WebAssemblyObject::WebAssemblyObject(JS::GlobalObject& global_object)
: Object(*global_object.object_prototype())
{
s_abstract_machine.enable_instruction_count_limit();
}

void WebAssemblyObject::initialize(JS::GlobalObject& global_object)
Expand Down

0 comments on commit 65cd552

Please sign in to comment.