11cb0ef41Sopenharmony_ci// Copyright 2018 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#include "src/codegen/string-constants.h" 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#include "src/base/functional.h" 81cb0ef41Sopenharmony_ci#include "src/objects/objects.h" 91cb0ef41Sopenharmony_ci#include "src/objects/string-inl.h" 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_cinamespace v8 { 121cb0ef41Sopenharmony_cinamespace internal { 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ciHandle<String> StringConstantBase::AllocateStringConstant( 151cb0ef41Sopenharmony_ci Isolate* isolate) const { 161cb0ef41Sopenharmony_ci if (!flattened_.is_null()) { 171cb0ef41Sopenharmony_ci return flattened_; 181cb0ef41Sopenharmony_ci } 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_ci Handle<String> result; 211cb0ef41Sopenharmony_ci switch (kind()) { 221cb0ef41Sopenharmony_ci case StringConstantKind::kStringLiteral: { 231cb0ef41Sopenharmony_ci result = static_cast<const StringLiteral*>(this)->str(); 241cb0ef41Sopenharmony_ci CHECK(!result.is_null()); 251cb0ef41Sopenharmony_ci break; 261cb0ef41Sopenharmony_ci } 271cb0ef41Sopenharmony_ci case StringConstantKind::kNumberToStringConstant: { 281cb0ef41Sopenharmony_ci auto num_constant = static_cast<const NumberToStringConstant*>(this); 291cb0ef41Sopenharmony_ci Handle<Object> num_obj = 301cb0ef41Sopenharmony_ci isolate->factory()->NewNumber(num_constant->num()); 311cb0ef41Sopenharmony_ci result = isolate->factory()->NumberToString(num_obj); 321cb0ef41Sopenharmony_ci CHECK(!result.is_null()); 331cb0ef41Sopenharmony_ci break; 341cb0ef41Sopenharmony_ci } 351cb0ef41Sopenharmony_ci case StringConstantKind::kStringCons: { 361cb0ef41Sopenharmony_ci Handle<String> lhs = 371cb0ef41Sopenharmony_ci static_cast<const StringCons*>(this)->lhs()->AllocateStringConstant( 381cb0ef41Sopenharmony_ci isolate); 391cb0ef41Sopenharmony_ci Handle<String> rhs = 401cb0ef41Sopenharmony_ci static_cast<const StringCons*>(this)->rhs()->AllocateStringConstant( 411cb0ef41Sopenharmony_ci isolate); 421cb0ef41Sopenharmony_ci result = isolate->factory()->NewConsString(lhs, rhs).ToHandleChecked(); 431cb0ef41Sopenharmony_ci break; 441cb0ef41Sopenharmony_ci } 451cb0ef41Sopenharmony_ci } 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci // TODO(mslekova): Normally we'd want to flatten the string here 481cb0ef41Sopenharmony_ci // but that results in OOM for too long strings. 491cb0ef41Sopenharmony_ci Memoize(result); 501cb0ef41Sopenharmony_ci return flattened_; 511cb0ef41Sopenharmony_ci} 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_cibool StringConstantBase::operator==(const StringConstantBase& other) const { 541cb0ef41Sopenharmony_ci if (kind() != other.kind()) return false; 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci switch (kind()) { 571cb0ef41Sopenharmony_ci case StringConstantKind::kStringLiteral: { 581cb0ef41Sopenharmony_ci return static_cast<const StringLiteral*>(this) == 591cb0ef41Sopenharmony_ci static_cast<const StringLiteral*>(&other); 601cb0ef41Sopenharmony_ci } 611cb0ef41Sopenharmony_ci case StringConstantKind::kNumberToStringConstant: { 621cb0ef41Sopenharmony_ci return static_cast<const NumberToStringConstant*>(this) == 631cb0ef41Sopenharmony_ci static_cast<const NumberToStringConstant*>(&other); 641cb0ef41Sopenharmony_ci } 651cb0ef41Sopenharmony_ci case StringConstantKind::kStringCons: { 661cb0ef41Sopenharmony_ci return static_cast<const StringCons*>(this) == 671cb0ef41Sopenharmony_ci static_cast<const StringCons*>(&other); 681cb0ef41Sopenharmony_ci } 691cb0ef41Sopenharmony_ci } 701cb0ef41Sopenharmony_ci UNREACHABLE(); 711cb0ef41Sopenharmony_ci} 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_cisize_t hash_value(StringConstantBase const& base) { 741cb0ef41Sopenharmony_ci switch (base.kind()) { 751cb0ef41Sopenharmony_ci case StringConstantKind::kStringLiteral: { 761cb0ef41Sopenharmony_ci return hash_value(*static_cast<const StringLiteral*>(&base)); 771cb0ef41Sopenharmony_ci } 781cb0ef41Sopenharmony_ci case StringConstantKind::kNumberToStringConstant: { 791cb0ef41Sopenharmony_ci return hash_value(*static_cast<const NumberToStringConstant*>(&base)); 801cb0ef41Sopenharmony_ci } 811cb0ef41Sopenharmony_ci case StringConstantKind::kStringCons: { 821cb0ef41Sopenharmony_ci return hash_value(*static_cast<const StringCons*>(&base)); 831cb0ef41Sopenharmony_ci } 841cb0ef41Sopenharmony_ci } 851cb0ef41Sopenharmony_ci UNREACHABLE(); 861cb0ef41Sopenharmony_ci} 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_cibool operator==(StringLiteral const& lhs, StringLiteral const& rhs) { 891cb0ef41Sopenharmony_ci return lhs.str().address() == rhs.str().address(); 901cb0ef41Sopenharmony_ci} 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_cibool operator!=(StringLiteral const& lhs, StringLiteral const& rhs) { 931cb0ef41Sopenharmony_ci return !(lhs == rhs); 941cb0ef41Sopenharmony_ci} 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_cisize_t hash_value(StringLiteral const& p) { 971cb0ef41Sopenharmony_ci return base::hash_combine(p.str().address()); 981cb0ef41Sopenharmony_ci} 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& os, StringLiteral const& p) { 1011cb0ef41Sopenharmony_ci return os << Brief(*p.str()); 1021cb0ef41Sopenharmony_ci} 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_cibool operator==(NumberToStringConstant const& lhs, 1051cb0ef41Sopenharmony_ci NumberToStringConstant const& rhs) { 1061cb0ef41Sopenharmony_ci return lhs.num() == rhs.num(); 1071cb0ef41Sopenharmony_ci} 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_cibool operator!=(NumberToStringConstant const& lhs, 1101cb0ef41Sopenharmony_ci NumberToStringConstant const& rhs) { 1111cb0ef41Sopenharmony_ci return !(lhs == rhs); 1121cb0ef41Sopenharmony_ci} 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_cisize_t hash_value(NumberToStringConstant const& p) { 1151cb0ef41Sopenharmony_ci return base::hash_combine(p.num()); 1161cb0ef41Sopenharmony_ci} 1171cb0ef41Sopenharmony_ci 1181cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& os, NumberToStringConstant const& p) { 1191cb0ef41Sopenharmony_ci return os << p.num(); 1201cb0ef41Sopenharmony_ci} 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_cibool operator==(StringCons const& lhs, StringCons const& rhs) { 1231cb0ef41Sopenharmony_ci // TODO(mslekova): Think if we can express this in a more readable manner 1241cb0ef41Sopenharmony_ci return *(lhs.lhs()) == *(rhs.lhs()) && *(lhs.rhs()) == *(rhs.rhs()); 1251cb0ef41Sopenharmony_ci} 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_cibool operator!=(StringCons const& lhs, StringCons const& rhs) { 1281cb0ef41Sopenharmony_ci return !(lhs == rhs); 1291cb0ef41Sopenharmony_ci} 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_cisize_t hash_value(StringCons const& p) { 1321cb0ef41Sopenharmony_ci return base::hash_combine(*(p.lhs()), *(p.rhs())); 1331cb0ef41Sopenharmony_ci} 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& os, const StringConstantBase* base) { 1361cb0ef41Sopenharmony_ci os << "DelayedStringConstant: "; 1371cb0ef41Sopenharmony_ci switch (base->kind()) { 1381cb0ef41Sopenharmony_ci case StringConstantKind::kStringLiteral: { 1391cb0ef41Sopenharmony_ci os << *static_cast<const StringLiteral*>(base); 1401cb0ef41Sopenharmony_ci break; 1411cb0ef41Sopenharmony_ci } 1421cb0ef41Sopenharmony_ci case StringConstantKind::kNumberToStringConstant: { 1431cb0ef41Sopenharmony_ci os << *static_cast<const NumberToStringConstant*>(base); 1441cb0ef41Sopenharmony_ci break; 1451cb0ef41Sopenharmony_ci } 1461cb0ef41Sopenharmony_ci case StringConstantKind::kStringCons: { 1471cb0ef41Sopenharmony_ci os << *static_cast<const StringCons*>(base); 1481cb0ef41Sopenharmony_ci break; 1491cb0ef41Sopenharmony_ci } 1501cb0ef41Sopenharmony_ci } 1511cb0ef41Sopenharmony_ci return os; 1521cb0ef41Sopenharmony_ci} 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& os, StringCons const& p) { 1551cb0ef41Sopenharmony_ci return os << p.lhs() << ", " << p.rhs(); 1561cb0ef41Sopenharmony_ci} 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_cisize_t StringConstantBase::GetMaxStringConstantLength() const { 1591cb0ef41Sopenharmony_ci switch (kind()) { 1601cb0ef41Sopenharmony_ci case StringConstantKind::kStringLiteral: { 1611cb0ef41Sopenharmony_ci return static_cast<const StringLiteral*>(this) 1621cb0ef41Sopenharmony_ci ->GetMaxStringConstantLength(); 1631cb0ef41Sopenharmony_ci } 1641cb0ef41Sopenharmony_ci case StringConstantKind::kNumberToStringConstant: { 1651cb0ef41Sopenharmony_ci return static_cast<const NumberToStringConstant*>(this) 1661cb0ef41Sopenharmony_ci ->GetMaxStringConstantLength(); 1671cb0ef41Sopenharmony_ci } 1681cb0ef41Sopenharmony_ci case StringConstantKind::kStringCons: { 1691cb0ef41Sopenharmony_ci return static_cast<const StringCons*>(this)->GetMaxStringConstantLength(); 1701cb0ef41Sopenharmony_ci } 1711cb0ef41Sopenharmony_ci } 1721cb0ef41Sopenharmony_ci UNREACHABLE(); 1731cb0ef41Sopenharmony_ci} 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_cisize_t StringLiteral::GetMaxStringConstantLength() const { return length_; } 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_cisize_t NumberToStringConstant::GetMaxStringConstantLength() const { 1781cb0ef41Sopenharmony_ci return kMaxDoubleStringLength; 1791cb0ef41Sopenharmony_ci} 1801cb0ef41Sopenharmony_ci 1811cb0ef41Sopenharmony_cisize_t StringCons::GetMaxStringConstantLength() const { 1821cb0ef41Sopenharmony_ci return lhs()->GetMaxStringConstantLength() + 1831cb0ef41Sopenharmony_ci rhs()->GetMaxStringConstantLength(); 1841cb0ef41Sopenharmony_ci} 1851cb0ef41Sopenharmony_ci 1861cb0ef41Sopenharmony_ci} // namespace internal 1871cb0ef41Sopenharmony_ci} // namespace v8 188