mirror of
https://github.com/RGBCube/serenity
synced 2025-07-23 09:37:34 +00:00
LibJS: Add the DataView built-in object
This commit is contained in:
parent
5b2255291e
commit
e4d267d4fb
15 changed files with 351 additions and 0 deletions
|
@ -37,6 +37,9 @@ set(SOURCES
|
||||||
Runtime/BooleanPrototype.cpp
|
Runtime/BooleanPrototype.cpp
|
||||||
Runtime/BoundFunction.cpp
|
Runtime/BoundFunction.cpp
|
||||||
Runtime/ConsoleObject.cpp
|
Runtime/ConsoleObject.cpp
|
||||||
|
Runtime/DataView.cpp
|
||||||
|
Runtime/DataViewConstructor.cpp
|
||||||
|
Runtime/DataViewPrototype.cpp
|
||||||
Runtime/DateConstructor.cpp
|
Runtime/DateConstructor.cpp
|
||||||
Runtime/Date.cpp
|
Runtime/Date.cpp
|
||||||
Runtime/DatePrototype.cpp
|
Runtime/DatePrototype.cpp
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
__JS_ENUMERATE(ArrayBuffer, array_buffer, ArrayBufferPrototype, ArrayBufferConstructor, void) \
|
__JS_ENUMERATE(ArrayBuffer, array_buffer, ArrayBufferPrototype, ArrayBufferConstructor, void) \
|
||||||
__JS_ENUMERATE(BigIntObject, bigint, BigIntPrototype, BigIntConstructor, void) \
|
__JS_ENUMERATE(BigIntObject, bigint, BigIntPrototype, BigIntConstructor, void) \
|
||||||
__JS_ENUMERATE(BooleanObject, boolean, BooleanPrototype, BooleanConstructor, void) \
|
__JS_ENUMERATE(BooleanObject, boolean, BooleanPrototype, BooleanConstructor, void) \
|
||||||
|
__JS_ENUMERATE(DataView, data_view, DataViewPrototype, DataViewConstructor, void) \
|
||||||
__JS_ENUMERATE(Date, date, DatePrototype, DateConstructor, void) \
|
__JS_ENUMERATE(Date, date, DatePrototype, DateConstructor, void) \
|
||||||
__JS_ENUMERATE(Error, error, ErrorPrototype, ErrorConstructor, void) \
|
__JS_ENUMERATE(Error, error, ErrorPrototype, ErrorConstructor, void) \
|
||||||
__JS_ENUMERATE(Function, function, FunctionPrototype, FunctionConstructor, void) \
|
__JS_ENUMERATE(Function, function, FunctionPrototype, FunctionConstructor, void) \
|
||||||
|
|
34
Userland/Libraries/LibJS/Runtime/DataView.cpp
Normal file
34
Userland/Libraries/LibJS/Runtime/DataView.cpp
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LibJS/Runtime/DataView.h>
|
||||||
|
|
||||||
|
namespace JS {
|
||||||
|
|
||||||
|
DataView* DataView::create(GlobalObject& global_object, ArrayBuffer* viewed_buffer, size_t byte_length, size_t byte_offset)
|
||||||
|
{
|
||||||
|
return global_object.heap().allocate<DataView>(global_object, *global_object.data_view_prototype(), viewed_buffer, byte_length, byte_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
DataView::DataView(Object& prototype, ArrayBuffer* viewed_buffer, size_t byte_length, size_t byte_offset)
|
||||||
|
: Object(prototype)
|
||||||
|
, m_viewed_array_buffer(viewed_buffer)
|
||||||
|
, m_byte_length(byte_length)
|
||||||
|
, m_byte_offset(byte_offset)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DataView::~DataView()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataView::visit_edges(Visitor& visitor)
|
||||||
|
{
|
||||||
|
Object::visit_edges(visitor);
|
||||||
|
visitor.visit(m_viewed_array_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
36
Userland/Libraries/LibJS/Runtime/DataView.h
Normal file
36
Userland/Libraries/LibJS/Runtime/DataView.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibJS/Runtime/ArrayBuffer.h>
|
||||||
|
#include <LibJS/Runtime/GlobalObject.h>
|
||||||
|
#include <LibJS/Runtime/Object.h>
|
||||||
|
|
||||||
|
namespace JS {
|
||||||
|
|
||||||
|
class DataView : public Object {
|
||||||
|
JS_OBJECT(DataView, Object);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static DataView* create(GlobalObject&, ArrayBuffer*, size_t byte_length, size_t byte_offset);
|
||||||
|
|
||||||
|
explicit DataView(Object& prototype, ArrayBuffer*, size_t byte_length, size_t byte_offset);
|
||||||
|
virtual ~DataView() override;
|
||||||
|
|
||||||
|
ArrayBuffer* viewed_array_buffer() const { return m_viewed_array_buffer; }
|
||||||
|
size_t byte_length() const { return m_byte_length; }
|
||||||
|
size_t byte_offset() const { return m_byte_offset; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void visit_edges(Visitor& visitor) override;
|
||||||
|
|
||||||
|
ArrayBuffer* m_viewed_array_buffer { nullptr };
|
||||||
|
size_t m_byte_length { 0 };
|
||||||
|
size_t m_byte_offset { 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
90
Userland/Libraries/LibJS/Runtime/DataViewConstructor.cpp
Normal file
90
Userland/Libraries/LibJS/Runtime/DataViewConstructor.cpp
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LibJS/Runtime/DataView.h>
|
||||||
|
#include <LibJS/Runtime/DataViewConstructor.h>
|
||||||
|
#include <LibJS/Runtime/Error.h>
|
||||||
|
#include <LibJS/Runtime/GlobalObject.h>
|
||||||
|
|
||||||
|
namespace JS {
|
||||||
|
|
||||||
|
DataViewConstructor::DataViewConstructor(GlobalObject& global_object)
|
||||||
|
: NativeFunction(vm().names.DataView, *global_object.function_prototype())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataViewConstructor::initialize(GlobalObject& global_object)
|
||||||
|
{
|
||||||
|
auto& vm = this->vm();
|
||||||
|
NativeFunction::initialize(global_object);
|
||||||
|
|
||||||
|
// 25.3.3.1 DataView.prototype, https://tc39.es/ecma262/#sec-dataview.prototype
|
||||||
|
define_property(vm.names.prototype, global_object.data_view_prototype(), 0);
|
||||||
|
|
||||||
|
define_property(vm.names.length, Value(1), Attribute::Configurable);
|
||||||
|
}
|
||||||
|
|
||||||
|
DataViewConstructor::~DataViewConstructor()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// 25.3.2.1 DataView ( buffer [ , byteOffset [ , byteLength ] ] ), https://tc39.es/ecma262/#sec-dataview-buffer-byteoffset-bytelength
|
||||||
|
Value DataViewConstructor::call()
|
||||||
|
{
|
||||||
|
auto& vm = this->vm();
|
||||||
|
vm.throw_exception<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, vm.names.DataView);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 25.3.2.1 DataView ( buffer [ , byteOffset [ , byteLength ] ] ), https://tc39.es/ecma262/#sec-dataview-buffer-byteoffset-bytelength
|
||||||
|
Value DataViewConstructor::construct(Function&)
|
||||||
|
{
|
||||||
|
auto& vm = this->vm();
|
||||||
|
auto buffer = vm.argument(0);
|
||||||
|
if (!buffer.is_object() || !is<ArrayBuffer>(buffer.as_object())) {
|
||||||
|
vm.throw_exception<TypeError>(global_object(), ErrorType::IsNotAn, buffer.to_string_without_side_effects(), vm.names.ArrayBuffer);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
auto& array_buffer = static_cast<ArrayBuffer&>(buffer.as_object());
|
||||||
|
|
||||||
|
auto offset = vm.argument(1).to_index(global_object());
|
||||||
|
if (vm.exception())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
if (array_buffer.is_detached()) {
|
||||||
|
vm.throw_exception<TypeError>(global_object(), ErrorType::DetachedArrayBuffer);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto buffer_byte_length = array_buffer.byte_length();
|
||||||
|
if (offset > buffer_byte_length) {
|
||||||
|
vm.throw_exception<RangeError>(global_object(), ErrorType::DataViewOutOfRangeByteOffset, offset, buffer_byte_length);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t view_byte_length;
|
||||||
|
if (vm.argument(2).is_undefined()) {
|
||||||
|
view_byte_length = buffer_byte_length - offset;
|
||||||
|
} else {
|
||||||
|
view_byte_length = vm.argument(2).to_index(global_object());
|
||||||
|
if (vm.exception())
|
||||||
|
return {};
|
||||||
|
if (offset + view_byte_length > buffer_byte_length) {
|
||||||
|
vm.throw_exception<RangeError>(global_object(), ErrorType::InvalidLength, vm.names.DataView);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Use OrdinaryCreateFromConstructor(newTarget, "%DataView.prototype%")
|
||||||
|
if (array_buffer.is_detached()) {
|
||||||
|
vm.throw_exception<TypeError>(global_object(), ErrorType::DetachedArrayBuffer);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return DataView::create(global_object(), &array_buffer, view_byte_length, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
28
Userland/Libraries/LibJS/Runtime/DataViewConstructor.h
Normal file
28
Userland/Libraries/LibJS/Runtime/DataViewConstructor.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibJS/Runtime/NativeFunction.h>
|
||||||
|
|
||||||
|
namespace JS {
|
||||||
|
|
||||||
|
class DataViewConstructor final : public NativeFunction {
|
||||||
|
JS_OBJECT(DataViewConstructor, NativeFunction);
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit DataViewConstructor(GlobalObject&);
|
||||||
|
virtual void initialize(GlobalObject&) override;
|
||||||
|
virtual ~DataViewConstructor() override;
|
||||||
|
|
||||||
|
virtual Value call() override;
|
||||||
|
virtual Value construct(Function&) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual bool has_constructor() const override { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
78
Userland/Libraries/LibJS/Runtime/DataViewPrototype.cpp
Normal file
78
Userland/Libraries/LibJS/Runtime/DataViewPrototype.cpp
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LibJS/Runtime/DataViewPrototype.h>
|
||||||
|
|
||||||
|
namespace JS {
|
||||||
|
|
||||||
|
DataViewPrototype::DataViewPrototype(GlobalObject& global_object)
|
||||||
|
: Object(*global_object.object_prototype())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataViewPrototype::initialize(GlobalObject& global_object)
|
||||||
|
{
|
||||||
|
auto& vm = this->vm();
|
||||||
|
Object::initialize(global_object);
|
||||||
|
|
||||||
|
define_native_accessor(vm.names.buffer, buffer_getter, {}, Attribute::Configurable);
|
||||||
|
define_native_accessor(vm.names.byteLength, byte_length_getter, {}, Attribute::Configurable);
|
||||||
|
define_native_accessor(vm.names.byteOffset, byte_offset_getter, {}, Attribute::Configurable);
|
||||||
|
|
||||||
|
// 25.3.4.25 DataView.prototype [ @@toStringTag ], https://tc39.es/ecma262/#sec-dataview.prototype-@@tostringtag
|
||||||
|
define_property(vm.well_known_symbol_to_string_tag(), js_string(global_object.heap(), vm.names.DataView.as_string()), Attribute::Configurable);
|
||||||
|
}
|
||||||
|
|
||||||
|
DataViewPrototype::~DataViewPrototype()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static DataView* typed_this(VM& vm, GlobalObject& global_object)
|
||||||
|
{
|
||||||
|
auto this_value = vm.this_value(global_object);
|
||||||
|
if (!this_value.is_object() || !is<DataView>(this_value.as_object())) {
|
||||||
|
vm.throw_exception<TypeError>(global_object, ErrorType::NotA, vm.names.DataView);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return static_cast<DataView*>(&this_value.as_object());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 25.3.4.1 get DataView.prototype.buffer, https://tc39.es/ecma262/#sec-get-dataview.prototype.buffer
|
||||||
|
JS_DEFINE_NATIVE_GETTER(DataViewPrototype::buffer_getter)
|
||||||
|
{
|
||||||
|
auto* data_view = typed_this(vm, global_object);
|
||||||
|
if (!data_view)
|
||||||
|
return {};
|
||||||
|
return data_view->viewed_array_buffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 25.3.4.2 get DataView.prototype.byteLength, https://tc39.es/ecma262/#sec-get-dataview.prototype.bytelength
|
||||||
|
JS_DEFINE_NATIVE_GETTER(DataViewPrototype::byte_length_getter)
|
||||||
|
{
|
||||||
|
auto* data_view = typed_this(vm, global_object);
|
||||||
|
if (!data_view)
|
||||||
|
return {};
|
||||||
|
if (data_view->viewed_array_buffer()->is_detached()) {
|
||||||
|
vm.throw_exception<TypeError>(global_object, ErrorType::DetachedArrayBuffer);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return Value(data_view->byte_length());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 25.3.4.3 get DataView.prototype.byteOffset, https://tc39.es/ecma262/#sec-get-dataview.prototype.byteoffset
|
||||||
|
JS_DEFINE_NATIVE_GETTER(DataViewPrototype::byte_offset_getter)
|
||||||
|
{
|
||||||
|
auto* data_view = typed_this(vm, global_object);
|
||||||
|
if (!data_view)
|
||||||
|
return {};
|
||||||
|
if (data_view->viewed_array_buffer()->is_detached()) {
|
||||||
|
vm.throw_exception<TypeError>(global_object, ErrorType::DetachedArrayBuffer);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return Value(data_view->byte_offset());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
27
Userland/Libraries/LibJS/Runtime/DataViewPrototype.h
Normal file
27
Userland/Libraries/LibJS/Runtime/DataViewPrototype.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibJS/Runtime/DataView.h>
|
||||||
|
|
||||||
|
namespace JS {
|
||||||
|
|
||||||
|
class DataViewPrototype final : public Object {
|
||||||
|
JS_OBJECT(DataViewPrototype, Object);
|
||||||
|
|
||||||
|
public:
|
||||||
|
DataViewPrototype(GlobalObject&);
|
||||||
|
virtual void initialize(GlobalObject&) override;
|
||||||
|
virtual ~DataViewPrototype() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
JS_DECLARE_NATIVE_GETTER(buffer_getter);
|
||||||
|
JS_DECLARE_NATIVE_GETTER(byte_length_getter);
|
||||||
|
JS_DECLARE_NATIVE_GETTER(byte_offset_getter);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -21,6 +21,7 @@
|
||||||
M(ClassIsAbstract, "Abstract class {} cannot be constructed directly") \
|
M(ClassIsAbstract, "Abstract class {} cannot be constructed directly") \
|
||||||
M(ConstructorWithoutNew, "{} constructor must be called with 'new'") \
|
M(ConstructorWithoutNew, "{} constructor must be called with 'new'") \
|
||||||
M(Convert, "Cannot convert {} to {}") \
|
M(Convert, "Cannot convert {} to {}") \
|
||||||
|
M(DataViewOutOfRangeByteOffset, "Data view byte offset {} is out of range for buffer with length {}") \
|
||||||
M(DescChangeNonConfigurable, "Cannot change attributes of non-configurable property '{}'") \
|
M(DescChangeNonConfigurable, "Cannot change attributes of non-configurable property '{}'") \
|
||||||
M(DescWriteNonWritable, "Cannot write to non-writable property '{}'") \
|
M(DescWriteNonWritable, "Cannot write to non-writable property '{}'") \
|
||||||
M(DetachedArrayBuffer, "ArrayBuffer is detached") \
|
M(DetachedArrayBuffer, "ArrayBuffer is detached") \
|
||||||
|
@ -36,6 +37,7 @@
|
||||||
M(InvalidTimeValue, "Invalid time value") \
|
M(InvalidTimeValue, "Invalid time value") \
|
||||||
M(InvalidRadix, "Radix must be an integer no less than 2, and no greater than 36") \
|
M(InvalidRadix, "Radix must be an integer no less than 2, and no greater than 36") \
|
||||||
M(IsNotA, "{} is not a {}") \
|
M(IsNotA, "{} is not a {}") \
|
||||||
|
M(IsNotAn, "{} is not an {}") \
|
||||||
M(IsNotAEvaluatedFrom, "{} is not a {} (evaluated from '{}')") \
|
M(IsNotAEvaluatedFrom, "{} is not a {} (evaluated from '{}')") \
|
||||||
M(IterableNextBadReturn, "iterator.next() returned a non-object value") \
|
M(IterableNextBadReturn, "iterator.next() returned a non-object value") \
|
||||||
M(IterableNextNotAFunction, "'next' property on returned object from Symbol.iterator method is " \
|
M(IterableNextNotAFunction, "'next' property on returned object from Symbol.iterator method is " \
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include <LibJS/Runtime/BooleanConstructor.h>
|
#include <LibJS/Runtime/BooleanConstructor.h>
|
||||||
#include <LibJS/Runtime/BooleanPrototype.h>
|
#include <LibJS/Runtime/BooleanPrototype.h>
|
||||||
#include <LibJS/Runtime/ConsoleObject.h>
|
#include <LibJS/Runtime/ConsoleObject.h>
|
||||||
|
#include <LibJS/Runtime/DataViewConstructor.h>
|
||||||
|
#include <LibJS/Runtime/DataViewPrototype.h>
|
||||||
#include <LibJS/Runtime/DateConstructor.h>
|
#include <LibJS/Runtime/DateConstructor.h>
|
||||||
#include <LibJS/Runtime/DatePrototype.h>
|
#include <LibJS/Runtime/DatePrototype.h>
|
||||||
#include <LibJS/Runtime/ErrorConstructor.h>
|
#include <LibJS/Runtime/ErrorConstructor.h>
|
||||||
|
@ -150,6 +152,7 @@ void GlobalObject::initialize_global_object()
|
||||||
add_constructor(vm.names.ArrayBuffer, m_array_buffer_constructor, m_array_buffer_prototype);
|
add_constructor(vm.names.ArrayBuffer, m_array_buffer_constructor, m_array_buffer_prototype);
|
||||||
add_constructor(vm.names.BigInt, m_bigint_constructor, m_bigint_prototype);
|
add_constructor(vm.names.BigInt, m_bigint_constructor, m_bigint_prototype);
|
||||||
add_constructor(vm.names.Boolean, m_boolean_constructor, m_boolean_prototype);
|
add_constructor(vm.names.Boolean, m_boolean_constructor, m_boolean_prototype);
|
||||||
|
add_constructor(vm.names.DataView, m_data_view_constructor, m_data_view_prototype);
|
||||||
add_constructor(vm.names.Date, m_date_constructor, m_date_prototype);
|
add_constructor(vm.names.Date, m_date_constructor, m_date_prototype);
|
||||||
add_constructor(vm.names.Error, m_error_constructor, m_error_prototype);
|
add_constructor(vm.names.Error, m_error_constructor, m_error_prototype);
|
||||||
add_constructor(vm.names.Function, m_function_constructor, m_function_prototype);
|
add_constructor(vm.names.Function, m_function_constructor, m_function_prototype);
|
||||||
|
|
15
Userland/Libraries/LibJS/Tests/builtins/DataView/DataView.js
Normal file
15
Userland/Libraries/LibJS/Tests/builtins/DataView/DataView.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
test("basic functionality", () => {
|
||||||
|
expect(DataView).toHaveLength(1);
|
||||||
|
expect(DataView.name).toBe("DataView");
|
||||||
|
expect(DataView.prototype.constructor).toBe(DataView);
|
||||||
|
|
||||||
|
const buffer = new ArrayBuffer();
|
||||||
|
expect(new DataView(buffer)).toBeInstanceOf(DataView);
|
||||||
|
expect(typeof new DataView(buffer)).toBe("object");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("DataView constructor must be invoked with 'new'", () => {
|
||||||
|
expect(() => {
|
||||||
|
DataView();
|
||||||
|
}).toThrowWithMessage(TypeError, "DataView constructor must be called with 'new'");
|
||||||
|
});
|
|
@ -0,0 +1,4 @@
|
||||||
|
test("basic functionality", () => {
|
||||||
|
const buffer = new ArrayBuffer();
|
||||||
|
expect(new DataView(buffer).buffer).toBe(buffer);
|
||||||
|
});
|
|
@ -0,0 +1,7 @@
|
||||||
|
test("basic functionality", () => {
|
||||||
|
const buffer = new ArrayBuffer(124);
|
||||||
|
expect(new DataView(buffer).byteLength).toBe(124);
|
||||||
|
expect(new DataView(buffer, 0, 1).byteLength).toBe(1);
|
||||||
|
expect(new DataView(buffer, 0, 64).byteLength).toBe(64);
|
||||||
|
expect(new DataView(buffer, 0, 123).byteLength).toBe(123);
|
||||||
|
});
|
|
@ -0,0 +1,7 @@
|
||||||
|
test("basic functionality", () => {
|
||||||
|
const buffer = new ArrayBuffer(124);
|
||||||
|
expect(new DataView(buffer).byteOffset).toBe(0);
|
||||||
|
expect(new DataView(buffer, 1).byteOffset).toBe(1);
|
||||||
|
expect(new DataView(buffer, 64).byteOffset).toBe(64);
|
||||||
|
expect(new DataView(buffer, 123).byteOffset).toBe(123);
|
||||||
|
});
|
|
@ -23,6 +23,7 @@
|
||||||
#include <LibJS/Runtime/Array.h>
|
#include <LibJS/Runtime/Array.h>
|
||||||
#include <LibJS/Runtime/ArrayBuffer.h>
|
#include <LibJS/Runtime/ArrayBuffer.h>
|
||||||
#include <LibJS/Runtime/BooleanObject.h>
|
#include <LibJS/Runtime/BooleanObject.h>
|
||||||
|
#include <LibJS/Runtime/DataView.h>
|
||||||
#include <LibJS/Runtime/Date.h>
|
#include <LibJS/Runtime/Date.h>
|
||||||
#include <LibJS/Runtime/Error.h>
|
#include <LibJS/Runtime/Error.h>
|
||||||
#include <LibJS/Runtime/Function.h>
|
#include <LibJS/Runtime/Function.h>
|
||||||
|
@ -397,6 +398,19 @@ static void print_typed_array(const JS::Object& object, HashTable<JS::Object*>&
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print_data_view(const JS::Object& object, HashTable<JS::Object*>& seen_objects)
|
||||||
|
{
|
||||||
|
auto& data_view = static_cast<const JS::DataView&>(object);
|
||||||
|
print_type("DataView");
|
||||||
|
out("\n byteLength: ");
|
||||||
|
print_value(JS::Value(data_view.byte_length()), seen_objects);
|
||||||
|
out("\n byteOffset: ");
|
||||||
|
print_value(JS::Value(data_view.byte_offset()), seen_objects);
|
||||||
|
out("\n buffer: ");
|
||||||
|
print_type("ArrayBuffer");
|
||||||
|
out(" @ {:p}", data_view.viewed_array_buffer());
|
||||||
|
}
|
||||||
|
|
||||||
static void print_primitive_wrapper_object(const FlyString& name, const JS::Object& object, HashTable<JS::Object*>& seen_objects)
|
static void print_primitive_wrapper_object(const FlyString& name, const JS::Object& object, HashTable<JS::Object*>& seen_objects)
|
||||||
{
|
{
|
||||||
// BooleanObject, NumberObject, StringObject
|
// BooleanObject, NumberObject, StringObject
|
||||||
|
@ -438,6 +452,8 @@ static void print_value(JS::Value value, HashTable<JS::Object*>& seen_objects)
|
||||||
return print_map(object, seen_objects);
|
return print_map(object, seen_objects);
|
||||||
if (is<JS::Set>(object))
|
if (is<JS::Set>(object))
|
||||||
return print_set(object, seen_objects);
|
return print_set(object, seen_objects);
|
||||||
|
if (is<JS::DataView>(object))
|
||||||
|
return print_data_view(object, seen_objects);
|
||||||
if (is<JS::ProxyObject>(object))
|
if (is<JS::ProxyObject>(object))
|
||||||
return print_proxy_object(object, seen_objects);
|
return print_proxy_object(object, seen_objects);
|
||||||
if (is<JS::Promise>(object))
|
if (is<JS::Promise>(object))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue