mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
LibJS: Make native function/property callbacks take VM, not Interpreter
More work on decoupling the general runtime from Interpreter. The goal is becoming clearer. Interpreter should be one possible way to execute code inside a VM. In the future we might have other ways :^)
This commit is contained in:
parent
1ff9d33131
commit
340a115dfe
Notes:
sideshowbarker
2024-07-19 02:10:35 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/340a115dfe9
64 changed files with 1160 additions and 1114 deletions
|
@ -43,7 +43,7 @@ DateCell::~DateCell()
|
|||
String DateCell::display(Cell& cell, const CellTypeMetadata& metadata) const
|
||||
{
|
||||
auto timestamp = js_value(cell, metadata);
|
||||
auto string = Core::DateTime::from_timestamp(timestamp.to_i32(cell.sheet->interpreter())).to_string(metadata.format.is_empty() ? "%Y-%m-%d %H:%M:%S" : metadata.format.characters());
|
||||
auto string = Core::DateTime::from_timestamp(timestamp.to_i32(cell.sheet->global_object())).to_string(metadata.format.is_empty() ? "%Y-%m-%d %H:%M:%S" : metadata.format.characters());
|
||||
|
||||
if (metadata.length >= 0)
|
||||
return string.substring(0, metadata.length);
|
||||
|
@ -53,7 +53,7 @@ String DateCell::display(Cell& cell, const CellTypeMetadata& metadata) const
|
|||
|
||||
JS::Value DateCell::js_value(Cell& cell, const CellTypeMetadata&) const
|
||||
{
|
||||
auto value = cell.js_data().to_double(cell.sheet->interpreter());
|
||||
auto value = cell.js_data().to_double(cell.sheet->global_object());
|
||||
return JS::Value(value / 1000); // Turn it to seconds
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ String NumericCell::display(Cell& cell, const CellTypeMetadata& metadata) const
|
|||
if (metadata.format.is_empty())
|
||||
string = value.to_string_without_side_effects();
|
||||
else
|
||||
string = format_double(metadata.format.characters(), value.to_double(cell.sheet->interpreter()));
|
||||
string = format_double(metadata.format.characters(), value.to_double(cell.sheet->global_object()));
|
||||
|
||||
if (metadata.length >= 0)
|
||||
return string.substring(0, metadata.length);
|
||||
|
@ -57,7 +57,7 @@ String NumericCell::display(Cell& cell, const CellTypeMetadata& metadata) const
|
|||
|
||||
JS::Value NumericCell::js_value(Cell& cell, const CellTypeMetadata&) const
|
||||
{
|
||||
return cell.js_data().to_number(cell.sheet->interpreter());
|
||||
return cell.js_data().to_number(cell.sheet->global_object());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -86,21 +86,21 @@ void SheetGlobalObject::initialize()
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::parse_cell_name)
|
||||
{
|
||||
if (interpreter.argument_count() != 1) {
|
||||
interpreter.vm().throw_exception<JS::TypeError>(global_object, "Expected exactly one argument to parse_cell_name()");
|
||||
if (vm.argument_count() != 1) {
|
||||
vm.throw_exception<JS::TypeError>(global_object, "Expected exactly one argument to parse_cell_name()");
|
||||
return {};
|
||||
}
|
||||
auto name_value = interpreter.argument(0);
|
||||
auto name_value = vm.argument(0);
|
||||
if (!name_value.is_string()) {
|
||||
interpreter.vm().throw_exception<JS::TypeError>(global_object, "Expected a String argument to parse_cell_name()");
|
||||
vm.throw_exception<JS::TypeError>(global_object, "Expected a String argument to parse_cell_name()");
|
||||
return {};
|
||||
}
|
||||
auto position = Sheet::parse_cell_name(name_value.as_string().string());
|
||||
if (!position.has_value())
|
||||
return JS::js_undefined();
|
||||
|
||||
auto object = JS::Object::create_empty(interpreter.global_object());
|
||||
object->put("column", JS::js_string(interpreter, position.value().column));
|
||||
auto object = JS::Object::create_empty(global_object);
|
||||
object->put("column", JS::js_string(vm, position.value().column));
|
||||
object->put("row", JS::Value((unsigned)position.value().row));
|
||||
|
||||
return object;
|
||||
|
@ -124,22 +124,22 @@ void WorkbookObject::initialize(JS::GlobalObject& global_object)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(WorkbookObject::sheet)
|
||||
{
|
||||
if (interpreter.argument_count() != 1) {
|
||||
interpreter.vm().throw_exception<JS::TypeError>(global_object, "Expected exactly one argument to sheet()");
|
||||
if (vm.argument_count() != 1) {
|
||||
vm.throw_exception<JS::TypeError>(global_object, "Expected exactly one argument to sheet()");
|
||||
return {};
|
||||
}
|
||||
auto name_value = interpreter.argument(0);
|
||||
auto name_value = vm.argument(0);
|
||||
if (!name_value.is_string() && !name_value.is_number()) {
|
||||
interpreter.vm().throw_exception<JS::TypeError>(global_object, "Expected a String or Number argument to sheet()");
|
||||
vm.throw_exception<JS::TypeError>(global_object, "Expected a String or Number argument to sheet()");
|
||||
return {};
|
||||
}
|
||||
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
|
||||
if (!this_object->inherits("WorkbookObject")) {
|
||||
interpreter.vm().throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, "WorkbookObject");
|
||||
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, "WorkbookObject");
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -75,13 +75,13 @@ static void update_function_name(Value& value, const FlyString& name)
|
|||
update_function_name(value, name, visited);
|
||||
}
|
||||
|
||||
static String get_function_name(Interpreter& interpreter, Value value)
|
||||
static String get_function_name(GlobalObject& global_object, Value value)
|
||||
{
|
||||
if (value.is_symbol())
|
||||
return String::format("[%s]", value.as_symbol().description().characters());
|
||||
if (value.is_string())
|
||||
return value.as_string().string();
|
||||
return value.to_string(interpreter);
|
||||
return value.to_string(global_object);
|
||||
}
|
||||
|
||||
Value ScopeNode::execute(Interpreter& interpreter, GlobalObject& global_object) const
|
||||
|
@ -106,6 +106,8 @@ Value ExpressionStatement::execute(Interpreter& interpreter, GlobalObject& globa
|
|||
|
||||
CallExpression::ThisAndCallee CallExpression::compute_this_and_callee(Interpreter& interpreter, GlobalObject& global_object) const
|
||||
{
|
||||
auto& vm = interpreter.vm();
|
||||
|
||||
if (is_new_expression()) {
|
||||
// Computing |this| is irrelevant for "new" expression.
|
||||
return { js_undefined(), m_callee->execute(interpreter, global_object) };
|
||||
|
@ -129,13 +131,13 @@ CallExpression::ThisAndCallee CallExpression::compute_this_and_callee(Interprete
|
|||
return {};
|
||||
}
|
||||
|
||||
auto* this_value = is_super_property_lookup ? &interpreter.this_value(global_object).as_object() : lookup_target.to_object(interpreter, global_object);
|
||||
auto* this_value = is_super_property_lookup ? &vm.this_value(global_object).as_object() : lookup_target.to_object(global_object);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
auto property_name = member_expression.computed_property_name(interpreter, global_object);
|
||||
if (!property_name.is_valid())
|
||||
return {};
|
||||
auto callee = lookup_target.to_object(interpreter, global_object)->get(property_name).value_or(js_undefined());
|
||||
auto callee = lookup_target.to_object(global_object)->get(property_name).value_or(js_undefined());
|
||||
return { this_value, callee };
|
||||
}
|
||||
return { &global_object, m_callee->execute(interpreter, global_object) };
|
||||
|
@ -387,7 +389,7 @@ Value ForInStatement::execute(Interpreter& interpreter, GlobalObject& global_obj
|
|||
auto rhs_result = m_rhs->execute(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
auto* object = rhs_result.to_object(interpreter, global_object);
|
||||
auto* object = rhs_result.to_object(global_object);
|
||||
while (object) {
|
||||
auto property_names = object->get_own_properties(*object, Object::PropertyKind::Key, true);
|
||||
for (auto& property_name : property_names.as_object().indexed_properties()) {
|
||||
|
@ -479,11 +481,11 @@ Value BinaryExpression::execute(Interpreter& interpreter, GlobalObject& global_o
|
|||
case BinaryOp::Modulo:
|
||||
return mod(interpreter, lhs_result, rhs_result);
|
||||
case BinaryOp::Exponentiation:
|
||||
return exp(interpreter, lhs_result, rhs_result);
|
||||
return exp(global_object, lhs_result, rhs_result);
|
||||
case BinaryOp::TypedEquals:
|
||||
return Value(strict_eq(interpreter, lhs_result, rhs_result));
|
||||
return Value(strict_eq(lhs_result, rhs_result));
|
||||
case BinaryOp::TypedInequals:
|
||||
return Value(!strict_eq(interpreter, lhs_result, rhs_result));
|
||||
return Value(!strict_eq(lhs_result, rhs_result));
|
||||
case BinaryOp::AbstractEquals:
|
||||
return Value(abstract_eq(interpreter, lhs_result, rhs_result));
|
||||
case BinaryOp::AbstractInequals:
|
||||
|
@ -511,7 +513,7 @@ Value BinaryExpression::execute(Interpreter& interpreter, GlobalObject& global_o
|
|||
case BinaryOp::In:
|
||||
return in(interpreter, lhs_result, rhs_result);
|
||||
case BinaryOp::InstanceOf:
|
||||
return instance_of(interpreter, lhs_result, rhs_result);
|
||||
return instance_of(global_object, lhs_result, rhs_result);
|
||||
}
|
||||
|
||||
ASSERT_NOT_REACHED();
|
||||
|
@ -576,6 +578,7 @@ Reference MemberExpression::to_reference(Interpreter& interpreter, GlobalObject&
|
|||
|
||||
Value UnaryExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
|
||||
{
|
||||
auto& vm = interpreter.vm();
|
||||
if (m_op == UnaryOp::Delete) {
|
||||
auto reference = m_lhs->to_reference(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
|
@ -586,7 +589,7 @@ Value UnaryExpression::execute(Interpreter& interpreter, GlobalObject& global_ob
|
|||
ASSERT(!reference.is_local_variable());
|
||||
if (reference.is_global_variable())
|
||||
return global_object.delete_property(reference.name());
|
||||
auto* base_object = reference.base().to_object(interpreter, global_object);
|
||||
auto* base_object = reference.base().to_object(global_object);
|
||||
if (!base_object)
|
||||
return {};
|
||||
return base_object->delete_property(reference.name());
|
||||
|
@ -626,25 +629,25 @@ Value UnaryExpression::execute(Interpreter& interpreter, GlobalObject& global_ob
|
|||
ASSERT_NOT_REACHED();
|
||||
return {};
|
||||
case Value::Type::Undefined:
|
||||
return js_string(interpreter, "undefined");
|
||||
return js_string(vm, "undefined");
|
||||
case Value::Type::Null:
|
||||
// yes, this is on purpose. yes, this is how javascript works.
|
||||
// yes, it's silly.
|
||||
return js_string(interpreter, "object");
|
||||
return js_string(vm, "object");
|
||||
case Value::Type::Number:
|
||||
return js_string(interpreter, "number");
|
||||
return js_string(vm, "number");
|
||||
case Value::Type::String:
|
||||
return js_string(interpreter, "string");
|
||||
return js_string(vm, "string");
|
||||
case Value::Type::Object:
|
||||
if (lhs_result.is_function())
|
||||
return js_string(interpreter, "function");
|
||||
return js_string(interpreter, "object");
|
||||
return js_string(vm, "function");
|
||||
return js_string(vm, "object");
|
||||
case Value::Type::Boolean:
|
||||
return js_string(interpreter, "boolean");
|
||||
return js_string(vm, "boolean");
|
||||
case Value::Type::Symbol:
|
||||
return js_string(interpreter, "symbol");
|
||||
return js_string(vm, "symbol");
|
||||
case Value::Type::BigInt:
|
||||
return js_string(interpreter, "bigint");
|
||||
return js_string(vm, "bigint");
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
@ -730,20 +733,20 @@ Value ClassExpression::execute(Interpreter& interpreter, GlobalObject& global_ob
|
|||
method_function.set_home_object(&target);
|
||||
|
||||
if (method.kind() == ClassMethod::Kind::Method) {
|
||||
target.define_property(StringOrSymbol::from_value(interpreter, key), method_value);
|
||||
target.define_property(StringOrSymbol::from_value(global_object, key), method_value);
|
||||
} else {
|
||||
String accessor_name = [&] {
|
||||
switch (method.kind()) {
|
||||
case ClassMethod::Kind::Getter:
|
||||
return String::format("get %s", get_function_name(interpreter, key).characters());
|
||||
return String::format("get %s", get_function_name(global_object, key).characters());
|
||||
case ClassMethod::Kind::Setter:
|
||||
return String::format("set %s", get_function_name(interpreter, key).characters());
|
||||
return String::format("set %s", get_function_name(global_object, key).characters());
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
}();
|
||||
update_function_name(method_value, accessor_name);
|
||||
target.define_accessor(StringOrSymbol::from_value(interpreter, key), method_function, method.kind() == ClassMethod::Kind::Getter, Attribute::Configurable | Attribute::Enumerable);
|
||||
target.define_accessor(StringOrSymbol::from_value(global_object, key), method_function, method.kind() == ClassMethod::Kind::Getter, Attribute::Configurable | Attribute::Enumerable);
|
||||
}
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
|
@ -1232,7 +1235,7 @@ Value AssignmentExpression::execute(Interpreter& interpreter, GlobalObject& glob
|
|||
lhs_result = m_lhs->execute(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
rhs_result = exp(interpreter, lhs_result, rhs_result);
|
||||
rhs_result = exp(global_object, lhs_result, rhs_result);
|
||||
break;
|
||||
case AssignmentOp::BitwiseAndAssignment:
|
||||
lhs_result = m_lhs->execute(interpreter, global_object);
|
||||
|
@ -1282,7 +1285,7 @@ Value AssignmentExpression::execute(Interpreter& interpreter, GlobalObject& glob
|
|||
interpreter.vm().throw_exception<ReferenceError>(global_object, ErrorType::InvalidLeftHandAssignment);
|
||||
return {};
|
||||
}
|
||||
update_function_name(rhs_result, get_function_name(interpreter, reference.name().to_value(interpreter)));
|
||||
update_function_name(rhs_result, get_function_name(global_object, reference.name().to_value(interpreter)));
|
||||
reference.put(interpreter, global_object, rhs_result);
|
||||
|
||||
if (interpreter.exception())
|
||||
|
@ -1298,7 +1301,7 @@ Value UpdateExpression::execute(Interpreter& interpreter, GlobalObject& global_o
|
|||
auto old_value = reference.get(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
old_value = old_value.to_numeric(interpreter);
|
||||
old_value = old_value.to_numeric(global_object);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
|
||||
|
@ -1528,7 +1531,7 @@ Value ObjectExpression::execute(Interpreter& interpreter, GlobalObject& global_o
|
|||
if (value.is_function() && property.is_method())
|
||||
value.as_function().set_home_object(object);
|
||||
|
||||
String name = get_function_name(interpreter, key);
|
||||
String name = get_function_name(global_object, key);
|
||||
if (property.type() == ObjectProperty::Type::Getter) {
|
||||
name = String::format("get %s", name.characters());
|
||||
} else if (property.type() == ObjectProperty::Type::Setter) {
|
||||
|
@ -1539,11 +1542,11 @@ Value ObjectExpression::execute(Interpreter& interpreter, GlobalObject& global_o
|
|||
|
||||
if (property.type() == ObjectProperty::Type::Getter || property.type() == ObjectProperty::Type::Setter) {
|
||||
ASSERT(value.is_function());
|
||||
object->define_accessor(PropertyName::from_value(interpreter, key), value.as_function(), property.type() == ObjectProperty::Type::Getter, Attribute::Configurable | Attribute::Enumerable);
|
||||
object->define_accessor(PropertyName::from_value(global_object, key), value.as_function(), property.type() == ObjectProperty::Type::Getter, Attribute::Configurable | Attribute::Enumerable);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
} else {
|
||||
object->define_property(PropertyName::from_value(interpreter, key), value);
|
||||
object->define_property(PropertyName::from_value(global_object, key), value);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
}
|
||||
|
@ -1577,7 +1580,7 @@ PropertyName MemberExpression::computed_property_name(Interpreter& interpreter,
|
|||
if (index.is_symbol())
|
||||
return &index.as_symbol();
|
||||
|
||||
auto index_string = index.to_string(interpreter);
|
||||
auto index_string = index.to_string(global_object);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
return index_string;
|
||||
|
@ -1599,7 +1602,7 @@ Value MemberExpression::execute(Interpreter& interpreter, GlobalObject& global_o
|
|||
auto object_value = m_object->execute(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
auto* object_result = object_value.to_object(interpreter, global_object);
|
||||
auto* object_result = object_value.to_object(global_object);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
auto property_name = computed_property_name(interpreter, global_object);
|
||||
|
@ -1697,7 +1700,7 @@ Value TemplateLiteral::execute(Interpreter& interpreter, GlobalObject& global_ob
|
|||
auto expr = expression.execute(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
auto string = expr.to_string(interpreter);
|
||||
auto string = expr.to_string(global_object);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
string_builder.append(string);
|
||||
|
@ -1849,7 +1852,7 @@ Value SwitchStatement::execute(Interpreter& interpreter, GlobalObject& global_ob
|
|||
auto test_result = switch_case.test()->execute(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
if (!strict_eq(interpreter, discriminant_result, test_result))
|
||||
if (!strict_eq(discriminant_result, test_result))
|
||||
continue;
|
||||
}
|
||||
falling_through = true;
|
||||
|
|
|
@ -27,22 +27,22 @@
|
|||
#pragma once
|
||||
|
||||
#define JS_DECLARE_NATIVE_FUNCTION(name) \
|
||||
static JS::Value name(JS::Interpreter&, JS::GlobalObject&)
|
||||
static JS::Value name(JS::VM&, JS::GlobalObject&)
|
||||
|
||||
#define JS_DECLARE_NATIVE_GETTER(name) \
|
||||
static JS::Value name(JS::Interpreter&, JS::GlobalObject&)
|
||||
static JS::Value name(JS::VM&, JS::GlobalObject&)
|
||||
|
||||
#define JS_DECLARE_NATIVE_SETTER(name) \
|
||||
static void name(JS::Interpreter&, JS::GlobalObject&, JS::Value)
|
||||
static void name(JS::VM&, JS::GlobalObject&, JS::Value)
|
||||
|
||||
#define JS_DEFINE_NATIVE_FUNCTION(name) \
|
||||
JS::Value name([[maybe_unused]] JS::Interpreter& interpreter, [[maybe_unused]] JS::GlobalObject& global_object)
|
||||
JS::Value name([[maybe_unused]] JS::VM& vm, [[maybe_unused]] JS::GlobalObject& global_object)
|
||||
|
||||
#define JS_DEFINE_NATIVE_GETTER(name) \
|
||||
JS::Value name([[maybe_unused]] JS::Interpreter& interpreter, [[maybe_unused]] JS::GlobalObject& global_object)
|
||||
JS::Value name([[maybe_unused]] JS::VM& vm, [[maybe_unused]] JS::GlobalObject& global_object)
|
||||
|
||||
#define JS_DEFINE_NATIVE_SETTER(name) \
|
||||
void name([[maybe_unused]] JS::Interpreter& interpreter, [[maybe_unused]] JS::GlobalObject& global_object, JS::Value value)
|
||||
void name([[maybe_unused]] JS::VM& vm, [[maybe_unused]] JS::GlobalObject& global_object, JS::Value value)
|
||||
|
||||
#define JS_ENUMERATE_NATIVE_OBJECTS \
|
||||
__JS_ENUMERATE(Array, array, ArrayPrototype, ArrayConstructor) \
|
||||
|
|
|
@ -49,13 +49,13 @@ Array::~Array()
|
|||
{
|
||||
}
|
||||
|
||||
Array* Array::typed_this(Interpreter& interpreter, GlobalObject& global_object)
|
||||
Array* Array::typed_this(VM& vm, GlobalObject& global_object)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (!this_object->is_array()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotAn, "Array");
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotAn, "Array");
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<Array*>(this_object);
|
||||
|
@ -63,7 +63,7 @@ Array* Array::typed_this(Interpreter& interpreter, GlobalObject& global_object)
|
|||
|
||||
JS_DEFINE_NATIVE_GETTER(Array::length_getter)
|
||||
{
|
||||
auto* array = typed_this(interpreter, global_object);
|
||||
auto* array = typed_this(vm, global_object);
|
||||
if (!array)
|
||||
return {};
|
||||
return Value(static_cast<i32>(array->indexed_properties().array_like_size()));
|
||||
|
@ -71,14 +71,14 @@ JS_DEFINE_NATIVE_GETTER(Array::length_getter)
|
|||
|
||||
JS_DEFINE_NATIVE_SETTER(Array::length_setter)
|
||||
{
|
||||
auto* array = typed_this(interpreter, global_object);
|
||||
auto* array = typed_this(vm, global_object);
|
||||
if (!array)
|
||||
return;
|
||||
auto length = value.to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto length = value.to_number(global_object);
|
||||
if (vm.exception())
|
||||
return;
|
||||
if (length.is_nan() || length.is_infinity() || length.as_double() < 0) {
|
||||
interpreter.vm().throw_exception<RangeError>(global_object, ErrorType::ArrayInvalidLength);
|
||||
vm.throw_exception<RangeError>(global_object, ErrorType::ArrayInvalidLength);
|
||||
return;
|
||||
}
|
||||
array->indexed_properties().set_array_like_size(length.as_double());
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
explicit Array(Object& prototype);
|
||||
virtual ~Array() override;
|
||||
|
||||
static Array* typed_this(Interpreter&, GlobalObject&);
|
||||
static Array* typed_this(VM&, GlobalObject&);
|
||||
|
||||
private:
|
||||
virtual bool is_array() const override { return true; }
|
||||
|
|
|
@ -88,8 +88,8 @@ Value ArrayConstructor::construct(Interpreter&, Function&)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
|
||||
{
|
||||
auto value = interpreter.argument(0);
|
||||
auto object = value.to_object(interpreter, global_object);
|
||||
auto value = vm.argument(0);
|
||||
auto object = value.to_object(global_object);
|
||||
if (!object)
|
||||
return {};
|
||||
|
||||
|
@ -98,23 +98,23 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
|
|||
// Array.from() lets you create Arrays from:
|
||||
if (auto size = object->indexed_properties().array_like_size()) {
|
||||
// * array-like objects (objects with a length property and indexed elements)
|
||||
MarkedValueList elements(interpreter.heap());
|
||||
MarkedValueList elements(vm.heap());
|
||||
elements.ensure_capacity(size);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
elements.append(object->get(i));
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
array->set_indexed_property_elements(move(elements));
|
||||
} else {
|
||||
// * iterable objects
|
||||
get_iterator_values(global_object, value, [&](Value element) {
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return IterationDecision::Break;
|
||||
array->indexed_properties().append(element);
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -126,15 +126,15 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::is_array)
|
||||
{
|
||||
auto value = interpreter.argument(0);
|
||||
auto value = vm.argument(0);
|
||||
return Value(value.is_array());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::of)
|
||||
{
|
||||
auto* array = Array::create(global_object);
|
||||
for (size_t i = 0; i < interpreter.argument_count(); ++i)
|
||||
array->indexed_properties().append(interpreter.argument(i));
|
||||
for (size_t i = 0; i < vm.argument_count(); ++i)
|
||||
array->indexed_properties().append(vm.argument(i));
|
||||
return array;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,9 +52,9 @@ ArrayIteratorPrototype::~ArrayIteratorPrototype()
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayIteratorPrototype::next)
|
||||
{
|
||||
auto this_value = interpreter.this_value(global_object);
|
||||
auto this_value = vm.this_value(global_object);
|
||||
if (!this_value.is_object() || !this_value.as_object().is_array_iterator_object()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotAn, "Array Iterator");
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotAn, "Array Iterator");
|
||||
return {};
|
||||
}
|
||||
auto& this_object = this_value.as_object();
|
||||
|
@ -80,7 +80,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayIteratorPrototype::next)
|
|||
return create_iterator_result_object(global_object, Value(static_cast<i32>(index)), false);
|
||||
|
||||
auto value = array.get(index);
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (iteration_kind == Object::PropertyKind::Value)
|
||||
return create_iterator_result_object(global_object, value, false);
|
||||
|
|
|
@ -87,47 +87,48 @@ ArrayPrototype::~ArrayPrototype()
|
|||
{
|
||||
}
|
||||
|
||||
static Function* callback_from_args(Interpreter& interpreter, const String& name)
|
||||
static Function* callback_from_args(GlobalObject& global_object, const String& name)
|
||||
{
|
||||
if (interpreter.argument_count() < 1) {
|
||||
interpreter.vm().throw_exception<TypeError>(interpreter.global_object(), ErrorType::ArrayPrototypeOneArg, name.characters());
|
||||
auto& vm = global_object.vm();
|
||||
if (vm.argument_count() < 1) {
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ArrayPrototypeOneArg, name.characters());
|
||||
return nullptr;
|
||||
}
|
||||
auto callback = interpreter.argument(0);
|
||||
auto callback = vm.argument(0);
|
||||
if (!callback.is_function()) {
|
||||
interpreter.vm().throw_exception<TypeError>(interpreter.global_object(), ErrorType::NotAFunction, callback.to_string_without_side_effects().characters());
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotAFunction, callback.to_string_without_side_effects().characters());
|
||||
return nullptr;
|
||||
}
|
||||
return &callback.as_function();
|
||||
}
|
||||
|
||||
static size_t get_length(Interpreter& interpreter, Object& object)
|
||||
static size_t get_length(VM& vm, Object& object)
|
||||
{
|
||||
auto length_property = object.get("length");
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return 0;
|
||||
return length_property.to_size_t(interpreter);
|
||||
return length_property.to_size_t(object.global_object());
|
||||
}
|
||||
|
||||
static void for_each_item(Interpreter& interpreter, GlobalObject& global_object, const String& name, AK::Function<IterationDecision(size_t index, Value value, Value callback_result)> callback, bool skip_empty = true)
|
||||
static void for_each_item(VM& vm, GlobalObject& global_object, const String& name, AK::Function<IterationDecision(size_t index, Value value, Value callback_result)> callback, bool skip_empty = true)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return;
|
||||
|
||||
auto initial_length = get_length(interpreter, *this_object);
|
||||
if (interpreter.exception())
|
||||
auto initial_length = get_length(vm, *this_object);
|
||||
if (vm.exception())
|
||||
return;
|
||||
|
||||
auto* callback_function = callback_from_args(interpreter, name);
|
||||
auto* callback_function = callback_from_args(global_object, name);
|
||||
if (!callback_function)
|
||||
return;
|
||||
|
||||
auto this_value = interpreter.argument(1);
|
||||
auto this_value = vm.argument(1);
|
||||
|
||||
for (size_t i = 0; i < initial_length; ++i) {
|
||||
auto value = this_object->get(i);
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return;
|
||||
if (value.is_empty()) {
|
||||
if (skip_empty)
|
||||
|
@ -135,8 +136,8 @@ static void for_each_item(Interpreter& interpreter, GlobalObject& global_object,
|
|||
value = js_undefined();
|
||||
}
|
||||
|
||||
auto callback_result = interpreter.call(*callback_function, this_value, value, Value((i32)i), this_object);
|
||||
if (interpreter.exception())
|
||||
auto callback_result = vm.call(*callback_function, this_value, value, Value((i32)i), this_object);
|
||||
if (vm.exception())
|
||||
return;
|
||||
|
||||
if (callback(i, value, callback_result) == IterationDecision::Break)
|
||||
|
@ -147,7 +148,7 @@ static void for_each_item(Interpreter& interpreter, GlobalObject& global_object,
|
|||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::filter)
|
||||
{
|
||||
auto* new_array = Array::create(global_object);
|
||||
for_each_item(interpreter, global_object, "filter", [&](auto, auto value, auto callback_result) {
|
||||
for_each_item(vm, global_object, "filter", [&](auto, auto value, auto callback_result) {
|
||||
if (callback_result.to_boolean())
|
||||
new_array->indexed_properties().append(value);
|
||||
return IterationDecision::Continue;
|
||||
|
@ -157,7 +158,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::filter)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::for_each)
|
||||
{
|
||||
for_each_item(interpreter, global_object, "forEach", [](auto, auto, auto) {
|
||||
for_each_item(vm, global_object, "forEach", [](auto, auto, auto) {
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
return js_undefined();
|
||||
|
@ -165,16 +166,16 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::for_each)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::map)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
auto initial_length = get_length(interpreter, *this_object);
|
||||
if (interpreter.exception())
|
||||
auto initial_length = get_length(vm, *this_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto* new_array = Array::create(global_object);
|
||||
new_array->indexed_properties().set_array_like_size(initial_length);
|
||||
for_each_item(interpreter, global_object, "map", [&](auto index, auto, auto callback_result) {
|
||||
if (interpreter.exception())
|
||||
for_each_item(vm, global_object, "map", [&](auto index, auto, auto callback_result) {
|
||||
if (vm.exception())
|
||||
return IterationDecision::Break;
|
||||
new_array->define_property(index, callback_result);
|
||||
return IterationDecision::Continue;
|
||||
|
@ -184,49 +185,49 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::map)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::push)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (this_object->is_array()) {
|
||||
auto* array = static_cast<Array*>(this_object);
|
||||
for (size_t i = 0; i < interpreter.argument_count(); ++i)
|
||||
array->indexed_properties().append(interpreter.argument(i));
|
||||
for (size_t i = 0; i < vm.argument_count(); ++i)
|
||||
array->indexed_properties().append(vm.argument(i));
|
||||
return Value(static_cast<i32>(array->indexed_properties().array_like_size()));
|
||||
}
|
||||
auto length = get_length(interpreter, *this_object);
|
||||
if (interpreter.exception())
|
||||
auto length = get_length(vm, *this_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto argument_count = interpreter.argument_count();
|
||||
auto argument_count = vm.argument_count();
|
||||
auto new_length = length + argument_count;
|
||||
if (new_length > MAX_ARRAY_LIKE_INDEX) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::ArrayMaxSize);
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ArrayMaxSize);
|
||||
return {};
|
||||
}
|
||||
for (size_t i = 0; i < argument_count; ++i) {
|
||||
this_object->put(length + i, interpreter.argument(i));
|
||||
if (interpreter.exception())
|
||||
this_object->put(length + i, vm.argument(i));
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
auto new_length_value = Value((i32)new_length);
|
||||
this_object->put("length", new_length_value);
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return new_length_value;
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::unshift)
|
||||
{
|
||||
auto* array = Array::typed_this(interpreter, global_object);
|
||||
auto* array = Array::typed_this(vm, global_object);
|
||||
if (!array)
|
||||
return {};
|
||||
for (size_t i = 0; i < interpreter.argument_count(); ++i)
|
||||
array->indexed_properties().insert(i, interpreter.argument(i));
|
||||
for (size_t i = 0; i < vm.argument_count(); ++i)
|
||||
array->indexed_properties().insert(i, vm.argument(i));
|
||||
return Value(static_cast<i32>(array->indexed_properties().array_like_size()));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::pop)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (this_object->is_array()) {
|
||||
|
@ -235,129 +236,129 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::pop)
|
|||
return js_undefined();
|
||||
return array->indexed_properties().take_last(array).value.value_or(js_undefined());
|
||||
}
|
||||
auto length = get_length(interpreter, *this_object);
|
||||
auto length = get_length(vm, *this_object);
|
||||
if (length == 0) {
|
||||
this_object->put("length", Value(0));
|
||||
return js_undefined();
|
||||
}
|
||||
auto index = length - 1;
|
||||
auto element = this_object->get(index).value_or(js_undefined());
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
this_object->delete_property(index);
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
this_object->put("length", Value((i32)index));
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return element;
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::shift)
|
||||
{
|
||||
auto* array = Array::typed_this(interpreter, global_object);
|
||||
auto* array = Array::typed_this(vm, global_object);
|
||||
if (!array)
|
||||
return {};
|
||||
if (array->indexed_properties().is_empty())
|
||||
return js_undefined();
|
||||
auto result = array->indexed_properties().take_first(array);
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return result.value.value_or(js_undefined());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_string)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
auto join_function = this_object->get("join");
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (!join_function.is_function())
|
||||
return ObjectPrototype::to_string(interpreter, global_object);
|
||||
return interpreter.call(join_function.as_function(), this_object);
|
||||
return ObjectPrototype::to_string(vm, global_object);
|
||||
return vm.call(join_function.as_function(), this_object);
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_locale_string)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
String separator = ","; // NOTE: This is implementation-specific.
|
||||
auto length = get_length(interpreter, *this_object);
|
||||
if (interpreter.exception())
|
||||
auto length = get_length(vm, *this_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
StringBuilder builder;
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
if (i > 0)
|
||||
builder.append(separator);
|
||||
auto value = this_object->get(i).value_or(js_undefined());
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (value.is_undefined() || value.is_null())
|
||||
continue;
|
||||
auto* value_object = value.to_object(interpreter, global_object);
|
||||
auto* value_object = value.to_object(global_object);
|
||||
ASSERT(value_object);
|
||||
auto locale_string_result = value_object->invoke("toLocaleString");
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto string = locale_string_result.to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto string = locale_string_result.to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
builder.append(string);
|
||||
}
|
||||
return js_string(interpreter, builder.to_string());
|
||||
return js_string(vm, builder.to_string());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::join)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
String separator = ",";
|
||||
if (interpreter.argument_count()) {
|
||||
separator = interpreter.argument(0).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (vm.argument_count()) {
|
||||
separator = vm.argument(0).to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
auto length = get_length(interpreter, *this_object);
|
||||
if (interpreter.exception())
|
||||
auto length = get_length(vm, *this_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
StringBuilder builder;
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
if (i > 0)
|
||||
builder.append(separator);
|
||||
auto value = this_object->get(i).value_or(js_undefined());
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (value.is_undefined() || value.is_null())
|
||||
continue;
|
||||
auto string = value.to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto string = value.to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
builder.append(string);
|
||||
}
|
||||
return js_string(interpreter, builder.to_string());
|
||||
return js_string(vm, builder.to_string());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::concat)
|
||||
{
|
||||
auto* array = Array::typed_this(interpreter, global_object);
|
||||
auto* array = Array::typed_this(vm, global_object);
|
||||
if (!array)
|
||||
return {};
|
||||
|
||||
auto* new_array = Array::create(global_object);
|
||||
new_array->indexed_properties().append_all(array, array->indexed_properties());
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
for (size_t i = 0; i < interpreter.argument_count(); ++i) {
|
||||
auto argument = interpreter.argument(i);
|
||||
for (size_t i = 0; i < vm.argument_count(); ++i) {
|
||||
auto argument = vm.argument(i);
|
||||
if (argument.is_array()) {
|
||||
auto& argument_object = argument.as_object();
|
||||
new_array->indexed_properties().append_all(&argument_object, argument_object.indexed_properties());
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
} else {
|
||||
new_array->indexed_properties().append(argument);
|
||||
|
@ -369,21 +370,21 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::concat)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::slice)
|
||||
{
|
||||
auto* array = Array::typed_this(interpreter, global_object);
|
||||
auto* array = Array::typed_this(vm, global_object);
|
||||
if (!array)
|
||||
return {};
|
||||
|
||||
auto* new_array = Array::create(global_object);
|
||||
if (interpreter.argument_count() == 0) {
|
||||
if (vm.argument_count() == 0) {
|
||||
new_array->indexed_properties().append_all(array, array->indexed_properties());
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return new_array;
|
||||
}
|
||||
|
||||
ssize_t array_size = static_cast<ssize_t>(array->indexed_properties().array_like_size());
|
||||
auto start_slice = interpreter.argument(0).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto start_slice = vm.argument(0).to_i32(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto end_slice = array_size;
|
||||
|
||||
|
@ -393,9 +394,9 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::slice)
|
|||
if (start_slice < 0)
|
||||
start_slice = end_slice + start_slice;
|
||||
|
||||
if (interpreter.argument_count() >= 2) {
|
||||
end_slice = interpreter.argument(1).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (vm.argument_count() >= 2) {
|
||||
end_slice = vm.argument(1).to_i32(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (end_slice < 0)
|
||||
end_slice = array_size + end_slice;
|
||||
|
@ -405,7 +406,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::slice)
|
|||
|
||||
for (ssize_t i = start_slice; i < end_slice; ++i) {
|
||||
new_array->indexed_properties().append(array->get(i));
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -414,30 +415,30 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::slice)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::index_of)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
i32 length = get_length(interpreter, *this_object);
|
||||
if (interpreter.exception())
|
||||
i32 length = get_length(vm, *this_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (length == 0)
|
||||
return Value(-1);
|
||||
i32 from_index = 0;
|
||||
if (interpreter.argument_count() >= 2) {
|
||||
from_index = interpreter.argument(1).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (vm.argument_count() >= 2) {
|
||||
from_index = vm.argument(1).to_i32(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (from_index >= length)
|
||||
return Value(-1);
|
||||
if (from_index < 0)
|
||||
from_index = max(length + from_index, 0);
|
||||
}
|
||||
auto search_element = interpreter.argument(0);
|
||||
auto search_element = vm.argument(0);
|
||||
for (i32 i = from_index; i < length; ++i) {
|
||||
auto element = this_object->get(i);
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (strict_eq(interpreter, element, search_element))
|
||||
if (strict_eq(element, search_element))
|
||||
return Value(i);
|
||||
}
|
||||
return Value(-1);
|
||||
|
@ -445,28 +446,28 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::index_of)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
|
||||
auto initial_length = get_length(interpreter, *this_object);
|
||||
if (interpreter.exception())
|
||||
auto initial_length = get_length(vm, *this_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
auto* callback_function = callback_from_args(interpreter, "reduce");
|
||||
auto* callback_function = callback_from_args(global_object, "reduce");
|
||||
if (!callback_function)
|
||||
return {};
|
||||
|
||||
size_t start = 0;
|
||||
|
||||
auto accumulator = js_undefined();
|
||||
if (interpreter.argument_count() > 1) {
|
||||
accumulator = interpreter.argument(1);
|
||||
if (vm.argument_count() > 1) {
|
||||
accumulator = vm.argument(1);
|
||||
} else {
|
||||
bool start_found = false;
|
||||
while (!start_found && start < initial_length) {
|
||||
auto value = this_object->get(start);
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
start_found = !value.is_empty();
|
||||
if (start_found)
|
||||
|
@ -474,7 +475,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce)
|
|||
start += 1;
|
||||
}
|
||||
if (!start_found) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::ReduceNoInitial);
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ReduceNoInitial);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
@ -483,13 +484,13 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce)
|
|||
|
||||
for (size_t i = start; i < initial_length; ++i) {
|
||||
auto value = this_object->get(i);
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (value.is_empty())
|
||||
continue;
|
||||
|
||||
accumulator = interpreter.call(*callback_function, this_value, accumulator, value, Value((i32)i), this_object);
|
||||
if (interpreter.exception())
|
||||
accumulator = vm.call(*callback_function, this_value, accumulator, value, Value((i32)i), this_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -498,28 +499,28 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce_right)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
|
||||
auto initial_length = get_length(interpreter, *this_object);
|
||||
if (interpreter.exception())
|
||||
auto initial_length = get_length(vm, *this_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
auto* callback_function = callback_from_args(interpreter, "reduceRight");
|
||||
auto* callback_function = callback_from_args(global_object, "reduceRight");
|
||||
if (!callback_function)
|
||||
return {};
|
||||
|
||||
int start = initial_length - 1;
|
||||
|
||||
auto accumulator = js_undefined();
|
||||
if (interpreter.argument_count() > 1) {
|
||||
accumulator = interpreter.argument(1);
|
||||
if (vm.argument_count() > 1) {
|
||||
accumulator = vm.argument(1);
|
||||
} else {
|
||||
bool start_found = false;
|
||||
while (!start_found && start >= 0) {
|
||||
auto value = this_object->get(start);
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
start_found = !value.is_empty();
|
||||
if (start_found)
|
||||
|
@ -527,7 +528,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce_right)
|
|||
start -= 1;
|
||||
}
|
||||
if (!start_found) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::ReduceNoInitial);
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ReduceNoInitial);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
@ -536,13 +537,13 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce_right)
|
|||
|
||||
for (int i = start; i >= 0; --i) {
|
||||
auto value = this_object->get(i);
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (value.is_empty())
|
||||
continue;
|
||||
|
||||
accumulator = interpreter.call(*callback_function, this_value, accumulator, value, Value((i32)i), this_object);
|
||||
if (interpreter.exception())
|
||||
accumulator = vm.call(*callback_function, this_value, accumulator, value, Value((i32)i), this_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -551,20 +552,20 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce_right)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reverse)
|
||||
{
|
||||
auto* array = Array::typed_this(interpreter, global_object);
|
||||
auto* array = Array::typed_this(vm, global_object);
|
||||
if (!array)
|
||||
return {};
|
||||
|
||||
if (array->indexed_properties().is_empty())
|
||||
return array;
|
||||
|
||||
MarkedValueList array_reverse(interpreter.heap());
|
||||
MarkedValueList array_reverse(vm.heap());
|
||||
auto size = array->indexed_properties().array_like_size();
|
||||
array_reverse.ensure_capacity(size);
|
||||
|
||||
for (ssize_t i = size - 1; i >= 0; --i) {
|
||||
array_reverse.append(array->get(i));
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -575,30 +576,30 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reverse)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::last_index_of)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
i32 length = get_length(interpreter, *this_object);
|
||||
if (interpreter.exception())
|
||||
i32 length = get_length(vm, *this_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (length == 0)
|
||||
return Value(-1);
|
||||
i32 from_index = length - 1;
|
||||
if (interpreter.argument_count() >= 2) {
|
||||
from_index = interpreter.argument(1).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (vm.argument_count() >= 2) {
|
||||
from_index = vm.argument(1).to_i32(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (from_index >= 0)
|
||||
from_index = min(from_index, length - 1);
|
||||
else
|
||||
from_index = length + from_index;
|
||||
}
|
||||
auto search_element = interpreter.argument(0);
|
||||
auto search_element = vm.argument(0);
|
||||
for (i32 i = from_index; i >= 0; --i) {
|
||||
auto element = this_object->get(i);
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (strict_eq(interpreter, element, search_element))
|
||||
if (strict_eq(element, search_element))
|
||||
return Value(i);
|
||||
}
|
||||
return Value(-1);
|
||||
|
@ -606,30 +607,30 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::last_index_of)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::includes)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
i32 length = get_length(interpreter, *this_object);
|
||||
if (interpreter.exception())
|
||||
i32 length = get_length(vm, *this_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (length == 0)
|
||||
return Value(false);
|
||||
i32 from_index = 0;
|
||||
if (interpreter.argument_count() >= 2) {
|
||||
from_index = interpreter.argument(1).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (vm.argument_count() >= 2) {
|
||||
from_index = vm.argument(1).to_i32(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (from_index >= length)
|
||||
return Value(false);
|
||||
if (from_index < 0)
|
||||
from_index = max(length + from_index, 0);
|
||||
}
|
||||
auto value_to_find = interpreter.argument(0);
|
||||
auto value_to_find = vm.argument(0);
|
||||
for (i32 i = from_index; i < length; ++i) {
|
||||
auto element = this_object->get(i).value_or(js_undefined());
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (same_value_zero(interpreter, element, value_to_find))
|
||||
if (same_value_zero(element, value_to_find))
|
||||
return Value(true);
|
||||
}
|
||||
return Value(false);
|
||||
|
@ -639,7 +640,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find)
|
|||
{
|
||||
auto result = js_undefined();
|
||||
for_each_item(
|
||||
interpreter, global_object, "find", [&](auto, auto value, auto callback_result) {
|
||||
vm, global_object, "find", [&](auto, auto value, auto callback_result) {
|
||||
if (callback_result.to_boolean()) {
|
||||
result = value;
|
||||
return IterationDecision::Break;
|
||||
|
@ -654,7 +655,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_index)
|
|||
{
|
||||
auto result_index = -1;
|
||||
for_each_item(
|
||||
interpreter, global_object, "findIndex", [&](auto index, auto, auto callback_result) {
|
||||
vm, global_object, "findIndex", [&](auto index, auto, auto callback_result) {
|
||||
if (callback_result.to_boolean()) {
|
||||
result_index = index;
|
||||
return IterationDecision::Break;
|
||||
|
@ -668,7 +669,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_index)
|
|||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::some)
|
||||
{
|
||||
auto result = false;
|
||||
for_each_item(interpreter, global_object, "some", [&](auto, auto, auto callback_result) {
|
||||
for_each_item(vm, global_object, "some", [&](auto, auto, auto callback_result) {
|
||||
if (callback_result.to_boolean()) {
|
||||
result = true;
|
||||
return IterationDecision::Break;
|
||||
|
@ -681,7 +682,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::some)
|
|||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::every)
|
||||
{
|
||||
auto result = true;
|
||||
for_each_item(interpreter, global_object, "every", [&](auto, auto, auto callback_result) {
|
||||
for_each_item(vm, global_object, "every", [&](auto, auto, auto callback_result) {
|
||||
if (!callback_result.to_boolean()) {
|
||||
result = false;
|
||||
return IterationDecision::Break;
|
||||
|
@ -693,16 +694,16 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::every)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
|
||||
auto initial_length = get_length(interpreter, *this_object);
|
||||
if (interpreter.exception())
|
||||
auto initial_length = get_length(vm, *this_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
auto relative_start = interpreter.argument(0).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto relative_start = vm.argument(0).to_i32(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
size_t actual_start;
|
||||
|
@ -715,12 +716,12 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
|
|||
size_t insert_count = 0;
|
||||
size_t actual_delete_count = 0;
|
||||
|
||||
if (interpreter.argument_count() == 1) {
|
||||
if (vm.argument_count() == 1) {
|
||||
actual_delete_count = initial_length - actual_start;
|
||||
} else if (interpreter.argument_count() >= 2) {
|
||||
insert_count = interpreter.argument_count() - 2;
|
||||
i32 delete_count = interpreter.argument(1).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
} else if (vm.argument_count() >= 2) {
|
||||
insert_count = vm.argument_count() - 2;
|
||||
i32 delete_count = vm.argument(1).to_i32(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
actual_delete_count = min((size_t)max(delete_count, 0), initial_length - actual_start);
|
||||
|
@ -729,7 +730,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
|
|||
size_t new_length = initial_length + insert_count - actual_delete_count;
|
||||
|
||||
if (new_length > MAX_ARRAY_LIKE_INDEX) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::ArrayMaxSize);
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ArrayMaxSize);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -737,7 +738,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
|
|||
|
||||
for (size_t i = 0; i < actual_delete_count; ++i) {
|
||||
auto value = this_object->get(actual_start + i);
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
removed_elements->indexed_properties().append(value);
|
||||
|
@ -746,7 +747,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
|
|||
if (insert_count < actual_delete_count) {
|
||||
for (size_t i = actual_start; i < initial_length - actual_delete_count; ++i) {
|
||||
auto from = this_object->get(i + actual_delete_count);
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
auto to = i + insert_count;
|
||||
|
@ -756,19 +757,19 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
|
|||
} else {
|
||||
this_object->delete_property(to);
|
||||
}
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
|
||||
for (size_t i = initial_length; i > new_length; --i) {
|
||||
this_object->delete_property(i - 1);
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
} else if (insert_count > actual_delete_count) {
|
||||
for (size_t i = initial_length - actual_delete_count; i > actual_start; --i) {
|
||||
auto from = this_object->get(i + actual_delete_count - 1);
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
auto to = i + insert_count - 1;
|
||||
|
@ -778,19 +779,19 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
|
|||
} else {
|
||||
this_object->delete_property(to);
|
||||
}
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < insert_count; ++i) {
|
||||
this_object->put(actual_start + i, interpreter.argument(i + 2));
|
||||
if (interpreter.exception())
|
||||
this_object->put(actual_start + i, vm.argument(i + 2));
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
|
||||
this_object->put("length", Value((i32)new_length));
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
return removed_elements;
|
||||
|
@ -798,26 +799,26 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::fill)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
|
||||
ssize_t length = get_length(interpreter, *this_object);
|
||||
if (interpreter.exception())
|
||||
ssize_t length = get_length(vm, *this_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
ssize_t relative_start = 0;
|
||||
ssize_t relative_end = length;
|
||||
|
||||
if (interpreter.argument_count() >= 2) {
|
||||
relative_start = interpreter.argument(1).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (vm.argument_count() >= 2) {
|
||||
relative_start = vm.argument(1).to_i32(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
|
||||
if (interpreter.argument_count() >= 3) {
|
||||
relative_end = interpreter.argument(2).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (vm.argument_count() >= 3) {
|
||||
relative_end = vm.argument(2).to_i32(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -834,8 +835,8 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::fill)
|
|||
to = min(relative_end, length);
|
||||
|
||||
for (size_t i = from; i < to; i++) {
|
||||
this_object->put(i, interpreter.argument(0));
|
||||
if (interpreter.exception())
|
||||
this_object->put(i, vm.argument(0));
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -844,7 +845,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::fill)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::values)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
|
||||
|
|
|
@ -52,13 +52,13 @@ BigIntPrototype::~BigIntPrototype()
|
|||
{
|
||||
}
|
||||
|
||||
static BigIntObject* bigint_object_from(Interpreter& interpreter, GlobalObject& global_object)
|
||||
static BigIntObject* bigint_object_from(VM& vm, GlobalObject& global_object)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return nullptr;
|
||||
if (!this_object->is_bigint_object()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotA, "BigInt");
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "BigInt");
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<BigIntObject*>(this_object);
|
||||
|
@ -66,20 +66,20 @@ static BigIntObject* bigint_object_from(Interpreter& interpreter, GlobalObject&
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(BigIntPrototype::to_string)
|
||||
{
|
||||
auto* bigint_object = bigint_object_from(interpreter, global_object);
|
||||
auto* bigint_object = bigint_object_from(vm, global_object);
|
||||
if (!bigint_object)
|
||||
return {};
|
||||
return js_string(interpreter, bigint_object->bigint().big_integer().to_base10());
|
||||
return js_string(vm, bigint_object->bigint().big_integer().to_base10());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(BigIntPrototype::to_locale_string)
|
||||
{
|
||||
return to_string(interpreter, global_object);
|
||||
return to_string(vm, global_object);
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(BigIntPrototype::value_of)
|
||||
{
|
||||
auto* bigint_object = bigint_object_from(interpreter, global_object);
|
||||
auto* bigint_object = bigint_object_from(vm, global_object);
|
||||
if (!bigint_object)
|
||||
return {};
|
||||
return bigint_object->value_of();
|
||||
|
|
|
@ -50,27 +50,27 @@ BooleanPrototype::~BooleanPrototype()
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(BooleanPrototype::to_string)
|
||||
{
|
||||
auto this_object = interpreter.this_value(global_object);
|
||||
auto this_object = vm.this_value(global_object);
|
||||
if (this_object.is_boolean()) {
|
||||
return js_string(interpreter.heap(), this_object.as_bool() ? "true" : "false");
|
||||
return js_string(vm, this_object.as_bool() ? "true" : "false");
|
||||
}
|
||||
if (!this_object.is_object() || !this_object.as_object().is_boolean_object()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotA, "Boolean");
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "Boolean");
|
||||
return {};
|
||||
}
|
||||
|
||||
bool bool_value = static_cast<BooleanObject&>(this_object.as_object()).value_of().as_bool();
|
||||
return js_string(interpreter.heap(), bool_value ? "true" : "false");
|
||||
return js_string(vm, bool_value ? "true" : "false");
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(BooleanPrototype::value_of)
|
||||
{
|
||||
auto this_object = interpreter.this_value(global_object);
|
||||
auto this_object = vm.this_value(global_object);
|
||||
if (this_object.is_boolean()) {
|
||||
return this_object;
|
||||
}
|
||||
if (!this_object.is_object() || !this_object.as_object().is_boolean_object()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotA, "Boolean");
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "Boolean");
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ Value BoundFunction::call()
|
|||
|
||||
Value BoundFunction::construct(Interpreter& interpreter, Function& new_target)
|
||||
{
|
||||
if (auto this_value = interpreter.this_value(global_object()); m_constructor_prototype && this_value.is_object()) {
|
||||
if (auto this_value = vm().this_value(global_object()); m_constructor_prototype && this_value.is_object()) {
|
||||
this_value.as_object().set_prototype(m_constructor_prototype);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
|
|
|
@ -60,47 +60,47 @@ ConsoleObject::~ConsoleObject()
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ConsoleObject::log)
|
||||
{
|
||||
return interpreter.console().log();
|
||||
return vm.interpreter().console().log();
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ConsoleObject::debug)
|
||||
{
|
||||
return interpreter.console().debug();
|
||||
return vm.interpreter().console().debug();
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ConsoleObject::info)
|
||||
{
|
||||
return interpreter.console().info();
|
||||
return vm.interpreter().console().info();
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ConsoleObject::warn)
|
||||
{
|
||||
return interpreter.console().warn();
|
||||
return vm.interpreter().console().warn();
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ConsoleObject::error)
|
||||
{
|
||||
return interpreter.console().error();
|
||||
return vm.interpreter().console().error();
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ConsoleObject::trace)
|
||||
{
|
||||
return interpreter.console().trace();
|
||||
return vm.interpreter().console().trace();
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ConsoleObject::count)
|
||||
{
|
||||
return interpreter.console().count();
|
||||
return vm.interpreter().console().count();
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ConsoleObject::count_reset)
|
||||
{
|
||||
return interpreter.console().count_reset();
|
||||
return vm.interpreter().console().count_reset();
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ConsoleObject::clear)
|
||||
{
|
||||
return interpreter.console().clear();
|
||||
return vm.interpreter().console().clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -165,31 +165,31 @@ Value DateConstructor::call()
|
|||
return js_string(heap(), static_cast<Date&>(date.as_object()).string());
|
||||
}
|
||||
|
||||
Value DateConstructor::construct(Interpreter& interpreter, Function&)
|
||||
Value DateConstructor::construct(Interpreter&, Function&)
|
||||
{
|
||||
if (interpreter.argument_count() == 0) {
|
||||
if (vm().argument_count() == 0) {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
auto datetime = Core::DateTime::now();
|
||||
auto milliseconds = static_cast<u16>(tv.tv_usec / 1000);
|
||||
return Date::create(global_object(), datetime, milliseconds);
|
||||
}
|
||||
if (interpreter.argument_count() == 1) {
|
||||
auto value = interpreter.argument(0);
|
||||
if (vm().argument_count() == 1) {
|
||||
auto value = vm().argument(0);
|
||||
if (value.is_string())
|
||||
value = parse_simplified_iso8601(value.as_string().string());
|
||||
// A timestamp since the epoch, in UTC.
|
||||
// FIXME: Date() probably should use a double as internal representation, so that NaN arguments and larger offsets are handled correctly.
|
||||
double value_as_double = value.to_double(interpreter);
|
||||
double value_as_double = value.to_double(global_object());
|
||||
auto datetime = Core::DateTime::from_timestamp(static_cast<time_t>(value_as_double / 1000));
|
||||
auto milliseconds = static_cast<u16>(fmod(value_as_double, 1000));
|
||||
return Date::create(global_object(), datetime, milliseconds);
|
||||
}
|
||||
// A date/time in components, in local time.
|
||||
// FIXME: This doesn't construct an "Invalid Date" object if one of the parameters is NaN.
|
||||
auto arg_or = [&interpreter](size_t i, i32 fallback) { return interpreter.argument_count() > i ? interpreter.argument(i).to_i32(interpreter) : fallback; };
|
||||
int year = interpreter.argument(0).to_i32(interpreter);
|
||||
int month_index = interpreter.argument(1).to_i32(interpreter);
|
||||
auto arg_or = [this](size_t i, i32 fallback) { return vm().argument_count() > i ? vm().argument(i).to_i32(global_object()) : fallback; };
|
||||
int year = vm().argument(0).to_i32(global_object());
|
||||
int month_index = vm().argument(1).to_i32(global_object());
|
||||
int day = arg_or(2, 1);
|
||||
int hours = arg_or(3, 0);
|
||||
int minutes = arg_or(4, 0);
|
||||
|
@ -219,11 +219,11 @@ JS_DEFINE_NATIVE_FUNCTION(DateConstructor::now)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DateConstructor::parse)
|
||||
{
|
||||
if (!interpreter.argument_count())
|
||||
if (!vm.argument_count())
|
||||
return js_nan();
|
||||
|
||||
auto iso_8601 = interpreter.argument(0).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto iso_8601 = vm.argument(0).to_string(global_object);
|
||||
if (vm.exception())
|
||||
return js_nan();
|
||||
|
||||
return parse_simplified_iso8601(iso_8601);
|
||||
|
@ -231,8 +231,8 @@ JS_DEFINE_NATIVE_FUNCTION(DateConstructor::parse)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DateConstructor::utc)
|
||||
{
|
||||
auto arg_or = [&interpreter](size_t i, i32 fallback) { return interpreter.argument_count() > i ? interpreter.argument(i).to_i32(interpreter) : fallback; };
|
||||
int year = interpreter.argument(0).to_i32(interpreter);
|
||||
auto arg_or = [&vm, &global_object](size_t i, i32 fallback) { return vm.argument_count() > i ? vm.argument(i).to_i32(global_object) : fallback; };
|
||||
int year = vm.argument(0).to_i32(global_object);
|
||||
if (year >= 0 && year <= 99)
|
||||
year += 1900;
|
||||
|
||||
|
|
|
@ -36,13 +36,13 @@
|
|||
|
||||
namespace JS {
|
||||
|
||||
static Date* typed_this(Interpreter& interpreter, GlobalObject& global_object)
|
||||
static Date* typed_this(VM& vm, GlobalObject& global_object)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return nullptr;
|
||||
if (!this_object->is_date()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotA, "Date");
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "Date");
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<Date*>(this_object);
|
||||
|
@ -96,7 +96,7 @@ DatePrototype::~DatePrototype()
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_date)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return Value(static_cast<double>(this_object->date()));
|
||||
|
@ -104,7 +104,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_date)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_day)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return Value(static_cast<double>(this_object->day()));
|
||||
|
@ -112,7 +112,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_day)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_full_year)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return Value(static_cast<double>(this_object->full_year()));
|
||||
|
@ -120,7 +120,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_full_year)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_hours)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return Value(static_cast<double>(this_object->hours()));
|
||||
|
@ -128,7 +128,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_hours)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_milliseconds)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return Value(static_cast<double>(this_object->milliseconds()));
|
||||
|
@ -136,7 +136,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_milliseconds)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_minutes)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return Value(static_cast<double>(this_object->minutes()));
|
||||
|
@ -144,7 +144,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_minutes)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_month)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return Value(static_cast<double>(this_object->month()));
|
||||
|
@ -152,7 +152,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_month)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_seconds)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return Value(static_cast<double>(this_object->seconds()));
|
||||
|
@ -160,7 +160,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_seconds)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_time)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return Value(this_object->time());
|
||||
|
@ -168,7 +168,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_time)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_date)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return Value(static_cast<double>(this_object->utc_date()));
|
||||
|
@ -176,7 +176,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_date)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_day)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return Value(static_cast<double>(this_object->utc_day()));
|
||||
|
@ -184,7 +184,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_day)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_full_year)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return Value(static_cast<double>(this_object->utc_full_year()));
|
||||
|
@ -192,7 +192,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_full_year)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_hours)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return Value(static_cast<double>(this_object->utc_hours()));
|
||||
|
@ -200,7 +200,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_hours)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_milliseconds)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return Value(static_cast<double>(this_object->utc_milliseconds()));
|
||||
|
@ -208,7 +208,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_milliseconds)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_month)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return Value(static_cast<double>(this_object->utc_month()));
|
||||
|
@ -216,7 +216,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_month)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_minutes)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return Value(static_cast<double>(this_object->utc_minutes()));
|
||||
|
@ -224,7 +224,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_minutes)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_seconds)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return Value(static_cast<double>(this_object->utc_seconds()));
|
||||
|
@ -232,68 +232,68 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_seconds)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_date_string)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
auto string = this_object->date_string();
|
||||
return js_string(interpreter, move(string));
|
||||
return js_string(vm, move(string));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_iso_string)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
auto string = this_object->iso_date_string();
|
||||
return js_string(interpreter, move(string));
|
||||
return js_string(vm, move(string));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_date_string)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
// FIXME: Optional locales, options params.
|
||||
auto string = this_object->locale_date_string();
|
||||
return js_string(interpreter, move(string));
|
||||
return js_string(vm, move(string));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_string)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
// FIXME: Optional locales, options params.
|
||||
auto string = this_object->locale_string();
|
||||
return js_string(interpreter, move(string));
|
||||
return js_string(vm, move(string));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_time_string)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
// FIXME: Optional locales, options params.
|
||||
auto string = this_object->locale_time_string();
|
||||
return js_string(interpreter, move(string));
|
||||
return js_string(vm, move(string));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_time_string)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
auto string = this_object->time_string();
|
||||
return js_string(interpreter, move(string));
|
||||
return js_string(vm, move(string));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_string)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
auto string = this_object->string();
|
||||
return js_string(interpreter, move(string));
|
||||
return js_string(vm, move(string));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,38 +56,38 @@ Value ErrorConstructor::construct(Interpreter& interpreter, Function&)
|
|||
{
|
||||
String message = "";
|
||||
if (!interpreter.call_frame().arguments.is_empty() && !interpreter.call_frame().arguments[0].is_undefined()) {
|
||||
message = interpreter.call_frame().arguments[0].to_string(interpreter);
|
||||
message = interpreter.call_frame().arguments[0].to_string(global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
}
|
||||
return Error::create(global_object(), "Error", message);
|
||||
}
|
||||
|
||||
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \
|
||||
ConstructorName::ConstructorName(GlobalObject& global_object) \
|
||||
: NativeFunction(*global_object.function_prototype()) \
|
||||
{ \
|
||||
} \
|
||||
void ConstructorName::initialize(GlobalObject& global_object) \
|
||||
{ \
|
||||
NativeFunction::initialize(global_object); \
|
||||
define_property("prototype", global_object.snake_name##_prototype(), 0); \
|
||||
define_property("length", Value(1), Attribute::Configurable); \
|
||||
} \
|
||||
ConstructorName::~ConstructorName() { } \
|
||||
Value ConstructorName::call() \
|
||||
{ \
|
||||
return construct(interpreter(), *this); \
|
||||
} \
|
||||
Value ConstructorName::construct(Interpreter& interpreter, Function&) \
|
||||
{ \
|
||||
String message = ""; \
|
||||
if (!interpreter.call_frame().arguments.is_empty() && !interpreter.call_frame().arguments[0].is_undefined()) { \
|
||||
message = interpreter.call_frame().arguments[0].to_string(interpreter); \
|
||||
if (interpreter.exception()) \
|
||||
return {}; \
|
||||
} \
|
||||
return ClassName::create(global_object(), message); \
|
||||
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \
|
||||
ConstructorName::ConstructorName(GlobalObject& global_object) \
|
||||
: NativeFunction(*global_object.function_prototype()) \
|
||||
{ \
|
||||
} \
|
||||
void ConstructorName::initialize(GlobalObject& global_object) \
|
||||
{ \
|
||||
NativeFunction::initialize(global_object); \
|
||||
define_property("prototype", global_object.snake_name##_prototype(), 0); \
|
||||
define_property("length", Value(1), Attribute::Configurable); \
|
||||
} \
|
||||
ConstructorName::~ConstructorName() { } \
|
||||
Value ConstructorName::call() \
|
||||
{ \
|
||||
return construct(interpreter(), *this); \
|
||||
} \
|
||||
Value ConstructorName::construct(Interpreter&, Function&) \
|
||||
{ \
|
||||
String message = ""; \
|
||||
if (!vm().call_frame().arguments.is_empty() && !vm().call_frame().arguments[0].is_undefined()) { \
|
||||
message = vm().call_frame().arguments[0].to_string(global_object()); \
|
||||
if (vm().exception()) \
|
||||
return {}; \
|
||||
} \
|
||||
return ClassName::create(global_object(), message); \
|
||||
}
|
||||
|
||||
JS_ENUMERATE_ERROR_SUBCLASSES
|
||||
|
|
|
@ -54,7 +54,7 @@ private:
|
|||
explicit ConstructorName(GlobalObject&); \
|
||||
virtual void initialize(GlobalObject&) override; \
|
||||
virtual ~ConstructorName() override; \
|
||||
virtual Value call() override; \
|
||||
virtual Value call() override; \
|
||||
virtual Value construct(Interpreter&, Function& new_target) override; \
|
||||
\
|
||||
private: \
|
||||
|
|
|
@ -55,76 +55,76 @@ ErrorPrototype::~ErrorPrototype()
|
|||
|
||||
JS_DEFINE_NATIVE_GETTER(ErrorPrototype::name_getter)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (!this_object->is_error()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotAn, "Error");
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotAn, "Error");
|
||||
return {};
|
||||
}
|
||||
return js_string(interpreter, static_cast<const Error*>(this_object)->name());
|
||||
return js_string(vm, static_cast<const Error*>(this_object)->name());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_SETTER(ErrorPrototype::name_setter)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return;
|
||||
if (!this_object->is_error()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotAn, "Error");
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotAn, "Error");
|
||||
return;
|
||||
}
|
||||
auto name = value.to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto name = value.to_string(global_object);
|
||||
if (vm.exception())
|
||||
return;
|
||||
static_cast<Error*>(this_object)->set_name(name);
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_GETTER(ErrorPrototype::message_getter)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (!this_object->is_error()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotAn, "Error");
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotAn, "Error");
|
||||
return {};
|
||||
}
|
||||
return js_string(interpreter, static_cast<const Error*>(this_object)->message());
|
||||
return js_string(vm, static_cast<const Error*>(this_object)->message());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ErrorPrototype::to_string)
|
||||
{
|
||||
if (!interpreter.this_value(global_object).is_object()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotAnObject, interpreter.this_value(global_object).to_string_without_side_effects().characters());
|
||||
if (!vm.this_value(global_object).is_object()) {
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObject, vm.this_value(global_object).to_string_without_side_effects().characters());
|
||||
return {};
|
||||
}
|
||||
auto& this_object = interpreter.this_value(global_object).as_object();
|
||||
auto& this_object = vm.this_value(global_object).as_object();
|
||||
|
||||
String name = "Error";
|
||||
auto name_property = this_object.get("name");
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (!name_property.is_empty() && !name_property.is_undefined()) {
|
||||
name = name_property.to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
name = name_property.to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
|
||||
String message = "";
|
||||
auto message_property = this_object.get("message");
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (!message_property.is_empty() && !message_property.is_undefined()) {
|
||||
message = message_property.to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
message = message_property.to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
|
||||
if (name.length() == 0)
|
||||
return js_string(interpreter, message);
|
||||
return js_string(vm, message);
|
||||
if (message.length() == 0)
|
||||
return js_string(interpreter, name);
|
||||
return js_string(interpreter, String::format("%s: %s", name.characters(), message.characters()));
|
||||
return js_string(vm, name);
|
||||
return js_string(vm, String::format("%s: %s", name.characters(), message.characters()));
|
||||
}
|
||||
|
||||
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \
|
||||
|
|
|
@ -61,7 +61,7 @@ BoundFunction* Function::bind(Value bound_this_value, Vector<Value> arguments)
|
|||
return bound_this_value;
|
||||
return &global_object();
|
||||
default:
|
||||
return bound_this_value.to_object(interpreter(), global_object());
|
||||
return bound_this_value.to_object(global_object());
|
||||
}
|
||||
}();
|
||||
|
||||
|
|
|
@ -58,25 +58,26 @@ Value FunctionConstructor::call()
|
|||
|
||||
Value FunctionConstructor::construct(Interpreter& interpreter, Function&)
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
String parameters_source = "";
|
||||
String body_source = "";
|
||||
if (interpreter.argument_count() == 1) {
|
||||
body_source = interpreter.argument(0).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (vm.argument_count() == 1) {
|
||||
body_source = vm.argument(0).to_string(global_object());
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
if (interpreter.argument_count() > 1) {
|
||||
if (vm.argument_count() > 1) {
|
||||
Vector<String> parameters;
|
||||
for (size_t i = 0; i < interpreter.argument_count() - 1; ++i) {
|
||||
parameters.append(interpreter.argument(i).to_string(interpreter));
|
||||
if (interpreter.exception())
|
||||
for (size_t i = 0; i < vm.argument_count() - 1; ++i) {
|
||||
parameters.append(vm.argument(i).to_string(global_object()));
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
StringBuilder parameters_builder;
|
||||
parameters_builder.join(',', parameters);
|
||||
parameters_source = parameters_builder.build();
|
||||
body_source = interpreter.argument(interpreter.argument_count() - 1).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
body_source = vm.argument(vm.argument_count() - 1).to_string(global_object());
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
auto source = String::format("function anonymous(%s) { %s }", parameters_source.characters(), body_source.characters());
|
||||
|
@ -84,7 +85,7 @@ Value FunctionConstructor::construct(Interpreter& interpreter, Function&)
|
|||
auto function_expression = parser.parse_function_node<FunctionExpression>();
|
||||
if (parser.has_errors()) {
|
||||
auto error = parser.errors()[0];
|
||||
interpreter.vm().throw_exception<SyntaxError>(global_object(), error.to_string());
|
||||
vm.throw_exception<SyntaxError>(global_object(), error.to_string());
|
||||
return {};
|
||||
}
|
||||
return function_expression->execute(interpreter, global_object());
|
||||
|
|
|
@ -62,53 +62,53 @@ FunctionPrototype::~FunctionPrototype()
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::apply)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (!this_object->is_function()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotA, "Function");
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "Function");
|
||||
return {};
|
||||
}
|
||||
auto& function = static_cast<Function&>(*this_object);
|
||||
auto this_arg = interpreter.argument(0);
|
||||
auto arg_array = interpreter.argument(1);
|
||||
auto this_arg = vm.argument(0);
|
||||
auto arg_array = vm.argument(1);
|
||||
if (arg_array.is_null() || arg_array.is_undefined())
|
||||
return interpreter.call(function, this_arg);
|
||||
return vm.call(function, this_arg);
|
||||
if (!arg_array.is_object()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::FunctionArgsNotObject);
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::FunctionArgsNotObject);
|
||||
return {};
|
||||
}
|
||||
auto length_property = arg_array.as_object().get("length");
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto length = length_property.to_size_t(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto length = length_property.to_size_t(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
MarkedValueList arguments(interpreter.heap());
|
||||
MarkedValueList arguments(vm.heap());
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
auto element = arg_array.as_object().get(i);
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
arguments.append(element.value_or(js_undefined()));
|
||||
}
|
||||
return interpreter.call(function, this_arg, move(arguments));
|
||||
return vm.call(function, this_arg, move(arguments));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::bind)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (!this_object->is_function()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotA, "Function");
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "Function");
|
||||
return {};
|
||||
}
|
||||
auto& this_function = static_cast<Function&>(*this_object);
|
||||
auto bound_this_arg = interpreter.argument(0);
|
||||
auto bound_this_arg = vm.argument(0);
|
||||
|
||||
Vector<Value> arguments;
|
||||
if (interpreter.argument_count() > 1) {
|
||||
arguments = interpreter.call_frame().arguments;
|
||||
if (vm.argument_count() > 1) {
|
||||
arguments = vm.call_frame().arguments;
|
||||
arguments.remove(0);
|
||||
}
|
||||
|
||||
|
@ -117,30 +117,30 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::bind)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::call)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (!this_object->is_function()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotA, "Function");
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "Function");
|
||||
return {};
|
||||
}
|
||||
auto& function = static_cast<Function&>(*this_object);
|
||||
auto this_arg = interpreter.argument(0);
|
||||
MarkedValueList arguments(interpreter.heap());
|
||||
if (interpreter.argument_count() > 1) {
|
||||
for (size_t i = 1; i < interpreter.argument_count(); ++i)
|
||||
arguments.append(interpreter.argument(i));
|
||||
auto this_arg = vm.argument(0);
|
||||
MarkedValueList arguments(vm.heap());
|
||||
if (vm.argument_count() > 1) {
|
||||
for (size_t i = 1; i < vm.argument_count(); ++i)
|
||||
arguments.append(vm.argument(i));
|
||||
}
|
||||
return interpreter.call(function, this_arg, move(arguments));
|
||||
return vm.call(function, this_arg, move(arguments));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::to_string)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (!this_object->is_function()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotA, "Function");
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "Function");
|
||||
return {};
|
||||
}
|
||||
String function_name = static_cast<Function*>(this_object)->name();
|
||||
|
@ -173,19 +173,19 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::to_string)
|
|||
function_name.is_null() ? "" : function_name.characters(),
|
||||
function_parameters.characters(),
|
||||
function_body.characters());
|
||||
return js_string(interpreter, function_source);
|
||||
return js_string(vm, function_source);
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::symbol_has_instance)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (!this_object->is_function()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotA, "Function");
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "Function");
|
||||
return {};
|
||||
}
|
||||
return ordinary_has_instance(interpreter, interpreter.argument(0), this_object);
|
||||
return ordinary_has_instance(global_object, vm.argument(0), this_object);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -153,36 +153,36 @@ void GlobalObject::visit_children(Visitor& visitor)
|
|||
JS_DEFINE_NATIVE_FUNCTION(GlobalObject::gc)
|
||||
{
|
||||
dbg() << "Forced garbage collection requested!";
|
||||
interpreter.heap().collect_garbage();
|
||||
vm.heap().collect_garbage();
|
||||
return js_undefined();
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(GlobalObject::is_nan)
|
||||
{
|
||||
auto number = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return Value(number.is_nan());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(GlobalObject::is_finite)
|
||||
{
|
||||
auto number = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return Value(number.is_finite_number());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(GlobalObject::parse_float)
|
||||
{
|
||||
if (interpreter.argument(0).is_number())
|
||||
return interpreter.argument(0);
|
||||
auto string = interpreter.argument(0).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (vm.argument(0).is_number())
|
||||
return vm.argument(0);
|
||||
auto string = vm.argument(0).to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
for (size_t length = string.length(); length > 0; --length) {
|
||||
// This can't throw, so no exception check is fine.
|
||||
auto number = Value(js_string(interpreter, string.substring(0, length))).to_number(interpreter);
|
||||
auto number = Value(js_string(vm, string.substring(0, length))).to_number(global_object);
|
||||
if (!number.is_nan())
|
||||
return number;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ Object* get_iterator(GlobalObject& global_object, Value value, String hint, Valu
|
|||
if (method.is_empty()) {
|
||||
if (hint == "async")
|
||||
TODO();
|
||||
auto object = value.to_object(interpreter, global_object);
|
||||
auto object = value.to_object(global_object);
|
||||
if (!object)
|
||||
return {};
|
||||
method = object->get(global_object.vm().well_known_symbol_iterator());
|
||||
|
|
|
@ -46,7 +46,7 @@ IteratorPrototype::~IteratorPrototype()
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(IteratorPrototype::symbol_iterator)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return this_object;
|
||||
|
|
|
@ -76,13 +76,13 @@ String JSONObject::stringify_impl(Interpreter& interpreter, GlobalObject& global
|
|||
return {};
|
||||
String item;
|
||||
if (replacer_value.is_string() || replacer_value.is_number()) {
|
||||
item = replacer_value.to_string(interpreter);
|
||||
item = replacer_value.to_string(global_object);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
} else if (replacer_value.is_object()) {
|
||||
auto& value_object = replacer_value.as_object();
|
||||
if (value_object.is_string_object() || value_object.is_number_object()) {
|
||||
item = value_object.value_of().to_string(interpreter);
|
||||
item = value_object.value_of().to_string(global_object);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
}
|
||||
|
@ -133,22 +133,23 @@ String JSONObject::stringify_impl(Interpreter& interpreter, GlobalObject& global
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(JSONObject::stringify)
|
||||
{
|
||||
if (!interpreter.argument_count())
|
||||
if (!vm.argument_count())
|
||||
return js_undefined();
|
||||
|
||||
auto value = interpreter.argument(0);
|
||||
auto replacer = interpreter.argument(1);
|
||||
auto space = interpreter.argument(2);
|
||||
auto value = vm.argument(0);
|
||||
auto replacer = vm.argument(1);
|
||||
auto space = vm.argument(2);
|
||||
|
||||
auto string = stringify_impl(interpreter, global_object, value, replacer, space);
|
||||
auto string = stringify_impl(vm.interpreter(), global_object, value, replacer, space);
|
||||
if (string.is_null())
|
||||
return js_undefined();
|
||||
|
||||
return js_string(interpreter, string);
|
||||
return js_string(vm, string);
|
||||
}
|
||||
|
||||
String JSONObject::serialize_json_property(Interpreter& interpreter, StringifyState& state, const PropertyName& key, Object* holder)
|
||||
{
|
||||
auto& global_object = interpreter.global_object();
|
||||
auto value = holder->get(key);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
|
@ -183,7 +184,7 @@ String JSONObject::serialize_json_property(Interpreter& interpreter, StringifySt
|
|||
return quote_json_string(value.as_string().string());
|
||||
if (value.is_number()) {
|
||||
if (value.is_finite_number())
|
||||
return value.to_string(interpreter);
|
||||
return value.to_string(global_object);
|
||||
return "null";
|
||||
}
|
||||
if (value.is_object() && !value.is_function()) {
|
||||
|
@ -192,7 +193,7 @@ String JSONObject::serialize_json_property(Interpreter& interpreter, StringifySt
|
|||
return serialize_json_object(interpreter, state, value.as_object());
|
||||
}
|
||||
if (value.is_bigint())
|
||||
interpreter.vm().throw_exception<TypeError>(interpreter.global_object(), ErrorType::JsonBigInt);
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::JsonBigInt);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -385,25 +386,25 @@ String JSONObject::quote_json_string(String string)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(JSONObject::parse)
|
||||
{
|
||||
if (!interpreter.argument_count())
|
||||
if (!vm.argument_count())
|
||||
return js_undefined();
|
||||
auto string = interpreter.argument(0).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto string = vm.argument(0).to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto reviver = interpreter.argument(1);
|
||||
auto reviver = vm.argument(1);
|
||||
|
||||
auto json = JsonValue::from_string(string);
|
||||
if (!json.has_value()) {
|
||||
interpreter.vm().throw_exception<SyntaxError>(global_object, ErrorType::JsonMalformed);
|
||||
vm.throw_exception<SyntaxError>(global_object, ErrorType::JsonMalformed);
|
||||
return {};
|
||||
}
|
||||
Value result = parse_json_value(interpreter, global_object, json.value());
|
||||
Value result = parse_json_value(vm.interpreter(), global_object, json.value());
|
||||
if (reviver.is_function()) {
|
||||
auto* holder_object = Object::create_empty(global_object);
|
||||
holder_object->define_property(String::empty(), result);
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return internalize_json_property(interpreter, holder_object, String::empty(), reviver.as_function());
|
||||
return internalize_json_property(vm.interpreter(), holder_object, String::empty(), reviver.as_function());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -84,15 +84,15 @@ MathObject::~MathObject()
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::abs)
|
||||
{
|
||||
auto number = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (number.is_nan())
|
||||
return js_nan();
|
||||
return Value(number.as_double() >= 0 ? number.as_double() : -number.as_double());
|
||||
}
|
||||
|
||||
Value MathObject::random(Interpreter&, GlobalObject&)
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::random)
|
||||
{
|
||||
#ifdef __serenity__
|
||||
double r = (double)arc4random() / (double)UINT32_MAX;
|
||||
|
@ -104,8 +104,8 @@ Value MathObject::random(Interpreter&, GlobalObject&)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::sqrt)
|
||||
{
|
||||
auto number = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (number.is_nan())
|
||||
return js_nan();
|
||||
|
@ -114,8 +114,8 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::sqrt)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::floor)
|
||||
{
|
||||
auto number = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (number.is_nan())
|
||||
return js_nan();
|
||||
|
@ -124,8 +124,8 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::floor)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::ceil)
|
||||
{
|
||||
auto number = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (number.is_nan())
|
||||
return js_nan();
|
||||
|
@ -137,8 +137,8 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::ceil)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::round)
|
||||
{
|
||||
auto number = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (number.is_nan())
|
||||
return js_nan();
|
||||
|
@ -147,15 +147,15 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::round)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::max)
|
||||
{
|
||||
if (!interpreter.argument_count())
|
||||
if (!vm.argument_count())
|
||||
return js_negative_infinity();
|
||||
|
||||
auto max = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto max = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
for (size_t i = 1; i < interpreter.argument_count(); ++i) {
|
||||
auto cur = interpreter.argument(i).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
for (size_t i = 1; i < vm.argument_count(); ++i) {
|
||||
auto cur = vm.argument(i).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
max = Value(cur.as_double() > max.as_double() ? cur : max);
|
||||
}
|
||||
|
@ -164,15 +164,15 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::max)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::min)
|
||||
{
|
||||
if (!interpreter.argument_count())
|
||||
if (!vm.argument_count())
|
||||
return js_infinity();
|
||||
|
||||
auto min = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto min = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
for (size_t i = 1; i < interpreter.argument_count(); ++i) {
|
||||
auto cur = interpreter.argument(i).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
for (size_t i = 1; i < vm.argument_count(); ++i) {
|
||||
auto cur = vm.argument(i).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
min = Value(cur.as_double() < min.as_double() ? cur : min);
|
||||
}
|
||||
|
@ -181,20 +181,20 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::min)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::trunc)
|
||||
{
|
||||
auto number = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (number.is_nan())
|
||||
return js_nan();
|
||||
if (number.as_double() < 0)
|
||||
return MathObject::ceil(interpreter, global_object);
|
||||
return MathObject::floor(interpreter, global_object);
|
||||
return MathObject::ceil(vm, global_object);
|
||||
return MathObject::floor(vm, global_object);
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::sin)
|
||||
{
|
||||
auto number = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (number.is_nan())
|
||||
return js_nan();
|
||||
|
@ -203,8 +203,8 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::sin)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::cos)
|
||||
{
|
||||
auto number = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (number.is_nan())
|
||||
return js_nan();
|
||||
|
@ -213,8 +213,8 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::cos)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::tan)
|
||||
{
|
||||
auto number = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (number.is_nan())
|
||||
return js_nan();
|
||||
|
@ -223,13 +223,13 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::tan)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::pow)
|
||||
{
|
||||
return JS::exp(interpreter, interpreter.argument(0), interpreter.argument(1));
|
||||
return JS::exp(global_object, vm.argument(0), vm.argument(1));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::exp)
|
||||
{
|
||||
auto number = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (number.is_nan())
|
||||
return js_nan();
|
||||
|
@ -238,8 +238,8 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::exp)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::expm1)
|
||||
{
|
||||
auto number = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (number.is_nan())
|
||||
return js_nan();
|
||||
|
@ -248,8 +248,8 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::expm1)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::sign)
|
||||
{
|
||||
auto number = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (number.is_positive_zero())
|
||||
return Value(0);
|
||||
|
@ -264,8 +264,8 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::sign)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::clz32)
|
||||
{
|
||||
auto number = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (!number.is_finite_number() || (unsigned)number.as_double() == 0)
|
||||
return Value(32);
|
||||
|
@ -274,8 +274,8 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::clz32)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::acosh)
|
||||
{
|
||||
auto number = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (number.as_double() < 1)
|
||||
return JS::js_nan();
|
||||
|
@ -284,16 +284,16 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::acosh)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::asinh)
|
||||
{
|
||||
auto number = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return Value(::asinh(number.as_double()));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::atanh)
|
||||
{
|
||||
auto number = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (number.as_double() > 1 || number.as_double() < -1)
|
||||
return JS::js_nan();
|
||||
|
@ -302,8 +302,8 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::atanh)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::log1p)
|
||||
{
|
||||
auto number = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (number.as_double() < -1)
|
||||
return JS::js_nan();
|
||||
|
@ -312,8 +312,8 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::log1p)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::cbrt)
|
||||
{
|
||||
auto number = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return Value(::cbrt(number.as_double()));
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
namespace JS {
|
||||
|
||||
NativeFunction* NativeFunction::create(GlobalObject& global_object, const FlyString& name, AK::Function<Value(Interpreter&, GlobalObject&)> function)
|
||||
NativeFunction* NativeFunction::create(GlobalObject& global_object, const FlyString& name, AK::Function<Value(VM&, GlobalObject&)> function)
|
||||
{
|
||||
return global_object.heap().allocate<NativeFunction>(global_object, name, move(function), *global_object.function_prototype());
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ NativeFunction::NativeFunction(Object& prototype)
|
|||
{
|
||||
}
|
||||
|
||||
NativeFunction::NativeFunction(const FlyString& name, AK::Function<Value(Interpreter&, GlobalObject&)> native_function, Object& prototype)
|
||||
NativeFunction::NativeFunction(const FlyString& name, AK::Function<Value(VM&, GlobalObject&)> native_function, Object& prototype)
|
||||
: Function(prototype)
|
||||
, m_name(name)
|
||||
, m_native_function(move(native_function))
|
||||
|
@ -60,7 +60,7 @@ NativeFunction::~NativeFunction()
|
|||
|
||||
Value NativeFunction::call()
|
||||
{
|
||||
return m_native_function(interpreter(), global_object());
|
||||
return m_native_function(vm(), global_object());
|
||||
}
|
||||
|
||||
Value NativeFunction::construct(Interpreter&, Function&)
|
||||
|
|
|
@ -35,9 +35,9 @@ class NativeFunction : public Function {
|
|||
JS_OBJECT(NativeFunction, Function);
|
||||
|
||||
public:
|
||||
static NativeFunction* create(GlobalObject&, const FlyString& name, AK::Function<Value(Interpreter&, GlobalObject&)>);
|
||||
static NativeFunction* create(GlobalObject&, const FlyString& name, AK::Function<Value(VM&, GlobalObject&)>);
|
||||
|
||||
explicit NativeFunction(const FlyString& name, AK::Function<Value(Interpreter&, GlobalObject&)>, Object& prototype);
|
||||
explicit NativeFunction(const FlyString& name, AK::Function<Value(VM&, GlobalObject&)>, Object& prototype);
|
||||
virtual void initialize(GlobalObject&) override { }
|
||||
virtual ~NativeFunction() override;
|
||||
|
||||
|
@ -56,7 +56,7 @@ private:
|
|||
virtual LexicalEnvironment* create_environment() override final;
|
||||
|
||||
FlyString m_name;
|
||||
AK::Function<Value(Interpreter&, GlobalObject&)> m_native_function;
|
||||
AK::Function<Value(VM&, GlobalObject&)> m_native_function;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
namespace JS {
|
||||
|
||||
NativeProperty::NativeProperty(AK::Function<Value(Interpreter&, GlobalObject&)> getter, AK::Function<void(Interpreter&, GlobalObject&, Value)> setter)
|
||||
NativeProperty::NativeProperty(AK::Function<Value(VM&, GlobalObject&)> getter, AK::Function<void(VM&, GlobalObject&, Value)> setter)
|
||||
: m_getter(move(getter))
|
||||
, m_setter(move(setter))
|
||||
{
|
||||
|
@ -39,18 +39,18 @@ NativeProperty::~NativeProperty()
|
|||
{
|
||||
}
|
||||
|
||||
Value NativeProperty::get(Interpreter& interpreter, GlobalObject& global_object) const
|
||||
Value NativeProperty::get(VM& vm, GlobalObject& global_object) const
|
||||
{
|
||||
if (!m_getter)
|
||||
return js_undefined();
|
||||
return m_getter(interpreter, global_object);
|
||||
return m_getter(vm, global_object);
|
||||
}
|
||||
|
||||
void NativeProperty::set(Interpreter& interpreter, GlobalObject& global_object, Value value)
|
||||
void NativeProperty::set(VM& vm, GlobalObject& global_object, Value value)
|
||||
{
|
||||
if (!m_setter)
|
||||
return;
|
||||
m_setter(interpreter, global_object, move(value));
|
||||
m_setter(vm, global_object, move(value));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,17 +33,17 @@ namespace JS {
|
|||
|
||||
class NativeProperty final : public Cell {
|
||||
public:
|
||||
NativeProperty(AK::Function<Value(Interpreter&, GlobalObject&)> getter, AK::Function<void(Interpreter&, GlobalObject&, Value)> setter);
|
||||
NativeProperty(AK::Function<Value(VM&, GlobalObject&)> getter, AK::Function<void(VM&, GlobalObject&, Value)> setter);
|
||||
virtual ~NativeProperty() override;
|
||||
|
||||
Value get(Interpreter&, GlobalObject&) const;
|
||||
void set(Interpreter&, GlobalObject&, Value);
|
||||
Value get(VM&, GlobalObject&) const;
|
||||
void set(VM&, GlobalObject&, Value);
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "NativeProperty"; }
|
||||
|
||||
AK::Function<Value(Interpreter&, GlobalObject&)> m_getter;
|
||||
AK::Function<void(Interpreter&, GlobalObject&, Value)> m_setter;
|
||||
AK::Function<Value(VM&, GlobalObject&)> m_getter;
|
||||
AK::Function<void(VM&, GlobalObject&, Value)> m_setter;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -69,15 +69,15 @@ Value NumberConstructor::call()
|
|||
{
|
||||
if (!vm().argument_count())
|
||||
return Value(0);
|
||||
return vm().argument(0).to_number(interpreter());
|
||||
return vm().argument(0).to_number(global_object());
|
||||
}
|
||||
|
||||
Value NumberConstructor::construct(Interpreter& interpreter, Function&)
|
||||
Value NumberConstructor::construct(Interpreter&, Function&)
|
||||
{
|
||||
double number = 0;
|
||||
if (interpreter.argument_count()) {
|
||||
number = interpreter.argument(0).to_double(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (vm().argument_count()) {
|
||||
number = vm().argument(0).to_double(global_object());
|
||||
if (vm().exception())
|
||||
return {};
|
||||
}
|
||||
return NumberObject::create(global_object(), number);
|
||||
|
@ -85,24 +85,24 @@ Value NumberConstructor::construct(Interpreter& interpreter, Function&)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(NumberConstructor::is_finite)
|
||||
{
|
||||
return Value(interpreter.argument(0).is_finite_number());
|
||||
return Value(vm.argument(0).is_finite_number());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(NumberConstructor::is_integer)
|
||||
{
|
||||
return Value(interpreter.argument(0).is_integer());
|
||||
return Value(vm.argument(0).is_integer());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(NumberConstructor::is_nan)
|
||||
{
|
||||
return Value(interpreter.argument(0).is_nan());
|
||||
return Value(vm.argument(0).is_nan());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(NumberConstructor::is_safe_integer)
|
||||
{
|
||||
if (!interpreter.argument(0).is_number())
|
||||
if (!vm.argument(0).is_number())
|
||||
return Value(false);
|
||||
auto value = interpreter.argument(0).as_double();
|
||||
auto value = vm.argument(0).as_double();
|
||||
return Value((int64_t)value == value && value >= MIN_SAFE_INTEGER && value <= MAX_SAFE_INTEGER);
|
||||
}
|
||||
|
||||
|
|
|
@ -63,37 +63,37 @@ JS_DEFINE_NATIVE_FUNCTION(NumberPrototype::to_string)
|
|||
{
|
||||
Value number_value;
|
||||
|
||||
auto this_value = interpreter.this_value(global_object);
|
||||
auto this_value = vm.this_value(global_object);
|
||||
if (this_value.is_number()) {
|
||||
number_value = this_value;
|
||||
} else if (this_value.is_object() && this_value.as_object().is_number_object()) {
|
||||
number_value = static_cast<NumberObject&>(this_value.as_object()).value_of();
|
||||
} else {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NumberIncompatibleThis, "toString");
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NumberIncompatibleThis, "toString");
|
||||
return {};
|
||||
}
|
||||
|
||||
int radix;
|
||||
auto argument = interpreter.argument(0);
|
||||
auto argument = vm.argument(0);
|
||||
if (argument.is_undefined()) {
|
||||
radix = 10;
|
||||
} else {
|
||||
radix = argument.to_i32(interpreter);
|
||||
radix = argument.to_i32(global_object);
|
||||
}
|
||||
|
||||
if (interpreter.exception() || radix < 2 || radix > 36) {
|
||||
interpreter.vm().throw_exception<RangeError>(global_object, ErrorType::InvalidRadix);
|
||||
if (vm.exception() || radix < 2 || radix > 36) {
|
||||
vm.throw_exception<RangeError>(global_object, ErrorType::InvalidRadix);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (number_value.is_positive_infinity())
|
||||
return js_string(interpreter, "Infinity");
|
||||
return js_string(vm, "Infinity");
|
||||
if (number_value.is_negative_infinity())
|
||||
return js_string(interpreter, "-Infinity");
|
||||
return js_string(vm, "-Infinity");
|
||||
if (number_value.is_nan())
|
||||
return js_string(interpreter, "NaN");
|
||||
return js_string(vm, "NaN");
|
||||
if (number_value.is_positive_zero() || number_value.is_negative_zero())
|
||||
return js_string(interpreter, "0");
|
||||
return js_string(vm, "0");
|
||||
|
||||
double number = number_value.as_double();
|
||||
bool negative = number < 0;
|
||||
|
@ -140,7 +140,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberPrototype::to_string)
|
|||
characters.take_last();
|
||||
}
|
||||
|
||||
return js_string(interpreter, String(characters.data(), characters.size()));
|
||||
return js_string(vm, String(characters.data(), characters.size()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -742,7 +742,7 @@ bool Object::put(const PropertyName& property_name, Value value, Value receiver)
|
|||
return put_own_property(*this, string_or_symbol, value, default_attributes, PutOwnPropertyMode::Put);
|
||||
}
|
||||
|
||||
bool Object::define_native_function(const StringOrSymbol& property_name, AK::Function<Value(Interpreter&, GlobalObject&)> native_function, i32 length, PropertyAttributes attribute)
|
||||
bool Object::define_native_function(const StringOrSymbol& property_name, AK::Function<Value(VM&, GlobalObject&)> native_function, i32 length, PropertyAttributes attribute)
|
||||
{
|
||||
String function_name;
|
||||
if (property_name.is_string()) {
|
||||
|
@ -760,7 +760,7 @@ bool Object::define_native_function(const StringOrSymbol& property_name, AK::Fun
|
|||
return define_property(property_name, function, attribute);
|
||||
}
|
||||
|
||||
bool Object::define_native_property(const StringOrSymbol& property_name, AK::Function<Value(Interpreter&, GlobalObject&)> getter, AK::Function<void(Interpreter&, GlobalObject&, Value)> setter, PropertyAttributes attribute)
|
||||
bool Object::define_native_property(const StringOrSymbol& property_name, AK::Function<Value(VM&, GlobalObject&)> getter, AK::Function<void(VM&, GlobalObject&, Value)> setter, PropertyAttributes attribute)
|
||||
{
|
||||
return define_property(property_name, heap().allocate_without_global_object<NativeProperty>(move(getter), move(setter)), attribute);
|
||||
}
|
||||
|
@ -846,7 +846,7 @@ Value Object::to_string() const
|
|||
interpreter.vm().throw_exception<TypeError>(global_object(), ErrorType::Convert, "object", "string");
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
auto* string = to_string_result.to_primitive_string(interpreter);
|
||||
auto* string = to_string_result.to_primitive_string(global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
return string;
|
||||
|
@ -872,7 +872,7 @@ Value Object::call_native_property_getter(Object* this_object, Value property) c
|
|||
ASSERT(property.is_native_property());
|
||||
auto& call_frame = vm().push_call_frame();
|
||||
call_frame.this_value = this_object;
|
||||
auto result = property.as_native_property().get(interpreter(), global_object());
|
||||
auto result = property.as_native_property().get(vm(), global_object());
|
||||
vm().pop_call_frame();
|
||||
return result;
|
||||
}
|
||||
|
@ -882,7 +882,7 @@ void Object::call_native_property_setter(Object* this_object, Value property, Va
|
|||
ASSERT(property.is_native_property());
|
||||
auto& call_frame = vm().push_call_frame();
|
||||
call_frame.this_value = this_object;
|
||||
property.as_native_property().set(interpreter(), global_object(), value);
|
||||
property.as_native_property().set(vm(), global_object(), value);
|
||||
vm().pop_call_frame();
|
||||
}
|
||||
|
||||
|
|
|
@ -105,8 +105,8 @@ public:
|
|||
bool define_property(const PropertyName&, Value value, PropertyAttributes attributes = default_attributes, bool throw_exceptions = true);
|
||||
bool define_accessor(const PropertyName&, Function& getter_or_setter, bool is_getter, PropertyAttributes attributes = default_attributes, bool throw_exceptions = true);
|
||||
|
||||
bool define_native_function(const StringOrSymbol& property_name, AK::Function<Value(Interpreter&, GlobalObject&)>, i32 length = 0, PropertyAttributes attributes = default_attributes);
|
||||
bool define_native_property(const StringOrSymbol& property_name, AK::Function<Value(Interpreter&, GlobalObject&)> getter, AK::Function<void(Interpreter&, GlobalObject&, Value)> setter, PropertyAttributes attributes = default_attributes);
|
||||
bool define_native_function(const StringOrSymbol& property_name, AK::Function<Value(VM&, GlobalObject&)>, i32 length = 0, PropertyAttributes attributes = default_attributes);
|
||||
bool define_native_property(const StringOrSymbol& property_name, AK::Function<Value(VM&, GlobalObject&)> getter, AK::Function<void(VM&, GlobalObject&, Value)> setter, PropertyAttributes attributes = default_attributes);
|
||||
|
||||
virtual Value delete_property(const PropertyName&);
|
||||
|
||||
|
|
|
@ -76,18 +76,18 @@ Value ObjectConstructor::construct(Interpreter&, Function&)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_names)
|
||||
{
|
||||
if (!interpreter.argument_count())
|
||||
if (!vm.argument_count())
|
||||
return {};
|
||||
auto* object = interpreter.argument(0).to_object(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
auto* object = vm.argument(0).to_object(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto* result = Array::create(global_object);
|
||||
for (auto& entry : object->indexed_properties())
|
||||
result->indexed_properties().append(js_string(interpreter, String::number(entry.index())));
|
||||
result->indexed_properties().append(js_string(vm, String::number(entry.index())));
|
||||
for (auto& it : object->shape().property_table_ordered()) {
|
||||
if (!it.key.is_string())
|
||||
continue;
|
||||
result->indexed_properties().append(js_string(interpreter, it.key.as_string()));
|
||||
result->indexed_properties().append(js_string(vm, it.key.as_string()));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -95,36 +95,36 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_names)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_prototype_of)
|
||||
{
|
||||
if (!interpreter.argument_count())
|
||||
if (!vm.argument_count())
|
||||
return {};
|
||||
auto* object = interpreter.argument(0).to_object(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
auto* object = vm.argument(0).to_object(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return object->prototype();
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::set_prototype_of)
|
||||
{
|
||||
if (interpreter.argument_count() < 2) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::ObjectSetPrototypeOfTwoArgs);
|
||||
if (vm.argument_count() < 2) {
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ObjectSetPrototypeOfTwoArgs);
|
||||
return {};
|
||||
}
|
||||
auto* object = interpreter.argument(0).to_object(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
auto* object = vm.argument(0).to_object(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto prototype_value = interpreter.argument(1);
|
||||
auto prototype_value = vm.argument(1);
|
||||
Object* prototype;
|
||||
if (prototype_value.is_null()) {
|
||||
prototype = nullptr;
|
||||
} else if (prototype_value.is_object()) {
|
||||
prototype = &prototype_value.as_object();
|
||||
} else {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::ObjectPrototypeWrongType);
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ObjectPrototypeWrongType);
|
||||
return {};
|
||||
}
|
||||
if (!object->set_prototype(prototype)) {
|
||||
if (!interpreter.exception())
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::ObjectSetPrototypeOfReturnedFalse);
|
||||
if (!vm.exception())
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ObjectSetPrototypeOfReturnedFalse);
|
||||
return {};
|
||||
}
|
||||
return object;
|
||||
|
@ -132,7 +132,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::set_prototype_of)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::is_extensible)
|
||||
{
|
||||
auto argument = interpreter.argument(0);
|
||||
auto argument = vm.argument(0);
|
||||
if (!argument.is_object())
|
||||
return Value(false);
|
||||
return Value(argument.as_object().is_extensible());
|
||||
|
@ -140,12 +140,12 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::is_extensible)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::prevent_extensions)
|
||||
{
|
||||
auto argument = interpreter.argument(0);
|
||||
auto argument = vm.argument(0);
|
||||
if (!argument.is_object())
|
||||
return argument;
|
||||
if (!argument.as_object().prevent_extensions()) {
|
||||
if (!interpreter.exception())
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::ObjectPreventExtensionsReturnedFalse);
|
||||
if (!vm.exception())
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ObjectPreventExtensionsReturnedFalse);
|
||||
return {};
|
||||
}
|
||||
return argument;
|
||||
|
@ -153,36 +153,36 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::prevent_extensions)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptor)
|
||||
{
|
||||
auto* object = interpreter.argument(0).to_object(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
auto* object = vm.argument(0).to_object(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto property_key = PropertyName::from_value(interpreter, interpreter.argument(1));
|
||||
if (interpreter.exception())
|
||||
auto property_key = PropertyName::from_value(global_object, vm.argument(1));
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return object->get_own_property_descriptor_object(property_key);
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::define_property_)
|
||||
{
|
||||
if (!interpreter.argument(0).is_object()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotAnObject, "Object argument");
|
||||
if (!vm.argument(0).is_object()) {
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObject, "Object argument");
|
||||
return {};
|
||||
}
|
||||
if (!interpreter.argument(2).is_object()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotAnObject, "Descriptor argument");
|
||||
if (!vm.argument(2).is_object()) {
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObject, "Descriptor argument");
|
||||
return {};
|
||||
}
|
||||
auto& object = interpreter.argument(0).as_object();
|
||||
auto property_key = StringOrSymbol::from_value(interpreter, interpreter.argument(1));
|
||||
if (interpreter.exception())
|
||||
auto& object = vm.argument(0).as_object();
|
||||
auto property_key = StringOrSymbol::from_value(global_object, vm.argument(1));
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto& descriptor = interpreter.argument(2).as_object();
|
||||
auto& descriptor = vm.argument(2).as_object();
|
||||
if (!object.define_property(property_key, descriptor)) {
|
||||
if (!interpreter.exception()) {
|
||||
if (!vm.exception()) {
|
||||
if (object.is_proxy_object()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::ObjectDefinePropertyReturnedFalse);
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ObjectDefinePropertyReturnedFalse);
|
||||
} else {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NonExtensibleDefine, property_key.to_display_string().characters());
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NonExtensibleDefine, property_key.to_display_string().characters());
|
||||
}
|
||||
}
|
||||
return {};
|
||||
|
@ -192,18 +192,18 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::define_property_)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::is)
|
||||
{
|
||||
return Value(same_value(interpreter, interpreter.argument(0), interpreter.argument(1)));
|
||||
return Value(same_value(vm.argument(0), vm.argument(1)));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::keys)
|
||||
{
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::ConvertUndefinedToObject);
|
||||
if (!vm.argument_count()) {
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ConvertUndefinedToObject);
|
||||
return {};
|
||||
}
|
||||
|
||||
auto* obj_arg = interpreter.argument(0).to_object(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
auto* obj_arg = vm.argument(0).to_object(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
return obj_arg->get_own_properties(*obj_arg, PropertyKind::Key, true);
|
||||
|
@ -211,12 +211,12 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::keys)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::values)
|
||||
{
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::ConvertUndefinedToObject);
|
||||
if (!vm.argument_count()) {
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ConvertUndefinedToObject);
|
||||
return {};
|
||||
}
|
||||
auto* obj_arg = interpreter.argument(0).to_object(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
auto* obj_arg = vm.argument(0).to_object(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
return obj_arg->get_own_properties(*obj_arg, PropertyKind::Value, true);
|
||||
|
@ -224,12 +224,12 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::values)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::entries)
|
||||
{
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::ConvertUndefinedToObject);
|
||||
if (!vm.argument_count()) {
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ConvertUndefinedToObject);
|
||||
return {};
|
||||
}
|
||||
auto* obj_arg = interpreter.argument(0).to_object(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
auto* obj_arg = vm.argument(0).to_object(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
return obj_arg->get_own_properties(*obj_arg, PropertyKind::KeyAndValue, true);
|
||||
|
|
|
@ -57,25 +57,25 @@ ObjectPrototype::~ObjectPrototype()
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::has_own_property)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
auto name = interpreter.argument(0).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto name = vm.argument(0).to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return Value(this_object->has_own_property(name));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::to_string)
|
||||
{
|
||||
auto this_value = interpreter.this_value(global_object);
|
||||
auto this_value = vm.this_value(global_object);
|
||||
|
||||
if (this_value.is_undefined())
|
||||
return js_string(interpreter, "[object Undefined]");
|
||||
return js_string(vm, "[object Undefined]");
|
||||
if (this_value.is_null())
|
||||
return js_string(interpreter, "[object Null]");
|
||||
return js_string(vm, "[object Null]");
|
||||
|
||||
auto* this_object = this_value.to_object(interpreter, global_object);
|
||||
auto* this_object = this_value.to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
|
||||
|
@ -104,12 +104,12 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::to_string)
|
|||
tag = "Object";
|
||||
}
|
||||
|
||||
return js_string(interpreter, String::format("[object %s]", tag.characters()));
|
||||
return js_string(vm, String::format("[object %s]", tag.characters()));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::to_locale_string)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return this_object->invoke("toString");
|
||||
|
@ -117,7 +117,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::to_locale_string)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::value_of)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return this_object->value_of();
|
||||
|
|
|
@ -48,7 +48,12 @@ PrimitiveString* js_string(Heap& heap, String string)
|
|||
|
||||
PrimitiveString* js_string(Interpreter& interpreter, String string)
|
||||
{
|
||||
return js_string(interpreter.heap(), string);
|
||||
return js_string(interpreter.heap(), move(string));
|
||||
}
|
||||
|
||||
PrimitiveString* js_string(VM& vm, String string)
|
||||
{
|
||||
return js_string(vm.heap(), move(string));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,5 +46,6 @@ private:
|
|||
|
||||
PrimitiveString* js_string(Heap&, String);
|
||||
PrimitiveString* js_string(Interpreter&, String);
|
||||
PrimitiveString* js_string(VM&, String);
|
||||
|
||||
}
|
||||
|
|
|
@ -40,14 +40,14 @@ public:
|
|||
Symbol,
|
||||
};
|
||||
|
||||
static PropertyName from_value(Interpreter& interpreter, Value value)
|
||||
static PropertyName from_value(GlobalObject& global_object, Value value)
|
||||
{
|
||||
if (value.is_symbol())
|
||||
return &value.as_symbol();
|
||||
if (value.is_number())
|
||||
return value.as_i32();
|
||||
if (!value.is_empty())
|
||||
return value.to_string(interpreter);
|
||||
return value.to_string(global_object);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
namespace JS {
|
||||
|
||||
bool static is_compatible_property_descriptor(Interpreter& interpreter, bool is_extensible, PropertyDescriptor new_descriptor, Optional<PropertyDescriptor> current_descriptor_optional)
|
||||
bool static is_compatible_property_descriptor(bool is_extensible, PropertyDescriptor new_descriptor, Optional<PropertyDescriptor> current_descriptor_optional)
|
||||
{
|
||||
if (!current_descriptor_optional.has_value())
|
||||
return is_extensible;
|
||||
|
@ -53,7 +53,7 @@ bool static is_compatible_property_descriptor(Interpreter& interpreter, bool is_
|
|||
if (current_descriptor.is_data_descriptor() && new_descriptor.is_data_descriptor() && !current_descriptor.attributes.is_configurable() && !current_descriptor.attributes.is_writable()) {
|
||||
if (new_descriptor.attributes.is_writable())
|
||||
return false;
|
||||
return new_descriptor.value.is_empty() && same_value(interpreter, new_descriptor.value, current_descriptor.value);
|
||||
return new_descriptor.value.is_empty() && same_value(new_descriptor.value, current_descriptor.value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ ProxyObject::~ProxyObject()
|
|||
Object* ProxyObject::prototype()
|
||||
{
|
||||
if (m_is_revoked) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
return nullptr;
|
||||
}
|
||||
auto trap = m_handler.get("getPrototypeOf");
|
||||
|
@ -86,15 +86,15 @@ Object* ProxyObject::prototype()
|
|||
if (trap.is_empty() || trap.is_undefined() || trap.is_null())
|
||||
return m_target.prototype();
|
||||
if (!trap.is_function()) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "getPrototypeOf");
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "getPrototypeOf");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), Value(&m_target));
|
||||
auto trap_result = vm().call(trap.as_function(), Value(&m_handler), Value(&m_target));
|
||||
if (vm().exception())
|
||||
return nullptr;
|
||||
if (!trap_result.is_object() && !trap_result.is_null()) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyGetPrototypeOfReturn);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyGetPrototypeOfReturn);
|
||||
return nullptr;
|
||||
}
|
||||
if (m_target.is_extensible()) {
|
||||
|
@ -107,8 +107,8 @@ Object* ProxyObject::prototype()
|
|||
auto target_proto = m_target.prototype();
|
||||
if (vm().exception())
|
||||
return nullptr;
|
||||
if (!same_value(interpreter(), trap_result, Value(target_proto))) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyGetPrototypeOfNonExtensible);
|
||||
if (!same_value(trap_result, Value(target_proto))) {
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyGetPrototypeOfNonExtensible);
|
||||
return nullptr;
|
||||
}
|
||||
return &trap_result.as_object();
|
||||
|
@ -117,7 +117,7 @@ Object* ProxyObject::prototype()
|
|||
const Object* ProxyObject::prototype() const
|
||||
{
|
||||
if (m_is_revoked) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
return nullptr;
|
||||
}
|
||||
return const_cast<const Object*>(const_cast<ProxyObject*>(this)->prototype());
|
||||
|
@ -126,7 +126,7 @@ const Object* ProxyObject::prototype() const
|
|||
bool ProxyObject::set_prototype(Object* object)
|
||||
{
|
||||
if (m_is_revoked) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
return false;
|
||||
}
|
||||
auto trap = m_handler.get("setPrototypeOf");
|
||||
|
@ -135,11 +135,11 @@ bool ProxyObject::set_prototype(Object* object)
|
|||
if (trap.is_empty() || trap.is_undefined() || trap.is_null())
|
||||
return m_target.set_prototype(object);
|
||||
if (!trap.is_function()) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "setPrototypeOf");
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "setPrototypeOf");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), Value(&m_target), Value(object)).to_boolean();
|
||||
auto trap_result = vm().call(trap.as_function(), Value(&m_handler), Value(&m_target), Value(object)).to_boolean();
|
||||
if (vm().exception() || !trap_result)
|
||||
return false;
|
||||
if (m_target.is_extensible())
|
||||
|
@ -147,8 +147,8 @@ bool ProxyObject::set_prototype(Object* object)
|
|||
auto* target_proto = m_target.prototype();
|
||||
if (vm().exception())
|
||||
return false;
|
||||
if (!same_value(interpreter(), Value(object), Value(target_proto))) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxySetPrototypeOfNonExtensible);
|
||||
if (!same_value(Value(object), Value(target_proto))) {
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxySetPrototypeOfNonExtensible);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -157,7 +157,7 @@ bool ProxyObject::set_prototype(Object* object)
|
|||
bool ProxyObject::is_extensible() const
|
||||
{
|
||||
if (m_is_revoked) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
return false;
|
||||
}
|
||||
auto trap = m_handler.get("isExtensible");
|
||||
|
@ -166,16 +166,16 @@ bool ProxyObject::is_extensible() const
|
|||
if (trap.is_empty() || trap.is_undefined() || trap.is_null())
|
||||
return m_target.is_extensible();
|
||||
if (!trap.is_function()) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "isExtensible");
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "isExtensible");
|
||||
return {};
|
||||
}
|
||||
|
||||
auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), Value(&m_target)).to_boolean();
|
||||
auto trap_result = vm().call(trap.as_function(), Value(&m_handler), Value(&m_target)).to_boolean();
|
||||
if (vm().exception())
|
||||
return false;
|
||||
if (trap_result != m_target.is_extensible()) {
|
||||
if (!vm().exception())
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyIsExtensibleReturn);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyIsExtensibleReturn);
|
||||
return false;
|
||||
}
|
||||
return trap_result;
|
||||
|
@ -184,7 +184,7 @@ bool ProxyObject::is_extensible() const
|
|||
bool ProxyObject::prevent_extensions()
|
||||
{
|
||||
if (m_is_revoked) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
return false;
|
||||
}
|
||||
auto trap = m_handler.get("preventExtensions");
|
||||
|
@ -193,16 +193,16 @@ bool ProxyObject::prevent_extensions()
|
|||
if (trap.is_empty() || trap.is_undefined() || trap.is_null())
|
||||
return m_target.prevent_extensions();
|
||||
if (!trap.is_function()) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "preventExtensions");
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "preventExtensions");
|
||||
return {};
|
||||
}
|
||||
|
||||
auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), Value(&m_target)).to_boolean();
|
||||
auto trap_result = vm().call(trap.as_function(), Value(&m_handler), Value(&m_target)).to_boolean();
|
||||
if (vm().exception())
|
||||
return false;
|
||||
if (trap_result && m_target.is_extensible()) {
|
||||
if (!vm().exception())
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyPreventExtensionsReturn);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyPreventExtensionsReturn);
|
||||
return false;
|
||||
}
|
||||
return trap_result;
|
||||
|
@ -211,7 +211,7 @@ bool ProxyObject::prevent_extensions()
|
|||
Optional<PropertyDescriptor> ProxyObject::get_own_property_descriptor(const PropertyName& name) const
|
||||
{
|
||||
if (m_is_revoked) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
return {};
|
||||
}
|
||||
auto trap = m_handler.get("getOwnPropertyDescriptor");
|
||||
|
@ -220,15 +220,15 @@ Optional<PropertyDescriptor> ProxyObject::get_own_property_descriptor(const Prop
|
|||
if (trap.is_empty() || trap.is_undefined() || trap.is_null())
|
||||
return m_target.get_own_property_descriptor(name);
|
||||
if (!trap.is_function()) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "getOwnPropertyDescriptor");
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "getOwnPropertyDescriptor");
|
||||
return {};
|
||||
}
|
||||
|
||||
auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), Value(&m_target), js_string(interpreter(), name.to_string()));
|
||||
auto trap_result = vm().call(trap.as_function(), Value(&m_handler), Value(&m_target), js_string(vm(), name.to_string()));
|
||||
if (vm().exception())
|
||||
return {};
|
||||
if (!trap_result.is_object() && !trap_result.is_undefined()) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyGetOwnDescriptorReturn);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyGetOwnDescriptorReturn);
|
||||
return {};
|
||||
}
|
||||
auto target_desc = m_target.get_own_property_descriptor(name);
|
||||
|
@ -238,12 +238,12 @@ Optional<PropertyDescriptor> ProxyObject::get_own_property_descriptor(const Prop
|
|||
if (!target_desc.has_value())
|
||||
return {};
|
||||
if (!target_desc.value().attributes.is_configurable()) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyGetOwnDescriptorNonConfigurable);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyGetOwnDescriptorNonConfigurable);
|
||||
return {};
|
||||
}
|
||||
if (!m_target.is_extensible()) {
|
||||
if (!vm().exception())
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyGetOwnDescriptorUndefReturn);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyGetOwnDescriptorUndefReturn);
|
||||
return {};
|
||||
}
|
||||
return {};
|
||||
|
@ -251,13 +251,13 @@ Optional<PropertyDescriptor> ProxyObject::get_own_property_descriptor(const Prop
|
|||
auto result_desc = PropertyDescriptor::from_dictionary(vm(), trap_result.as_object());
|
||||
if (vm().exception())
|
||||
return {};
|
||||
if (!is_compatible_property_descriptor(interpreter(), m_target.is_extensible(), result_desc, target_desc)) {
|
||||
if (!is_compatible_property_descriptor(m_target.is_extensible(), result_desc, target_desc)) {
|
||||
if (!vm().exception())
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyGetOwnDescriptorInvalidDescriptor);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyGetOwnDescriptorInvalidDescriptor);
|
||||
return {};
|
||||
}
|
||||
if (!result_desc.attributes.is_configurable() && (!target_desc.has_value() || target_desc.value().attributes.is_configurable())) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyGetOwnDescriptorInvalidNonConfig);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyGetOwnDescriptorInvalidNonConfig);
|
||||
return {};
|
||||
}
|
||||
return result_desc;
|
||||
|
@ -266,7 +266,7 @@ Optional<PropertyDescriptor> ProxyObject::get_own_property_descriptor(const Prop
|
|||
bool ProxyObject::define_property(const StringOrSymbol& property_name, const Object& descriptor, bool throw_exceptions)
|
||||
{
|
||||
if (m_is_revoked) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
return false;
|
||||
}
|
||||
auto trap = m_handler.get("defineProperty");
|
||||
|
@ -275,11 +275,11 @@ bool ProxyObject::define_property(const StringOrSymbol& property_name, const Obj
|
|||
if (trap.is_empty() || trap.is_undefined() || trap.is_null())
|
||||
return m_target.define_property(property_name, descriptor, throw_exceptions);
|
||||
if (!trap.is_function()) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "defineProperty");
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "defineProperty");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), Value(&m_target), property_name.to_value(interpreter()), Value(const_cast<Object*>(&descriptor))).to_boolean();
|
||||
auto trap_result = vm().call(trap.as_function(), Value(&m_handler), Value(&m_target), property_name.to_value(interpreter()), Value(const_cast<Object*>(&descriptor))).to_boolean();
|
||||
if (vm().exception() || !trap_result)
|
||||
return false;
|
||||
auto target_desc = m_target.get_own_property_descriptor(property_name);
|
||||
|
@ -293,21 +293,21 @@ bool ProxyObject::define_property(const StringOrSymbol& property_name, const Obj
|
|||
if (!target_desc.has_value()) {
|
||||
if (!m_target.is_extensible()) {
|
||||
if (!vm().exception())
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyDefinePropNonExtensible);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyDefinePropNonExtensible);
|
||||
return false;
|
||||
}
|
||||
if (setting_config_false) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyDefinePropNonConfigurableNonExisting);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyDefinePropNonConfigurableNonExisting);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!is_compatible_property_descriptor(interpreter(), m_target.is_extensible(), PropertyDescriptor::from_dictionary(vm(), descriptor), target_desc)) {
|
||||
if (!is_compatible_property_descriptor(m_target.is_extensible(), PropertyDescriptor::from_dictionary(vm(), descriptor), target_desc)) {
|
||||
if (!vm().exception())
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyDefinePropIncompatibleDescriptor);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyDefinePropIncompatibleDescriptor);
|
||||
return false;
|
||||
}
|
||||
if (setting_config_false && target_desc.value().attributes.is_configurable()) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyDefinePropExistingConfigurable);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyDefinePropExistingConfigurable);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ bool ProxyObject::define_property(const StringOrSymbol& property_name, const Obj
|
|||
bool ProxyObject::has_property(const PropertyName& name) const
|
||||
{
|
||||
if (m_is_revoked) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
return false;
|
||||
}
|
||||
auto trap = m_handler.get("has");
|
||||
|
@ -326,11 +326,11 @@ bool ProxyObject::has_property(const PropertyName& name) const
|
|||
if (trap.is_empty() || trap.is_undefined() || trap.is_null())
|
||||
return m_target.has_property(name);
|
||||
if (!trap.is_function()) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "has");
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "has");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), Value(&m_target), js_string(interpreter(), name.to_string())).to_boolean();
|
||||
auto trap_result = vm().call(trap.as_function(), Value(&m_handler), Value(&m_target), js_string(vm(), name.to_string())).to_boolean();
|
||||
if (vm().exception())
|
||||
return false;
|
||||
if (!trap_result) {
|
||||
|
@ -339,12 +339,12 @@ bool ProxyObject::has_property(const PropertyName& name) const
|
|||
return false;
|
||||
if (target_desc.has_value()) {
|
||||
if (!target_desc.value().attributes.is_configurable()) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyHasExistingNonConfigurable);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyHasExistingNonConfigurable);
|
||||
return false;
|
||||
}
|
||||
if (!m_target.is_extensible()) {
|
||||
if (!vm().exception())
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyHasExistingNonExtensible);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyHasExistingNonExtensible);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -355,7 +355,7 @@ bool ProxyObject::has_property(const PropertyName& name) const
|
|||
Value ProxyObject::get(const PropertyName& name, Value) const
|
||||
{
|
||||
if (m_is_revoked) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
return {};
|
||||
}
|
||||
auto trap = m_handler.get("get");
|
||||
|
@ -364,23 +364,23 @@ Value ProxyObject::get(const PropertyName& name, Value) const
|
|||
if (trap.is_empty() || trap.is_undefined() || trap.is_null())
|
||||
return m_target.get(name);
|
||||
if (!trap.is_function()) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "get");
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "get");
|
||||
return {};
|
||||
}
|
||||
|
||||
auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), Value(&m_target), js_string(interpreter(), name.to_string()), Value(const_cast<ProxyObject*>(this)));
|
||||
auto trap_result = vm().call(trap.as_function(), Value(&m_handler), Value(&m_target), js_string(vm(), name.to_string()), Value(const_cast<ProxyObject*>(this)));
|
||||
if (vm().exception())
|
||||
return {};
|
||||
auto target_desc = m_target.get_own_property_descriptor(name);
|
||||
if (target_desc.has_value()) {
|
||||
if (vm().exception())
|
||||
return {};
|
||||
if (target_desc.value().is_data_descriptor() && !target_desc.value().attributes.is_writable() && !same_value(interpreter(), trap_result, target_desc.value().value)) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyGetImmutableDataProperty);
|
||||
if (target_desc.value().is_data_descriptor() && !target_desc.value().attributes.is_writable() && !same_value(trap_result, target_desc.value().value)) {
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyGetImmutableDataProperty);
|
||||
return {};
|
||||
}
|
||||
if (target_desc.value().is_accessor_descriptor() && target_desc.value().getter == nullptr && !trap_result.is_undefined()) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyGetNonConfigurableAccessor);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyGetNonConfigurableAccessor);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
@ -390,7 +390,7 @@ Value ProxyObject::get(const PropertyName& name, Value) const
|
|||
bool ProxyObject::put(const PropertyName& name, Value value, Value)
|
||||
{
|
||||
if (m_is_revoked) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
return false;
|
||||
}
|
||||
auto trap = m_handler.get("set");
|
||||
|
@ -399,22 +399,22 @@ bool ProxyObject::put(const PropertyName& name, Value value, Value)
|
|||
if (trap.is_empty() || trap.is_undefined() || trap.is_null())
|
||||
return m_target.put(name, value);
|
||||
if (!trap.is_function()) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "set");
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "set");
|
||||
return false;
|
||||
}
|
||||
auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), Value(&m_target), js_string(interpreter(), name.to_string()), value, Value(const_cast<ProxyObject*>(this))).to_boolean();
|
||||
auto trap_result = vm().call(trap.as_function(), Value(&m_handler), Value(&m_target), js_string(vm(), name.to_string()), value, Value(const_cast<ProxyObject*>(this))).to_boolean();
|
||||
if (vm().exception() || !trap_result)
|
||||
return false;
|
||||
auto target_desc = m_target.get_own_property_descriptor(name);
|
||||
if (vm().exception())
|
||||
return false;
|
||||
if (target_desc.has_value() && !target_desc.value().attributes.is_configurable()) {
|
||||
if (target_desc.value().is_data_descriptor() && !target_desc.value().attributes.is_writable() && !same_value(interpreter(), value, target_desc.value().value)) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxySetImmutableDataProperty);
|
||||
if (target_desc.value().is_data_descriptor() && !target_desc.value().attributes.is_writable() && !same_value(value, target_desc.value().value)) {
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxySetImmutableDataProperty);
|
||||
return false;
|
||||
}
|
||||
if (target_desc.value().is_accessor_descriptor() && !target_desc.value().setter) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxySetNonConfigurableAccessor);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxySetNonConfigurableAccessor);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -423,7 +423,7 @@ bool ProxyObject::put(const PropertyName& name, Value value, Value)
|
|||
Value ProxyObject::delete_property(const PropertyName& name)
|
||||
{
|
||||
if (m_is_revoked) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
return {};
|
||||
}
|
||||
auto trap = m_handler.get("deleteProperty");
|
||||
|
@ -432,11 +432,11 @@ Value ProxyObject::delete_property(const PropertyName& name)
|
|||
if (trap.is_empty() || trap.is_undefined() || trap.is_null())
|
||||
return m_target.delete_property(name);
|
||||
if (!trap.is_function()) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "deleteProperty");
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "deleteProperty");
|
||||
return {};
|
||||
}
|
||||
|
||||
auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), Value(&m_target), js_string(interpreter(), name.to_string())).to_boolean();
|
||||
auto trap_result = vm().call(trap.as_function(), Value(&m_handler), Value(&m_target), js_string(vm(), name.to_string())).to_boolean();
|
||||
if (vm().exception())
|
||||
return {};
|
||||
if (!trap_result)
|
||||
|
@ -447,7 +447,7 @@ Value ProxyObject::delete_property(const PropertyName& name)
|
|||
if (!target_desc.has_value())
|
||||
return Value(true);
|
||||
if (!target_desc.value().attributes.is_configurable()) {
|
||||
interpreter().vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyDeleteNonConfigurable);
|
||||
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyDeleteNonConfigurable);
|
||||
return {};
|
||||
}
|
||||
return Value(true);
|
||||
|
@ -494,35 +494,36 @@ Value ProxyObject::call()
|
|||
|
||||
Value ProxyObject::construct(Interpreter& interpreter, Function& new_target)
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
if (!is_function()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object(), ErrorType::NotAConstructor, Value(this).to_string_without_side_effects().characters());
|
||||
vm.throw_exception<TypeError>(global_object(), ErrorType::NotAConstructor, Value(this).to_string_without_side_effects().characters());
|
||||
return {};
|
||||
}
|
||||
if (m_is_revoked) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
vm.throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||
return {};
|
||||
}
|
||||
auto trap = m_handler.get("construct");
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (trap.is_empty() || trap.is_undefined() || trap.is_null())
|
||||
return static_cast<Function&>(m_target).construct(interpreter, new_target);
|
||||
if (!trap.is_function()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "construct");
|
||||
vm.throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "construct");
|
||||
return {};
|
||||
}
|
||||
|
||||
MarkedValueList arguments(interpreter.heap());
|
||||
MarkedValueList arguments(vm.heap());
|
||||
arguments.append(Value(&m_target));
|
||||
auto arguments_array = Array::create(interpreter.global_object());
|
||||
interpreter.vm().for_each_argument([&](auto& argument) {
|
||||
auto arguments_array = Array::create(global_object());
|
||||
vm.for_each_argument([&](auto& argument) {
|
||||
arguments_array->indexed_properties().append(argument);
|
||||
});
|
||||
arguments.append(arguments_array);
|
||||
arguments.append(Value(&new_target));
|
||||
auto result = interpreter.call(trap.as_function(), Value(&m_handler), move(arguments));
|
||||
auto result = vm.call(trap.as_function(), Value(&m_handler), move(arguments));
|
||||
if (!result.is_object()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyConstructBadReturnType);
|
||||
vm.throw_exception<TypeError>(global_object(), ErrorType::ProxyConstructBadReturnType);
|
||||
return {};
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -55,7 +55,7 @@ void Reference::put(Interpreter& interpreter, GlobalObject& global_object, Value
|
|||
return;
|
||||
}
|
||||
|
||||
auto* object = base().to_object(interpreter, global_object);
|
||||
auto* object = base().to_object(global_object);
|
||||
if (!object)
|
||||
return;
|
||||
|
||||
|
@ -97,7 +97,7 @@ Value Reference::get(Interpreter& interpreter, GlobalObject& global_object)
|
|||
return value;
|
||||
}
|
||||
|
||||
auto* object = base().to_object(interpreter, global_object);
|
||||
auto* object = base().to_object(global_object);
|
||||
if (!object)
|
||||
return {};
|
||||
|
||||
|
|
|
@ -34,42 +34,45 @@
|
|||
|
||||
namespace JS {
|
||||
|
||||
static Object* get_target_object_from(Interpreter& interpreter, const String& name)
|
||||
static Object* get_target_object_from(GlobalObject& global_object, const String& name)
|
||||
{
|
||||
auto target = interpreter.argument(0);
|
||||
auto& vm = global_object.vm();
|
||||
auto target = vm.argument(0);
|
||||
if (!target.is_object()) {
|
||||
interpreter.vm().throw_exception<TypeError>(interpreter.global_object(), ErrorType::ReflectArgumentMustBeAnObject, name.characters());
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ReflectArgumentMustBeAnObject, name.characters());
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<Object*>(&target.as_object());
|
||||
}
|
||||
|
||||
static Function* get_target_function_from(Interpreter& interpreter, const String& name)
|
||||
static Function* get_target_function_from(GlobalObject& global_object, const String& name)
|
||||
{
|
||||
auto target = interpreter.argument(0);
|
||||
auto& vm = global_object.vm();
|
||||
auto target = vm.argument(0);
|
||||
if (!target.is_function()) {
|
||||
interpreter.vm().throw_exception<TypeError>(interpreter.global_object(), ErrorType::ReflectArgumentMustBeAFunction, name.characters());
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ReflectArgumentMustBeAFunction, name.characters());
|
||||
return nullptr;
|
||||
}
|
||||
return &target.as_function();
|
||||
}
|
||||
|
||||
static void prepare_arguments_list(Interpreter& interpreter, Value value, MarkedValueList* arguments)
|
||||
static void prepare_arguments_list(GlobalObject& global_object, Value value, MarkedValueList* arguments)
|
||||
{
|
||||
auto& vm = global_object.vm();
|
||||
if (!value.is_object()) {
|
||||
interpreter.vm().throw_exception<TypeError>(interpreter.global_object(), ErrorType::ReflectBadArgumentsList);
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ReflectBadArgumentsList);
|
||||
return;
|
||||
}
|
||||
auto& arguments_list = value.as_object();
|
||||
auto length_property = arguments_list.get("length");
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return;
|
||||
auto length = length_property.to_size_t(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto length = length_property.to_size_t(global_object);
|
||||
if (vm.exception())
|
||||
return;
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
auto element = arguments_list.get(String::number(i));
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return;
|
||||
arguments->append(element.value_or(js_undefined()));
|
||||
}
|
||||
|
@ -105,70 +108,70 @@ ReflectObject::~ReflectObject()
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ReflectObject::apply)
|
||||
{
|
||||
auto* target = get_target_function_from(interpreter, "apply");
|
||||
auto* target = get_target_function_from(global_object, "apply");
|
||||
if (!target)
|
||||
return {};
|
||||
auto this_arg = interpreter.argument(1);
|
||||
MarkedValueList arguments(interpreter.heap());
|
||||
prepare_arguments_list(interpreter, interpreter.argument(2), &arguments);
|
||||
if (interpreter.exception())
|
||||
auto this_arg = vm.argument(1);
|
||||
MarkedValueList arguments(vm.heap());
|
||||
prepare_arguments_list(global_object, vm.argument(2), &arguments);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return interpreter.call(*target, this_arg, move(arguments));
|
||||
return vm.call(*target, this_arg, move(arguments));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ReflectObject::construct)
|
||||
{
|
||||
auto* target = get_target_function_from(interpreter, "construct");
|
||||
auto* target = get_target_function_from(global_object, "construct");
|
||||
if (!target)
|
||||
return {};
|
||||
MarkedValueList arguments(interpreter.heap());
|
||||
prepare_arguments_list(interpreter, interpreter.argument(1), &arguments);
|
||||
if (interpreter.exception())
|
||||
MarkedValueList arguments(vm.heap());
|
||||
prepare_arguments_list(global_object, vm.argument(1), &arguments);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto* new_target = target;
|
||||
if (interpreter.argument_count() > 2) {
|
||||
auto new_target_value = interpreter.argument(2);
|
||||
if (vm.argument_count() > 2) {
|
||||
auto new_target_value = vm.argument(2);
|
||||
if (!new_target_value.is_function()
|
||||
|| (new_target_value.as_object().is_native_function() && !static_cast<NativeFunction&>(new_target_value.as_object()).has_constructor())) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::ReflectBadNewTarget);
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ReflectBadNewTarget);
|
||||
return {};
|
||||
}
|
||||
new_target = &new_target_value.as_function();
|
||||
}
|
||||
return interpreter.vm().construct(*target, *new_target, move(arguments), global_object);
|
||||
return vm.construct(*target, *new_target, move(arguments), global_object);
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ReflectObject::define_property)
|
||||
{
|
||||
auto* target = get_target_object_from(interpreter, "defineProperty");
|
||||
auto* target = get_target_object_from(global_object, "defineProperty");
|
||||
if (!target)
|
||||
return {};
|
||||
if (!interpreter.argument(2).is_object()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::ReflectBadDescriptorArgument);
|
||||
if (!vm.argument(2).is_object()) {
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ReflectBadDescriptorArgument);
|
||||
return {};
|
||||
}
|
||||
auto property_key = StringOrSymbol::from_value(interpreter, interpreter.argument(1));
|
||||
if (interpreter.exception())
|
||||
auto property_key = StringOrSymbol::from_value(global_object, vm.argument(1));
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto& descriptor = interpreter.argument(2).as_object();
|
||||
auto& descriptor = vm.argument(2).as_object();
|
||||
auto success = target->define_property(property_key, descriptor, false);
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return Value(success);
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ReflectObject::delete_property)
|
||||
{
|
||||
auto* target = get_target_object_from(interpreter, "deleteProperty");
|
||||
auto* target = get_target_object_from(global_object, "deleteProperty");
|
||||
if (!target)
|
||||
return {};
|
||||
|
||||
auto property_key = interpreter.argument(1);
|
||||
auto property_name = PropertyName::from_value(interpreter, property_key);
|
||||
if (interpreter.exception())
|
||||
auto property_key = vm.argument(1);
|
||||
auto property_name = PropertyName::from_value(global_object, property_key);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto property_key_number = property_key.to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto property_key_number = property_key.to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (property_key_number.is_finite_number()) {
|
||||
auto property_key_as_double = property_key_number.as_double();
|
||||
|
@ -180,32 +183,32 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::delete_property)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ReflectObject::get)
|
||||
{
|
||||
auto* target = get_target_object_from(interpreter, "get");
|
||||
auto* target = get_target_object_from(global_object, "get");
|
||||
if (!target)
|
||||
return {};
|
||||
auto property_key = PropertyName::from_value(interpreter, interpreter.argument(1));
|
||||
if (interpreter.exception())
|
||||
auto property_key = PropertyName::from_value(global_object, vm.argument(1));
|
||||
if (vm.exception())
|
||||
return {};
|
||||
Value receiver = {};
|
||||
if (interpreter.argument_count() > 2)
|
||||
receiver = interpreter.argument(2);
|
||||
if (vm.argument_count() > 2)
|
||||
receiver = vm.argument(2);
|
||||
return target->get(property_key, receiver).value_or(js_undefined());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ReflectObject::get_own_property_descriptor)
|
||||
{
|
||||
auto* target = get_target_object_from(interpreter, "getOwnPropertyDescriptor");
|
||||
auto* target = get_target_object_from(global_object, "getOwnPropertyDescriptor");
|
||||
if (!target)
|
||||
return {};
|
||||
auto property_key = PropertyName::from_value(interpreter, interpreter.argument(1));
|
||||
if (interpreter.exception())
|
||||
auto property_key = PropertyName::from_value(global_object, vm.argument(1));
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return target->get_own_property_descriptor_object(property_key);
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ReflectObject::get_prototype_of)
|
||||
{
|
||||
auto* target = get_target_object_from(interpreter, "getPrototypeOf");
|
||||
auto* target = get_target_object_from(global_object, "getPrototypeOf");
|
||||
if (!target)
|
||||
return {};
|
||||
return target->prototype();
|
||||
|
@ -213,18 +216,18 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::get_prototype_of)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ReflectObject::has)
|
||||
{
|
||||
auto* target = get_target_object_from(interpreter, "has");
|
||||
auto* target = get_target_object_from(global_object, "has");
|
||||
if (!target)
|
||||
return {};
|
||||
auto property_key = PropertyName::from_value(interpreter, interpreter.argument(1));
|
||||
if (interpreter.exception())
|
||||
auto property_key = PropertyName::from_value(global_object, vm.argument(1));
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return Value(target->has_property(property_key));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ReflectObject::is_extensible)
|
||||
{
|
||||
auto* target = get_target_object_from(interpreter, "isExtensible");
|
||||
auto* target = get_target_object_from(global_object, "isExtensible");
|
||||
if (!target)
|
||||
return {};
|
||||
return Value(target->is_extensible());
|
||||
|
@ -232,7 +235,7 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::is_extensible)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ReflectObject::own_keys)
|
||||
{
|
||||
auto* target = get_target_object_from(interpreter, "ownKeys");
|
||||
auto* target = get_target_object_from(global_object, "ownKeys");
|
||||
if (!target)
|
||||
return {};
|
||||
return target->get_own_properties(*target, PropertyKind::Key);
|
||||
|
@ -240,7 +243,7 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::own_keys)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ReflectObject::prevent_extensions)
|
||||
{
|
||||
auto* target = get_target_object_from(interpreter, "preventExtensions");
|
||||
auto* target = get_target_object_from(global_object, "preventExtensions");
|
||||
if (!target)
|
||||
return {};
|
||||
return Value(target->prevent_extensions());
|
||||
|
@ -248,27 +251,27 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::prevent_extensions)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ReflectObject::set)
|
||||
{
|
||||
auto* target = get_target_object_from(interpreter, "set");
|
||||
auto* target = get_target_object_from(global_object, "set");
|
||||
if (!target)
|
||||
return {};
|
||||
auto property_key = interpreter.argument(1).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto property_key = vm.argument(1).to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto value = interpreter.argument(2);
|
||||
auto value = vm.argument(2);
|
||||
Value receiver = {};
|
||||
if (interpreter.argument_count() > 3)
|
||||
receiver = interpreter.argument(3);
|
||||
if (vm.argument_count() > 3)
|
||||
receiver = vm.argument(3);
|
||||
return Value(target->put(property_key, value, receiver));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ReflectObject::set_prototype_of)
|
||||
{
|
||||
auto* target = get_target_object_from(interpreter, "setPrototypeOf");
|
||||
auto* target = get_target_object_from(global_object, "setPrototypeOf");
|
||||
if (!target)
|
||||
return {};
|
||||
auto prototype_value = interpreter.argument(1);
|
||||
auto prototype_value = vm.argument(1);
|
||||
if (!prototype_value.is_object() && !prototype_value.is_null()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::ObjectPrototypeWrongType);
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ObjectPrototypeWrongType);
|
||||
return {};
|
||||
}
|
||||
Object* prototype = nullptr;
|
||||
|
|
|
@ -53,15 +53,16 @@ Value RegExpConstructor::call()
|
|||
return construct(interpreter(), *this);
|
||||
}
|
||||
|
||||
Value RegExpConstructor::construct(Interpreter& interpreter, Function&)
|
||||
Value RegExpConstructor::construct(Interpreter&, Function&)
|
||||
{
|
||||
if (!interpreter.argument_count())
|
||||
auto& vm = this->vm();
|
||||
if (!vm.argument_count())
|
||||
return RegExpObject::create(global_object(), "(?:)", "");
|
||||
auto contents = interpreter.argument(0).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto contents = vm.argument(0).to_string(global_object());
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto flags = interpreter.argument_count() > 1 ? interpreter.argument(1).to_string(interpreter) : "";
|
||||
if (interpreter.exception())
|
||||
auto flags = vm.argument_count() > 1 ? vm.argument(1).to_string(global_object()) : "";
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return RegExpObject::create(global_object(), contents, flags);
|
||||
}
|
||||
|
|
|
@ -35,13 +35,13 @@
|
|||
|
||||
namespace JS {
|
||||
|
||||
static ScriptFunction* typed_this(Interpreter& interpreter, GlobalObject& global_object)
|
||||
static ScriptFunction* typed_this(VM& vm, GlobalObject& global_object)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return nullptr;
|
||||
if (!this_object->is_function()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotAFunctionNoParam);
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotAFunctionNoParam);
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<ScriptFunction*>(this_object);
|
||||
|
@ -154,7 +154,7 @@ Value ScriptFunction::construct(Interpreter&, Function&)
|
|||
|
||||
JS_DEFINE_NATIVE_GETTER(ScriptFunction::length_getter)
|
||||
{
|
||||
auto* function = typed_this(interpreter, global_object);
|
||||
auto* function = typed_this(vm, global_object);
|
||||
if (!function)
|
||||
return {};
|
||||
return Value(static_cast<i32>(function->m_function_length));
|
||||
|
@ -162,10 +162,10 @@ JS_DEFINE_NATIVE_GETTER(ScriptFunction::length_getter)
|
|||
|
||||
JS_DEFINE_NATIVE_GETTER(ScriptFunction::name_getter)
|
||||
{
|
||||
auto* function = typed_this(interpreter, global_object);
|
||||
auto* function = typed_this(vm, global_object);
|
||||
if (!function)
|
||||
return {};
|
||||
return js_string(interpreter, function->name().is_null() ? "" : function->name());
|
||||
return js_string(vm, function->name().is_null() ? "" : function->name());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -61,19 +61,19 @@ Value StringConstructor::call()
|
|||
return js_string(heap(), "");
|
||||
if (vm().argument(0).is_symbol())
|
||||
return js_string(heap(), vm().argument(0).as_symbol().to_string());
|
||||
auto* string = vm().argument(0).to_primitive_string(interpreter());
|
||||
auto* string = vm().argument(0).to_primitive_string(global_object());
|
||||
if (vm().exception())
|
||||
return {};
|
||||
return string;
|
||||
}
|
||||
|
||||
Value StringConstructor::construct(Interpreter& interpreter, Function&)
|
||||
Value StringConstructor::construct(Interpreter&, Function&)
|
||||
{
|
||||
PrimitiveString* primitive_string = nullptr;
|
||||
if (!interpreter.argument_count())
|
||||
primitive_string = js_string(interpreter, "");
|
||||
if (!vm().argument_count())
|
||||
primitive_string = js_string(vm(), "");
|
||||
else
|
||||
primitive_string = interpreter.argument(0).to_primitive_string(interpreter);
|
||||
primitive_string = vm().argument(0).to_primitive_string(global_object());
|
||||
if (!primitive_string)
|
||||
return {};
|
||||
return StringObject::create(global_object(), *primitive_string);
|
||||
|
@ -81,55 +81,55 @@ Value StringConstructor::construct(Interpreter& interpreter, Function&)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringConstructor::raw)
|
||||
{
|
||||
auto* template_object = interpreter.argument(0).to_object(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
auto* template_object = vm.argument(0).to_object(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
auto raw = template_object->get("raw");
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (raw.is_empty() || raw.is_undefined() || raw.is_null()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::StringRawCannotConvert, raw.is_null() ? "null" : "undefined");
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::StringRawCannotConvert, raw.is_null() ? "null" : "undefined");
|
||||
return {};
|
||||
}
|
||||
if (!raw.is_array())
|
||||
return js_string(interpreter, "");
|
||||
return js_string(vm, "");
|
||||
|
||||
auto* array = static_cast<Array*>(raw.to_object(interpreter, global_object));
|
||||
auto* array = static_cast<Array*>(raw.to_object(global_object));
|
||||
auto& raw_array_elements = array->indexed_properties();
|
||||
StringBuilder builder;
|
||||
|
||||
for (size_t i = 0; i < raw_array_elements.array_like_size(); ++i) {
|
||||
auto result = raw_array_elements.get(array, i);
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (!result.has_value())
|
||||
continue;
|
||||
builder.append(result.value().value.to_string(interpreter));
|
||||
if (interpreter.exception())
|
||||
builder.append(result.value().value.to_string(global_object));
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (i + 1 < interpreter.argument_count() && i < raw_array_elements.array_like_size() - 1) {
|
||||
builder.append(interpreter.argument(i + 1).to_string(interpreter));
|
||||
if (interpreter.exception())
|
||||
if (i + 1 < vm.argument_count() && i < raw_array_elements.array_like_size() - 1) {
|
||||
builder.append(vm.argument(i + 1).to_string(global_object));
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
return js_string(interpreter, builder.build());
|
||||
return js_string(vm, builder.build());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringConstructor::from_char_code)
|
||||
{
|
||||
StringBuilder builder;
|
||||
for (size_t i = 0; i < interpreter.argument_count(); ++i) {
|
||||
auto char_code = interpreter.argument(i).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
for (size_t i = 0; i < vm.argument_count(); ++i) {
|
||||
auto char_code = vm.argument(i).to_i32(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto truncated = char_code & 0xffff;
|
||||
// FIXME: We need an Utf16View :^)
|
||||
builder.append(Utf32View((u32*)&truncated, 1));
|
||||
}
|
||||
return js_string(interpreter, builder.build());
|
||||
return js_string(vm, builder.build());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -52,9 +52,9 @@ StringIteratorPrototype::~StringIteratorPrototype()
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringIteratorPrototype::next)
|
||||
{
|
||||
auto this_value = interpreter.this_value(global_object);
|
||||
auto this_value = vm.this_value(global_object);
|
||||
if (!this_value.is_object() || !this_value.as_object().is_string_iterator_object()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotA, "String Iterator");
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "String Iterator");
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringIteratorPrototype::next)
|
|||
builder.append_code_point(*utf8_iterator);
|
||||
++utf8_iterator;
|
||||
|
||||
return create_iterator_result_object(global_object, js_string(interpreter, builder.to_string()), false);
|
||||
return create_iterator_result_object(global_object, js_string(vm, builder.to_string()), false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,12 +34,12 @@ namespace JS {
|
|||
|
||||
class StringOrSymbol {
|
||||
public:
|
||||
static StringOrSymbol from_value(Interpreter& interpreter, Value value)
|
||||
static StringOrSymbol from_value(GlobalObject& global_object, Value value)
|
||||
{
|
||||
if (value.is_symbol())
|
||||
return &value.as_symbol();
|
||||
if (!value.is_empty())
|
||||
return value.to_string(interpreter);
|
||||
return value.to_string(global_object);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -40,24 +40,24 @@
|
|||
|
||||
namespace JS {
|
||||
|
||||
static StringObject* typed_this(Interpreter& interpreter, GlobalObject& global_object)
|
||||
static StringObject* typed_this(VM& vm, GlobalObject& global_object)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return nullptr;
|
||||
if (!this_object->is_string_object()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotA, "String");
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "String");
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<StringObject*>(this_object);
|
||||
}
|
||||
|
||||
static String ak_string_from(Interpreter& interpreter, GlobalObject& global_object)
|
||||
static String ak_string_from(VM& vm, GlobalObject& global_object)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return Value(this_object).to_string(interpreter);
|
||||
return Value(this_object).to_string(global_object);
|
||||
}
|
||||
|
||||
StringPrototype::StringPrototype(GlobalObject& global_object)
|
||||
|
@ -98,30 +98,30 @@ StringPrototype::~StringPrototype()
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::char_at)
|
||||
{
|
||||
auto string = ak_string_from(interpreter, global_object);
|
||||
auto string = ak_string_from(vm, global_object);
|
||||
if (string.is_null())
|
||||
return {};
|
||||
i32 index = 0;
|
||||
if (interpreter.argument_count()) {
|
||||
index = interpreter.argument(0).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (vm.argument_count()) {
|
||||
index = vm.argument(0).to_i32(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
if (index < 0 || index >= static_cast<i32>(string.length()))
|
||||
return js_string(interpreter, String::empty());
|
||||
return js_string(vm, String::empty());
|
||||
// FIXME: This should return a character corresponding to the i'th UTF-16 code point.
|
||||
return js_string(interpreter, string.substring(index, 1));
|
||||
return js_string(vm, string.substring(index, 1));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::char_code_at)
|
||||
{
|
||||
auto string = ak_string_from(interpreter, global_object);
|
||||
auto string = ak_string_from(vm, global_object);
|
||||
if (string.is_null())
|
||||
return {};
|
||||
i32 index = 0;
|
||||
if (interpreter.argument_count()) {
|
||||
index = interpreter.argument(0).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (vm.argument_count()) {
|
||||
index = vm.argument(0).to_i32(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
if (index < 0 || index >= static_cast<i32>(string.length()))
|
||||
|
@ -132,50 +132,50 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::char_code_at)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::repeat)
|
||||
{
|
||||
auto string = ak_string_from(interpreter, global_object);
|
||||
auto string = ak_string_from(vm, global_object);
|
||||
if (string.is_null())
|
||||
return {};
|
||||
if (!interpreter.argument_count())
|
||||
return js_string(interpreter, String::empty());
|
||||
auto count_value = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (!vm.argument_count())
|
||||
return js_string(vm, String::empty());
|
||||
auto count_value = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (count_value.as_double() < 0) {
|
||||
interpreter.vm().throw_exception<RangeError>(global_object, ErrorType::StringRepeatCountMustBe, "positive");
|
||||
vm.throw_exception<RangeError>(global_object, ErrorType::StringRepeatCountMustBe, "positive");
|
||||
return {};
|
||||
}
|
||||
if (count_value.is_infinity()) {
|
||||
interpreter.vm().throw_exception<RangeError>(global_object, ErrorType::StringRepeatCountMustBe, "finite");
|
||||
vm.throw_exception<RangeError>(global_object, ErrorType::StringRepeatCountMustBe, "finite");
|
||||
return {};
|
||||
}
|
||||
auto count = count_value.to_size_t(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto count = count_value.to_size_t(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
StringBuilder builder;
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
builder.append(string);
|
||||
return js_string(interpreter, builder.to_string());
|
||||
return js_string(vm, builder.to_string());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::starts_with)
|
||||
{
|
||||
auto string = ak_string_from(interpreter, global_object);
|
||||
auto string = ak_string_from(vm, global_object);
|
||||
if (string.is_null())
|
||||
return {};
|
||||
if (!interpreter.argument_count())
|
||||
if (!vm.argument_count())
|
||||
return Value(false);
|
||||
auto search_string = interpreter.argument(0).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto search_string = vm.argument(0).to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto string_length = string.length();
|
||||
auto search_string_length = search_string.length();
|
||||
size_t start = 0;
|
||||
if (interpreter.argument_count() > 1) {
|
||||
auto number = interpreter.argument(1).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (vm.argument_count() > 1) {
|
||||
auto number = vm.argument(1).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (!number.is_nan())
|
||||
start = min(number.to_size_t(interpreter), string_length);
|
||||
start = min(number.to_size_t(global_object), string_length);
|
||||
}
|
||||
if (start + search_string_length > string_length)
|
||||
return Value(false);
|
||||
|
@ -186,34 +186,34 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::starts_with)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::index_of)
|
||||
{
|
||||
auto string = ak_string_from(interpreter, global_object);
|
||||
auto string = ak_string_from(vm, global_object);
|
||||
if (string.is_null())
|
||||
return {};
|
||||
auto needle = interpreter.argument(0).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto needle = vm.argument(0).to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return Value((i32)string.index_of(needle).value_or(-1));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::to_lowercase)
|
||||
{
|
||||
auto string = ak_string_from(interpreter, global_object);
|
||||
auto string = ak_string_from(vm, global_object);
|
||||
if (string.is_null())
|
||||
return {};
|
||||
return js_string(interpreter, string.to_lowercase());
|
||||
return js_string(vm, string.to_lowercase());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::to_uppercase)
|
||||
{
|
||||
auto string = ak_string_from(interpreter, global_object);
|
||||
auto string = ak_string_from(vm, global_object);
|
||||
if (string.is_null())
|
||||
return {};
|
||||
return js_string(interpreter, string.to_uppercase());
|
||||
return js_string(vm, string.to_uppercase());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_GETTER(StringPrototype::length_getter)
|
||||
{
|
||||
auto* string_object = typed_this(interpreter, global_object);
|
||||
auto* string_object = typed_this(vm, global_object);
|
||||
if (!string_object)
|
||||
return {};
|
||||
return Value((i32)string_object->primitive_string().string().length());
|
||||
|
@ -221,10 +221,10 @@ JS_DEFINE_NATIVE_GETTER(StringPrototype::length_getter)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::to_string)
|
||||
{
|
||||
auto* string_object = typed_this(interpreter, global_object);
|
||||
auto* string_object = typed_this(vm, global_object);
|
||||
if (!string_object)
|
||||
return {};
|
||||
return js_string(interpreter, string_object->primitive_string().string());
|
||||
return js_string(vm, string_object->primitive_string().string());
|
||||
}
|
||||
|
||||
enum class PadPlacement {
|
||||
|
@ -232,21 +232,22 @@ enum class PadPlacement {
|
|||
End,
|
||||
};
|
||||
|
||||
static Value pad_string(Interpreter& interpreter, const String& string, PadPlacement placement)
|
||||
static Value pad_string(GlobalObject& global_object, const String& string, PadPlacement placement)
|
||||
{
|
||||
auto max_length = interpreter.argument(0).to_size_t(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto& vm = global_object.vm();
|
||||
auto max_length = vm.argument(0).to_size_t(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (max_length <= string.length())
|
||||
return js_string(interpreter, string);
|
||||
return js_string(vm, string);
|
||||
|
||||
String fill_string = " ";
|
||||
if (!interpreter.argument(1).is_undefined()) {
|
||||
fill_string = interpreter.argument(1).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (!vm.argument(1).is_undefined()) {
|
||||
fill_string = vm.argument(1).to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (fill_string.is_empty())
|
||||
return js_string(interpreter, string);
|
||||
return js_string(vm, string);
|
||||
}
|
||||
|
||||
auto fill_length = max_length - string.length();
|
||||
|
@ -257,92 +258,92 @@ static Value pad_string(Interpreter& interpreter, const String& string, PadPlace
|
|||
auto filler = filler_builder.build().substring(0, fill_length);
|
||||
|
||||
if (placement == PadPlacement::Start)
|
||||
return js_string(interpreter, String::format("%s%s", filler.characters(), string.characters()));
|
||||
return js_string(interpreter, String::format("%s%s", string.characters(), filler.characters()));
|
||||
return js_string(vm, String::format("%s%s", filler.characters(), string.characters()));
|
||||
return js_string(vm, String::format("%s%s", string.characters(), filler.characters()));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::pad_start)
|
||||
{
|
||||
auto string = ak_string_from(interpreter, global_object);
|
||||
auto string = ak_string_from(vm, global_object);
|
||||
if (string.is_null())
|
||||
return {};
|
||||
return pad_string(interpreter, string, PadPlacement::Start);
|
||||
return pad_string(global_object, string, PadPlacement::Start);
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::pad_end)
|
||||
{
|
||||
auto string = ak_string_from(interpreter, global_object);
|
||||
auto string = ak_string_from(vm, global_object);
|
||||
if (string.is_null())
|
||||
return {};
|
||||
return pad_string(interpreter, string, PadPlacement::End);
|
||||
return pad_string(global_object, string, PadPlacement::End);
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::trim)
|
||||
{
|
||||
auto string = ak_string_from(interpreter, global_object);
|
||||
auto string = ak_string_from(vm, global_object);
|
||||
if (string.is_null())
|
||||
return {};
|
||||
return js_string(interpreter, string.trim_whitespace(String::TrimMode::Both));
|
||||
return js_string(vm, string.trim_whitespace(String::TrimMode::Both));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::trim_start)
|
||||
{
|
||||
auto string = ak_string_from(interpreter, global_object);
|
||||
auto string = ak_string_from(vm, global_object);
|
||||
if (string.is_null())
|
||||
return {};
|
||||
return js_string(interpreter, string.trim_whitespace(String::TrimMode::Left));
|
||||
return js_string(vm, string.trim_whitespace(String::TrimMode::Left));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::trim_end)
|
||||
{
|
||||
auto string = ak_string_from(interpreter, global_object);
|
||||
auto string = ak_string_from(vm, global_object);
|
||||
if (string.is_null())
|
||||
return {};
|
||||
return js_string(interpreter, string.trim_whitespace(String::TrimMode::Right));
|
||||
return js_string(vm, string.trim_whitespace(String::TrimMode::Right));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::concat)
|
||||
{
|
||||
auto string = ak_string_from(interpreter, global_object);
|
||||
auto string = ak_string_from(vm, global_object);
|
||||
if (string.is_null())
|
||||
return {};
|
||||
StringBuilder builder;
|
||||
builder.append(string);
|
||||
for (size_t i = 0; i < interpreter.argument_count(); ++i) {
|
||||
auto string_argument = interpreter.argument(i).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
for (size_t i = 0; i < vm.argument_count(); ++i) {
|
||||
auto string_argument = vm.argument(i).to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
builder.append(string_argument);
|
||||
}
|
||||
return js_string(interpreter, builder.to_string());
|
||||
return js_string(vm, builder.to_string());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substring)
|
||||
{
|
||||
auto string = ak_string_from(interpreter, global_object);
|
||||
auto string = ak_string_from(vm, global_object);
|
||||
if (string.is_null())
|
||||
return {};
|
||||
if (interpreter.argument_count() == 0)
|
||||
return js_string(interpreter, string);
|
||||
if (vm.argument_count() == 0)
|
||||
return js_string(vm, string);
|
||||
|
||||
// FIXME: index_start and index_end should index a UTF-16 code_point view of the string.
|
||||
auto string_length = string.length();
|
||||
auto index_start = min(interpreter.argument(0).to_size_t(interpreter), string_length);
|
||||
if (interpreter.exception())
|
||||
auto index_start = min(vm.argument(0).to_size_t(global_object), string_length);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto index_end = string_length;
|
||||
if (interpreter.argument_count() >= 2) {
|
||||
index_end = min(interpreter.argument(1).to_size_t(interpreter), string_length);
|
||||
if (interpreter.exception())
|
||||
if (vm.argument_count() >= 2) {
|
||||
index_end = min(vm.argument(1).to_size_t(global_object), string_length);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
|
||||
if (index_start == index_end)
|
||||
return js_string(interpreter, String(""));
|
||||
return js_string(vm, String(""));
|
||||
|
||||
if (index_start > index_end) {
|
||||
if (interpreter.argument_count() == 1)
|
||||
return js_string(interpreter, String(""));
|
||||
if (vm.argument_count() == 1)
|
||||
return js_string(vm, String(""));
|
||||
auto temp_index_start = index_start;
|
||||
index_start = index_end;
|
||||
index_end = temp_index_start;
|
||||
|
@ -350,23 +351,23 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substring)
|
|||
|
||||
auto part_length = index_end - index_start;
|
||||
auto string_part = string.substring(index_start, part_length);
|
||||
return js_string(interpreter, string_part);
|
||||
return js_string(vm, string_part);
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::includes)
|
||||
{
|
||||
auto string = ak_string_from(interpreter, global_object);
|
||||
auto string = ak_string_from(vm, global_object);
|
||||
if (string.is_null())
|
||||
return {};
|
||||
auto search_string = interpreter.argument(0).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto search_string = vm.argument(0).to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
// FIXME: position should index a UTF-16 code_point view of the string.
|
||||
size_t position = 0;
|
||||
if (interpreter.argument_count() >= 2) {
|
||||
position = interpreter.argument(1).to_size_t(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (vm.argument_count() >= 2) {
|
||||
position = vm.argument(1).to_size_t(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (position >= string.length())
|
||||
return Value(false);
|
||||
|
@ -382,17 +383,17 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::includes)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::slice)
|
||||
{
|
||||
auto string = ak_string_from(interpreter, global_object);
|
||||
auto string = ak_string_from(vm, global_object);
|
||||
if (string.is_null())
|
||||
return {};
|
||||
|
||||
if (interpreter.argument_count() == 0)
|
||||
return js_string(interpreter, string);
|
||||
if (vm.argument_count() == 0)
|
||||
return js_string(vm, string);
|
||||
|
||||
// FIXME: index_start and index_end should index a UTF-16 code_point view of the string.
|
||||
auto string_length = static_cast<i32>(string.length());
|
||||
auto index_start = interpreter.argument(0).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto index_start = vm.argument(0).to_i32(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto index_end = string_length;
|
||||
|
||||
|
@ -402,13 +403,13 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::slice)
|
|||
else if (index_start < 0)
|
||||
index_start = string_length + index_start;
|
||||
|
||||
if (interpreter.argument_count() >= 2) {
|
||||
index_end = interpreter.argument(1).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (vm.argument_count() >= 2) {
|
||||
index_end = vm.argument(1).to_i32(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
if (index_end < negative_min_index)
|
||||
return js_string(interpreter, String::empty());
|
||||
return js_string(vm, String::empty());
|
||||
|
||||
if (index_end > string_length)
|
||||
index_end = string_length;
|
||||
|
@ -417,33 +418,33 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::slice)
|
|||
}
|
||||
|
||||
if (index_start >= index_end)
|
||||
return js_string(interpreter, String::empty());
|
||||
return js_string(vm, String::empty());
|
||||
|
||||
auto part_length = index_end - index_start;
|
||||
auto string_part = string.substring(index_start, part_length);
|
||||
return js_string(interpreter, string_part);
|
||||
return js_string(vm, string_part);
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::last_index_of)
|
||||
{
|
||||
auto string = ak_string_from(interpreter, global_object);
|
||||
auto string = ak_string_from(vm, global_object);
|
||||
if (string.is_null())
|
||||
return {};
|
||||
|
||||
if (interpreter.argument_count() == 0)
|
||||
if (vm.argument_count() == 0)
|
||||
return Value(-1);
|
||||
|
||||
auto search_string = interpreter.argument(0).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto search_string = vm.argument(0).to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (search_string.length() > string.length())
|
||||
return Value(-1);
|
||||
auto max_index = string.length() - search_string.length();
|
||||
auto from_index = max_index;
|
||||
if (interpreter.argument_count() >= 2) {
|
||||
if (vm.argument_count() >= 2) {
|
||||
// FIXME: from_index should index a UTF-16 code_point view of the string.
|
||||
from_index = min(interpreter.argument(1).to_size_t(interpreter), max_index);
|
||||
if (interpreter.exception())
|
||||
from_index = min(vm.argument(1).to_size_t(global_object), max_index);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -458,14 +459,14 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::last_index_of)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::symbol_iterator)
|
||||
{
|
||||
auto this_object = interpreter.this_value(global_object);
|
||||
auto this_object = vm.this_value(global_object);
|
||||
if (this_object.is_undefined() || this_object.is_null()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::ToObjectNullOrUndef);
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ToObjectNullOrUndef);
|
||||
return {};
|
||||
}
|
||||
|
||||
auto string = this_object.to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto string = this_object.to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return StringIterator::create(global_object, string);
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ Value SymbolConstructor::call()
|
|||
{
|
||||
if (!vm().argument_count())
|
||||
return js_symbol(heap(), "", false);
|
||||
return js_symbol(heap(), vm().argument(0).to_string(interpreter()), false);
|
||||
return js_symbol(heap(), vm().argument(0).to_string(global_object()), false);
|
||||
}
|
||||
|
||||
Value SymbolConstructor::construct(Interpreter& interpreter, Function&)
|
||||
|
@ -72,10 +72,10 @@ Value SymbolConstructor::construct(Interpreter& interpreter, Function&)
|
|||
JS_DEFINE_NATIVE_FUNCTION(SymbolConstructor::for_)
|
||||
{
|
||||
String description;
|
||||
if (!interpreter.argument_count()) {
|
||||
if (!vm.argument_count()) {
|
||||
description = "undefined";
|
||||
} else {
|
||||
description = interpreter.argument(0).to_string(interpreter);
|
||||
description = vm.argument(0).to_string(global_object);
|
||||
}
|
||||
|
||||
return global_object.vm().get_global_symbol(description);
|
||||
|
@ -83,15 +83,15 @@ JS_DEFINE_NATIVE_FUNCTION(SymbolConstructor::for_)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(SymbolConstructor::key_for)
|
||||
{
|
||||
auto argument = interpreter.argument(0);
|
||||
auto argument = vm.argument(0);
|
||||
if (!argument.is_symbol()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotASymbol, argument.to_string_without_side_effects().characters());
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotASymbol, argument.to_string_without_side_effects().characters());
|
||||
return {};
|
||||
}
|
||||
|
||||
auto& symbol = argument.as_symbol();
|
||||
if (symbol.is_global())
|
||||
return js_string(interpreter, symbol.description());
|
||||
return js_string(vm, symbol.description());
|
||||
|
||||
return js_undefined();
|
||||
}
|
||||
|
|
|
@ -58,13 +58,13 @@ SymbolPrototype::~SymbolPrototype()
|
|||
{
|
||||
}
|
||||
|
||||
static SymbolObject* typed_this(Interpreter& interpreter, GlobalObject& global_object)
|
||||
static SymbolObject* typed_this(VM& vm, GlobalObject& global_object)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return nullptr;
|
||||
if (!this_object->is_symbol_object()) {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotA, "Symbol");
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "Symbol");
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<SymbolObject*>(this_object);
|
||||
|
@ -72,24 +72,24 @@ static SymbolObject* typed_this(Interpreter& interpreter, GlobalObject& global_o
|
|||
|
||||
JS_DEFINE_NATIVE_GETTER(SymbolPrototype::description_getter)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return js_string(interpreter, this_object->description());
|
||||
return js_string(vm, this_object->description());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(SymbolPrototype::to_string)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
auto string = this_object->primitive_symbol().to_string();
|
||||
return js_string(interpreter, move(string));
|
||||
return js_string(vm, move(string));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(SymbolPrototype::value_of)
|
||||
{
|
||||
auto* this_object = typed_this(interpreter, global_object);
|
||||
auto* this_object = typed_this(vm, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
return this_object->value_of();
|
||||
|
|
|
@ -55,11 +55,11 @@ Uint8ClampedArray::~Uint8ClampedArray()
|
|||
|
||||
JS_DEFINE_NATIVE_GETTER(Uint8ClampedArray::length_getter)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (StringView(this_object->class_name()) != "Uint8ClampedArray") {
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::NotA, "Uint8ClampedArray");
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "Uint8ClampedArray");
|
||||
return {};
|
||||
}
|
||||
return Value(static_cast<const Uint8ClampedArray*>(this_object)->length());
|
||||
|
@ -69,7 +69,7 @@ bool Uint8ClampedArray::put_by_index(u32 property_index, Value value)
|
|||
{
|
||||
// FIXME: Use attributes
|
||||
ASSERT(property_index < m_length);
|
||||
auto number = value.to_i32(interpreter());
|
||||
auto number = value.to_i32(global_object());
|
||||
if (vm().exception())
|
||||
return {};
|
||||
m_data[property_index] = clamp(number, 0, 255);
|
||||
|
|
|
@ -300,7 +300,7 @@ Value VM::get_new_target() const
|
|||
return get_this_environment()->new_target();
|
||||
}
|
||||
|
||||
Value VM::call(Function& function, Value this_value, Optional<MarkedValueList> arguments)
|
||||
Value VM::call_internal(Function& function, Value this_value, Optional<MarkedValueList> arguments)
|
||||
{
|
||||
ASSERT(!exception());
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <LibJS/Heap/Heap.h>
|
||||
#include <LibJS/Runtime/ErrorTypes.h>
|
||||
#include <LibJS/Runtime/Exception.h>
|
||||
#include <LibJS/Runtime/MarkedValueList.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
|
||||
namespace JS {
|
||||
|
@ -206,11 +207,26 @@ public:
|
|||
const LexicalEnvironment* get_this_environment() const;
|
||||
Value get_new_target() const;
|
||||
|
||||
[[nodiscard]] Value call(Function&, Value this_value, Optional<MarkedValueList> arguments);
|
||||
template<typename... Args>
|
||||
[[nodiscard]] ALWAYS_INLINE Value call(Function& function, Value this_value, Args... args)
|
||||
{
|
||||
// Are there any values in this argpack?
|
||||
// args = [] -> if constexpr (false)
|
||||
// args = [x, y, z] -> if constexpr ((void)x, true || ...)
|
||||
if constexpr ((((void)args, true) || ...)) {
|
||||
MarkedValueList arglist { heap() };
|
||||
(..., arglist.append(move(args)));
|
||||
return call(function, this_value, move(arglist));
|
||||
}
|
||||
|
||||
return call(function, this_value);
|
||||
}
|
||||
|
||||
private:
|
||||
VM();
|
||||
|
||||
[[nodiscard]] Value call_internal(Function&, Value this_value, Optional<MarkedValueList> arguments);
|
||||
|
||||
Exception* m_exception { nullptr };
|
||||
|
||||
Heap m_heap;
|
||||
|
@ -234,4 +250,13 @@ private:
|
|||
#undef __JS_ENUMERATE
|
||||
};
|
||||
|
||||
template<>
|
||||
[[nodiscard]] ALWAYS_INLINE Value VM::call(Function& function, Value this_value, MarkedValueList arguments) { return call_internal(function, this_value, move(arguments)); }
|
||||
|
||||
template<>
|
||||
[[nodiscard]] ALWAYS_INLINE Value VM::call(Function& function, Value this_value, Optional<MarkedValueList> arguments) { return call_internal(function, this_value, move(arguments)); }
|
||||
|
||||
template<>
|
||||
[[nodiscard]] ALWAYS_INLINE Value VM::call(Function& function, Value this_value) { return call(function, this_value, Optional<MarkedValueList> {}); }
|
||||
|
||||
}
|
||||
|
|
|
@ -134,17 +134,17 @@ String Value::to_string_without_side_effects() const
|
|||
}
|
||||
}
|
||||
|
||||
PrimitiveString* Value::to_primitive_string(Interpreter& interpreter)
|
||||
PrimitiveString* Value::to_primitive_string(GlobalObject& global_object)
|
||||
{
|
||||
if (is_string())
|
||||
return &as_string();
|
||||
auto string = to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto string = to_string(global_object);
|
||||
if (global_object.vm().exception())
|
||||
return nullptr;
|
||||
return js_string(interpreter, string);
|
||||
return js_string(global_object.heap(), string);
|
||||
}
|
||||
|
||||
String Value::to_string(Interpreter& interpreter) const
|
||||
String Value::to_string(GlobalObject& global_object) const
|
||||
{
|
||||
switch (m_type) {
|
||||
case Type::Undefined:
|
||||
|
@ -164,15 +164,15 @@ String Value::to_string(Interpreter& interpreter) const
|
|||
case Type::String:
|
||||
return m_value.as_string->string();
|
||||
case Type::Symbol:
|
||||
interpreter.vm().throw_exception<TypeError>(interpreter.global_object(), ErrorType::Convert, "symbol", "string");
|
||||
global_object.vm().throw_exception<TypeError>(global_object, ErrorType::Convert, "symbol", "string");
|
||||
return {};
|
||||
case Type::BigInt:
|
||||
return m_value.as_bigint->big_integer().to_base10();
|
||||
case Type::Object: {
|
||||
auto primitive_value = as_object().to_primitive(PreferredType::String);
|
||||
if (interpreter.exception())
|
||||
if (global_object.vm().exception())
|
||||
return {};
|
||||
return primitive_value.to_string(interpreter);
|
||||
return primitive_value.to_string(global_object);
|
||||
}
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
|
@ -211,12 +211,12 @@ Value Value::to_primitive(PreferredType preferred_type) const
|
|||
return *this;
|
||||
}
|
||||
|
||||
Object* Value::to_object(Interpreter& interpreter, GlobalObject& global_object) const
|
||||
Object* Value::to_object(GlobalObject& global_object) const
|
||||
{
|
||||
switch (m_type) {
|
||||
case Type::Undefined:
|
||||
case Type::Null:
|
||||
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::ToObjectNullOrUndef);
|
||||
global_object.vm().throw_exception<TypeError>(global_object, ErrorType::ToObjectNullOrUndef);
|
||||
return nullptr;
|
||||
case Type::Boolean:
|
||||
return BooleanObject::create(global_object, m_value.as_bool);
|
||||
|
@ -236,17 +236,17 @@ Object* Value::to_object(Interpreter& interpreter, GlobalObject& global_object)
|
|||
}
|
||||
}
|
||||
|
||||
Value Value::to_numeric(Interpreter& interpreter) const
|
||||
Value Value::to_numeric(GlobalObject& global_object) const
|
||||
{
|
||||
auto primitive = to_primitive(Value::PreferredType::Number);
|
||||
if (interpreter.exception())
|
||||
if (global_object.vm().exception())
|
||||
return {};
|
||||
if (primitive.is_bigint())
|
||||
return primitive;
|
||||
return primitive.to_number(interpreter);
|
||||
return primitive.to_number(global_object);
|
||||
}
|
||||
|
||||
Value Value::to_number(Interpreter& interpreter) const
|
||||
Value Value::to_number(GlobalObject& global_object) const
|
||||
{
|
||||
switch (m_type) {
|
||||
case Type::Undefined:
|
||||
|
@ -272,16 +272,16 @@ Value Value::to_number(Interpreter& interpreter) const
|
|||
return Value(parsed_double);
|
||||
}
|
||||
case Type::Symbol:
|
||||
interpreter.vm().throw_exception<TypeError>(interpreter.global_object(), ErrorType::Convert, "symbol", "number");
|
||||
global_object.vm().throw_exception<TypeError>(global_object, ErrorType::Convert, "symbol", "number");
|
||||
return {};
|
||||
case Type::BigInt:
|
||||
interpreter.vm().throw_exception<TypeError>(interpreter.global_object(), ErrorType::Convert, "BigInt", "number");
|
||||
global_object.vm().throw_exception<TypeError>(global_object, ErrorType::Convert, "BigInt", "number");
|
||||
return {};
|
||||
case Type::Object: {
|
||||
auto primitive = m_value.as_object->to_primitive(PreferredType::Number);
|
||||
if (interpreter.exception())
|
||||
if (global_object.vm().exception())
|
||||
return {};
|
||||
return primitive.to_number(interpreter);
|
||||
return primitive.to_number(global_object);
|
||||
}
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
|
@ -337,18 +337,18 @@ size_t Value::as_size_t() const
|
|||
return min((double)as_i32(), MAX_ARRAY_LIKE_INDEX);
|
||||
}
|
||||
|
||||
double Value::to_double(Interpreter& interpreter) const
|
||||
double Value::to_double(GlobalObject& global_object) const
|
||||
{
|
||||
auto number = to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = to_number(global_object);
|
||||
if (global_object.vm().exception())
|
||||
return 0;
|
||||
return number.as_double();
|
||||
}
|
||||
|
||||
i32 Value::to_i32(Interpreter& interpreter) const
|
||||
i32 Value::to_i32(GlobalObject& global_object) const
|
||||
{
|
||||
auto number = to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = to_number(global_object);
|
||||
if (global_object.vm().exception())
|
||||
return 0;
|
||||
if (number.is_nan())
|
||||
return 0;
|
||||
|
@ -357,12 +357,12 @@ i32 Value::to_i32(Interpreter& interpreter) const
|
|||
return number.as_i32();
|
||||
}
|
||||
|
||||
size_t Value::to_size_t(Interpreter& interpreter) const
|
||||
size_t Value::to_size_t(GlobalObject& global_object) const
|
||||
{
|
||||
if (is_empty())
|
||||
return 0;
|
||||
auto number = to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto number = to_number(global_object);
|
||||
if (global_object.vm().exception())
|
||||
return 0;
|
||||
if (number.is_nan())
|
||||
return 0;
|
||||
|
@ -405,10 +405,10 @@ Value less_than_equals(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
|
||||
Value bitwise_and(Interpreter& interpreter, Value lhs, Value rhs)
|
||||
{
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter);
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter);
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
if (both_number(lhs_numeric, rhs_numeric)) {
|
||||
|
@ -424,10 +424,10 @@ Value bitwise_and(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
|
||||
Value bitwise_or(Interpreter& interpreter, Value lhs, Value rhs)
|
||||
{
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter);
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter);
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
if (both_number(lhs_numeric, rhs_numeric)) {
|
||||
|
@ -447,10 +447,10 @@ Value bitwise_or(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
|
||||
Value bitwise_xor(Interpreter& interpreter, Value lhs, Value rhs)
|
||||
{
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter);
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter);
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
if (both_number(lhs_numeric, rhs_numeric)) {
|
||||
|
@ -470,7 +470,7 @@ Value bitwise_xor(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
|
||||
Value bitwise_not(Interpreter& interpreter, Value lhs)
|
||||
{
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter);
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
if (lhs_numeric.is_number())
|
||||
|
@ -483,12 +483,12 @@ Value bitwise_not(Interpreter& interpreter, Value lhs)
|
|||
|
||||
Value unary_plus(Interpreter& interpreter, Value lhs)
|
||||
{
|
||||
return lhs.to_number(interpreter);
|
||||
return lhs.to_number(interpreter.global_object());
|
||||
}
|
||||
|
||||
Value unary_minus(Interpreter& interpreter, Value lhs)
|
||||
{
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter);
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
if (lhs_numeric.is_number()) {
|
||||
|
@ -505,10 +505,10 @@ Value unary_minus(Interpreter& interpreter, Value lhs)
|
|||
|
||||
Value left_shift(Interpreter& interpreter, Value lhs, Value rhs)
|
||||
{
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter);
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter);
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
if (both_number(lhs_numeric, rhs_numeric)) {
|
||||
|
@ -526,10 +526,10 @@ Value left_shift(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
|
||||
Value right_shift(Interpreter& interpreter, Value lhs, Value rhs)
|
||||
{
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter);
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter);
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
if (both_number(lhs_numeric, rhs_numeric)) {
|
||||
|
@ -547,10 +547,10 @@ Value right_shift(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
|
||||
Value unsigned_right_shift(Interpreter& interpreter, Value lhs, Value rhs)
|
||||
{
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter);
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter);
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
if (both_number(lhs_numeric, rhs_numeric)) {
|
||||
|
@ -574,10 +574,10 @@ Value add(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
return {};
|
||||
|
||||
if (lhs_primitive.is_string() || rhs_primitive.is_string()) {
|
||||
auto lhs_string = lhs_primitive.to_string(interpreter);
|
||||
auto lhs_string = lhs_primitive.to_string(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
auto rhs_string = rhs_primitive.to_string(interpreter);
|
||||
auto rhs_string = rhs_primitive.to_string(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
StringBuilder builder(lhs_string.length() + rhs_string.length());
|
||||
|
@ -586,10 +586,10 @@ Value add(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
return js_string(interpreter, builder.to_string());
|
||||
}
|
||||
|
||||
auto lhs_numeric = lhs_primitive.to_numeric(interpreter);
|
||||
auto lhs_numeric = lhs_primitive.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
auto rhs_numeric = rhs_primitive.to_numeric(interpreter);
|
||||
auto rhs_numeric = rhs_primitive.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
if (both_number(lhs_numeric, rhs_numeric))
|
||||
|
@ -602,10 +602,10 @@ Value add(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
|
||||
Value sub(Interpreter& interpreter, Value lhs, Value rhs)
|
||||
{
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter);
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter);
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
if (both_number(lhs_numeric, rhs_numeric))
|
||||
|
@ -618,10 +618,10 @@ Value sub(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
|
||||
Value mul(Interpreter& interpreter, Value lhs, Value rhs)
|
||||
{
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter);
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter);
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
if (both_number(lhs_numeric, rhs_numeric))
|
||||
|
@ -634,10 +634,10 @@ Value mul(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
|
||||
Value div(Interpreter& interpreter, Value lhs, Value rhs)
|
||||
{
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter);
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter);
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
if (both_number(lhs_numeric, rhs_numeric))
|
||||
|
@ -650,10 +650,10 @@ Value div(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
|
||||
Value mod(Interpreter& interpreter, Value lhs, Value rhs)
|
||||
{
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter);
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter);
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
if (both_number(lhs_numeric, rhs_numeric)) {
|
||||
|
@ -670,19 +670,20 @@ Value mod(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
return {};
|
||||
}
|
||||
|
||||
Value exp(Interpreter& interpreter, Value lhs, Value rhs)
|
||||
Value exp(GlobalObject& global_object, Value lhs, Value rhs)
|
||||
{
|
||||
auto lhs_numeric = lhs.to_numeric(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto& vm = global_object.vm();
|
||||
auto lhs_numeric = lhs.to_numeric(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto rhs_numeric = rhs.to_numeric(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto rhs_numeric = rhs.to_numeric(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (both_number(lhs_numeric, rhs_numeric))
|
||||
return Value(pow(lhs_numeric.as_double(), rhs_numeric.as_double()));
|
||||
if (both_bigint(lhs_numeric, rhs_numeric))
|
||||
return js_bigint(interpreter, Crypto::NumberTheory::Power(lhs_numeric.as_bigint().big_integer(), rhs_numeric.as_bigint().big_integer()));
|
||||
interpreter.vm().throw_exception<TypeError>(interpreter.global_object(), ErrorType::BigIntBadOperatorOtherType, "exponentiation");
|
||||
return js_bigint(vm.heap(), Crypto::NumberTheory::Power(lhs_numeric.as_bigint().big_integer(), rhs_numeric.as_bigint().big_integer()));
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::BigIntBadOperatorOtherType, "exponentiation");
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -692,44 +693,46 @@ Value in(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
interpreter.vm().throw_exception<TypeError>(interpreter.global_object(), ErrorType::InOperatorWithObject);
|
||||
return {};
|
||||
}
|
||||
auto lhs_string = lhs.to_string(interpreter);
|
||||
auto lhs_string = lhs.to_string(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
return Value(rhs.as_object().has_property(lhs_string));
|
||||
}
|
||||
|
||||
Value instance_of(Interpreter& interpreter, Value lhs, Value rhs)
|
||||
Value instance_of(GlobalObject& global_object, Value lhs, Value rhs)
|
||||
{
|
||||
auto& vm = global_object.vm();
|
||||
if (!rhs.is_object()) {
|
||||
interpreter.vm().throw_exception<TypeError>(interpreter.global_object(), ErrorType::NotAnObject, rhs.to_string_without_side_effects().characters());
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObject, rhs.to_string_without_side_effects().characters());
|
||||
return {};
|
||||
}
|
||||
auto has_instance_method = rhs.as_object().get(interpreter.vm().well_known_symbol_has_instance());
|
||||
auto has_instance_method = rhs.as_object().get(vm.well_known_symbol_has_instance());
|
||||
if (!has_instance_method.is_empty()) {
|
||||
if (!has_instance_method.is_function()) {
|
||||
interpreter.vm().throw_exception<TypeError>(interpreter.global_object(), ErrorType::NotAFunction, has_instance_method.to_string_without_side_effects().characters());
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotAFunction, has_instance_method.to_string_without_side_effects().characters());
|
||||
return {};
|
||||
}
|
||||
|
||||
return Value(interpreter.call(has_instance_method.as_function(), rhs, lhs).to_boolean());
|
||||
return Value(vm.call(has_instance_method.as_function(), rhs, lhs).to_boolean());
|
||||
}
|
||||
|
||||
if (!rhs.is_function()) {
|
||||
interpreter.vm().throw_exception<TypeError>(interpreter.global_object(), ErrorType::NotAFunction, rhs.to_string_without_side_effects().characters());
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotAFunction, rhs.to_string_without_side_effects().characters());
|
||||
return {};
|
||||
}
|
||||
return ordinary_has_instance(interpreter, lhs, rhs);
|
||||
return ordinary_has_instance(global_object, lhs, rhs);
|
||||
}
|
||||
|
||||
Value ordinary_has_instance(Interpreter& interpreter, Value lhs, Value rhs)
|
||||
Value ordinary_has_instance(GlobalObject& global_object, Value lhs, Value rhs)
|
||||
{
|
||||
auto& vm = global_object.vm();
|
||||
if (!rhs.is_function())
|
||||
return Value(false);
|
||||
auto& rhs_function = rhs.as_function();
|
||||
|
||||
if (rhs_function.is_bound_function()) {
|
||||
auto& bound_target = static_cast<BoundFunction&>(rhs_function);
|
||||
return instance_of(interpreter, lhs, Value(&bound_target.target_function()));
|
||||
return instance_of(global_object, lhs, Value(&bound_target.target_function()));
|
||||
}
|
||||
|
||||
if (!lhs.is_object())
|
||||
|
@ -737,20 +740,20 @@ Value ordinary_has_instance(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
|
||||
Object* lhs_object = &lhs.as_object();
|
||||
auto rhs_prototype = rhs_function.get("prototype");
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
if (!rhs_prototype.is_object()) {
|
||||
interpreter.vm().throw_exception<TypeError>(interpreter.global_object(), ErrorType::InstanceOfOperatorBadPrototype, rhs_prototype.to_string_without_side_effects().characters());
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::InstanceOfOperatorBadPrototype, rhs_prototype.to_string_without_side_effects().characters());
|
||||
return {};
|
||||
}
|
||||
while (true) {
|
||||
lhs_object = lhs_object->prototype();
|
||||
if (interpreter.exception())
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (!lhs_object)
|
||||
return Value(false);
|
||||
if (same_value(interpreter, rhs_prototype, lhs_object))
|
||||
if (same_value(rhs_prototype, lhs_object))
|
||||
return Value(true);
|
||||
}
|
||||
}
|
||||
|
@ -760,7 +763,7 @@ const LogStream& operator<<(const LogStream& stream, const Value& value)
|
|||
return stream << (value.is_empty() ? "<empty>" : value.to_string_without_side_effects());
|
||||
}
|
||||
|
||||
bool same_value(Interpreter& interpreter, Value lhs, Value rhs)
|
||||
bool same_value(Value lhs, Value rhs)
|
||||
{
|
||||
if (lhs.type() != rhs.type())
|
||||
return false;
|
||||
|
@ -783,10 +786,10 @@ bool same_value(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
return lhs_big_integer == rhs_big_integer;
|
||||
}
|
||||
|
||||
return same_value_non_numeric(interpreter, lhs, rhs);
|
||||
return same_value_non_numeric(lhs, rhs);
|
||||
}
|
||||
|
||||
bool same_value_zero(Interpreter& interpreter, Value lhs, Value rhs)
|
||||
bool same_value_zero(Value lhs, Value rhs)
|
||||
{
|
||||
if (lhs.type() != rhs.type())
|
||||
return false;
|
||||
|
@ -800,10 +803,10 @@ bool same_value_zero(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
if (lhs.is_bigint())
|
||||
return lhs.as_bigint().big_integer() == rhs.as_bigint().big_integer();
|
||||
|
||||
return same_value_non_numeric(interpreter, lhs, rhs);
|
||||
return same_value_non_numeric(lhs, rhs);
|
||||
}
|
||||
|
||||
bool same_value_non_numeric(Interpreter&, Value lhs, Value rhs)
|
||||
bool same_value_non_numeric(Value lhs, Value rhs)
|
||||
{
|
||||
ASSERT(!lhs.is_number() && !lhs.is_bigint());
|
||||
ASSERT(lhs.type() == rhs.type());
|
||||
|
@ -825,7 +828,7 @@ bool same_value_non_numeric(Interpreter&, Value lhs, Value rhs)
|
|||
}
|
||||
}
|
||||
|
||||
bool strict_eq(Interpreter& interpreter, Value lhs, Value rhs)
|
||||
bool strict_eq(Value lhs, Value rhs)
|
||||
{
|
||||
if (lhs.type() != rhs.type())
|
||||
return false;
|
||||
|
@ -841,22 +844,22 @@ bool strict_eq(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
if (lhs.is_bigint())
|
||||
return lhs.as_bigint().big_integer() == rhs.as_bigint().big_integer();
|
||||
|
||||
return same_value_non_numeric(interpreter, lhs, rhs);
|
||||
return same_value_non_numeric(lhs, rhs);
|
||||
}
|
||||
|
||||
bool abstract_eq(Interpreter& interpreter, Value lhs, Value rhs)
|
||||
{
|
||||
if (lhs.type() == rhs.type())
|
||||
return strict_eq(interpreter, lhs, rhs);
|
||||
return strict_eq(lhs, rhs);
|
||||
|
||||
if ((lhs.is_undefined() || lhs.is_null()) && (rhs.is_undefined() || rhs.is_null()))
|
||||
return true;
|
||||
|
||||
if (lhs.is_number() && rhs.is_string())
|
||||
return abstract_eq(interpreter, lhs, rhs.to_number(interpreter));
|
||||
return abstract_eq(interpreter, lhs, rhs.to_number(interpreter.global_object()));
|
||||
|
||||
if (lhs.is_string() && rhs.is_number())
|
||||
return abstract_eq(interpreter, lhs.to_number(interpreter), rhs);
|
||||
return abstract_eq(interpreter, lhs.to_number(interpreter.global_object()), rhs);
|
||||
|
||||
if (lhs.is_bigint() && rhs.is_string()) {
|
||||
auto& rhs_string = rhs.as_string().string();
|
||||
|
@ -869,10 +872,10 @@ bool abstract_eq(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
return abstract_eq(interpreter, rhs, lhs);
|
||||
|
||||
if (lhs.is_boolean())
|
||||
return abstract_eq(interpreter, lhs.to_number(interpreter), rhs);
|
||||
return abstract_eq(interpreter, lhs.to_number(interpreter.global_object()), rhs);
|
||||
|
||||
if (rhs.is_boolean())
|
||||
return abstract_eq(interpreter, lhs, rhs.to_number(interpreter));
|
||||
return abstract_eq(interpreter, lhs, rhs.to_number(interpreter.global_object()));
|
||||
|
||||
if ((lhs.is_string() || lhs.is_number() || lhs.is_bigint() || lhs.is_symbol()) && rhs.is_object())
|
||||
return abstract_eq(interpreter, lhs, rhs.to_primitive());
|
||||
|
@ -960,10 +963,10 @@ TriState abstract_relation(Interpreter& interpreter, bool left_first, Value lhs,
|
|||
return TriState::False;
|
||||
}
|
||||
|
||||
auto x_numeric = x_primitive.to_numeric(interpreter);
|
||||
auto x_numeric = x_primitive.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
auto y_numeric = y_primitive.to_numeric(interpreter);
|
||||
auto y_numeric = y_primitive.to_numeric(interpreter.global_object());
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
|
||||
|
@ -1014,7 +1017,7 @@ size_t length_of_array_like(Interpreter& interpreter, Value value)
|
|||
auto result = value.as_object().get("length");
|
||||
if (interpreter.exception())
|
||||
return 0;
|
||||
return result.to_size_t(interpreter);
|
||||
return result.to_size_t(interpreter.global_object());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -240,16 +240,16 @@ public:
|
|||
i32 as_i32() const;
|
||||
size_t as_size_t() const;
|
||||
|
||||
String to_string(Interpreter&) const;
|
||||
PrimitiveString* to_primitive_string(Interpreter&);
|
||||
String to_string(GlobalObject&) const;
|
||||
PrimitiveString* to_primitive_string(GlobalObject&);
|
||||
Value to_primitive(PreferredType preferred_type = PreferredType::Default) const;
|
||||
Object* to_object(Interpreter&, GlobalObject&) const;
|
||||
Value to_numeric(Interpreter&) const;
|
||||
Value to_number(Interpreter&) const;
|
||||
Object* to_object(GlobalObject&) const;
|
||||
Value to_numeric(GlobalObject&) const;
|
||||
Value to_number(GlobalObject&) const;
|
||||
BigInt* to_bigint(GlobalObject&) const;
|
||||
double to_double(Interpreter&) const;
|
||||
i32 to_i32(Interpreter&) const;
|
||||
size_t to_size_t(Interpreter&) const;
|
||||
double to_double(GlobalObject&) const;
|
||||
i32 to_i32(GlobalObject&) const;
|
||||
size_t to_size_t(GlobalObject&) const;
|
||||
bool to_boolean() const;
|
||||
|
||||
String to_string_without_side_effects() const;
|
||||
|
@ -320,16 +320,16 @@ Value sub(Interpreter&, Value lhs, Value rhs);
|
|||
Value mul(Interpreter&, Value lhs, Value rhs);
|
||||
Value div(Interpreter&, Value lhs, Value rhs);
|
||||
Value mod(Interpreter&, Value lhs, Value rhs);
|
||||
Value exp(Interpreter&, Value lhs, Value rhs);
|
||||
Value exp(GlobalObject&, Value lhs, Value rhs);
|
||||
Value in(Interpreter&, Value lhs, Value rhs);
|
||||
Value instance_of(Interpreter&, Value lhs, Value rhs);
|
||||
Value ordinary_has_instance(Interpreter& interpreter, Value lhs, Value rhs);
|
||||
Value instance_of(GlobalObject&, Value lhs, Value rhs);
|
||||
Value ordinary_has_instance(GlobalObject&, Value lhs, Value rhs);
|
||||
|
||||
bool abstract_eq(Interpreter&, Value lhs, Value rhs);
|
||||
bool strict_eq(Interpreter&, Value lhs, Value rhs);
|
||||
bool same_value(Interpreter&, Value lhs, Value rhs);
|
||||
bool same_value_zero(Interpreter&, Value lhs, Value rhs);
|
||||
bool same_value_non_numeric(Interpreter&, Value lhs, Value rhs);
|
||||
bool strict_eq(Value lhs, Value rhs);
|
||||
bool same_value(Value lhs, Value rhs);
|
||||
bool same_value_zero(Value lhs, Value rhs);
|
||||
bool same_value_non_numeric(Value lhs, Value rhs);
|
||||
TriState abstract_relation(Interpreter&, bool left_first, Value lhs, Value rhs);
|
||||
size_t length_of_array_like(Interpreter&, Value);
|
||||
|
||||
|
|
|
@ -62,14 +62,14 @@ LocationObject::~LocationObject()
|
|||
JS_DEFINE_NATIVE_GETTER(LocationObject::href_getter)
|
||||
{
|
||||
auto& window = static_cast<WindowObject&>(global_object);
|
||||
return JS::js_string(interpreter, window.impl().document().url().to_string());
|
||||
return JS::js_string(vm, window.impl().document().url().to_string());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_SETTER(LocationObject::href_setter)
|
||||
{
|
||||
auto& window = static_cast<WindowObject&>(global_object);
|
||||
auto new_href = value.to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto new_href = value.to_string(global_object);
|
||||
if (vm.exception())
|
||||
return;
|
||||
window.impl().did_set_location_href({}, new_href);
|
||||
}
|
||||
|
@ -77,13 +77,13 @@ JS_DEFINE_NATIVE_SETTER(LocationObject::href_setter)
|
|||
JS_DEFINE_NATIVE_GETTER(LocationObject::pathname_getter)
|
||||
{
|
||||
auto& window = static_cast<WindowObject&>(global_object);
|
||||
return JS::js_string(interpreter, window.impl().document().url().path());
|
||||
return JS::js_string(vm, window.impl().document().url().path());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_GETTER(LocationObject::hostname_getter)
|
||||
{
|
||||
auto& window = static_cast<WindowObject&>(global_object);
|
||||
return JS::js_string(interpreter, window.impl().document().url().host());
|
||||
return JS::js_string(vm, window.impl().document().url().host());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_GETTER(LocationObject::host_getter)
|
||||
|
@ -94,7 +94,7 @@ JS_DEFINE_NATIVE_GETTER(LocationObject::host_getter)
|
|||
builder.append(url.host());
|
||||
builder.append(':');
|
||||
builder.appendf("%u", url.port());
|
||||
return JS::js_string(interpreter, builder.to_string());
|
||||
return JS::js_string(vm, builder.to_string());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_GETTER(LocationObject::hash_getter)
|
||||
|
@ -102,11 +102,11 @@ JS_DEFINE_NATIVE_GETTER(LocationObject::hash_getter)
|
|||
auto& window = static_cast<WindowObject&>(global_object);
|
||||
auto fragment = window.impl().document().url().fragment();
|
||||
if (!fragment.length())
|
||||
return JS::js_string(interpreter, "");
|
||||
return JS::js_string(vm, "");
|
||||
StringBuilder builder;
|
||||
builder.append('#');
|
||||
builder.append(fragment);
|
||||
return JS::js_string(interpreter, builder.to_string());
|
||||
return JS::js_string(vm, builder.to_string());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_GETTER(LocationObject::search_getter)
|
||||
|
@ -114,11 +114,11 @@ JS_DEFINE_NATIVE_GETTER(LocationObject::search_getter)
|
|||
auto& window = static_cast<WindowObject&>(global_object);
|
||||
auto query = window.impl().document().url().query();
|
||||
if (!query.length())
|
||||
return JS::js_string(interpreter, "");
|
||||
return JS::js_string(vm, "");
|
||||
StringBuilder builder;
|
||||
builder.append('?');
|
||||
builder.append(query);
|
||||
return JS::js_string(interpreter, builder.to_string());
|
||||
return JS::js_string(vm, builder.to_string());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_GETTER(LocationObject::protocol_getter)
|
||||
|
@ -127,7 +127,7 @@ JS_DEFINE_NATIVE_GETTER(LocationObject::protocol_getter)
|
|||
StringBuilder builder;
|
||||
builder.append(window.impl().document().url().protocol());
|
||||
builder.append(':');
|
||||
return JS::js_string(interpreter, builder.to_string());
|
||||
return JS::js_string(vm, builder.to_string());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(LocationObject::reload)
|
||||
|
|
|
@ -62,7 +62,7 @@ NavigatorObject::~NavigatorObject()
|
|||
|
||||
JS_DEFINE_NATIVE_GETTER(NavigatorObject::user_agent_getter)
|
||||
{
|
||||
return JS::js_string(interpreter, ResourceLoader::the().user_agent());
|
||||
return JS::js_string(vm, ResourceLoader::the().user_agent());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -99,15 +99,15 @@ Origin WindowObject::origin() const
|
|||
return impl().document().origin();
|
||||
}
|
||||
|
||||
static DOM::Window* impl_from(JS::Interpreter& interpreter, JS::GlobalObject& global_object)
|
||||
static DOM::Window* impl_from(JS::VM& vm, JS::GlobalObject& global_object)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object) {
|
||||
ASSERT_NOT_REACHED();
|
||||
return nullptr;
|
||||
}
|
||||
if (StringView("WindowObject") != this_object->class_name()) {
|
||||
interpreter.vm().throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, "WindowObject");
|
||||
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, "WindowObject");
|
||||
return nullptr;
|
||||
}
|
||||
return &static_cast<WindowObject*>(this_object)->impl();
|
||||
|
@ -115,13 +115,13 @@ static DOM::Window* impl_from(JS::Interpreter& interpreter, JS::GlobalObject& gl
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(WindowObject::alert)
|
||||
{
|
||||
auto* impl = impl_from(interpreter, global_object);
|
||||
auto* impl = impl_from(vm, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
String message = "";
|
||||
if (interpreter.argument_count()) {
|
||||
message = interpreter.argument(0).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (vm.argument_count()) {
|
||||
message = vm.argument(0).to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
impl->alert(message);
|
||||
|
@ -130,13 +130,13 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::alert)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(WindowObject::confirm)
|
||||
{
|
||||
auto* impl = impl_from(interpreter, global_object);
|
||||
auto* impl = impl_from(vm, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
String message = "";
|
||||
if (interpreter.argument_count()) {
|
||||
message = interpreter.argument(0).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (vm.argument_count()) {
|
||||
message = vm.argument(0).to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
return JS::Value(impl->confirm(message));
|
||||
|
@ -144,24 +144,24 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::confirm)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(WindowObject::set_interval)
|
||||
{
|
||||
auto* impl = impl_from(interpreter, global_object);
|
||||
auto* impl = impl_from(vm, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.vm().throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountAtLeastOne, "setInterval");
|
||||
if (!vm.argument_count()) {
|
||||
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountAtLeastOne, "setInterval");
|
||||
return {};
|
||||
}
|
||||
auto* callback_object = interpreter.argument(0).to_object(interpreter, global_object);
|
||||
auto* callback_object = vm.argument(0).to_object(global_object);
|
||||
if (!callback_object)
|
||||
return {};
|
||||
if (!callback_object->is_function()) {
|
||||
interpreter.vm().throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAFunctionNoParam);
|
||||
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAFunctionNoParam);
|
||||
return {};
|
||||
}
|
||||
i32 interval = 0;
|
||||
if (interpreter.argument_count() >= 2) {
|
||||
interval = interpreter.argument(1).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (vm.argument_count() >= 2) {
|
||||
interval = vm.argument(1).to_i32(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (interval < 0)
|
||||
interval = 0;
|
||||
|
@ -173,24 +173,24 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::set_interval)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(WindowObject::set_timeout)
|
||||
{
|
||||
auto* impl = impl_from(interpreter, global_object);
|
||||
auto* impl = impl_from(vm, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.vm().throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountAtLeastOne, "setTimeout");
|
||||
if (!vm.argument_count()) {
|
||||
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountAtLeastOne, "setTimeout");
|
||||
return {};
|
||||
}
|
||||
auto* callback_object = interpreter.argument(0).to_object(interpreter, global_object);
|
||||
auto* callback_object = vm.argument(0).to_object(global_object);
|
||||
if (!callback_object)
|
||||
return {};
|
||||
if (!callback_object->is_function()) {
|
||||
interpreter.vm().throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAFunctionNoParam);
|
||||
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAFunctionNoParam);
|
||||
return {};
|
||||
}
|
||||
i32 interval = 0;
|
||||
if (interpreter.argument_count() >= 2) {
|
||||
interval = interpreter.argument(1).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
if (vm.argument_count() >= 2) {
|
||||
interval = vm.argument(1).to_i32(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (interval < 0)
|
||||
interval = 0;
|
||||
|
@ -202,15 +202,15 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::set_timeout)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(WindowObject::clear_timeout)
|
||||
{
|
||||
auto* impl = impl_from(interpreter, global_object);
|
||||
auto* impl = impl_from(vm, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.vm().throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountAtLeastOne, "clearTimeout");
|
||||
if (!vm.argument_count()) {
|
||||
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountAtLeastOne, "clearTimeout");
|
||||
return {};
|
||||
}
|
||||
i32 timer_id = interpreter.argument(0).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
i32 timer_id = vm.argument(0).to_i32(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
impl->clear_timeout(timer_id);
|
||||
return JS::js_undefined();
|
||||
|
@ -218,15 +218,15 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::clear_timeout)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(WindowObject::clear_interval)
|
||||
{
|
||||
auto* impl = impl_from(interpreter, global_object);
|
||||
auto* impl = impl_from(vm, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.vm().throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountAtLeastOne, "clearInterval");
|
||||
if (!vm.argument_count()) {
|
||||
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountAtLeastOne, "clearInterval");
|
||||
return {};
|
||||
}
|
||||
i32 timer_id = interpreter.argument(0).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
i32 timer_id = vm.argument(0).to_i32(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
impl->clear_timeout(timer_id);
|
||||
return JS::js_undefined();
|
||||
|
@ -234,18 +234,18 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::clear_interval)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(WindowObject::request_animation_frame)
|
||||
{
|
||||
auto* impl = impl_from(interpreter, global_object);
|
||||
auto* impl = impl_from(vm, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.vm().throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountOne, "requestAnimationFrame");
|
||||
if (!vm.argument_count()) {
|
||||
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountOne, "requestAnimationFrame");
|
||||
return {};
|
||||
}
|
||||
auto* callback_object = interpreter.argument(0).to_object(interpreter, global_object);
|
||||
auto* callback_object = vm.argument(0).to_object(global_object);
|
||||
if (!callback_object)
|
||||
return {};
|
||||
if (!callback_object->is_function()) {
|
||||
interpreter.vm().throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAFunctionNoParam);
|
||||
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAFunctionNoParam);
|
||||
return {};
|
||||
}
|
||||
return JS::Value(impl->request_animation_frame(*static_cast<JS::Function*>(callback_object)));
|
||||
|
@ -253,15 +253,15 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::request_animation_frame)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(WindowObject::cancel_animation_frame)
|
||||
{
|
||||
auto* impl = impl_from(interpreter, global_object);
|
||||
auto* impl = impl_from(vm, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.vm().throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountOne, "cancelAnimationFrame");
|
||||
if (!vm.argument_count()) {
|
||||
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountOne, "cancelAnimationFrame");
|
||||
return {};
|
||||
}
|
||||
auto id = interpreter.argument(0).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto id = vm.argument(0).to_i32(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
impl->cancel_animation_frame(id);
|
||||
return JS::js_undefined();
|
||||
|
@ -269,52 +269,52 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::cancel_animation_frame)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(WindowObject::atob)
|
||||
{
|
||||
auto* impl = impl_from(interpreter, global_object);
|
||||
auto* impl = impl_from(vm, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.vm().throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountOne, "atob");
|
||||
if (!vm.argument_count()) {
|
||||
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountOne, "atob");
|
||||
return {};
|
||||
}
|
||||
auto string = interpreter.argument(0).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto string = vm.argument(0).to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto decoded = decode_base64(StringView(string));
|
||||
|
||||
// decode_base64() returns a byte string. LibJS uses UTF-8 for strings. Use Latin1Decoder to convert bytes 128-255 to UTF-8.
|
||||
return JS::js_string(interpreter, TextCodec::decoder_for("iso-8859-1")->to_utf8(decoded));
|
||||
return JS::js_string(vm, TextCodec::decoder_for("iso-8859-1")->to_utf8(decoded));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(WindowObject::btoa)
|
||||
{
|
||||
auto* impl = impl_from(interpreter, global_object);
|
||||
auto* impl = impl_from(vm, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.vm().throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountOne, "btoa");
|
||||
if (!vm.argument_count()) {
|
||||
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountOne, "btoa");
|
||||
return {};
|
||||
}
|
||||
auto string = interpreter.argument(0).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto string = vm.argument(0).to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
Vector<u8> byte_string;
|
||||
byte_string.ensure_capacity(string.length());
|
||||
for (u32 code_point : Utf8View(string)) {
|
||||
if (code_point > 0xff) {
|
||||
interpreter.vm().throw_exception<JS::InvalidCharacterError>(global_object, JS::ErrorType::NotAByteString, "btoa");
|
||||
vm.throw_exception<JS::InvalidCharacterError>(global_object, JS::ErrorType::NotAByteString, "btoa");
|
||||
return {};
|
||||
}
|
||||
byte_string.append(code_point);
|
||||
}
|
||||
|
||||
auto encoded = encode_base64(byte_string.span());
|
||||
return JS::js_string(interpreter, move(encoded));
|
||||
return JS::js_string(vm, move(encoded));
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_GETTER(WindowObject::document_getter)
|
||||
{
|
||||
auto* impl = impl_from(interpreter, global_object);
|
||||
auto* impl = impl_from(vm, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
return wrap(global_object, impl->document());
|
||||
|
|
|
@ -58,13 +58,13 @@ XMLHttpRequestPrototype::~XMLHttpRequestPrototype()
|
|||
{
|
||||
}
|
||||
|
||||
static XMLHttpRequest* impl_from(JS::Interpreter& interpreter, JS::GlobalObject& global_object)
|
||||
static XMLHttpRequest* impl_from(JS::VM& vm, JS::GlobalObject& global_object)
|
||||
{
|
||||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return nullptr;
|
||||
if (StringView("XMLHttpRequestWrapper") != this_object->class_name()) {
|
||||
interpreter.vm().throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, "XMLHttpRequest");
|
||||
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, "XMLHttpRequest");
|
||||
return nullptr;
|
||||
}
|
||||
return &static_cast<XMLHttpRequestWrapper*>(this_object)->impl();
|
||||
|
@ -72,14 +72,14 @@ static XMLHttpRequest* impl_from(JS::Interpreter& interpreter, JS::GlobalObject&
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(XMLHttpRequestPrototype::open)
|
||||
{
|
||||
auto* impl = impl_from(interpreter, global_object);
|
||||
auto* impl = impl_from(vm, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
auto arg0 = interpreter.argument(0).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto arg0 = vm.argument(0).to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto arg1 = interpreter.argument(1).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto arg1 = vm.argument(1).to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
impl->open(arg0, arg1);
|
||||
return JS::js_undefined();
|
||||
|
@ -87,7 +87,7 @@ JS_DEFINE_NATIVE_FUNCTION(XMLHttpRequestPrototype::open)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(XMLHttpRequestPrototype::send)
|
||||
{
|
||||
auto* impl = impl_from(interpreter, global_object);
|
||||
auto* impl = impl_from(vm, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
impl->send();
|
||||
|
@ -96,7 +96,7 @@ JS_DEFINE_NATIVE_FUNCTION(XMLHttpRequestPrototype::send)
|
|||
|
||||
JS_DEFINE_NATIVE_GETTER(XMLHttpRequestPrototype::ready_state_getter)
|
||||
{
|
||||
auto* impl = impl_from(interpreter, global_object);
|
||||
auto* impl = impl_from(vm, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
return JS::Value((i32)impl->ready_state());
|
||||
|
@ -104,10 +104,10 @@ JS_DEFINE_NATIVE_GETTER(XMLHttpRequestPrototype::ready_state_getter)
|
|||
|
||||
JS_DEFINE_NATIVE_GETTER(XMLHttpRequestPrototype::response_text_getter)
|
||||
{
|
||||
auto* impl = impl_from(interpreter, global_object);
|
||||
auto* impl = impl_from(vm, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
return JS::js_string(interpreter, impl->response_text());
|
||||
return JS::js_string(vm, impl->response_text());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -500,13 +500,13 @@ void generate_implementation(const IDL::Interface& interface)
|
|||
|
||||
// Implementation: impl_from()
|
||||
if (!interface.attributes.is_empty() || !interface.functions.is_empty()) {
|
||||
out() << "static " << interface.fully_qualified_name << "* impl_from(JS::Interpreter& interpreter, JS::GlobalObject& global_object)";
|
||||
out() << "static " << interface.fully_qualified_name << "* impl_from(JS::VM& vm, JS::GlobalObject& global_object)";
|
||||
out() << "{";
|
||||
out() << " auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);";
|
||||
out() << " auto* this_object = vm.this_value(global_object).to_object(global_object);";
|
||||
out() << " if (!this_object)";
|
||||
out() << " return {};";
|
||||
out() << " if (!this_object->inherits(\"" << wrapper_class << "\")) {";
|
||||
out() << " interpreter.vm().throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, \"" << interface.fully_qualified_name << "\");";
|
||||
out() << " vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, \"" << interface.fully_qualified_name << "\");";
|
||||
out() << " return nullptr;";
|
||||
out() << " }";
|
||||
out() << " return &static_cast<" << wrapper_class << "*>(this_object)->impl();";
|
||||
|
@ -521,27 +521,27 @@ void generate_implementation(const IDL::Interface& interface)
|
|||
out() << " return {};";
|
||||
};
|
||||
if (parameter.type.name == "DOMString") {
|
||||
out() << " auto " << cpp_name << " = " << js_name << js_suffix << ".to_string(interpreter);";
|
||||
out() << " if (interpreter.exception())";
|
||||
out() << " auto " << cpp_name << " = " << js_name << js_suffix << ".to_string(global_object);";
|
||||
out() << " if (vm.exception())";
|
||||
generate_return();
|
||||
} else if (parameter.type.name == "EventListener") {
|
||||
out() << " if (!" << js_name << js_suffix << ".is_function()) {";
|
||||
out() << " interpreter.vm().throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, \"Function\");";
|
||||
out() << " vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, \"Function\");";
|
||||
generate_return();
|
||||
out() << " }";
|
||||
out() << " auto " << cpp_name << " = adopt(*new EventListener(JS::make_handle(&" << js_name << js_suffix << ".as_function())));";
|
||||
} else if (is_wrappable_type(parameter.type)) {
|
||||
out() << " auto " << cpp_name << "_object = " << js_name << js_suffix << ".to_object(interpreter, global_object);";
|
||||
out() << " if (interpreter.exception())";
|
||||
out() << " auto " << cpp_name << "_object = " << js_name << js_suffix << ".to_object(global_object);";
|
||||
out() << " if (vm.exception())";
|
||||
generate_return();
|
||||
out() << " if (!" << cpp_name << "_object->inherits(\"" << parameter.type.name << "Wrapper\")) {";
|
||||
out() << " interpreter.vm().throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, \"" << parameter.type.name << "\");";
|
||||
out() << " vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, \"" << parameter.type.name << "\");";
|
||||
generate_return();
|
||||
out() << " }";
|
||||
out() << " auto& " << cpp_name << " = static_cast<" << parameter.type.name << "Wrapper*>(" << cpp_name << "_object)->impl();";
|
||||
} else if (parameter.type.name == "double") {
|
||||
out() << " auto " << cpp_name << " = " << js_name << js_suffix << ".to_double(interpreter);";
|
||||
out() << " if (interpreter.exception())";
|
||||
out() << " auto " << cpp_name << " = " << js_name << js_suffix << ".to_double(global_object);";
|
||||
out() << " if (vm.exception())";
|
||||
generate_return();
|
||||
} else if (parameter.type.name == "boolean") {
|
||||
out() << " auto " << cpp_name << " = " << js_name << js_suffix << ".to_boolean();";
|
||||
|
@ -556,7 +556,7 @@ void generate_implementation(const IDL::Interface& interface)
|
|||
size_t argument_index = 0;
|
||||
for (auto& parameter : parameters) {
|
||||
parameter_names.append(snake_name(parameter.name));
|
||||
out() << " auto arg" << argument_index << " = interpreter.argument(" << argument_index << ");";
|
||||
out() << " auto arg" << argument_index << " = vm.argument(" << argument_index << ");";
|
||||
generate_to_cpp(parameter, "arg", argument_index, snake_name(parameter.name), return_void);
|
||||
++argument_index;
|
||||
}
|
||||
|
@ -580,7 +580,7 @@ void generate_implementation(const IDL::Interface& interface)
|
|||
}
|
||||
|
||||
if (return_type.name == "DOMString") {
|
||||
out() << " return JS::js_string(interpreter, retval);";
|
||||
out() << " return JS::js_string(vm, retval);";
|
||||
} else if (return_type.name == "ArrayFromVector") {
|
||||
// FIXME: Remove this fake type hack once it's no longer needed.
|
||||
// Basically once we have NodeList we can throw this out.
|
||||
|
@ -604,7 +604,7 @@ void generate_implementation(const IDL::Interface& interface)
|
|||
for (auto& attribute : interface.attributes) {
|
||||
out() << "JS_DEFINE_NATIVE_GETTER(" << wrapper_class << "::" << attribute.getter_callback_name << ")";
|
||||
out() << "{";
|
||||
out() << " auto* impl = impl_from(interpreter, global_object);";
|
||||
out() << " auto* impl = impl_from(vm, global_object);";
|
||||
out() << " if (!impl)";
|
||||
out() << " return {};";
|
||||
|
||||
|
@ -629,7 +629,7 @@ void generate_implementation(const IDL::Interface& interface)
|
|||
if (!attribute.readonly) {
|
||||
out() << "JS_DEFINE_NATIVE_SETTER(" << wrapper_class << "::" << attribute.setter_callback_name << ")";
|
||||
out() << "{";
|
||||
out() << " auto* impl = impl_from(interpreter, global_object);";
|
||||
out() << " auto* impl = impl_from(vm, global_object);";
|
||||
out() << " if (!impl)";
|
||||
out() << " return;";
|
||||
|
||||
|
@ -652,15 +652,15 @@ void generate_implementation(const IDL::Interface& interface)
|
|||
for (auto& function : interface.functions) {
|
||||
out() << "JS_DEFINE_NATIVE_FUNCTION(" << wrapper_class << "::" << snake_name(function.name) << ")";
|
||||
out() << "{";
|
||||
out() << " auto* impl = impl_from(interpreter, global_object);";
|
||||
out() << " auto* impl = impl_from(vm, global_object);";
|
||||
out() << " if (!impl)";
|
||||
out() << " return {};";
|
||||
if (function.length() > 0) {
|
||||
out() << " if (interpreter.argument_count() < " << function.length() << ") {";
|
||||
out() << " if (vm.argument_count() < " << function.length() << ") {";
|
||||
if (function.length() == 1)
|
||||
out() << " interpreter.vm().throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountOne, \"" << function.name << "\");";
|
||||
out() << " vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountOne, \"" << function.name << "\");";
|
||||
else
|
||||
out() << " interpreter.vm().throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountMany, \"" << function.name << "\", \"" << function.length() << "\");";
|
||||
out() << " vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountMany, \"" << function.name << "\", \"" << function.length() << "\");";
|
||||
out() << " return {};";
|
||||
out() << " }";
|
||||
}
|
||||
|
|
|
@ -390,9 +390,9 @@ ReplObject::~ReplObject()
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ReplObject::save_to_file)
|
||||
{
|
||||
if (!interpreter.argument_count())
|
||||
if (!vm.argument_count())
|
||||
return JS::Value(false);
|
||||
String save_path = interpreter.argument(0).to_string_without_side_effects();
|
||||
String save_path = vm.argument(0).to_string_without_side_effects();
|
||||
StringView path = StringView(save_path.characters());
|
||||
if (write_to_file(path)) {
|
||||
return JS::Value(true);
|
||||
|
@ -402,9 +402,9 @@ JS_DEFINE_NATIVE_FUNCTION(ReplObject::save_to_file)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ReplObject::exit_interpreter)
|
||||
{
|
||||
if (!interpreter.argument_count())
|
||||
if (!vm.argument_count())
|
||||
exit(0);
|
||||
auto exit_code = interpreter.argument(0).to_number(interpreter);
|
||||
auto exit_code = vm.argument(0).to_number(global_object);
|
||||
if (::vm->exception())
|
||||
return {};
|
||||
exit(exit_code.as_double());
|
||||
|
@ -422,10 +422,10 @@ JS_DEFINE_NATIVE_FUNCTION(ReplObject::repl_help)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ReplObject::load_file)
|
||||
{
|
||||
if (!interpreter.argument_count())
|
||||
if (!vm.argument_count())
|
||||
return JS::Value(false);
|
||||
|
||||
for (auto& file : interpreter.call_frame().arguments) {
|
||||
for (auto& file : vm.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)) {
|
||||
|
@ -439,7 +439,7 @@ JS_DEFINE_NATIVE_FUNCTION(ReplObject::load_file)
|
|||
} else {
|
||||
source = file_contents;
|
||||
}
|
||||
parse_and_run(interpreter, source);
|
||||
parse_and_run(vm.interpreter(), source);
|
||||
}
|
||||
return JS::Value(true);
|
||||
}
|
||||
|
@ -822,7 +822,7 @@ int main(int argc, char** argv)
|
|||
if (!variable.is_object())
|
||||
break;
|
||||
|
||||
const auto* object = variable.to_object(*interpreter, interpreter->global_object());
|
||||
const auto* object = variable.to_object(interpreter->global_object());
|
||||
const auto& shape = object->shape();
|
||||
list_all_properties(shape, property_name);
|
||||
if (results.size())
|
||||
|
|
|
@ -160,7 +160,7 @@ void TestRunnerGlobalObject::initialize()
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(TestRunnerGlobalObject::is_strict_mode)
|
||||
{
|
||||
return JS::Value(interpreter.in_strict_mode());
|
||||
return JS::Value(vm.interpreter().in_strict_mode());
|
||||
}
|
||||
|
||||
static void cleanup_and_exit()
|
||||
|
|
|
@ -125,8 +125,8 @@ TestRunnerObject::~TestRunnerObject()
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(TestRunnerObject::change_page)
|
||||
{
|
||||
auto url = interpreter.argument(0).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
auto url = vm.argument(0).to_string(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
if (g_on_page_change)
|
||||
|
|
Loading…
Reference in a new issue