From e0d7d3c3d5ae33093c17bc1186300714681a48ab Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 6 Aug 2022 00:48:22 +0200 Subject: [PATCH] LibJS: Teach String.prototype.concat() to create rope strings Defer serialization of the concatenated strings until later. This is used heavily in SunSpider's string-validate-input subtest, which sees a small progression. --- .../LibJS/Runtime/StringPrototype.cpp | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp index 03709565cec..61f598f8837 100644 --- a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp @@ -525,14 +525,26 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::trim_end) // 22.1.3.5 String.prototype.concat ( ...args ), https://tc39.es/ecma262/#sec-string.prototype.concat JS_DEFINE_NATIVE_FUNCTION(StringPrototype::concat) { - auto string = TRY(ak_string_from(vm, global_object)); - StringBuilder builder; - builder.append(string); + // 1. Let O be ? RequireObjectCoercible(this value). + auto object = TRY(require_object_coercible(global_object, vm.this_value(global_object))); + + // 2. Let S be ? ToString(O). + auto* string = TRY(object.to_primitive_string(global_object)); + + // 3. Let R be S. + auto* result = string; + + // 4. For each element next of args, do for (size_t i = 0; i < vm.argument_count(); ++i) { - auto string_argument = TRY(vm.argument(i).to_string(global_object)); - builder.append(string_argument); + // a. Let nextString be ? ToString(next). + auto* next_string = TRY(vm.argument(i).to_primitive_string(global_object)); + + // b. Set R to the string-concatenation of R and nextString. + result = js_rope_string(vm, *result, *next_string); } - return js_string(vm, builder.to_string()); + + // 5. Return R. + return result; } // 22.1.3.24 String.prototype.substring ( start, end ), https://tc39.es/ecma262/#sec-string.prototype.substring