2
0

SubString.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "RuntimeLibraryPch.h"
  6. namespace Js
  7. {
  8. DEFINE_RECYCLER_TRACKER_PERF_COUNTER(SubString);
  9. inline SubString::SubString(void const * originalFullStringReference, const char16* subString, charcount_t length, ScriptContext *scriptContext) :
  10. JavascriptString(scriptContext->GetLibrary()->GetStringTypeStatic())
  11. {
  12. this->SetBuffer(subString);
  13. this->originalFullStringReference = originalFullStringReference;
  14. this->SetLength(length);
  15. #ifdef PROFILE_STRINGS
  16. StringProfiler::RecordNewString( scriptContext, this->UnsafeGetBuffer(), this->GetLength() );
  17. #endif
  18. }
  19. JavascriptString* SubString::New(JavascriptString* string, charcount_t start, charcount_t length)
  20. {
  21. AssertMsg( IsValidCharCount(start), "start is out of range" );
  22. AssertMsg( IsValidCharCount(length), "length is out of range" );
  23. ScriptContext *scriptContext = string->GetScriptContext();
  24. if (!length)
  25. {
  26. return scriptContext->GetLibrary()->GetEmptyString();
  27. }
  28. Recycler* recycler = scriptContext->GetRecycler();
  29. AssertOrFailFast(string->GetLength() >= start + length);
  30. const char16 * subString = string->GetString() + start;
  31. void const * originalFullStringReference = string->GetOriginalStringReference();
  32. #if SYSINFO_IMAGE_BASE_AVAILABLE
  33. AssertMsg(AutoSystemInfo::IsJscriptModulePointer((void*)originalFullStringReference)
  34. || recycler->IsValidObject((void*)originalFullStringReference)
  35. || (VirtualTableInfo<PropertyRecord>::HasVirtualTable((void*)originalFullStringReference) && ((PropertyRecord*)originalFullStringReference)->IsBound())
  36. || (string->GetLength() == 1 && originalFullStringReference == scriptContext->GetLibrary()->GetCharStringCache().GetStringForChar(string->GetString()[0])->UnsafeGetBuffer()),
  37. "Owning pointer for SubString must be static or GC pointer, property record bound by thread allocator, or character buffer in global string cache");
  38. #endif
  39. return RecyclerNew(recycler, SubString, originalFullStringReference, subString, length, scriptContext);
  40. }
  41. JavascriptString* SubString::New(const char16* string, charcount_t start, charcount_t length, ScriptContext *scriptContext)
  42. {
  43. AssertMsg( IsValidCharCount(start), "start is out of range" );
  44. AssertMsg( IsValidCharCount(length), "length is out of range" );
  45. if (!length)
  46. {
  47. return scriptContext->GetLibrary()->GetEmptyString();
  48. }
  49. Recycler* recycler = scriptContext->GetRecycler();
  50. return RecyclerNew(recycler, SubString, string, string + start, length, scriptContext);
  51. }
  52. const char16* SubString::GetSz()
  53. {
  54. if (originalFullStringReference)
  55. {
  56. Recycler* recycler = this->GetScriptContext()->GetRecycler();
  57. char16 * newInstance = AllocateLeafAndCopySz(recycler, UnsafeGetBuffer(), GetLength());
  58. this->SetBuffer(newInstance);
  59. // We don't need the string reference anymore, set it to nullptr and use this to know our string is nullptr terminated
  60. originalFullStringReference = nullptr;
  61. }
  62. return UnsafeGetBuffer();
  63. }
  64. void const * SubString::GetOriginalStringReference()
  65. {
  66. if (originalFullStringReference != nullptr)
  67. {
  68. return originalFullStringReference;
  69. }
  70. return __super::GetOriginalStringReference();
  71. }
  72. size_t SubString::GetAllocatedByteCount() const
  73. {
  74. if (originalFullStringReference)
  75. {
  76. return 0;
  77. }
  78. return __super::GetAllocatedByteCount();
  79. }
  80. bool SubString::IsSubstring() const
  81. {
  82. if (originalFullStringReference)
  83. {
  84. return true;
  85. }
  86. return false;
  87. }
  88. void SubString::CachePropertyRecord(_In_ PropertyRecord const* propertyRecord)
  89. {
  90. // Now that the property record owns a copy of the string data, transform
  91. // this instance into a more efficient type.
  92. this->originalFullStringReference = nullptr;
  93. LiteralStringWithPropertyStringPtr* converted = LiteralStringWithPropertyStringPtr::ConvertString(this);
  94. converted->CachePropertyRecordImpl(propertyRecord);
  95. }
  96. }