From e33820b557c4370e631f03921b310621c441ab91 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Sun, 31 May 2020 00:47:28 +0100 Subject: [PATCH] LibJS: Add String.fromCharCode() --- Libraries/LibJS/Runtime/StringConstructor.cpp | 19 ++++++++++++++- Libraries/LibJS/Runtime/StringConstructor.h | 1 + Libraries/LibJS/Tests/String.fromCharCode.js | 23 +++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 Libraries/LibJS/Tests/String.fromCharCode.js diff --git a/Libraries/LibJS/Runtime/StringConstructor.cpp b/Libraries/LibJS/Runtime/StringConstructor.cpp index fd24023a74..314683eced 100644 --- a/Libraries/LibJS/Runtime/StringConstructor.cpp +++ b/Libraries/LibJS/Runtime/StringConstructor.cpp @@ -25,6 +25,7 @@ */ #include +#include #include #include #include @@ -40,7 +41,9 @@ StringConstructor::StringConstructor() define_property("prototype", interpreter().global_object().string_prototype(), 0); define_property("length", Value(1), Attribute::Configurable); - define_native_function("raw", raw, 0, Attribute::Writable | Attribute::Configurable); + u8 attr = Attribute::Writable | Attribute::Configurable; + define_native_function("raw", raw, 0, attr); + define_native_function("fromCharCode", from_char_code, 1, attr); } StringConstructor::~StringConstructor() @@ -106,4 +109,18 @@ Value StringConstructor::raw(Interpreter& interpreter) return js_string(interpreter, builder.build()); } +Value StringConstructor::from_char_code(Interpreter& interpreter) +{ + StringBuilder builder; + for (size_t i = 0; i < interpreter.argument_count(); ++i) { + auto char_code = interpreter.argument(i).to_i32(interpreter); + if (interpreter.exception()) + return {}; + auto truncated = char_code & 0xffff; + // FIXME: We need an Utf16View :^) + builder.append(Utf32View((u32*)&truncated, 1)); + } + return js_string(interpreter, builder.build()); +} + } diff --git a/Libraries/LibJS/Runtime/StringConstructor.h b/Libraries/LibJS/Runtime/StringConstructor.h index 7e33c08910..1cc6f8a089 100644 --- a/Libraries/LibJS/Runtime/StringConstructor.h +++ b/Libraries/LibJS/Runtime/StringConstructor.h @@ -43,6 +43,7 @@ private: virtual const char* class_name() const override { return "StringConstructor"; } static Value raw(Interpreter&); + static Value from_char_code(Interpreter&); }; } diff --git a/Libraries/LibJS/Tests/String.fromCharCode.js b/Libraries/LibJS/Tests/String.fromCharCode.js new file mode 100644 index 0000000000..3273209292 --- /dev/null +++ b/Libraries/LibJS/Tests/String.fromCharCode.js @@ -0,0 +1,23 @@ +load("test-common.js"); + +try { + assert(String.fromCharCode.length === 1); + + assert(String.fromCharCode() === ""); + assert(String.fromCharCode(0) === "\u0000"); + assert(String.fromCharCode(false) === "\u0000"); + assert(String.fromCharCode(null) === "\u0000"); + assert(String.fromCharCode(undefined) === "\u0000"); + assert(String.fromCharCode(1) === "\u0001"); + assert(String.fromCharCode(true) === "\u0001"); + assert(String.fromCharCode(-1) === "\uffff"); + assert(String.fromCharCode(0xffff) === "\uffff"); + assert(String.fromCharCode(0x123ffff) === "\uffff"); + assert(String.fromCharCode(65) === "A"); + assert(String.fromCharCode(65, 66, 67) === "ABC"); + assert(String.fromCharCode(228, 246, 252) === "äöü"); + + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +}