Skip to content

Commit

Permalink
Changing JsCreateString to create Utf8Strings directly
Browse files Browse the repository at this point in the history
Also changing CompileRun to detect Utf8Strings and pass them through
to RunScriptCore which can already deal with utf8 sources.
  • Loading branch information
MSLaguana committed Jul 25, 2018
1 parent cd74d97 commit f22a24b
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 7 deletions.
30 changes: 24 additions & 6 deletions lib/Jsrt/Jsrt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4781,9 +4781,17 @@ CHAKRA_API JsCreateString(

return ContextAPINoScriptWrapper([&](Js::ScriptContext *scriptContext, TTDRecorder& _actionEntryPopper) -> JsErrorCode {

Js::JavascriptString *stringValue = Js::LiteralStringWithPropertyStringPtr::
NewFromCString(content, (CharCount)length, scriptContext->GetLibrary());
char * recyclerBuffer = RecyclerNewArrayLeaf(scriptContext->GetRecycler(), char, length);
if (recyclerBuffer == nullptr)
{
Js::JavascriptError::ThrowOutOfMemoryError(scriptContext);
}

memcpy_s(recyclerBuffer, length, content, length);

Js::JavascriptString *stringValue = RecyclerNew(scriptContext->GetRecycler(), Js::Utf8String, recyclerBuffer, length, scriptContext->GetLibrary()->GetStringTypeStatic());

// TODO: With TTD enabled we immediately flatten these strings to utf16. Perhaps we should handle this differently.
PERFORM_JSRT_TTD_RECORD_ACTION(scriptContext, RecordJsRTCreateString, stringValue->GetSz(), stringValue->GetLength());

*value = stringValue;
Expand Down Expand Up @@ -4966,10 +4974,20 @@ _ALWAYSINLINE JsErrorCode CompileRun(
if (isString)
{
Js::JavascriptString* jsString = Js::JavascriptString::FromVar(scriptVal);
script = (const byte*)jsString->GetSz();

// JavascriptString is 2 bytes (WCHAR/char16)
cb = jsString->GetLength() * sizeof(WCHAR);
if (Js::Utf8String::Is(jsString))
{
// If we have a utf8 buffer, we can parse that directly
Js::Utf8String * utf8String = Js::Utf8String::From(jsString);
script = (const byte*)utf8String->Utf8Buffer();
cb = utf8String->Utf8Length();
scriptFlag = (LoadScriptFlag)(scriptFlag | LoadScriptFlag_Utf8Source);
}
else
{
script = (const byte*)jsString->GetSz();
// JavascriptString is 2 bytes (WCHAR/char16)
cb = jsString->GetLength() * sizeof(WCHAR);
}
}

if (!Js::JavascriptString::Is(sourceUrl))
Expand Down
48 changes: 47 additions & 1 deletion lib/Runtime/Library/Utf8String.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,40 @@ namespace Js
this->SetBuffer(originalString->UnsafeGetBuffer());
}

Utf8String(_In_reads_(utf8Length) char* buffer, size_t utf8Length, _In_ StaticType* type) :
JavascriptString(type),
utf8String(nullptr)
{
SetUtf8Buffer(buffer, utf8Length);

charcount_t utf16Length = 0;
utf8::DecodeOptions opts;
LPCUTF8 buf = reinterpret_cast<LPCUTF8>(buffer);
LPCUTF8 end = buf + utf8Length;
while (buf < end)
{
if ((*buf & 0x80) == 0)
{
// Single byte character
utf16Length++;
buf++;
}
else
{
// Decode a single utf16 character, and increment the pointer
// to the start of the next character.
char16 c1 = *buf;
++buf;
utf8::DecodeTail(c1, buf, end, opts);
utf16Length++;
}
}

this->SetLength(utf16Length);
this->SetBuffer(nullptr);
}


size_t Utf8Length() const
{
return this->utf8String->length;
Expand All @@ -67,7 +101,9 @@ namespace Js
// Fetching the char* from the Field(char*) first so we can then cast to LPCUTF8
const char* bufferStart = this->utf8String->buffer;
LPCUTF8 start = reinterpret_cast<LPCUTF8>(bufferStart);
utf8::DecodeUnitsIntoAndNullTerminateNoAdvance(buffer, start, start + this->utf8String->length);
size_t decodeLength = utf8::DecodeUnitsIntoAndNullTerminateNoAdvance(buffer, start, start + this->utf8String->length);

Assert(decodeLength == this->GetLength());

buffer[this->GetLength()] = 0;

Expand All @@ -80,6 +116,16 @@ namespace Js
return VirtualTableInfo<Js::Utf8String>::HasVirtualTable(obj);
}

static Utf8String* From(RecyclableObject* obj)
{
if (Utf8String::Is(obj))
{
return static_cast<Utf8String*>(obj);
}

return nullptr;
}

template <typename StringType>
static Utf8String * ConvertString(StringType * originalString, _In_reads_(utf8Length) char* buffer, size_t utf8Length)
{
Expand Down

0 comments on commit f22a24b

Please sign in to comment.