mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 02:27:43 +00:00
LibJS: Add "Heap" and "Runtime" subdirectories
Let's try to keep LibJS tidy as it expands. :^)
This commit is contained in:
parent
6780d70fb1
commit
19452230cd
39 changed files with 99 additions and 98 deletions
60
Libraries/LibJS/Runtime/Cell.cpp
Normal file
60
Libraries/LibJS/Runtime/Cell.cpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/LogStream.h>
|
||||
#include <LibJS/Heap/Heap.h>
|
||||
#include <LibJS/Heap/HeapBlock.h>
|
||||
#include <LibJS/Runtime/Cell.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
#include <LibJS/Runtime/PrimitiveString.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
void Cell::Visitor::visit(Value value)
|
||||
{
|
||||
if (value.is_cell())
|
||||
visit(value.as_cell());
|
||||
}
|
||||
|
||||
Heap& Cell::heap() const
|
||||
{
|
||||
return HeapBlock::from_cell(this)->heap();
|
||||
}
|
||||
|
||||
Interpreter& Cell::interpreter()
|
||||
{
|
||||
return heap().interpreter();
|
||||
}
|
||||
|
||||
const LogStream& operator<<(const LogStream& stream, const Cell* cell)
|
||||
{
|
||||
if (!cell)
|
||||
return stream << "Cell{nullptr}";
|
||||
return stream << cell->class_name() << '{' << static_cast<const void*>(cell) << '}';
|
||||
}
|
||||
|
||||
}
|
64
Libraries/LibJS/Runtime/Cell.h
Normal file
64
Libraries/LibJS/Runtime/Cell.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Forward.h>
|
||||
#include <LibJS/Forward.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
class Cell {
|
||||
public:
|
||||
virtual ~Cell() {}
|
||||
|
||||
bool is_marked() const { return m_mark; }
|
||||
void set_marked(bool b) { m_mark = b; }
|
||||
|
||||
bool is_live() const { return m_live; }
|
||||
void set_live(bool b) { m_live = b; }
|
||||
|
||||
virtual const char* class_name() const = 0;
|
||||
|
||||
class Visitor {
|
||||
public:
|
||||
virtual void visit(Cell*) = 0;
|
||||
void visit(Value);
|
||||
};
|
||||
|
||||
virtual void visit_children(Visitor&) {}
|
||||
|
||||
Heap& heap() const;
|
||||
Interpreter& interpreter();
|
||||
|
||||
private:
|
||||
bool m_mark { false };
|
||||
bool m_live { true };
|
||||
};
|
||||
|
||||
const LogStream& operator<<(const LogStream&, const Cell*);
|
||||
|
||||
}
|
40
Libraries/LibJS/Runtime/Function.cpp
Normal file
40
Libraries/LibJS/Runtime/Function.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <LibJS/Runtime/Function.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
Function::Function()
|
||||
{
|
||||
}
|
||||
|
||||
Function::~Function()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
48
Libraries/LibJS/Runtime/Function.h
Normal file
48
Libraries/LibJS/Runtime/Function.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
class Function : public Object {
|
||||
public:
|
||||
virtual ~Function();
|
||||
|
||||
virtual Value call(Interpreter&, Vector<Value>) = 0;
|
||||
|
||||
protected:
|
||||
Function();
|
||||
virtual const char* class_name() const override { return "Function"; }
|
||||
|
||||
private:
|
||||
virtual bool is_function() const final { return true; }
|
||||
};
|
||||
|
||||
}
|
31
Libraries/LibJS/Runtime/GlobalObject.cpp
Normal file
31
Libraries/LibJS/Runtime/GlobalObject.cpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
#include <AK/LogStream.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibJS/Heap/Heap.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/ConsoleObject.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
#include <LibJS/Runtime/NativeFunction.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
GlobalObject::GlobalObject()
|
||||
{
|
||||
put_native_function("print", [](Object*, Vector<Value> arguments) -> Value {
|
||||
for (auto& argument : arguments)
|
||||
printf("%s ", argument.to_string().characters());
|
||||
return js_undefined();
|
||||
});
|
||||
put_native_function("gc", [](Object* this_object, Vector<Value>) -> Value {
|
||||
dbg() << "Forced garbage collection requested!";
|
||||
this_object->heap().collect_garbage();
|
||||
return js_undefined();
|
||||
});
|
||||
}
|
||||
|
||||
GlobalObject::~GlobalObject()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
16
Libraries/LibJS/Runtime/GlobalObject.h
Normal file
16
Libraries/LibJS/Runtime/GlobalObject.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
class GlobalObject final : public Object {
|
||||
public:
|
||||
explicit GlobalObject();
|
||||
virtual ~GlobalObject() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "GlobalObject"; }
|
||||
};
|
||||
|
||||
}
|
49
Libraries/LibJS/Runtime/NativeFunction.cpp
Normal file
49
Libraries/LibJS/Runtime/NativeFunction.cpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/NativeFunction.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
NativeFunction::NativeFunction(AK::Function<Value(Object*, Vector<Value>)> native_function)
|
||||
: m_native_function(move(native_function))
|
||||
{
|
||||
}
|
||||
|
||||
NativeFunction::~NativeFunction()
|
||||
{
|
||||
}
|
||||
|
||||
Value NativeFunction::call(Interpreter& interpreter, Vector<Value> arguments)
|
||||
{
|
||||
auto this_value = interpreter.this_value();
|
||||
ASSERT(this_value.is_object());
|
||||
return m_native_function(this_value.as_object(), move(arguments));
|
||||
}
|
||||
|
||||
}
|
48
Libraries/LibJS/Runtime/NativeFunction.h
Normal file
48
Libraries/LibJS/Runtime/NativeFunction.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <LibJS/Runtime/Function.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
class NativeFunction final : public Function {
|
||||
public:
|
||||
explicit NativeFunction(AK::Function<Value(Object*, Vector<Value>)>);
|
||||
virtual ~NativeFunction() override;
|
||||
|
||||
virtual Value call(Interpreter&, Vector<Value>) override;
|
||||
|
||||
private:
|
||||
virtual bool is_native_function() const override { return true; }
|
||||
virtual const char* class_name() const override { return "NativeFunction"; }
|
||||
|
||||
AK::Function<Value(Object*, Vector<Value>)> m_native_function;
|
||||
};
|
||||
|
||||
}
|
56
Libraries/LibJS/Runtime/NativeProperty.cpp
Normal file
56
Libraries/LibJS/Runtime/NativeProperty.cpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <LibJS/Runtime/NativeProperty.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
NativeProperty::NativeProperty(AK::Function<Value(Object*)> getter, AK::Function<void(Object*, Value)> setter)
|
||||
: m_getter(move(getter))
|
||||
, m_setter(move(setter))
|
||||
{
|
||||
}
|
||||
|
||||
NativeProperty::~NativeProperty()
|
||||
{
|
||||
}
|
||||
|
||||
Value NativeProperty::get(Object* object) const
|
||||
{
|
||||
if (!m_getter)
|
||||
return js_undefined();
|
||||
return m_getter(object);
|
||||
}
|
||||
|
||||
void NativeProperty::set(Object* object, Value value)
|
||||
{
|
||||
if (!m_setter)
|
||||
return;
|
||||
m_setter(object, move(value));
|
||||
}
|
||||
|
||||
}
|
50
Libraries/LibJS/Runtime/NativeProperty.h
Normal file
50
Libraries/LibJS/Runtime/NativeProperty.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
class NativeProperty final : public Object {
|
||||
public:
|
||||
NativeProperty(AK::Function<Value(Object*)> getter, AK::Function<void(Object*, Value)> setter);
|
||||
virtual ~NativeProperty() override;
|
||||
|
||||
Value get(Object*) const;
|
||||
void set(Object*, Value);
|
||||
|
||||
private:
|
||||
virtual bool is_native_property() const override { return true; }
|
||||
virtual const char* class_name() const override { return "NativeProperty"; }
|
||||
|
||||
AK::Function<Value(Object*)> m_getter;
|
||||
AK::Function<void(Object*, Value)> m_setter;
|
||||
};
|
||||
|
||||
}
|
120
Libraries/LibJS/Runtime/Object.cpp
Normal file
120
Libraries/LibJS/Runtime/Object.cpp
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <LibJS/Heap/Heap.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/NativeFunction.h>
|
||||
#include <LibJS/Runtime/NativeProperty.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
Object::Object()
|
||||
{
|
||||
set_prototype(interpreter().object_prototype());
|
||||
}
|
||||
|
||||
Object::~Object()
|
||||
{
|
||||
}
|
||||
|
||||
Value Object::get(String property_name) const
|
||||
{
|
||||
const Object* object = this;
|
||||
while (object) {
|
||||
auto value = object->m_properties.get(property_name);
|
||||
if (value.has_value()) {
|
||||
if (value.value().is_object() && value.value().as_object()->is_native_property())
|
||||
return static_cast<const NativeProperty*>(value.value().as_object())->get(const_cast<Object*>(this));
|
||||
return value.value();
|
||||
}
|
||||
object = object->prototype();
|
||||
}
|
||||
return js_undefined();
|
||||
}
|
||||
|
||||
void Object::put(String property_name, Value value)
|
||||
{
|
||||
m_properties.set(property_name, move(value));
|
||||
}
|
||||
|
||||
void Object::put_native_function(String property_name, AK::Function<Value(Object*, Vector<Value>)> native_function)
|
||||
{
|
||||
put(property_name, heap().allocate<NativeFunction>(move(native_function)));
|
||||
}
|
||||
|
||||
void Object::put_native_property(String property_name, AK::Function<Value(Object*)> getter, AK::Function<void(Object*, Value)> setter)
|
||||
{
|
||||
put(property_name, heap().allocate<NativeProperty>(move(getter), move(setter)));
|
||||
}
|
||||
|
||||
void Object::visit_children(Cell::Visitor& visitor)
|
||||
{
|
||||
Cell::visit_children(visitor);
|
||||
if (m_prototype)
|
||||
visitor.visit(m_prototype);
|
||||
for (auto& it : m_properties)
|
||||
visitor.visit(it.value);
|
||||
}
|
||||
|
||||
bool Object::has_own_property(const String& property_name) const
|
||||
{
|
||||
return m_properties.get(property_name).has_value();
|
||||
}
|
||||
|
||||
Value Object::to_primitive(PreferredType preferred_type) const
|
||||
{
|
||||
Value result = js_undefined();
|
||||
|
||||
switch (preferred_type) {
|
||||
case PreferredType::Default:
|
||||
case PreferredType::Number: {
|
||||
result = value_of();
|
||||
if (result.is_object()) {
|
||||
result = to_string();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PreferredType::String: {
|
||||
result = to_string();
|
||||
if (result.is_object())
|
||||
result = value_of();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(!result.is_object());
|
||||
return result;
|
||||
}
|
||||
|
||||
Value Object::to_string() const
|
||||
{
|
||||
return js_string(heap(), String::format("[object %s]", class_name()));
|
||||
}
|
||||
|
||||
}
|
77
Libraries/LibJS/Runtime/Object.h
Normal file
77
Libraries/LibJS/Runtime/Object.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibJS/Runtime/Cell.h>
|
||||
#include <LibJS/Runtime/PrimitiveString.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
class Object : public Cell {
|
||||
public:
|
||||
Object();
|
||||
virtual ~Object();
|
||||
|
||||
Value get(String property_name) const;
|
||||
void put(String property_name, Value);
|
||||
|
||||
void put_native_function(String property_name, AK::Function<Value(Object*, Vector<Value>)>);
|
||||
void put_native_property(String property_name, AK::Function<Value(Object*)> getter, AK::Function<void(Object*, Value)> setter);
|
||||
|
||||
virtual bool is_function() const { return false; }
|
||||
virtual bool is_native_function() const { return false; }
|
||||
virtual bool is_string_object() const { return false; }
|
||||
virtual bool is_native_property() const { return false; }
|
||||
|
||||
virtual const char* class_name() const override { return "Object"; }
|
||||
virtual void visit_children(Cell::Visitor&) override;
|
||||
|
||||
Object* prototype() { return m_prototype; }
|
||||
const Object* prototype() const { return m_prototype; }
|
||||
void set_prototype(Object* prototype) { m_prototype = prototype; }
|
||||
|
||||
bool has_own_property(const String& property_name) const;
|
||||
enum class PreferredType {
|
||||
Default,
|
||||
String,
|
||||
Number,
|
||||
};
|
||||
|
||||
virtual Value value_of() const { return Value(const_cast<Object*>(this)); }
|
||||
virtual Value to_primitive(PreferredType preferred_type = PreferredType::Default) const;
|
||||
virtual Value to_string() const;
|
||||
|
||||
private:
|
||||
HashMap<String, Value> m_properties;
|
||||
Object* m_prototype { nullptr };
|
||||
};
|
||||
|
||||
}
|
63
Libraries/LibJS/Runtime/ObjectPrototype.cpp
Normal file
63
Libraries/LibJS/Runtime/ObjectPrototype.cpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibJS/Heap/Heap.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/ObjectPrototype.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
ObjectPrototype::ObjectPrototype()
|
||||
{
|
||||
set_prototype(nullptr);
|
||||
|
||||
put_native_function("hasOwnProperty", [](Object* this_object, Vector<Value> arguments) -> Value {
|
||||
ASSERT(this_object);
|
||||
if (arguments.is_empty())
|
||||
return js_undefined();
|
||||
return Value(this_object->has_own_property(arguments[0].to_string()));
|
||||
});
|
||||
|
||||
put_native_function("toString", [](Object* this_object, Vector<Value>) -> Value {
|
||||
ASSERT(this_object);
|
||||
|
||||
return Value(this_object->to_string());
|
||||
});
|
||||
|
||||
put_native_function("valueOf", [](Object* this_object, Vector<Value>) -> Value {
|
||||
ASSERT(this_object);
|
||||
return this_object->value_of();
|
||||
});
|
||||
}
|
||||
|
||||
ObjectPrototype::~ObjectPrototype()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
42
Libraries/LibJS/Runtime/ObjectPrototype.h
Normal file
42
Libraries/LibJS/Runtime/ObjectPrototype.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
class ObjectPrototype final : public Object {
|
||||
public:
|
||||
ObjectPrototype();
|
||||
virtual ~ObjectPrototype() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "ObjectPrototype"; }
|
||||
};
|
||||
|
||||
}
|
46
Libraries/LibJS/Runtime/PrimitiveString.cpp
Normal file
46
Libraries/LibJS/Runtime/PrimitiveString.cpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <LibJS/Heap/Heap.h>
|
||||
#include <LibJS/Runtime/PrimitiveString.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
PrimitiveString::PrimitiveString(String string)
|
||||
: m_string(move(string))
|
||||
{
|
||||
}
|
||||
|
||||
PrimitiveString::~PrimitiveString()
|
||||
{
|
||||
}
|
||||
|
||||
PrimitiveString* js_string(Heap& heap, String string)
|
||||
{
|
||||
return heap.allocate<PrimitiveString>(move(string));
|
||||
}
|
||||
|
||||
}
|
49
Libraries/LibJS/Runtime/PrimitiveString.h
Normal file
49
Libraries/LibJS/Runtime/PrimitiveString.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <LibJS/Runtime/Cell.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
class PrimitiveString final : public Cell {
|
||||
public:
|
||||
explicit PrimitiveString(String);
|
||||
virtual ~PrimitiveString();
|
||||
|
||||
const String& string() const { return m_string; }
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "PrimitiveString"; }
|
||||
|
||||
String m_string;
|
||||
};
|
||||
|
||||
PrimitiveString* js_string(Heap&, String);
|
||||
|
||||
}
|
56
Libraries/LibJS/Runtime/ScriptFunction.cpp
Normal file
56
Libraries/LibJS/Runtime/ScriptFunction.cpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Stephan Unverwerth <s.unverwerth@gmx.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/ScriptFunction.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
ScriptFunction::ScriptFunction(const ScopeNode& body, Vector<String> parameters)
|
||||
: m_body(body)
|
||||
, m_parameters(move(parameters))
|
||||
{
|
||||
}
|
||||
|
||||
ScriptFunction::~ScriptFunction()
|
||||
{
|
||||
}
|
||||
|
||||
Value ScriptFunction::call(Interpreter& interpreter, Vector<Value> argument_values)
|
||||
{
|
||||
Vector<Argument> arguments;
|
||||
for (size_t i = 0; i < m_parameters.size(); ++i) {
|
||||
auto name = parameters()[i];
|
||||
auto value = js_undefined();
|
||||
if (i < argument_values.size())
|
||||
value = argument_values[i];
|
||||
arguments.append({ move(name), move(value) });
|
||||
}
|
||||
return interpreter.run(m_body, move(arguments), ScopeType::Function);
|
||||
}
|
||||
|
||||
}
|
51
Libraries/LibJS/Runtime/ScriptFunction.h
Normal file
51
Libraries/LibJS/Runtime/ScriptFunction.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibJS/Runtime/Function.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
class ScriptFunction final : public Function {
|
||||
public:
|
||||
ScriptFunction(const ScopeNode& body, Vector<String> parameters = {});
|
||||
virtual ~ScriptFunction();
|
||||
|
||||
const ScopeNode& body() const { return m_body; }
|
||||
const Vector<String>& parameters() const { return m_parameters; };
|
||||
|
||||
virtual Value call(Interpreter&, Vector<Value>) override;
|
||||
|
||||
private:
|
||||
virtual bool is_script_function() const final { return true; }
|
||||
virtual const char* class_name() const override { return "ScriptFunction"; }
|
||||
|
||||
const ScopeNode& m_body;
|
||||
const Vector<String> m_parameters;
|
||||
};
|
||||
|
||||
}
|
52
Libraries/LibJS/Runtime/StringObject.cpp
Normal file
52
Libraries/LibJS/Runtime/StringObject.cpp
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <LibJS/Heap/Heap.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/PrimitiveString.h>
|
||||
#include <LibJS/Runtime/StringObject.h>
|
||||
#include <LibJS/Runtime/StringPrototype.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
StringObject::StringObject(PrimitiveString* string)
|
||||
: m_string(string)
|
||||
{
|
||||
set_prototype(interpreter().string_prototype());
|
||||
}
|
||||
|
||||
StringObject::~StringObject()
|
||||
{
|
||||
}
|
||||
|
||||
void StringObject::visit_children(Cell::Visitor& visitor)
|
||||
{
|
||||
Object::visit_children(visitor);
|
||||
visitor.visit(m_string);
|
||||
}
|
||||
|
||||
}
|
52
Libraries/LibJS/Runtime/StringObject.h
Normal file
52
Libraries/LibJS/Runtime/StringObject.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
class StringObject final : public Object {
|
||||
public:
|
||||
explicit StringObject(PrimitiveString*);
|
||||
virtual ~StringObject() override;
|
||||
|
||||
virtual void visit_children(Visitor&) override;
|
||||
const PrimitiveString* primitive_string() const { return m_string; }
|
||||
virtual Value value_of() const override
|
||||
{
|
||||
return Value(m_string);
|
||||
}
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "StringObject"; }
|
||||
virtual bool is_string_object() const override { return true; }
|
||||
|
||||
PrimitiveString* m_string { nullptr };
|
||||
};
|
||||
|
||||
}
|
80
Libraries/LibJS/Runtime/StringPrototype.cpp
Normal file
80
Libraries/LibJS/Runtime/StringPrototype.cpp
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <LibJS/Heap/Heap.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/PrimitiveString.h>
|
||||
#include <LibJS/Runtime/StringObject.h>
|
||||
#include <LibJS/Runtime/StringPrototype.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
StringPrototype::StringPrototype()
|
||||
{
|
||||
put_native_property(
|
||||
"length", [](Object* this_object) {
|
||||
ASSERT(this_object);
|
||||
ASSERT(this_object->is_string_object());
|
||||
return Value((i32) static_cast<const StringObject*>(this_object)->primitive_string()->string().length());
|
||||
},
|
||||
nullptr);
|
||||
put_native_function("charAt", [](Object* this_object, Vector<Value> arguments) -> Value {
|
||||
ASSERT(this_object);
|
||||
i32 index = 0;
|
||||
if (!arguments.is_empty())
|
||||
index = arguments[0].to_i32();
|
||||
ASSERT(this_object->is_string_object());
|
||||
auto underlying_string = static_cast<const StringObject*>(this_object)->primitive_string()->string();
|
||||
if (index < 0 || index >= static_cast<i32>(underlying_string.length()))
|
||||
return js_string(this_object->heap(), String::empty());
|
||||
return js_string(this_object->heap(), underlying_string.substring(index, 1));
|
||||
});
|
||||
put_native_function("repeat", [](Object* this_object, Vector<Value> arguments) -> Value {
|
||||
ASSERT(this_object->is_string_object());
|
||||
if (arguments.is_empty())
|
||||
return js_string(this_object->heap(), String::empty());
|
||||
i32 count = 0;
|
||||
count = arguments[0].to_i32();
|
||||
if (count < 0) {
|
||||
// FIXME: throw RangeError
|
||||
return js_undefined();
|
||||
}
|
||||
auto* string_object = static_cast<StringObject*>(this_object);
|
||||
StringBuilder builder;
|
||||
for (i32 i = 0; i < count; ++i)
|
||||
builder.append(string_object->primitive_string()->string());
|
||||
return js_string(this_object->heap(), builder.to_string());
|
||||
});
|
||||
}
|
||||
|
||||
StringPrototype::~StringPrototype()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
42
Libraries/LibJS/Runtime/StringPrototype.h
Normal file
42
Libraries/LibJS/Runtime/StringPrototype.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
class StringPrototype final : public Object {
|
||||
public:
|
||||
StringPrototype();
|
||||
virtual ~StringPrototype() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "StringPrototype"; }
|
||||
};
|
||||
|
||||
}
|
256
Libraries/LibJS/Runtime/Value.cpp
Normal file
256
Libraries/LibJS/Runtime/Value.cpp
Normal file
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <LibJS/Heap/Heap.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
#include <LibJS/Runtime/PrimitiveString.h>
|
||||
#include <LibJS/Runtime/StringObject.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
String Value::to_string() const
|
||||
{
|
||||
if (is_boolean())
|
||||
return as_bool() ? "true" : "false";
|
||||
|
||||
if (is_null())
|
||||
return "null";
|
||||
|
||||
if (is_undefined())
|
||||
return "undefined";
|
||||
|
||||
if (is_number())
|
||||
// FIXME: This needs improvement.
|
||||
return String::number((i32)as_double());
|
||||
|
||||
if (is_object())
|
||||
return as_object()->to_primitive(Object::PreferredType::String).to_string();
|
||||
|
||||
if (is_string())
|
||||
return m_value.as_string->string();
|
||||
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
bool Value::to_boolean() const
|
||||
{
|
||||
switch (m_type) {
|
||||
case Type::Boolean:
|
||||
return m_value.as_bool;
|
||||
case Type::Number:
|
||||
return !(m_value.as_double == 0 || m_value.as_double == -0);
|
||||
case Type::Null:
|
||||
case Type::Undefined:
|
||||
return false;
|
||||
case Type::String:
|
||||
return !as_string()->string().is_empty();
|
||||
case Type::Object:
|
||||
return true;
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
Value Value::to_object(Heap& heap) const
|
||||
{
|
||||
if (is_object())
|
||||
return const_cast<Object*>(as_object());
|
||||
|
||||
if (is_string())
|
||||
return heap.allocate<StringObject>(m_value.as_string);
|
||||
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
Value Value::to_number() const
|
||||
{
|
||||
switch (m_type) {
|
||||
case Type::Boolean:
|
||||
return Value(m_value.as_bool ? 1 : 0);
|
||||
case Type::Number:
|
||||
return Value(m_value.as_double);
|
||||
case Type::Null:
|
||||
return Value(0);
|
||||
case Type::String: {
|
||||
bool ok;
|
||||
//FIXME: Parse in a better way
|
||||
auto parsed_int = as_string()->string().to_int(ok);
|
||||
if (ok)
|
||||
return Value(parsed_int);
|
||||
|
||||
//FIXME: Implement 'NaN'
|
||||
ASSERT_NOT_REACHED();
|
||||
|
||||
break;
|
||||
}
|
||||
case Type::Undefined:
|
||||
//FIXME: Implement 'NaN'
|
||||
ASSERT_NOT_REACHED();
|
||||
case Type::Object:
|
||||
return m_value.as_object->to_primitive(Object::PreferredType::Number).to_number();
|
||||
}
|
||||
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
i32 Value::to_i32() const
|
||||
{
|
||||
return static_cast<i32>(to_number().as_double());
|
||||
}
|
||||
|
||||
Value greater_than(Value lhs, Value rhs)
|
||||
{
|
||||
return Value(lhs.to_number().as_double() > rhs.to_number().as_double());
|
||||
}
|
||||
|
||||
Value greater_than_equals(Value lhs, Value rhs)
|
||||
{
|
||||
return Value(lhs.to_number().as_double() >= rhs.to_number().as_double());
|
||||
}
|
||||
|
||||
Value less_than(Value lhs, Value rhs)
|
||||
{
|
||||
return Value(lhs.to_number().as_double() < rhs.to_number().as_double());
|
||||
}
|
||||
|
||||
Value less_than_equals(Value lhs, Value rhs)
|
||||
{
|
||||
return Value(lhs.to_number().as_double() <= rhs.to_number().as_double());
|
||||
}
|
||||
|
||||
Value bitwise_and(Value lhs, Value rhs)
|
||||
{
|
||||
return Value((i32)lhs.to_number().as_double() & (i32)rhs.to_number().as_double());
|
||||
}
|
||||
|
||||
Value bitwise_or(Value lhs, Value rhs)
|
||||
{
|
||||
return Value((i32)lhs.to_number().as_double() | (i32)rhs.to_number().as_double());
|
||||
}
|
||||
|
||||
Value bitwise_xor(Value lhs, Value rhs)
|
||||
{
|
||||
return Value((i32)lhs.to_number().as_double() ^ (i32)rhs.to_number().as_double());
|
||||
}
|
||||
|
||||
Value bitwise_not(Value lhs)
|
||||
{
|
||||
return Value(~(i32)lhs.to_number().as_double());
|
||||
}
|
||||
|
||||
Value left_shift(Value lhs, Value rhs)
|
||||
{
|
||||
return Value((i32)lhs.to_number().as_double() << (i32)rhs.to_number().as_double());
|
||||
}
|
||||
|
||||
Value right_shift(Value lhs, Value rhs)
|
||||
{
|
||||
return Value((i32)lhs.to_number().as_double() >> (i32)rhs.to_number().as_double());
|
||||
}
|
||||
|
||||
Value add(Value lhs, Value rhs)
|
||||
{
|
||||
if (lhs.is_string() || rhs.is_string())
|
||||
return js_string((lhs.is_string() ? lhs : rhs).as_string()->heap(), String::format("%s%s", lhs.to_string().characters(), rhs.to_string().characters()));
|
||||
|
||||
return Value(lhs.to_number().as_double() + rhs.to_number().as_double());
|
||||
}
|
||||
|
||||
Value sub(Value lhs, Value rhs)
|
||||
{
|
||||
return Value(lhs.to_number().as_double() - rhs.to_number().as_double());
|
||||
}
|
||||
|
||||
Value mul(Value lhs, Value rhs)
|
||||
{
|
||||
return Value(lhs.to_number().as_double() * rhs.to_number().as_double());
|
||||
}
|
||||
|
||||
Value div(Value lhs, Value rhs)
|
||||
{
|
||||
return Value(lhs.to_number().as_double() / rhs.to_number().as_double());
|
||||
}
|
||||
|
||||
Value typed_eq(Value lhs, Value rhs)
|
||||
{
|
||||
if (rhs.type() != lhs.type())
|
||||
return Value(false);
|
||||
|
||||
switch (lhs.type()) {
|
||||
case Value::Type::Undefined:
|
||||
return Value(true);
|
||||
case Value::Type::Null:
|
||||
return Value(true);
|
||||
case Value::Type::Number:
|
||||
return Value(lhs.as_double() == rhs.as_double());
|
||||
case Value::Type::String:
|
||||
return Value(lhs.as_string()->string() == rhs.as_string()->string());
|
||||
case Value::Type::Boolean:
|
||||
return Value(lhs.as_bool() == rhs.as_bool());
|
||||
case Value::Type::Object:
|
||||
return Value(lhs.as_object() == rhs.as_object());
|
||||
}
|
||||
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
Value eq(Value lhs, Value rhs)
|
||||
{
|
||||
if (lhs.type() == rhs.type())
|
||||
return typed_eq(lhs, rhs);
|
||||
|
||||
if ((lhs.is_undefined() || lhs.is_null()) && (rhs.is_undefined() || rhs.is_null()))
|
||||
return Value(true);
|
||||
|
||||
if (lhs.is_object() && rhs.is_boolean())
|
||||
return eq(lhs.as_object()->to_primitive(), rhs.to_number());
|
||||
|
||||
if (lhs.is_boolean() && rhs.is_object())
|
||||
return eq(lhs.to_number(), rhs.as_object()->to_primitive());
|
||||
|
||||
if (lhs.is_object())
|
||||
return eq(lhs.as_object()->to_primitive(), rhs);
|
||||
|
||||
if (rhs.is_object())
|
||||
return eq(lhs, rhs.as_object()->to_primitive());
|
||||
|
||||
if (lhs.is_number() || rhs.is_number())
|
||||
return Value(lhs.to_number().as_double() == rhs.to_number().as_double());
|
||||
|
||||
if ((lhs.is_string() && rhs.is_boolean()) || (lhs.is_string() && rhs.is_boolean()))
|
||||
return Value(lhs.to_number().as_double() == rhs.to_number().as_double());
|
||||
|
||||
return Value(false);
|
||||
}
|
||||
|
||||
const LogStream& operator<<(const LogStream& stream, const Value& value)
|
||||
{
|
||||
return stream << value.to_string();
|
||||
}
|
||||
|
||||
}
|
182
Libraries/LibJS/Runtime/Value.h
Normal file
182
Libraries/LibJS/Runtime/Value.h
Normal file
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Assertions.h>
|
||||
#include <AK/Forward.h>
|
||||
#include <AK/LogStream.h>
|
||||
#include <LibJS/Forward.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
class Value {
|
||||
public:
|
||||
enum class Type {
|
||||
Undefined,
|
||||
Null,
|
||||
Number,
|
||||
String,
|
||||
Object,
|
||||
Boolean,
|
||||
};
|
||||
|
||||
bool is_undefined() const { return m_type == Type::Undefined; }
|
||||
bool is_null() const { return m_type == Type::Null; }
|
||||
bool is_number() const { return m_type == Type::Number; }
|
||||
bool is_string() const { return m_type == Type::String; }
|
||||
bool is_object() const { return m_type == Type::Object; }
|
||||
bool is_boolean() const { return m_type == Type::Boolean; }
|
||||
bool is_cell() const { return is_string() || is_object(); }
|
||||
|
||||
explicit Value(bool value)
|
||||
: m_type(Type::Boolean)
|
||||
{
|
||||
m_value.as_bool = value;
|
||||
}
|
||||
|
||||
explicit Value(double value)
|
||||
: m_type(Type::Number)
|
||||
{
|
||||
m_value.as_double = value;
|
||||
}
|
||||
|
||||
explicit Value(i32 value)
|
||||
: m_type(Type::Number)
|
||||
{
|
||||
m_value.as_double = value;
|
||||
}
|
||||
|
||||
Value(Object* object)
|
||||
: m_type(Type::Object)
|
||||
{
|
||||
m_value.as_object = object;
|
||||
}
|
||||
|
||||
Value(PrimitiveString* string)
|
||||
: m_type(Type::String)
|
||||
{
|
||||
m_value.as_string = string;
|
||||
}
|
||||
|
||||
explicit Value(Type type)
|
||||
: m_type(type)
|
||||
{
|
||||
}
|
||||
|
||||
Type type() const { return m_type; }
|
||||
|
||||
double as_double() const
|
||||
{
|
||||
ASSERT(type() == Type::Number);
|
||||
return m_value.as_double;
|
||||
}
|
||||
|
||||
bool as_bool() const
|
||||
{
|
||||
ASSERT(type() == Type::Boolean);
|
||||
return m_value.as_bool;
|
||||
}
|
||||
|
||||
Object* as_object()
|
||||
{
|
||||
ASSERT(type() == Type::Object);
|
||||
return m_value.as_object;
|
||||
}
|
||||
|
||||
const Object* as_object() const
|
||||
{
|
||||
ASSERT(type() == Type::Object);
|
||||
return m_value.as_object;
|
||||
}
|
||||
|
||||
PrimitiveString* as_string()
|
||||
{
|
||||
ASSERT(is_string());
|
||||
return m_value.as_string;
|
||||
}
|
||||
|
||||
const PrimitiveString* as_string() const
|
||||
{
|
||||
ASSERT(is_string());
|
||||
return m_value.as_string;
|
||||
}
|
||||
|
||||
Cell* as_cell()
|
||||
{
|
||||
ASSERT(is_cell());
|
||||
return m_value.as_cell;
|
||||
}
|
||||
|
||||
String to_string() const;
|
||||
bool to_boolean() const;
|
||||
Value to_number() const;
|
||||
i32 to_i32() const;
|
||||
|
||||
Value to_object(Heap&) const;
|
||||
|
||||
private:
|
||||
Type m_type { Type::Undefined };
|
||||
|
||||
union {
|
||||
bool as_bool;
|
||||
double as_double;
|
||||
PrimitiveString* as_string;
|
||||
Object* as_object;
|
||||
Cell* as_cell;
|
||||
} m_value;
|
||||
};
|
||||
|
||||
inline Value js_undefined()
|
||||
{
|
||||
return Value(Value::Type::Undefined);
|
||||
}
|
||||
|
||||
inline Value js_null()
|
||||
{
|
||||
return Value(Value::Type::Null);
|
||||
}
|
||||
|
||||
Value greater_than(Value lhs, Value rhs);
|
||||
Value greater_than_equals(Value lhs, Value rhs);
|
||||
Value less_than(Value lhs, Value rhs);
|
||||
Value less_than_equals(Value lhs, Value rhs);
|
||||
Value bitwise_and(Value lhs, Value rhs);
|
||||
Value bitwise_or(Value lhs, Value rhs);
|
||||
Value bitwise_xor(Value lhs, Value rhs);
|
||||
Value bitwise_not(Value);
|
||||
Value left_shift(Value lhs, Value rhs);
|
||||
Value right_shift(Value lhs, Value rhs);
|
||||
Value add(Value lhs, Value rhs);
|
||||
Value sub(Value lhs, Value rhs);
|
||||
Value mul(Value lhs, Value rhs);
|
||||
Value div(Value lhs, Value rhs);
|
||||
Value eq(Value lhs, Value rhs);
|
||||
Value typed_eq(Value lhs, Value rhs);
|
||||
|
||||
const LogStream& operator<<(const LogStream&, const Value&);
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue