diff options
Diffstat (limited to 'deps/v8/src/builtins/builtins-string.tq')
-rw-r--r-- | deps/v8/src/builtins/builtins-string.tq | 385 |
1 files changed, 189 insertions, 196 deletions
diff --git a/deps/v8/src/builtins/builtins-string.tq b/deps/v8/src/builtins/builtins-string.tq index 61cd984e7f4..a4edc94418c 100644 --- a/deps/v8/src/builtins/builtins-string.tq +++ b/deps/v8/src/builtins/builtins-string.tq @@ -5,222 +5,215 @@ #include 'src/builtins/builtins-string-gen.h' namespace string { - extern macro StringBuiltinsAssembler::SubString(String, uintptr, uintptr): - String; - - // ES6 #sec-string.prototype.tostring - transitioning javascript builtin - StringPrototypeToString( - js-implicit context: NativeContext, receiver: JSAny)(): JSAny { - return ToThisValue( - receiver, PrimitiveType::kString, 'String.prototype.toString'); - } - - // ES6 #sec-string.prototype.valueof - transitioning javascript builtin - StringPrototypeValueOf(js-implicit context: NativeContext, receiver: JSAny)(): - JSAny { - return ToThisValue( - receiver, PrimitiveType::kString, 'String.prototype.valueOf'); - } +extern macro StringBuiltinsAssembler::SubString( + String, uintptr, uintptr): String; + +// ES6 #sec-string.prototype.tostring +transitioning javascript builtin +StringPrototypeToString( + js-implicit context: NativeContext, receiver: JSAny)(): JSAny { + return ToThisValue( + receiver, PrimitiveType::kString, 'String.prototype.toString'); +} - extern macro StringBuiltinsAssembler::LoadSurrogatePairAt( - String, intptr, intptr, constexpr UnicodeEncoding): int32; - extern macro StringBuiltinsAssembler::StringFromSingleUTF16EncodedCodePoint( - int32): String; - - // This function assumes StringPrimitiveWithNoCustomIteration is true. - transitioning builtin StringToList(implicit context: Context)(string: String): - JSArray { - const kind = ElementsKind::PACKED_ELEMENTS; - const stringLength: intptr = string.length_intptr; - - const nativeContext = LoadNativeContext(context); - const map: Map = LoadJSArrayElementsMap(kind, nativeContext); - const array: JSArray = AllocateJSArray( - kind, map, stringLength, SmiTag(stringLength), - AllocationFlag::kAllowLargeObjectAllocation); - const elements = UnsafeCast<FixedArray>(array.elements); - const encoding = UnicodeEncoding::UTF16; - let arrayLength: Smi = 0; - let i: intptr = 0; - while (i < stringLength) { - const ch: int32 = LoadSurrogatePairAt(string, stringLength, i, encoding); - const value: String = StringFromSingleUTF16EncodedCodePoint(ch); - elements[arrayLength] = value; - // Increment and continue the loop. - i = i + value.length_intptr; - arrayLength++; - } - assert(arrayLength >= 0); - assert(SmiTag(stringLength) >= arrayLength); - array.length = arrayLength; +// ES6 #sec-string.prototype.valueof +transitioning javascript builtin +StringPrototypeValueOf( + js-implicit context: NativeContext, receiver: JSAny)(): JSAny { + return ToThisValue( + receiver, PrimitiveType::kString, 'String.prototype.valueOf'); +} - return array; +extern macro StringBuiltinsAssembler::LoadSurrogatePairAt( + String, intptr, intptr, constexpr UnicodeEncoding): int32; +extern macro StringBuiltinsAssembler::StringFromSingleUTF16EncodedCodePoint( + int32): String; + +// This function assumes StringPrimitiveWithNoCustomIteration is true. +transitioning builtin StringToList(implicit context: Context)(string: String): + JSArray { + const kind = ElementsKind::PACKED_ELEMENTS; + const stringLength: intptr = string.length_intptr; + + const nativeContext = LoadNativeContext(context); + const map: Map = LoadJSArrayElementsMap(kind, nativeContext); + const array: JSArray = AllocateJSArray( + kind, map, stringLength, SmiTag(stringLength), + AllocationFlag::kAllowLargeObjectAllocation); + const elements = UnsafeCast<FixedArray>(array.elements); + const encoding = UnicodeEncoding::UTF16; + let arrayLength: Smi = 0; + let i: intptr = 0; + while (i < stringLength) { + const ch: int32 = LoadSurrogatePairAt(string, stringLength, i, encoding); + const value: String = StringFromSingleUTF16EncodedCodePoint(ch); + elements[arrayLength] = value; + // Increment and continue the loop. + i = i + value.length_intptr; + arrayLength++; } + assert(arrayLength >= 0); + assert(SmiTag(stringLength) >= arrayLength); + array.length = arrayLength; - transitioning macro GenerateStringAt(implicit context: Context)( - receiver: JSAny, position: JSAny, - methodName: constexpr string): never labels - IfInBounds(String, uintptr, uintptr), IfOutOfBounds { - // 1. Let O be ? RequireObjectCoercible(this value). - // 2. Let S be ? ToString(O). - const string: String = ToThisString(receiver, methodName); - - // 3. Let position be ? ToInteger(pos). - const indexNumber: Number = ToInteger_Inline(position); - - // Convert the {position} to a uintptr and check that it's in bounds of - // the {string}. - typeswitch (indexNumber) { - case (indexSmi: Smi): { - const length: uintptr = string.length_uintptr; - const index: uintptr = Unsigned(Convert<intptr>(indexSmi)); - // Max string length fits Smi range, so we can do an unsigned bounds - // check. - const kMaxStringLengthFitsSmi: constexpr bool = - kStringMaxLengthUintptr < kSmiMaxValue; - StaticAssert(kMaxStringLengthFitsSmi); - if (index >= length) goto IfOutOfBounds; - goto IfInBounds(string, index, length); - } - case (indexHeapNumber: HeapNumber): { - assert(IsNumberNormalized(indexHeapNumber)); - // Valid string indices fit into Smi range, so HeapNumber index is - // definitely an out of bounds case. - goto IfOutOfBounds; - } - } - } + return array; +} - // ES6 #sec-string.prototype.charat - transitioning javascript builtin StringPrototypeCharAt( - js-implicit context: NativeContext, - receiver: JSAny)(position: JSAny): JSAny { - try { - GenerateStringAt(receiver, position, 'String.prototype.charAt') - otherwise IfInBounds, IfOutOfBounds; - } - label IfInBounds(string: String, index: uintptr, _length: uintptr) { - const code: int32 = StringCharCodeAt(string, index); - return StringFromSingleCharCode(code); +transitioning macro GenerateStringAt(implicit context: Context)( + receiver: JSAny, position: JSAny, + methodName: constexpr string): never labels +IfInBounds(String, uintptr, uintptr), IfOutOfBounds { + // 1. Let O be ? RequireObjectCoercible(this value). + // 2. Let S be ? ToString(O). + const string: String = ToThisString(receiver, methodName); + + // 3. Let position be ? ToInteger(pos). + const indexNumber: Number = ToInteger_Inline(position); + + // Convert the {position} to a uintptr and check that it's in bounds of + // the {string}. + typeswitch (indexNumber) { + case (indexSmi: Smi): { + const length: uintptr = string.length_uintptr; + const index: uintptr = Unsigned(Convert<intptr>(indexSmi)); + // Max string length fits Smi range, so we can do an unsigned bounds + // check. + const kMaxStringLengthFitsSmi: constexpr bool = + kStringMaxLengthUintptr < kSmiMaxValue; + StaticAssert(kMaxStringLengthFitsSmi); + if (index >= length) goto IfOutOfBounds; + goto IfInBounds(string, index, length); } - label IfOutOfBounds { - return kEmptyString; + case (indexHeapNumber: HeapNumber): { + assert(IsNumberNormalized(indexHeapNumber)); + // Valid string indices fit into Smi range, so HeapNumber index is + // definitely an out of bounds case. + goto IfOutOfBounds; } } +} - // ES6 #sec-string.prototype.charcodeat - transitioning javascript builtin StringPrototypeCharCodeAt( - js-implicit context: NativeContext, - receiver: JSAny)(position: JSAny): JSAny { - try { - GenerateStringAt(receiver, position, 'String.prototype.charCodeAt') - otherwise IfInBounds, IfOutOfBounds; - } - label IfInBounds(string: String, index: uintptr, _length: uintptr) { - const code: int32 = StringCharCodeAt(string, index); - return Convert<Smi>(code); - } - label IfOutOfBounds { - return kNaN; - } +// ES6 #sec-string.prototype.charat +transitioning javascript builtin StringPrototypeCharAt( + js-implicit context: NativeContext, + receiver: JSAny)(position: JSAny): JSAny { + try { + GenerateStringAt(receiver, position, 'String.prototype.charAt') + otherwise IfInBounds, IfOutOfBounds; + } label IfInBounds(string: String, index: uintptr, _length: uintptr) { + const code: int32 = StringCharCodeAt(string, index); + return StringFromSingleCharCode(code); + } label IfOutOfBounds { + return kEmptyString; } +} - // ES6 #sec-string.prototype.codepointat - transitioning javascript builtin StringPrototypeCodePointAt( - js-implicit context: NativeContext, - receiver: JSAny)(position: JSAny): JSAny { - try { - GenerateStringAt(receiver, position, 'String.prototype.codePointAt') - otherwise IfInBounds, IfOutOfBounds; - } - label IfInBounds(string: String, index: uintptr, length: uintptr) { - // This is always a call to a builtin from Javascript, so we need to - // produce UTF32. - const code: int32 = LoadSurrogatePairAt( - string, Signed(length), Signed(index), UnicodeEncoding::UTF32); - return Convert<Smi>(code); - } - label IfOutOfBounds { - return Undefined; - } +// ES6 #sec-string.prototype.charcodeat +transitioning javascript builtin StringPrototypeCharCodeAt( + js-implicit context: NativeContext, + receiver: JSAny)(position: JSAny): JSAny { + try { + GenerateStringAt(receiver, position, 'String.prototype.charCodeAt') + otherwise IfInBounds, IfOutOfBounds; + } label IfInBounds(string: String, index: uintptr, _length: uintptr) { + const code: int32 = StringCharCodeAt(string, index); + return Convert<Smi>(code); + } label IfOutOfBounds { + return kNaN; } +} - // ES6 String.prototype.concat(...args) - // ES6 #sec-string.prototype.concat - transitioning javascript builtin StringPrototypeConcat( - js-implicit context: NativeContext, - receiver: JSAny)(...arguments): JSAny { - // Check that {receiver} is coercible to Object and convert it to a String. - let string: String = ToThisString(receiver, 'String.prototype.concat'); - - // Concatenate all the arguments passed to this builtin. - const length: intptr = Convert<intptr>(arguments.length); - for (let i: intptr = 0; i < length; i++) { - const temp: String = ToString_Inline(arguments[i]); - string = string + temp; - } - return string; +// ES6 #sec-string.prototype.codepointat +transitioning javascript builtin StringPrototypeCodePointAt( + js-implicit context: NativeContext, + receiver: JSAny)(position: JSAny): JSAny { + try { + GenerateStringAt(receiver, position, 'String.prototype.codePointAt') + otherwise IfInBounds, IfOutOfBounds; + } label IfInBounds(string: String, index: uintptr, length: uintptr) { + // This is always a call to a builtin from Javascript, so we need to + // produce UTF32. + const code: int32 = LoadSurrogatePairAt( + string, Signed(length), Signed(index), UnicodeEncoding::UTF32); + return Convert<Smi>(code); + } label IfOutOfBounds { + return Undefined; + } +} + +// ES6 String.prototype.concat(...args) +// ES6 #sec-string.prototype.concat +transitioning javascript builtin StringPrototypeConcat( + js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny { + // Check that {receiver} is coercible to Object and convert it to a String. + let string: String = ToThisString(receiver, 'String.prototype.concat'); + + // Concatenate all the arguments passed to this builtin. + const length: intptr = Convert<intptr>(arguments.length); + for (let i: intptr = 0; i < length; i++) { + const temp: String = ToString_Inline(arguments[i]); + string = string + temp; } + return string; +} - extern transitioning runtime - SymbolDescriptiveString(implicit context: Context)(Symbol): String; - - // ES #sec-string-constructor - // https://tc39.github.io/ecma262/#sec-string-constructor - transitioning javascript builtin StringConstructor( - js-implicit context: NativeContext, receiver: JSAny, newTarget: JSAny, - target: JSFunction)(...arguments): JSAny { - const length: intptr = Convert<intptr>(arguments.length); - let s: String; - // 1. If no arguments were passed to this function invocation, let s be "". - if (length == 0) { - s = EmptyStringConstant(); - } else { - // 2. Else, - // 2. a. If NewTarget is undefined and Type(value) is Symbol, return - // SymbolDescriptiveString(value). - if (newTarget == Undefined) { - typeswitch (arguments[0]) { - case (value: Symbol): { - return SymbolDescriptiveString(value); - } - case (JSAny): { - } +extern transitioning runtime +SymbolDescriptiveString(implicit context: Context)(Symbol): String; + +// ES #sec-string-constructor +// https://tc39.github.io/ecma262/#sec-string-constructor +transitioning javascript builtin StringConstructor( + js-implicit context: NativeContext, receiver: JSAny, newTarget: JSAny, + target: JSFunction)(...arguments): JSAny { + const length: intptr = Convert<intptr>(arguments.length); + let s: String; + // 1. If no arguments were passed to this function invocation, let s be "". + if (length == 0) { + s = EmptyStringConstant(); + } else { + // 2. Else, + // 2. a. If NewTarget is undefined and Type(value) is Symbol, return + // SymbolDescriptiveString(value). + if (newTarget == Undefined) { + typeswitch (arguments[0]) { + case (value: Symbol): { + return SymbolDescriptiveString(value); + } + case (JSAny): { } } - // 2. b. Let s be ? ToString(value). - s = ToString_Inline(arguments[0]); - } - // 3. If NewTarget is undefined, return s. - if (newTarget == Undefined) { - return s; } - // 4. Return ! StringCreate(s, ? GetPrototypeFromConstructor(NewTarget, - // "%String.prototype%")). - const map = GetDerivedMap(target, UnsafeCast<JSReceiver>(newTarget)); - const obj = - UnsafeCast<JSPrimitiveWrapper>(AllocateFastOrSlowJSObjectFromMap(map)); - obj.value = s; - return obj; + // 2. b. Let s be ? ToString(value). + s = ToString_Inline(arguments[0]); } - - transitioning builtin StringAddConvertLeft(implicit context: Context)( - left: JSAny, right: String): String { - return ToStringImpl(context, ToPrimitiveDefault(left)) + right; + // 3. If NewTarget is undefined, return s. + if (newTarget == Undefined) { + return s; } + // 4. Return ! StringCreate(s, ? GetPrototypeFromConstructor(NewTarget, + // "%String.prototype%")). + const map = GetDerivedMap(target, UnsafeCast<JSReceiver>(newTarget)); + const obj = + UnsafeCast<JSPrimitiveWrapper>(AllocateFastOrSlowJSObjectFromMap(map)); + obj.value = s; + return obj; +} - transitioning builtin StringAddConvertRight(implicit context: Context)( - left: String, right: JSAny): String { - return left + ToStringImpl(context, ToPrimitiveDefault(right)); - } +transitioning builtin StringAddConvertLeft(implicit context: Context)( + left: JSAny, right: String): String { + return ToStringImpl(context, ToPrimitiveDefault(left)) + right; +} - builtin StringCharAt(implicit context: Context)( - receiver: String, position: uintptr): String { - // Load the character code at the {position} from the {receiver}. - const code: int32 = StringCharCodeAt(receiver, position); - // And return the single character string with only that {code} - return StringFromSingleCharCode(code); - } +transitioning builtin StringAddConvertRight(implicit context: Context)( + left: String, right: JSAny): String { + return left + ToStringImpl(context, ToPrimitiveDefault(right)); +} + +builtin StringCharAt(implicit context: Context)( + receiver: String, position: uintptr): String { + // Load the character code at the {position} from the {receiver}. + const code: int32 = StringCharCodeAt(receiver, position); + // And return the single character string with only that {code} + return StringFromSingleCharCode(code); +} } |