Port StringIteratorPrototypeNext to Torque
Bug: v8:8996 Change-Id: Ie4b17928fcb9d426bade5afc1238d24bc75ec13e Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1594275 Commit-Queue: Z Nguyen-Huu <duongn@microsoft.com> Reviewed-by: Simon Zünd <szuend@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Peter Wong <peter.wm.wong@gmail.com> Cr-Commit-Position: refs/heads/master@{#61252}
This commit is contained in:
parent
a542b735b4
commit
a1c23ec8ed
@ -532,11 +532,6 @@ extern class JSGlobalObject extends JSObject {
|
||||
global_proxy: JSGlobalProxy;
|
||||
}
|
||||
|
||||
extern class JSIteratorResult extends JSObject {
|
||||
value: Object;
|
||||
done: Boolean;
|
||||
}
|
||||
|
||||
extern class JSAsyncFromSyncIterator extends JSObject {
|
||||
sync_iterator: JSReceiver;
|
||||
next: Object;
|
||||
@ -619,6 +614,10 @@ type ToIntegerTruncationMode
|
||||
constexpr 'CodeStubAssembler::ToIntegerTruncationMode';
|
||||
type AllocationFlags constexpr 'AllocationFlags';
|
||||
|
||||
type UnicodeEncoding constexpr 'UnicodeEncoding';
|
||||
const UTF16:
|
||||
constexpr UnicodeEncoding generates 'UnicodeEncoding::UTF16';
|
||||
|
||||
extern class Foreign extends HeapObject { foreign_address: RawPtr; }
|
||||
|
||||
extern class InterceptorInfo extends Struct {
|
||||
@ -991,6 +990,22 @@ extern class JSRegExp extends JSObject {
|
||||
flags: Smi | Undefined;
|
||||
}
|
||||
|
||||
extern class JSIteratorResult extends JSObject {
|
||||
value: Object;
|
||||
done: Boolean;
|
||||
}
|
||||
|
||||
macro NewJSIteratorResult(implicit context: Context)(
|
||||
value: Object, done: Boolean): JSIteratorResult {
|
||||
return new JSIteratorResult{
|
||||
map: GetIteratorResultMap(),
|
||||
properties_or_hash: kEmptyFixedArray,
|
||||
elements: kEmptyFixedArray,
|
||||
value,
|
||||
done
|
||||
};
|
||||
}
|
||||
|
||||
// Note: Although a condition for a FastJSRegExp is having a positive smi
|
||||
// lastIndex (see RegExpBuiltinsAssembler::BranchIfFastRegExp), it is possible
|
||||
// for this to change without transitioning the transient type. As a precaution,
|
||||
@ -1185,6 +1200,8 @@ extern macro ThrowTypeError(implicit context: Context)(
|
||||
constexpr MessageTemplate, constexpr string): never;
|
||||
extern macro ThrowTypeError(implicit context: Context)(
|
||||
constexpr MessageTemplate, Object): never;
|
||||
extern macro ThrowTypeError(implicit context: Context)(
|
||||
constexpr MessageTemplate, Object, Object): never;
|
||||
extern macro ThrowTypeError(implicit context: Context)(
|
||||
constexpr MessageTemplate, Object, Object, Object): never;
|
||||
extern macro ArraySpeciesCreate(Context, Object, Number): JSReceiver;
|
||||
@ -1456,6 +1473,8 @@ extern macro HeapObjectToJSDataView(HeapObject): JSDataView
|
||||
labels CastError;
|
||||
extern macro HeapObjectToJSProxy(HeapObject): JSProxy
|
||||
labels CastError;
|
||||
extern macro HeapObjectToJSStringIterator(HeapObject): JSStringIterator
|
||||
labels CastError;
|
||||
extern macro HeapObjectToJSArrayBuffer(HeapObject): JSArrayBuffer
|
||||
labels CastError;
|
||||
extern macro TaggedToHeapObject(Object): HeapObject
|
||||
@ -1548,6 +1567,11 @@ Cast<JSProxy>(o: HeapObject): JSProxy
|
||||
return HeapObjectToJSProxy(o) otherwise CastError;
|
||||
}
|
||||
|
||||
Cast<JSStringIterator>(o: HeapObject): JSStringIterator
|
||||
labels CastError {
|
||||
return HeapObjectToJSStringIterator(o) otherwise CastError;
|
||||
}
|
||||
|
||||
Cast<JSTypedArray>(o: HeapObject): JSTypedArray
|
||||
labels CastError {
|
||||
if (IsJSTypedArray(o)) return %RawDownCast<JSTypedArray>(o);
|
||||
@ -2189,6 +2213,9 @@ macro GetProxyRevocableResultMap(implicit context: Context)(): Map {
|
||||
return UnsafeCast<Map>(
|
||||
LoadNativeContext(context)[PROXY_REVOCABLE_RESULT_MAP_INDEX]);
|
||||
}
|
||||
macro GetIteratorResultMap(implicit context: Context)(): Map {
|
||||
return UnsafeCast<Map>(LoadNativeContext(context)[ITERATOR_RESULT_MAP_INDEX]);
|
||||
}
|
||||
macro GetInitialStringIteratorMap(implicit context: Context)(): Map {
|
||||
return UnsafeCast<Map>(
|
||||
LoadNativeContext(context)[INITIAL_STRING_ITERATOR_MAP_INDEX]);
|
||||
|
@ -999,9 +999,6 @@ namespace internal {
|
||||
/* ES6 #sec-string.raw */ \
|
||||
CPP(StringRaw) \
|
||||
\
|
||||
/* StringIterator */ \
|
||||
/* ES6 #sec-%stringiteratorprototype%.next */ \
|
||||
TFJ(StringIteratorPrototypeNext, 0, kReceiver) \
|
||||
TFS(StringToList, kSource) \
|
||||
\
|
||||
/* Symbol */ \
|
||||
|
@ -2268,59 +2268,6 @@ TNode<Int32T> StringBuiltinsAssembler::LoadSurrogatePairAt(
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
// ES6 #sec-%stringiteratorprototype%.next
|
||||
TF_BUILTIN(StringIteratorPrototypeNext, StringBuiltinsAssembler) {
|
||||
VARIABLE(var_value, MachineRepresentation::kTagged);
|
||||
VARIABLE(var_done, MachineRepresentation::kTagged);
|
||||
|
||||
var_value.Bind(UndefinedConstant());
|
||||
var_done.Bind(TrueConstant());
|
||||
|
||||
Label throw_bad_receiver(this), next_codepoint(this), return_result(this);
|
||||
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
Node* iterator = Parameter(Descriptor::kReceiver);
|
||||
|
||||
GotoIf(TaggedIsSmi(iterator), &throw_bad_receiver);
|
||||
GotoIfNot(
|
||||
InstanceTypeEqual(LoadInstanceType(iterator), JS_STRING_ITERATOR_TYPE),
|
||||
&throw_bad_receiver);
|
||||
|
||||
Node* string = LoadObjectField(iterator, JSStringIterator::kStringOffset);
|
||||
TNode<IntPtrT> position = SmiUntag(
|
||||
CAST(LoadObjectField(iterator, JSStringIterator::kNextIndexOffset)));
|
||||
TNode<IntPtrT> length = LoadStringLengthAsWord(string);
|
||||
|
||||
Branch(IntPtrLessThan(position, length), &next_codepoint, &return_result);
|
||||
|
||||
BIND(&next_codepoint);
|
||||
{
|
||||
UnicodeEncoding encoding = UnicodeEncoding::UTF16;
|
||||
TNode<Int32T> ch = LoadSurrogatePairAt(string, length, position, encoding);
|
||||
TNode<String> value = StringFromSingleCodePoint(ch, encoding);
|
||||
var_value.Bind(value);
|
||||
TNode<IntPtrT> length = LoadStringLengthAsWord(value);
|
||||
StoreObjectFieldNoWriteBarrier(iterator, JSStringIterator::kNextIndexOffset,
|
||||
SmiTag(Signed(IntPtrAdd(position, length))));
|
||||
var_done.Bind(FalseConstant());
|
||||
Goto(&return_result);
|
||||
}
|
||||
|
||||
BIND(&return_result);
|
||||
{
|
||||
Node* result =
|
||||
AllocateJSIteratorResult(context, var_value.value(), var_done.value());
|
||||
Return(result);
|
||||
}
|
||||
|
||||
BIND(&throw_bad_receiver);
|
||||
{
|
||||
// The {receiver} is not a valid JSGeneratorObject.
|
||||
ThrowTypeError(context, MessageTemplate::kIncompatibleMethodReceiver,
|
||||
StringConstant("String Iterator.prototype.next"), iterator);
|
||||
}
|
||||
}
|
||||
|
||||
void StringBuiltinsAssembler::BranchIfStringPrimitiveWithNoCustomIteration(
|
||||
TNode<Object> object, TNode<Context> context, Label* if_true,
|
||||
Label* if_false) {
|
||||
|
@ -28,6 +28,11 @@ class StringBuiltinsAssembler : public CodeStubAssembler {
|
||||
Label* if_true,
|
||||
Label* if_false);
|
||||
|
||||
TNode<Int32T> LoadSurrogatePairAt(SloppyTNode<String> string,
|
||||
SloppyTNode<IntPtrT> length,
|
||||
SloppyTNode<IntPtrT> index,
|
||||
UnicodeEncoding encoding);
|
||||
|
||||
protected:
|
||||
TNode<JSArray> StringToList(TNode<Context> context, TNode<String> string);
|
||||
|
||||
@ -72,11 +77,6 @@ class StringBuiltinsAssembler : public CodeStubAssembler {
|
||||
TNode<Object> default_return,
|
||||
const StringAtAccessor& accessor);
|
||||
|
||||
TNode<Int32T> LoadSurrogatePairAt(SloppyTNode<String> string,
|
||||
SloppyTNode<IntPtrT> length,
|
||||
SloppyTNode<IntPtrT> index,
|
||||
UnicodeEncoding encoding);
|
||||
|
||||
void StringIndexOf(Node* const subject_string, Node* const search_string,
|
||||
Node* const position,
|
||||
const std::function<void(Node*)>& f_return);
|
||||
|
@ -42,9 +42,7 @@ namespace object {
|
||||
}
|
||||
label IfSlow {
|
||||
const result: JSObject = NewJSObject();
|
||||
const fastIteratorResultMap: Map =
|
||||
Cast<Map>(LoadNativeContext(context)[ITERATOR_RESULT_MAP_INDEX])
|
||||
otherwise unreachable;
|
||||
const fastIteratorResultMap: Map = GetIteratorResultMap();
|
||||
let i: iterator::IteratorRecord = iterator::GetIterator(iterable);
|
||||
try {
|
||||
assert(!IsNullOrUndefined(i.object));
|
||||
|
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include 'src/builtins/builtins-string-gen.h'
|
||||
|
||||
namespace string_iterator {
|
||||
|
||||
macro NewJSStringIterator(implicit context: Context)(
|
||||
@ -23,4 +25,29 @@ namespace string_iterator {
|
||||
const index: Smi = 0;
|
||||
return NewJSStringIterator(name, index);
|
||||
}
|
||||
|
||||
extern macro StringBuiltinsAssembler::LoadSurrogatePairAt(
|
||||
String, intptr, intptr, constexpr UnicodeEncoding): int32;
|
||||
extern macro StringFromSingleCodePoint(int32, constexpr UnicodeEncoding):
|
||||
String;
|
||||
|
||||
// ES6 #sec-%stringiteratorprototype%.next
|
||||
transitioning javascript builtin StringIteratorPrototypeNext(
|
||||
implicit context: Context)(receiver: Object): JSIteratorResult {
|
||||
const iterator = Cast<JSStringIterator>(receiver) otherwise ThrowTypeError(
|
||||
kIncompatibleMethodReceiver, 'String Iterator.prototype.next',
|
||||
receiver);
|
||||
const string = iterator.string;
|
||||
const position: intptr = SmiUntag(iterator.next_index);
|
||||
const length: intptr = string.length_intptr;
|
||||
if (position >= length) {
|
||||
return NewJSIteratorResult(Undefined, True);
|
||||
}
|
||||
// Move to next codepoint.
|
||||
const encoding = UTF16;
|
||||
const ch = LoadSurrogatePairAt(string, length, position, encoding);
|
||||
const value: String = StringFromSingleCodePoint(ch, encoding);
|
||||
iterator.next_index = SmiTag(position + value.length_intptr);
|
||||
return NewJSIteratorResult(value, False);
|
||||
}
|
||||
}
|
||||
|
@ -6208,6 +6208,11 @@ TNode<BoolT> CodeStubAssembler::IsJSProxy(SloppyTNode<HeapObject> object) {
|
||||
return HasInstanceType(object, JS_PROXY_TYPE);
|
||||
}
|
||||
|
||||
TNode<BoolT> CodeStubAssembler::IsJSStringIterator(
|
||||
SloppyTNode<HeapObject> object) {
|
||||
return HasInstanceType(object, JS_STRING_ITERATOR_TYPE);
|
||||
}
|
||||
|
||||
TNode<BoolT> CodeStubAssembler::IsJSGlobalProxy(
|
||||
SloppyTNode<HeapObject> object) {
|
||||
return HasInstanceType(object, JS_GLOBAL_PROXY_TYPE);
|
||||
|
@ -365,6 +365,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
return CAST(heap_object);
|
||||
}
|
||||
|
||||
TNode<JSStringIterator> HeapObjectToJSStringIterator(
|
||||
TNode<HeapObject> heap_object, Label* fail) {
|
||||
GotoIfNot(IsJSStringIterator(heap_object), fail);
|
||||
return CAST(heap_object);
|
||||
}
|
||||
|
||||
TNode<JSReceiver> HeapObjectToCallable(TNode<HeapObject> heap_object,
|
||||
Label* fail) {
|
||||
GotoIfNot(IsCallable(heap_object), fail);
|
||||
@ -2193,6 +2199,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
TNode<BoolT> IsJSPromiseMap(SloppyTNode<Map> map);
|
||||
TNode<BoolT> IsJSPromise(SloppyTNode<HeapObject> object);
|
||||
TNode<BoolT> IsJSProxy(SloppyTNode<HeapObject> object);
|
||||
TNode<BoolT> IsJSStringIterator(SloppyTNode<HeapObject> object);
|
||||
TNode<BoolT> IsJSReceiverInstanceType(SloppyTNode<Int32T> instance_type);
|
||||
TNode<BoolT> IsJSReceiverMap(SloppyTNode<Map> map);
|
||||
TNode<BoolT> IsJSReceiver(SloppyTNode<HeapObject> object);
|
||||
|
Loading…
Reference in New Issue
Block a user