-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathCharStringCache.cpp
More file actions
97 lines (82 loc) · 3.65 KB
/
CharStringCache.cpp
File metadata and controls
97 lines (82 loc) · 3.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Copyright (c) 2021 ChakraCore Project Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#include "RuntimeBasePch.h"
#include "Library/String/ProfileString.h"
#include "Library/String/SingleCharString.h"
using namespace Js;
CharStringCache::CharStringCache() : charStringCache(nullptr)
{
ClearArray(charStringCacheA);
}
JavascriptString* CharStringCache::GetStringForCharA(char c)
{
AssertMsg(JavascriptString::IsASCII7BitChar(c), "GetStringForCharA must be called with ASCII 7bit chars only");
PropertyString * str = charStringCacheA[(int)c];
if (str == nullptr)
{
PropertyRecord const * propertyRecord;
char16 wc = c;
JavascriptLibrary * javascriptLibrary = JavascriptLibrary::FromCharStringCache(this);
javascriptLibrary->GetScriptContext()->GetOrAddPropertyRecord(&wc, 1, &propertyRecord);
str = javascriptLibrary->CreatePropertyString(propertyRecord);
charStringCacheA[(int)c] = str;
}
return str;
}
JavascriptString* CharStringCache::GetStringForChar(char16 c)
{
JIT_HELPER_NOT_REENTRANT_NOLOCK_HEADER(GetStringForChar);
#ifdef PROFILE_STRINGS
StringProfiler::RecordSingleCharStringRequest(JavascriptLibrary::FromCharStringCache(this)->GetScriptContext());
#endif
if (JavascriptString::IsASCII7BitChar(c))
{
return GetStringForCharA(JavascriptString::ToASCII7BitChar(c));
}
return GetStringForCharW(c);
JIT_HELPER_END(GetStringForChar);
}
JIT_HELPER_TEMPLATE(GetStringForChar, GetStringForCharCodePoint)
JavascriptString* CharStringCache::GetStringForCharW(char16 c)
{
Assert(!JavascriptString::IsASCII7BitChar(c));
JavascriptString* str;
ScriptContext * scriptContext = JavascriptLibrary::FromCharStringCache(this)->GetScriptContext();
if (!scriptContext->IsClosed())
{
if (charStringCache == nullptr)
{
Recycler * recycler = scriptContext->GetRecycler();
charStringCache = RecyclerNew(recycler, CharStringCacheMap, recycler, 17);
}
if (!charStringCache->TryGetValue(c, &str))
{
str = SingleCharString::New(c, scriptContext);
charStringCache->Add(c, str);
}
}
else
{
str = SingleCharString::New(c, scriptContext);
}
return str;
}
JavascriptString* CharStringCache::GetStringForCharSP(codepoint_t c)
{
Assert(c >= 0x10000);
CompileAssert(sizeof(char16) * 2 == sizeof(codepoint_t));
ScriptContext* scriptContext = JavascriptLibrary::FromCharStringCache(this)->GetScriptContext();
// #sec - string.fromcodepoint: "If nextCP < 0 or nextCP > 0x10FFFF, throw a RangeError exception"
if (c > 0x10FFFF)
{
JavascriptError::ThrowRangeError(scriptContext, JSERR_InvalidCodePoint, scriptContext->GetIntegerString(c));
}
char16 buffer[2];
Js::NumberUtilities::CodePointAsSurrogatePair(c, buffer, buffer + 1);
JavascriptString* str = JavascriptString::NewCopyBuffer(buffer, 2, scriptContext);
// TODO: perhaps do some sort of cache for supplementary characters
return str;
}