#ifndef V8_BUILTINS_BUILTINS_STRING_GEN_H_
#define V8_BUILTINS_BUILTINS_STRING_GEN_H_
#include "src/codegen/code-stub-assembler.h"
#include "src/objects/string.h"
namespace v8 {
namespace internal {
class StringBuiltinsAssembler : public CodeStubAssembler {
public:
explicit StringBuiltinsAssembler(compiler::CodeAssemblerState* state)
: CodeStubAssembler(state) {}
TNode<String> GetSubstitution(TNode<Context> context,
TNode<String> subject_string,
TNode<Smi> match_start_index,
TNode<Smi> match_end_index,
TNode<String> replace_string);
void StringEqual_Core(TNode<String> lhs, TNode<Word32T> lhs_instance_type,
TNode<String> rhs, TNode<Word32T> rhs_instance_type,
TNode<IntPtrT> length, Label* if_equal,
Label* if_not_equal, Label* if_indirect);
void BranchIfStringPrimitiveWithNoCustomIteration(TNode<Object> object,
TNode<Context> context,
Label* if_true,
Label* if_false);
TNode<Int32T> LoadSurrogatePairAt(TNode<String> string, TNode<IntPtrT> length,
TNode<IntPtrT> index,
UnicodeEncoding encoding);
TNode<BoolT> HasUnpairedSurrogate(TNode<String> string, Label* if_indirect);
void ReplaceUnpairedSurrogates(TNode<String> source, TNode<String> dest,
Label* if_indirect);
TNode<String> StringFromSingleUTF16EncodedCodePoint(TNode<Int32T> codepoint);
TNode<String> SubString(TNode<String> string, TNode<IntPtrT> from,
TNode<IntPtrT> to);
TNode<String> SubString(TNode<String> string, TNode<UintPtrT> from,
TNode<UintPtrT> to) {
return SubString(string, Signed(from), Signed(to));
}
template <typename T>
void CopyStringCharacters(TNode<T> from_string, TNode<String> to_string,
TNode<IntPtrT> from_index, TNode<IntPtrT> to_index,
TNode<IntPtrT> character_count,
String::Encoding from_encoding,
String::Encoding to_encoding);
TNode<IntPtrT> SearchOneByteStringInTwoByteString(
const TNode<RawPtrT> subject_ptr, const TNode<IntPtrT> subject_length,
const TNode<RawPtrT> search_ptr, const TNode<IntPtrT> search_length,
const TNode<IntPtrT> start_position);
TNode<IntPtrT> SearchOneByteStringInOneByteString(
const TNode<RawPtrT> subject_ptr, const TNode<IntPtrT> subject_length,
const TNode<RawPtrT> search_ptr, const TNode<IntPtrT> search_length,
const TNode<IntPtrT> start_position);
TNode<IntPtrT> SearchTwoByteStringInTwoByteString(
const TNode<RawPtrT> subject_ptr, const TNode<IntPtrT> subject_length,
const TNode<RawPtrT> search_ptr, const TNode<IntPtrT> search_length,
const TNode<IntPtrT> start_position);
TNode<IntPtrT> SearchTwoByteStringInOneByteString(
const TNode<RawPtrT> subject_ptr, const TNode<IntPtrT> subject_length,
const TNode<RawPtrT> search_ptr, const TNode<IntPtrT> search_length,
const TNode<IntPtrT> start_position);
TNode<IntPtrT> SearchOneByteInOneByteString(
const TNode<RawPtrT> subject_ptr, const TNode<IntPtrT> subject_length,
const TNode<RawPtrT> search_ptr, const TNode<IntPtrT> start_position);
TNode<Smi> IndexOfDollarChar(const TNode<Context> context,
const TNode<String> string);
protected:
enum class StringComparison {
kLessThan,
kLessThanOrEqual,
kGreaterThan,
kGreaterThanOrEqual,
kCompare
};
void StringEqual_FastLoop(TNode<String> lhs, TNode<Word32T> lhs_instance_type,
TNode<String> rhs, TNode<Word32T> rhs_instance_type,
TNode<IntPtrT> byte_length, Label* if_equal,
Label* if_not_equal);
void StringEqual_Loop(TNode<String> lhs, TNode<Word32T> lhs_instance_type,
MachineType lhs_type, TNode<String> rhs,
TNode<Word32T> rhs_instance_type, MachineType rhs_type,
TNode<IntPtrT> length, Label* if_equal,
Label* if_not_equal);
TNode<RawPtrT> DirectStringData(TNode<String> string,
TNode<Word32T> string_instance_type);
template <typename SubjectChar, typename PatternChar>
TNode<IntPtrT> CallSearchStringRaw(const TNode<RawPtrT> subject_ptr,
const TNode<IntPtrT> subject_length,
const TNode<RawPtrT> search_ptr,
const TNode<IntPtrT> search_length,
const TNode<IntPtrT> start_position);
void GenerateStringEqual(TNode<String> left, TNode<String> right,
TNode<IntPtrT> length);
template <typename SeqStringT, typename CharT>
void GenerateSeqStringRelationalComparison(TNode<String> left,
TNode<String> right,
Label* if_less, Label* if_equal,
Label* if_greater);
void GenerateStringRelationalComparison(TNode<String> left,
TNode<String> right,
StringComparison op);
TNode<JSArray> StringToArray(TNode<NativeContext> context,
TNode<String> subject_string,
TNode<Smi> subject_length,
TNode<Number> limit_number);
TNode<BoolT> SmiIsNegative(TNode<Smi> value) {
return SmiLessThan(value, SmiConstant(0));
}
TNode<String> AllocateConsString(TNode<Uint32T> length, TNode<String> left,
TNode<String> right);
TNode<String> StringAdd(TNode<ContextOrEmptyContext> context,
TNode<String> left, TNode<String> right);
void BranchIfCanDerefIndirectString(TNode<String> string,
TNode<Int32T> instance_type,
Label* can_deref, Label* cannot_deref);
void DerefIndirectString(TVariable<String>* var_string,
TNode<Int32T> instance_type);
void MaybeDerefIndirectString(TVariable<String>* var_string,
TNode<Int32T> instance_type, Label* did_deref,
Label* cannot_deref);
void MaybeDerefIndirectStrings(TVariable<String>* var_left,
TNode<Int32T> left_instance_type,
TVariable<String>* var_right,
TNode<Int32T> right_instance_type,
Label* did_something);
TNode<String> DerefIndirectString(TNode<String> string,
TNode<Int32T> instance_type,
Label* cannot_deref);
using NodeFunction0 = std::function<void()>;
using NodeFunction1 = std::function<void(TNode<Object> fn)>;
using DescriptorIndexNameValue =
PrototypeCheckAssembler::DescriptorIndexNameValue;
void MaybeCallFunctionAtSymbol(
const TNode<Context> context, const TNode<JSAny> object,
const TNode<Object> maybe_string, Handle<Symbol> symbol,
DescriptorIndexNameValue additional_property_to_check,
const NodeFunction0& regexp_call, const NodeFunction1& generic_call);
private:
template <typename T>
TNode<String> AllocAndCopyStringCharacters(TNode<T> from,
TNode<BoolT> from_is_one_byte,
TNode<IntPtrT> from_index,
TNode<IntPtrT> character_count);
};
}
}
#endif