Prechádzať zdrojové kódy

LibJS: Add argument(i) and argument_count() to Interpreter

Add some convenience accessors for retrieving arguments from the
current call frame.
Andreas Kling 5 rokov pred
rodič
commit
cd1d369cdd

+ 15 - 0
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())

+ 2 - 2
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<Array*>(this_object)->push(interpreter.call_frame().arguments[0]);
+    static_cast<Array*>(this_object)->push(interpreter.argument(0));
     return Value(static_cast<const Array*>(this_object)->length());
 }
 

+ 3 - 3
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');

+ 2 - 2
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());
 }
 
 }

+ 2 - 2
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());

+ 8 - 8
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<Array>();
@@ -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<Object&>(interpreter.call_frame().arguments[1].as_object()));
+    object->set_prototype(&const_cast<Object&>(interpreter.argument(1).as_object()));
     return {};
 }
 

+ 3 - 3
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)

+ 9 - 9
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<const StringObject*>(this_object)->primitive_string()->string();
     if (index < 0 || index >= static_cast<i32>(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<StringObject*>(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<i32>(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();
     }

+ 5 - 5
Userland/js.cpp

@@ -211,9 +211,9 @@ ReplObject::~ReplObject()
 
 JS::Value ReplObject::exit_interpreter(JS::Interpreter& interpreter)
 {
-    if (interpreter.call_frame().arguments.is_empty())
+    if (!interpreter.argument_count())
         exit(0);
-    int exit_code = interpreter.call_frame().arguments[0].to_number().as_double();
+    int exit_code = interpreter.argument(0).to_number().as_double();
     exit(exit_code);
     return JS::js_undefined();
 }
@@ -230,10 +230,10 @@ JS::Value ReplObject::repl_help(JS::Interpreter& interpreter)
 
 JS::Value ReplObject::load_file(JS::Interpreter& interpreter)
 {
-    if (interpreter.call_frame().arguments.is_empty())
+    if (!interpreter.argument_count())
         return JS::Value(false);
-    Vector<JS::Value> files = interpreter.call_frame().arguments;
-    for (JS::Value file : files) {
+
+    for (auto& file : interpreter.call_frame().arguments) {
         String file_name = file.as_string()->string();
         auto js_file = Core::File::construct(file_name);
         if (!js_file->open(Core::IODevice::ReadOnly)) {