- Revision
- 270005
- Author
- [email protected]
- Date
- 2020-11-18 18:32:56 -0800 (Wed, 18 Nov 2020)
Log Message
[JSC] Reinstate String#at
https://bugs.webkit.org/show_bug.cgi?id=219124
Reviewed by Yusuke Suzuki.
JSTests:
* stress/at-method.js: Re-add tests.
* test262/config.yaml: Re-enable feature.
* test262/expectations.yaml:
"at/prop-desc.js" failures are due to a typo; will be fixed in https://github.com/tc39/test262/pull/2908.
Source/_javascript_Core:
At this week's TC39 meeting, consensus was achieved on renaming item() *and* keeping it for strings too.
Accordingly, this patch reinstates String.prototype.at behind the existing useAtMethod runtime option.
* builtins/StringPrototype.js:
(at):
* runtime/StringPrototype.cpp:
(JSC::StringPrototype::finishCreation):
Modified Paths
Diff
Modified: trunk/JSTests/ChangeLog (270004 => 270005)
--- trunk/JSTests/ChangeLog 2020-11-19 01:42:45 UTC (rev 270004)
+++ trunk/JSTests/ChangeLog 2020-11-19 02:32:56 UTC (rev 270005)
@@ -1,3 +1,15 @@
+2020-11-18 Ross Kirsling <[email protected]>
+
+ [JSC] Reinstate String#at
+ https://bugs.webkit.org/show_bug.cgi?id=219124
+
+ Reviewed by Yusuke Suzuki.
+
+ * stress/at-method.js: Re-add tests.
+ * test262/config.yaml: Re-enable feature.
+ * test262/expectations.yaml:
+ "at/prop-desc.js" failures are due to a typo; will be fixed in https://github.com/tc39/test262/pull/2908.
+
2020-11-17 Yusuke Suzuki <[email protected]>
[JSC] Improve Wasm binary test coverage
Modified: trunk/JSTests/stress/at-method.js (270004 => 270005)
--- trunk/JSTests/stress/at-method.js 2020-11-19 01:42:45 UTC (rev 270004)
+++ trunk/JSTests/stress/at-method.js 2020-11-19 02:32:56 UTC (rev 270005)
@@ -49,3 +49,21 @@
shouldBe(ta.at(null), ta[0]);
shouldBe(ta.at({ valueOf: () => -1 }), ta[ta.length - 1]);
}
+
+shouldBe(String.prototype.at.length, 1);
+shouldThrowTypeError(() => String.prototype.at.call(undefined));
+shouldThrowTypeError(() => String.prototype.at.call(null));
+
+const string = 'abc';
+// intentionally go one too far to ensure that we get undefined instead of wrapping
+for (let i = 0; i <= string.length; i++) {
+ shouldBe(string.at(i), string[i]);
+ shouldBe(string.at(-i - 1), string[string.length - i - 1]);
+}
+shouldBe(string.at(), string[0]);
+shouldBe(string.at(null), string[0]);
+shouldBe(string.at({ valueOf: () => -1 }), string[string.length - 1]);
+
+const emojiPseudoString = { toString: () => '😅' };
+shouldBe(String.prototype.at.call(emojiPseudoString, 0), '\u{d83d}');
+shouldBe(String.prototype.at.call(emojiPseudoString, -1), '\u{de05}');
Modified: trunk/JSTests/test262/config.yaml (270004 => 270005)
--- trunk/JSTests/test262/config.yaml 2020-11-19 01:42:45 UTC (rev 270004)
+++ trunk/JSTests/test262/config.yaml 2020-11-19 02:32:56 UTC (rev 270005)
@@ -10,6 +10,7 @@
Atomics: useSharedArrayBuffer
Array.prototype.at: useAtMethod
TypedArray.prototype.at: useAtMethod
+ String.prototype.at: useAtMethod
skip:
features:
- Atomics.waitAsync
@@ -27,8 +28,6 @@
- regexp-match-indices
- top-level-await
- Intl.ListFormat
-
- - String.prototype.at
paths:
- test/built-ins/DataView/prototype/getBigInt64
- test/built-ins/DataView/prototype/getBigUint64
Modified: trunk/JSTests/test262/expectations.yaml (270004 => 270005)
--- trunk/JSTests/test262/expectations.yaml 2020-11-19 01:42:45 UTC (rev 270004)
+++ trunk/JSTests/test262/expectations.yaml 2020-11-19 02:32:56 UTC (rev 270005)
@@ -823,6 +823,9 @@
test/built-ins/RegExp/quantifier-integer-limit.js:
default: 'SyntaxError: Invalid regular _expression_: number too large in {} quantifier'
strict mode: 'SyntaxError: Invalid regular _expression_: number too large in {} quantifier'
+test/built-ins/String/prototype/at/prop-desc.js:
+ default: 'Test262Error: descriptor should be writable'
+ strict mode: 'Test262Error: descriptor should be writable'
test/built-ins/TypedArray/prototype/at/prop-desc.js:
default: 'Test262Error: descriptor should be writable'
strict mode: 'Test262Error: descriptor should be writable'
Modified: trunk/Source/_javascript_Core/ChangeLog (270004 => 270005)
--- trunk/Source/_javascript_Core/ChangeLog 2020-11-19 01:42:45 UTC (rev 270004)
+++ trunk/Source/_javascript_Core/ChangeLog 2020-11-19 02:32:56 UTC (rev 270005)
@@ -1,3 +1,18 @@
+2020-11-18 Ross Kirsling <[email protected]>
+
+ [JSC] Reinstate String#at
+ https://bugs.webkit.org/show_bug.cgi?id=219124
+
+ Reviewed by Yusuke Suzuki.
+
+ At this week's TC39 meeting, consensus was achieved on renaming item() *and* keeping it for strings too.
+ Accordingly, this patch reinstates String.prototype.at behind the existing useAtMethod runtime option.
+
+ * builtins/StringPrototype.js:
+ (at):
+ * runtime/StringPrototype.cpp:
+ (JSC::StringPrototype::finishCreation):
+
2020-11-17 Yusuke Suzuki <[email protected]>
[JSC] Improve Wasm binary test coverage
Modified: trunk/Source/_javascript_Core/builtins/StringPrototype.js (270004 => 270005)
--- trunk/Source/_javascript_Core/builtins/StringPrototype.js 2020-11-19 01:42:45 UTC (rev 270004)
+++ trunk/Source/_javascript_Core/builtins/StringPrototype.js 2020-11-19 02:32:56 UTC (rev 270005)
@@ -340,6 +340,25 @@
return @tailCallForwardArguments(@stringConcatSlowPath, this);
}
+// FIXME: This is extremely similar to charAt, so we should optimize it accordingly.
+// https://bugs.webkit.org/show_bug.cgi?id=217139
+function at(index)
+{
+ "use strict";
+
+ if (@isUndefinedOrNull(this))
+ @throwTypeError("String.prototype.at requires that |this| not be null or undefined");
+
+ var string = @toString(this);
+ var length = string.length;
+
+ var k = @toInteger(index);
+ if (k < 0)
+ k += length;
+
+ return (k >= 0 && k < length) ? string[k] : @undefined;
+}
+
@globalPrivate
function createHTML(func, string, tag, attribute, value)
{
Modified: trunk/Source/_javascript_Core/runtime/StringPrototype.cpp (270004 => 270005)
--- trunk/Source/_javascript_Core/runtime/StringPrototype.cpp 2020-11-19 01:42:45 UTC (rev 270004)
+++ trunk/Source/_javascript_Core/runtime/StringPrototype.cpp 2020-11-19 02:32:56 UTC (rev 270005)
@@ -151,6 +151,9 @@
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("normalize", stringProtoFuncNormalize, static_cast<unsigned>(PropertyAttribute::DontEnum), 0);
JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().charCodeAtPrivateName(), stringProtoFuncCharCodeAt, static_cast<unsigned>(PropertyAttribute::DontEnum), 1, CharCodeAtIntrinsic);
+ if (Options::useAtMethod())
+ JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().atPublicName(), stringPrototypeAtCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum));
+
JSFunction* trimStartFunction = JSFunction::create(vm, globalObject, 0, "trimStart"_s, stringProtoFuncTrimStart, NoIntrinsic);
JSFunction* trimEndFunction = JSFunction::create(vm, globalObject, 0, "trimEnd"_s, stringProtoFuncTrimEnd, NoIntrinsic);
putDirectWithoutTransition(vm, Identifier::fromString(vm, "trimStart"), trimStartFunction, static_cast<unsigned>(PropertyAttribute::DontEnum));