From cd1d369cdd86b4870d65bc9ad856e8a0850cb4fb Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 1 Apr 2020 22:38:59 +0200 Subject: LibJS: Add argument(i) and argument_count() to Interpreter Add some convenience accessors for retrieving arguments from the current call frame. --- Libraries/LibJS/Interpreter.h | 15 +++++++++++++++ Libraries/LibJS/Runtime/ArrayPrototype.cpp | 4 ++-- Libraries/LibJS/Runtime/ConsoleObject.cpp | 6 +++--- Libraries/LibJS/Runtime/GlobalObject.cpp | 4 ++-- Libraries/LibJS/Runtime/MathObject.cpp | 4 ++-- Libraries/LibJS/Runtime/ObjectConstructor.cpp | 16 ++++++++-------- Libraries/LibJS/Runtime/ObjectPrototype.cpp | 6 +++--- Libraries/LibJS/Runtime/StringPrototype.cpp | 18 +++++++++--------- 8 files changed, 44 insertions(+), 29 deletions(-) (limited to 'Libraries') diff --git a/Libraries/LibJS/Interpreter.h b/Libraries/LibJS/Interpreter.h index 0f366c2df0..77a4f7622c 100644 --- a/Libraries/LibJS/Interpreter.h +++ b/Libraries/LibJS/Interpreter.h @@ -107,6 +107,21 @@ public: void pop_call_frame() { m_call_stack.take_last(); } const CallFrame& call_frame() { return m_call_stack.last(); } + size_t argument_count() const + { + if (m_call_stack.is_empty()) + return 0; + return m_call_stack.last().arguments.size(); + } + + Value argument(size_t index) const + { + if (m_call_stack.is_empty()) + return {}; + auto& arguments = m_call_stack.last().arguments; + return index < arguments.size() ? arguments[index] : js_undefined(); + } + Value this_value() const { if (m_call_stack.is_empty()) diff --git a/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Libraries/LibJS/Runtime/ArrayPrototype.cpp index 0d3db3d188..1fb33347b0 100644 --- a/Libraries/LibJS/Runtime/ArrayPrototype.cpp +++ b/Libraries/LibJS/Runtime/ArrayPrototype.cpp @@ -50,9 +50,9 @@ Value ArrayPrototype::push(Interpreter& interpreter) if (!this_object) return {}; ASSERT(this_object->is_array()); - if (interpreter.call_frame().arguments.is_empty()) + if (!interpreter.argument_count()) return js_undefined(); - static_cast(this_object)->push(interpreter.call_frame().arguments[0]); + static_cast(this_object)->push(interpreter.argument(0)); return Value(static_cast(this_object)->length()); } diff --git a/Libraries/LibJS/Runtime/ConsoleObject.cpp b/Libraries/LibJS/Runtime/ConsoleObject.cpp index ee359d29df..02c8f6fc67 100644 --- a/Libraries/LibJS/Runtime/ConsoleObject.cpp +++ b/Libraries/LibJS/Runtime/ConsoleObject.cpp @@ -43,9 +43,9 @@ ConsoleObject::~ConsoleObject() Value ConsoleObject::log(Interpreter& interpreter) { - for (size_t i = 0; i < interpreter.call_frame().arguments.size(); ++i) { - printf("%s", interpreter.call_frame().arguments[i].to_string().characters()); - if (i != interpreter.call_frame().arguments.size() - 1) + for (size_t i = 0; i < interpreter.argument_count(); ++i) { + printf("%s", interpreter.argument(i).to_string().characters()); + if (i != interpreter.argument_count() - 1) putchar(' '); } putchar('\n'); diff --git a/Libraries/LibJS/Runtime/GlobalObject.cpp b/Libraries/LibJS/Runtime/GlobalObject.cpp index c09c5ce3cd..2035791fb9 100644 --- a/Libraries/LibJS/Runtime/GlobalObject.cpp +++ b/Libraries/LibJS/Runtime/GlobalObject.cpp @@ -39,9 +39,9 @@ Value GlobalObject::gc(Interpreter& interpreter) Value GlobalObject::is_nan(Interpreter& interpreter) { - if (interpreter.call_frame().arguments.size() < 1) + if (interpreter.argument_count() < 1) return js_undefined(); - return Value(interpreter.call_frame().arguments[0].to_number().is_nan()); + return Value(interpreter.argument(0).to_number().is_nan()); } } diff --git a/Libraries/LibJS/Runtime/MathObject.cpp b/Libraries/LibJS/Runtime/MathObject.cpp index 611a556a6c..225d2005b3 100644 --- a/Libraries/LibJS/Runtime/MathObject.cpp +++ b/Libraries/LibJS/Runtime/MathObject.cpp @@ -53,10 +53,10 @@ MathObject::~MathObject() Value MathObject::abs(Interpreter& interpreter) { - if (interpreter.call_frame().arguments.is_empty()) + if (!interpreter.argument_count()) return js_nan(); - auto number = interpreter.call_frame().arguments[0].to_number(); + auto number = interpreter.argument(0).to_number(); if (number.is_nan()) return js_nan(); return Value(number.as_double() >= 0 ? number.as_double() : -number.as_double()); diff --git a/Libraries/LibJS/Runtime/ObjectConstructor.cpp b/Libraries/LibJS/Runtime/ObjectConstructor.cpp index 613e34c76b..ee529724cb 100644 --- a/Libraries/LibJS/Runtime/ObjectConstructor.cpp +++ b/Libraries/LibJS/Runtime/ObjectConstructor.cpp @@ -57,9 +57,9 @@ Value ObjectConstructor::construct(Interpreter& interpreter) Value ObjectConstructor::get_own_property_names(Interpreter& interpreter) { - if (interpreter.call_frame().arguments.size() < 1) + if (!interpreter.argument_count()) return {}; - auto* object = interpreter.call_frame().arguments[0].to_object(interpreter.heap()); + auto* object = interpreter.argument(0).to_object(interpreter.heap()); if (interpreter.exception()) return {}; auto* result = interpreter.heap().allocate(); @@ -75,9 +75,9 @@ Value ObjectConstructor::get_own_property_names(Interpreter& interpreter) Value ObjectConstructor::get_prototype_of(Interpreter& interpreter) { - if (interpreter.call_frame().arguments.size() < 1) + if (!interpreter.argument_count()) return {}; - auto* object = interpreter.call_frame().arguments[0].to_object(interpreter.heap()); + auto* object = interpreter.argument(0).to_object(interpreter.heap()); if (interpreter.exception()) return {}; return object->prototype(); @@ -85,14 +85,14 @@ Value ObjectConstructor::get_prototype_of(Interpreter& interpreter) Value ObjectConstructor::set_prototype_of(Interpreter& interpreter) { - if (interpreter.call_frame().arguments.size() < 2) + if (interpreter.argument_count() < 2) return {}; - if (!interpreter.call_frame().arguments[1].is_object()) + if (!interpreter.argument(0).is_object()) return {}; - auto* object = interpreter.call_frame().arguments[0].to_object(interpreter.heap()); + auto* object = interpreter.argument(0).to_object(interpreter.heap()); if (interpreter.exception()) return {}; - object->set_prototype(&const_cast(interpreter.call_frame().arguments[1].as_object())); + object->set_prototype(&const_cast(interpreter.argument(1).as_object())); return {}; } diff --git a/Libraries/LibJS/Runtime/ObjectPrototype.cpp b/Libraries/LibJS/Runtime/ObjectPrototype.cpp index 96eaa42602..8884056e90 100644 --- a/Libraries/LibJS/Runtime/ObjectPrototype.cpp +++ b/Libraries/LibJS/Runtime/ObjectPrototype.cpp @@ -51,9 +51,9 @@ Value ObjectPrototype::has_own_property(Interpreter& interpreter) auto* this_object = interpreter.this_value().to_object(interpreter.heap()); if (!this_object) return {}; - if (interpreter.call_frame().arguments.is_empty()) - return js_undefined(); - return Value(this_object->has_own_property(interpreter.call_frame().arguments[0].to_string())); + if (!interpreter.argument_count()) + return {}; + return Value(this_object->has_own_property(interpreter.argument(0).to_string())); } Value ObjectPrototype::to_string(Interpreter& interpreter) diff --git a/Libraries/LibJS/Runtime/StringPrototype.cpp b/Libraries/LibJS/Runtime/StringPrototype.cpp index 6e871db061..6a2cd0e8bd 100644 --- a/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/Libraries/LibJS/Runtime/StringPrototype.cpp @@ -54,8 +54,8 @@ Value StringPrototype::char_at(Interpreter& interpreter) if (!this_object) return {}; i32 index = 0; - if (!interpreter.call_frame().arguments.is_empty()) - index = interpreter.call_frame().arguments[0].to_i32(); + if (interpreter.argument_count()) + index = interpreter.argument(0).to_i32(); ASSERT(this_object->is_string_object()); auto underlying_string = static_cast(this_object)->primitive_string()->string(); if (index < 0 || index >= static_cast(underlying_string.length())) @@ -69,13 +69,13 @@ Value StringPrototype::repeat(Interpreter& interpreter) if (!this_object) return {}; ASSERT(this_object->is_string_object()); - if (interpreter.call_frame().arguments.is_empty()) + if (!interpreter.argument_count()) return js_string(interpreter.heap(), String::empty()); i32 count = 0; - count = interpreter.call_frame().arguments[0].to_i32(); + count = interpreter.argument(0).to_i32(); if (count < 0) { // FIXME: throw RangeError - return js_undefined(); + return {}; } auto* string_object = static_cast(this_object); StringBuilder builder; @@ -89,13 +89,13 @@ Value StringPrototype::starts_with(Interpreter& interpreter) auto* this_object = interpreter.this_value().to_object(interpreter.heap()); if (!this_object) return {}; - if (interpreter.call_frame().arguments.is_empty()) + if (!interpreter.argument_count()) return Value(false); - auto search_string = interpreter.call_frame().arguments[0].to_string(); + auto search_string = interpreter.argument(0).to_string(); auto search_string_length = static_cast(search_string.length()); i32 position = 0; - if (interpreter.call_frame().arguments.size() > 1) { - auto number = interpreter.call_frame().arguments[1].to_number(); + if (interpreter.argument_count() > 1) { + auto number = interpreter.argument(1).to_number(); if (!number.is_nan()) position = number.to_i32(); } -- cgit v1.2.3