mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 02:08:11 +00:00
LibJS: Add argument(i) and argument_count() to Interpreter
Add some convenience accessors for retrieving arguments from the current call frame.
This commit is contained in:
parent
1549c5c48b
commit
cd1d369cdd
9 changed files with 49 additions and 34 deletions
|
@ -107,6 +107,21 @@ public:
|
||||||
void pop_call_frame() { m_call_stack.take_last(); }
|
void pop_call_frame() { m_call_stack.take_last(); }
|
||||||
const CallFrame& call_frame() { return m_call_stack.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
|
Value this_value() const
|
||||||
{
|
{
|
||||||
if (m_call_stack.is_empty())
|
if (m_call_stack.is_empty())
|
||||||
|
|
|
@ -50,9 +50,9 @@ Value ArrayPrototype::push(Interpreter& interpreter)
|
||||||
if (!this_object)
|
if (!this_object)
|
||||||
return {};
|
return {};
|
||||||
ASSERT(this_object->is_array());
|
ASSERT(this_object->is_array());
|
||||||
if (interpreter.call_frame().arguments.is_empty())
|
if (!interpreter.argument_count())
|
||||||
return js_undefined();
|
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());
|
return Value(static_cast<const Array*>(this_object)->length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,9 +43,9 @@ ConsoleObject::~ConsoleObject()
|
||||||
|
|
||||||
Value ConsoleObject::log(Interpreter& interpreter)
|
Value ConsoleObject::log(Interpreter& interpreter)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < interpreter.call_frame().arguments.size(); ++i) {
|
for (size_t i = 0; i < interpreter.argument_count(); ++i) {
|
||||||
printf("%s", interpreter.call_frame().arguments[i].to_string().characters());
|
printf("%s", interpreter.argument(i).to_string().characters());
|
||||||
if (i != interpreter.call_frame().arguments.size() - 1)
|
if (i != interpreter.argument_count() - 1)
|
||||||
putchar(' ');
|
putchar(' ');
|
||||||
}
|
}
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
|
|
|
@ -39,9 +39,9 @@ Value GlobalObject::gc(Interpreter& interpreter)
|
||||||
|
|
||||||
Value GlobalObject::is_nan(Interpreter& interpreter)
|
Value GlobalObject::is_nan(Interpreter& interpreter)
|
||||||
{
|
{
|
||||||
if (interpreter.call_frame().arguments.size() < 1)
|
if (interpreter.argument_count() < 1)
|
||||||
return js_undefined();
|
return js_undefined();
|
||||||
return Value(interpreter.call_frame().arguments[0].to_number().is_nan());
|
return Value(interpreter.argument(0).to_number().is_nan());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,10 +53,10 @@ MathObject::~MathObject()
|
||||||
|
|
||||||
Value MathObject::abs(Interpreter& interpreter)
|
Value MathObject::abs(Interpreter& interpreter)
|
||||||
{
|
{
|
||||||
if (interpreter.call_frame().arguments.is_empty())
|
if (!interpreter.argument_count())
|
||||||
return js_nan();
|
return js_nan();
|
||||||
|
|
||||||
auto number = interpreter.call_frame().arguments[0].to_number();
|
auto number = interpreter.argument(0).to_number();
|
||||||
if (number.is_nan())
|
if (number.is_nan())
|
||||||
return js_nan();
|
return js_nan();
|
||||||
return Value(number.as_double() >= 0 ? number.as_double() : -number.as_double());
|
return Value(number.as_double() >= 0 ? number.as_double() : -number.as_double());
|
||||||
|
|
|
@ -57,9 +57,9 @@ Value ObjectConstructor::construct(Interpreter& interpreter)
|
||||||
|
|
||||||
Value ObjectConstructor::get_own_property_names(Interpreter& interpreter)
|
Value ObjectConstructor::get_own_property_names(Interpreter& interpreter)
|
||||||
{
|
{
|
||||||
if (interpreter.call_frame().arguments.size() < 1)
|
if (!interpreter.argument_count())
|
||||||
return {};
|
return {};
|
||||||
auto* object = interpreter.call_frame().arguments[0].to_object(interpreter.heap());
|
auto* object = interpreter.argument(0).to_object(interpreter.heap());
|
||||||
if (interpreter.exception())
|
if (interpreter.exception())
|
||||||
return {};
|
return {};
|
||||||
auto* result = interpreter.heap().allocate<Array>();
|
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)
|
Value ObjectConstructor::get_prototype_of(Interpreter& interpreter)
|
||||||
{
|
{
|
||||||
if (interpreter.call_frame().arguments.size() < 1)
|
if (!interpreter.argument_count())
|
||||||
return {};
|
return {};
|
||||||
auto* object = interpreter.call_frame().arguments[0].to_object(interpreter.heap());
|
auto* object = interpreter.argument(0).to_object(interpreter.heap());
|
||||||
if (interpreter.exception())
|
if (interpreter.exception())
|
||||||
return {};
|
return {};
|
||||||
return object->prototype();
|
return object->prototype();
|
||||||
|
@ -85,14 +85,14 @@ Value ObjectConstructor::get_prototype_of(Interpreter& interpreter)
|
||||||
|
|
||||||
Value ObjectConstructor::set_prototype_of(Interpreter& interpreter)
|
Value ObjectConstructor::set_prototype_of(Interpreter& interpreter)
|
||||||
{
|
{
|
||||||
if (interpreter.call_frame().arguments.size() < 2)
|
if (interpreter.argument_count() < 2)
|
||||||
return {};
|
return {};
|
||||||
if (!interpreter.call_frame().arguments[1].is_object())
|
if (!interpreter.argument(0).is_object())
|
||||||
return {};
|
return {};
|
||||||
auto* object = interpreter.call_frame().arguments[0].to_object(interpreter.heap());
|
auto* object = interpreter.argument(0).to_object(interpreter.heap());
|
||||||
if (interpreter.exception())
|
if (interpreter.exception())
|
||||||
return {};
|
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 {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,9 +51,9 @@ Value ObjectPrototype::has_own_property(Interpreter& interpreter)
|
||||||
auto* this_object = interpreter.this_value().to_object(interpreter.heap());
|
auto* this_object = interpreter.this_value().to_object(interpreter.heap());
|
||||||
if (!this_object)
|
if (!this_object)
|
||||||
return {};
|
return {};
|
||||||
if (interpreter.call_frame().arguments.is_empty())
|
if (!interpreter.argument_count())
|
||||||
return js_undefined();
|
return {};
|
||||||
return Value(this_object->has_own_property(interpreter.call_frame().arguments[0].to_string()));
|
return Value(this_object->has_own_property(interpreter.argument(0).to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Value ObjectPrototype::to_string(Interpreter& interpreter)
|
Value ObjectPrototype::to_string(Interpreter& interpreter)
|
||||||
|
|
|
@ -54,8 +54,8 @@ Value StringPrototype::char_at(Interpreter& interpreter)
|
||||||
if (!this_object)
|
if (!this_object)
|
||||||
return {};
|
return {};
|
||||||
i32 index = 0;
|
i32 index = 0;
|
||||||
if (!interpreter.call_frame().arguments.is_empty())
|
if (interpreter.argument_count())
|
||||||
index = interpreter.call_frame().arguments[0].to_i32();
|
index = interpreter.argument(0).to_i32();
|
||||||
ASSERT(this_object->is_string_object());
|
ASSERT(this_object->is_string_object());
|
||||||
auto underlying_string = static_cast<const StringObject*>(this_object)->primitive_string()->string();
|
auto underlying_string = static_cast<const StringObject*>(this_object)->primitive_string()->string();
|
||||||
if (index < 0 || index >= static_cast<i32>(underlying_string.length()))
|
if (index < 0 || index >= static_cast<i32>(underlying_string.length()))
|
||||||
|
@ -69,13 +69,13 @@ Value StringPrototype::repeat(Interpreter& interpreter)
|
||||||
if (!this_object)
|
if (!this_object)
|
||||||
return {};
|
return {};
|
||||||
ASSERT(this_object->is_string_object());
|
ASSERT(this_object->is_string_object());
|
||||||
if (interpreter.call_frame().arguments.is_empty())
|
if (!interpreter.argument_count())
|
||||||
return js_string(interpreter.heap(), String::empty());
|
return js_string(interpreter.heap(), String::empty());
|
||||||
i32 count = 0;
|
i32 count = 0;
|
||||||
count = interpreter.call_frame().arguments[0].to_i32();
|
count = interpreter.argument(0).to_i32();
|
||||||
if (count < 0) {
|
if (count < 0) {
|
||||||
// FIXME: throw RangeError
|
// FIXME: throw RangeError
|
||||||
return js_undefined();
|
return {};
|
||||||
}
|
}
|
||||||
auto* string_object = static_cast<StringObject*>(this_object);
|
auto* string_object = static_cast<StringObject*>(this_object);
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
|
@ -89,13 +89,13 @@ Value StringPrototype::starts_with(Interpreter& interpreter)
|
||||||
auto* this_object = interpreter.this_value().to_object(interpreter.heap());
|
auto* this_object = interpreter.this_value().to_object(interpreter.heap());
|
||||||
if (!this_object)
|
if (!this_object)
|
||||||
return {};
|
return {};
|
||||||
if (interpreter.call_frame().arguments.is_empty())
|
if (!interpreter.argument_count())
|
||||||
return Value(false);
|
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());
|
auto search_string_length = static_cast<i32>(search_string.length());
|
||||||
i32 position = 0;
|
i32 position = 0;
|
||||||
if (interpreter.call_frame().arguments.size() > 1) {
|
if (interpreter.argument_count() > 1) {
|
||||||
auto number = interpreter.call_frame().arguments[1].to_number();
|
auto number = interpreter.argument(1).to_number();
|
||||||
if (!number.is_nan())
|
if (!number.is_nan())
|
||||||
position = number.to_i32();
|
position = number.to_i32();
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,9 +211,9 @@ ReplObject::~ReplObject()
|
||||||
|
|
||||||
JS::Value ReplObject::exit_interpreter(JS::Interpreter& interpreter)
|
JS::Value ReplObject::exit_interpreter(JS::Interpreter& interpreter)
|
||||||
{
|
{
|
||||||
if (interpreter.call_frame().arguments.is_empty())
|
if (!interpreter.argument_count())
|
||||||
exit(0);
|
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);
|
exit(exit_code);
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}
|
}
|
||||||
|
@ -230,10 +230,10 @@ JS::Value ReplObject::repl_help(JS::Interpreter& interpreter)
|
||||||
|
|
||||||
JS::Value ReplObject::load_file(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);
|
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();
|
String file_name = file.as_string()->string();
|
||||||
auto js_file = Core::File::construct(file_name);
|
auto js_file = Core::File::construct(file_name);
|
||||||
if (!js_file->open(Core::IODevice::ReadOnly)) {
|
if (!js_file->open(Core::IODevice::ReadOnly)) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue