| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #pragma once
- // Note: this file is to work around linker unresolved externals WRT templatized types.
- // It's better than putting function bodies in .h file because bodies depend on other classes, such as ScriptContext,
- // for which normally only forward declarations would be available in .h file.
- // The reason why these are available in .inl is because .inl files are included in the very end in Runtime.h.
- namespace Js
- {
- template <typename StringType>
- inline LiteralStringWithPropertyStringPtr * LiteralStringWithPropertyStringPtr::ConvertString(StringType * originalString)
- {
- CompileAssert(sizeof(StringType) >= sizeof(LiteralStringWithPropertyStringPtr));
- VirtualTableInfo<LiteralStringWithPropertyStringPtr>::SetVirtualTable(originalString);
- LiteralStringWithPropertyStringPtr * convertedString = (LiteralStringWithPropertyStringPtr *)originalString;
- convertedString->SetPropertyString(nullptr);
- return convertedString;
- }
- /////////////////////// ConcatStringBase //////////////////////////
- template <typename ConcatStringType>
- inline const char16* ConcatStringBase::GetSzImpl()
- {
- AssertCanHandleOutOfMemory();
- Assert(!this->IsFinalized());
- Assert(!this->IsFinalized());
- ScriptContext* scriptContext = this->GetScriptContext();
- charcount_t allocSize = SafeSzSize();
- Recycler* recycler = scriptContext->GetRecycler();
- char16* target = RecyclerNewArrayLeaf(recycler, char16, allocSize);
- Copy<ConcatStringType>(target, GetLength());
- target[GetLength()] = _u('\0');
- SetBuffer(target);
- return JavascriptString::GetSz();
- }
- /////////////////////// ConcatStringN //////////////////////////
- template<int N>
- ConcatStringN<N>::ConcatStringN(StaticType* stringTypeStatic, bool doZeroSlotsAndLength) :
- ConcatStringBase(stringTypeStatic)
- {
- Assert(stringTypeStatic);
- if (doZeroSlotsAndLength)
- {
- ClearArray(m_slots, N);
- this->SetLength(0); // Note: the length does not include null character.
- }
- }
- // static
- template<int N>
- ConcatStringN<N>* ConcatStringN<N>::New(ScriptContext* scriptContext)
- {
- Assert(scriptContext);
- return RecyclerNew(scriptContext->GetRecycler(), ConcatStringN<N>, scriptContext->GetLibrary()->GetStringTypeStatic());
- }
- // Set the slot at specified index to specified value.
- template<int N>
- void ConcatStringN<N>::SetItem(_In_range_(0, N - 1) int index, JavascriptString* value)
- {
- Assert(index >= 0 && index < N);
- // Note: value can be NULL. // TODO: should we just assert for non-zero?
- charcount_t oldItemLen = m_slots[index] ? m_slots[index]->GetLength() : 0;
- charcount_t newItemLen = value ? value->GetLength() : 0;
- if (value)
- {
- value = CompoundString::GetImmutableOrScriptUnreferencedString(value);
- }
- m_slots[index] = value;
- charcount_t newTotalLen = this->GetLength() - oldItemLen + newItemLen;
- this->SetLength(newTotalLen);
- }
- template<int N>
- inline const char16 * ConcatStringN<N>::GetSz()
- {
- const char16 * sz = GetSzImpl<ConcatStringN>();
- // Allow slots to be garbage collected if no more refs.
- ClearArray(m_slots, N);
- LiteralStringWithPropertyStringPtr::ConvertString(this);
- return sz;
- }
- /////////////////////// ConcatStringWrapping //////////////////////////
- template<char16 L, char16 R>
- ConcatStringWrapping<L, R>::ConcatStringWrapping(JavascriptString* inner) :
- ConcatStringBase(inner->GetLibrary()->GetStringTypeStatic()),
- m_inner(CompoundString::GetImmutableOrScriptUnreferencedString(inner))
- {
- this->SetLength(inner->GetLength() + 2); // does not include null character
- }
- template<char16 L, char16 R>
- ConcatStringWrapping<L, R>* ConcatStringWrapping<L, R>::New(JavascriptString* inner)
- {
- Recycler* recycler = inner->GetRecycler();
- //return RecyclerNew(recycler, ConcatStringWrapping<L, R>, inner);
- // Expand the RecyclerNew macro as it breaks for more than one template arguments.
- #ifdef TRACK_ALLOC
- return new (recycler->TrackAllocInfo(TrackAllocData::CreateTrackAllocData(typeid(ConcatStringWrapping<L, R>), 0, (size_t)-1, __FILE__, __LINE__)),
- &Recycler::Alloc) ConcatStringWrapping<L, R>(inner);
- #else
- return new (recycler, &Recycler::Alloc) ConcatStringWrapping<L, R>(inner);
- #endif
- }
- template<char16 L, char16 R>
- inline const char16 * ConcatStringWrapping<L, R>::GetSz()
- {
- const char16 * sz = GetSzImpl<ConcatStringWrapping>();
- m_inner = nullptr;
- ClearArray(m_slots);
- LiteralStringWithPropertyStringPtr::ConvertString(this);
- return sz;
- }
- template<char16 L, char16 R>
- inline JavascriptString* ConcatStringWrapping<L, R>::GetFirstItem() const
- {
- Assert(m_inner);
- char16 lBuf[2] = { L, '\0' };
- return this->GetLibrary()->CreateStringFromCppLiteral(lBuf);
- }
- template<char16 L, char16 R>
- inline JavascriptString* ConcatStringWrapping<L, R>::GetLastItem() const
- {
- Assert(m_inner);
- char16 rBuf[2] = { R, '\0' };
- return this->GetLibrary()->CreateStringFromCppLiteral(rBuf);
- }
- } // namespace Js.
|