From 2c5b9fb8f96a8601f1ea28ef58c720108e052dbd Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 15 Mar 2020 15:02:49 +0100 Subject: [PATCH] LibJS: Add StringPrototype and make it the prototype of StringObject This patch adds String.prototype.charAt() to demonstrate that prototype property lookup works, and that you can call a prototype function on an object, and it will do what you expect. :^) --- Base/home/anon/js/charAt.js | 2 + Libraries/LibJS/Makefile | 1 + Libraries/LibJS/StringObject.cpp | 3 ++ Libraries/LibJS/StringObject.h | 4 ++ Libraries/LibJS/StringPrototype.cpp | 57 +++++++++++++++++++++++++++++ Libraries/LibJS/StringPrototype.h | 42 +++++++++++++++++++++ 6 files changed, 109 insertions(+) create mode 100644 Base/home/anon/js/charAt.js create mode 100644 Libraries/LibJS/StringPrototype.cpp create mode 100644 Libraries/LibJS/StringPrototype.h diff --git a/Base/home/anon/js/charAt.js b/Base/home/anon/js/charAt.js new file mode 100644 index 0000000000..610305e6ce --- /dev/null +++ b/Base/home/anon/js/charAt.js @@ -0,0 +1,2 @@ +var foo = "foobar"; +print(foo.charAt(3)); diff --git a/Libraries/LibJS/Makefile b/Libraries/LibJS/Makefile index 4bdd216e00..f32336e837 100644 --- a/Libraries/LibJS/Makefile +++ b/Libraries/LibJS/Makefile @@ -13,6 +13,7 @@ OBJS = \ PrimitiveString.o \ ScriptFunction.o \ StringObject.o \ + StringPrototype.o \ Token.o \ Value.o diff --git a/Libraries/LibJS/StringObject.cpp b/Libraries/LibJS/StringObject.cpp index f8b14d1d8b..fbb1ec32f3 100644 --- a/Libraries/LibJS/StringObject.cpp +++ b/Libraries/LibJS/StringObject.cpp @@ -24,8 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include +#include #include namespace JS { @@ -33,6 +35,7 @@ namespace JS { StringObject::StringObject(PrimitiveString* string) : m_string(string) { + set_prototype(heap().allocate()); put("length", Value(static_cast(m_string->string().length()))); } diff --git a/Libraries/LibJS/StringObject.h b/Libraries/LibJS/StringObject.h index 3a9ccfc990..cfeddfb57a 100644 --- a/Libraries/LibJS/StringObject.h +++ b/Libraries/LibJS/StringObject.h @@ -37,8 +37,12 @@ public: virtual void visit_children(Visitor&) override; + const PrimitiveString* primitive_string() const { return 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 }; }; diff --git a/Libraries/LibJS/StringPrototype.cpp b/Libraries/LibJS/StringPrototype.cpp new file mode 100644 index 0000000000..3d1f50ede6 --- /dev/null +++ b/Libraries/LibJS/StringPrototype.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020, Andreas Kling + * 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 +#include +#include +#include +#include +#include +#include + +namespace JS { + +StringPrototype::StringPrototype() +{ + put_native_function("charAt", [](Interpreter& interpreter, Vector arguments) -> Value { + i32 index = 0; + if (!arguments.is_empty()) + index = arguments[0].to_i32(); + Value this_value = interpreter.this_value(); + ASSERT(this_value.is_object()); + ASSERT(this_value.as_object()->is_string_object()); + auto underlying_string = static_cast(this_value.as_object())->primitive_string()->string(); + if (index < 0 || index >= static_cast(underlying_string.length())) + return js_string(interpreter.heap(), String::empty()); + return js_string(interpreter.heap(), underlying_string.substring(index, 1)); + }); +} + +StringPrototype::~StringPrototype() +{ +} + +} diff --git a/Libraries/LibJS/StringPrototype.h b/Libraries/LibJS/StringPrototype.h new file mode 100644 index 0000000000..1d87dbb866 --- /dev/null +++ b/Libraries/LibJS/StringPrototype.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020, Andreas Kling + * 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 + +namespace JS { + +class StringPrototype final : public Object { +public: + StringPrototype(); + virtual ~StringPrototype() override; + +private: + virtual const char* class_name() const override { return "StringPrototype"; } +}; + +}