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:
Z Duong Nguyen-Huu 2019-05-06 09:36:35 -07:00 committed by Commit Bot
parent a542b735b4
commit a1c23ec8ed
8 changed files with 77 additions and 69 deletions

View File

@ -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]);

View File

@ -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 */ \

View File

@ -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) {

View File

@ -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);

View File

@ -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));

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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);