Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 97 additions & 38 deletions bin/ch/WScriptJsrt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,12 +201,19 @@ JsValueRef WScriptJsrt::LoadScriptFileHelper(JsValueRef callee, JsValueRef *argu
hr = Helpers::LoadScriptFromFile(*fileName, fileContent);
if (FAILED(hr))
{
fwprintf(stderr, _u("Couldn't load file.\n"));
}
else
{
returnValue = LoadScript(callee, *fileName, fileContent, *scriptInjectType ? *scriptInjectType : "self", isSourceModule, WScriptJsrt::FinalizeFree, true);
// check if have it registered
AutoString *data;
if (!SourceMap::Find(fileName, &data))
{
fprintf(stderr, "Couldn't load file '%s'\n", fileName.GetString());
IfJsrtErrorSetGo(ChakraRTInterface::JsGetUndefinedValue(&returnValue));
return returnValue;
}

fileContent = data->GetString();
}

returnValue = LoadScript(callee, *fileName, fileContent, *scriptInjectType ? *scriptInjectType : "self", isSourceModule, WScriptJsrt::FinalizeFree, true);
}
}

Expand Down Expand Up @@ -395,15 +402,15 @@ JsErrorCode WScriptJsrt::LoadModuleFromString(LPCSTR fileName, LPCSTR fileConten

// ParseModuleSource is sync, while additional fetch & evaluation are async.
unsigned int fileContentLength = (fileContent == nullptr) ? 0 : (unsigned int)strlen(fileContent);

if (isFile && fullName)
{
JsValueRef moduleUrl;
ChakraRTInterface::JsCreateString(fullName, strlen(fullName), &moduleUrl);
errorCode = ChakraRTInterface::JsSetModuleHostInfo(requestModule, JsModuleHostInfo_Url, moduleUrl);
IfJsrtErrorFail(errorCode, errorCode);
}

errorCode = ChakraRTInterface::JsParseModuleSource(requestModule, dwSourceCookie, (LPBYTE)fileContent,
fileContentLength, JsParseModuleSourceFlags_DataIsUTF8, &errorObject);
if ((errorCode != JsNoError) && errorObject != JS_INVALID_REFERENCE && fileContent != nullptr && !HostConfigFlags::flags.IgnoreScriptErrorCode)
Expand Down Expand Up @@ -857,6 +864,7 @@ bool WScriptJsrt::Initialize()
IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "LoadBinaryFile", LoadBinaryFileCallback));
IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "LoadTextFile", LoadTextFileCallback));
IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "Flag", FlagCallback));
IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "RegisterModuleSource", RegisterModuleSourceCallback));

// ToDo Remove
IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "Edit", EmptyCallback));
Expand Down Expand Up @@ -1045,6 +1053,32 @@ void CALLBACK WScriptJsrt::JsContextBeforeCollectCallback(JsRef contextRef, void
}
#endif

FileNode * SourceMap::root = nullptr;
JsValueRef __stdcall WScriptJsrt::RegisterModuleSourceCallback(JsValueRef callee, bool isConstructCall,
JsValueRef *arguments, unsigned short argumentCount, void *callbackState)
{
HRESULT hr = E_FAIL;
JsValueRef returnValue = JS_INVALID_REFERENCE;
JsErrorCode errorCode = JsNoError;

if (argumentCount < 3)
{
IfJsrtErrorSetGo(ChakraRTInterface::JsGetUndefinedValue(&returnValue));
}
else
{
AutoString fileName;
AutoString data;
IfJsrtErrorSetGo(fileName.Initialize(arguments[1]));
IfJsrtErrorSetGo(data.Initialize(arguments[2]));

SourceMap::Add(fileName, data);
}

Error:
return returnValue;
}

JsValueRef __stdcall WScriptJsrt::LoadTextFileCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState)
{
HRESULT hr = E_FAIL;
Expand All @@ -1069,14 +1103,21 @@ JsValueRef __stdcall WScriptJsrt::LoadTextFileCallback(JsValueRef callee, bool i

if (FAILED(hr))
{
fwprintf(stderr, _u("Couldn't load file.\n"));
IfJsrtErrorSetGo(ChakraRTInterface::JsGetUndefinedValue(&returnValue));
}
else
{
IfJsrtErrorSetGo(ChakraRTInterface::JsCreateString(
fileContent, lengthBytes, &returnValue));
// check if have it registered
AutoString *data;
if (!SourceMap::Find(fileName, &data))
{
fprintf(stderr, "Couldn't load file '%s'\n", fileName.GetString());
IfJsrtErrorSetGo(ChakraRTInterface::JsGetUndefinedValue(&returnValue));
return returnValue;
}

fileContent = data->GetString();
lengthBytes = (UINT) data->GetLength();
}

IfJsrtErrorSetGo(ChakraRTInterface::JsCreateString(
fileContent, lengthBytes, &returnValue));
}
}

Expand All @@ -1094,6 +1135,7 @@ JsValueRef __stdcall WScriptJsrt::LoadBinaryFileCallback(JsValueRef callee,
HRESULT hr = E_FAIL;
JsValueRef returnValue = JS_INVALID_REFERENCE;
JsErrorCode errorCode = JsNoError;
bool isHeapAlloc = true;

if (argumentCount < 2)
{
Expand All @@ -1111,29 +1153,42 @@ JsValueRef __stdcall WScriptJsrt::LoadBinaryFileCallback(JsValueRef callee,
UINT lengthBytes = 0;

hr = Helpers::LoadBinaryFile(*fileName, fileContent, lengthBytes);

if (FAILED(hr))
{
fwprintf(stderr, _u("Couldn't load file.\n"));
// check if have it registered
AutoString *data;
if (!SourceMap::Find(fileName, &data))
{
fprintf(stderr, "Couldn't load file '%s'\n", fileName.GetString());
IfJsrtErrorSetGoLabel(ChakraRTInterface::JsGetUndefinedValue(&returnValue), Error);
return returnValue;
}

isHeapAlloc = false;
fileContent = data->GetString();
lengthBytes = (UINT) data->GetLength();
}

JsValueRef arrayBuffer;
IfJsrtErrorSetGoLabel(ChakraRTInterface::JsCreateArrayBuffer(lengthBytes, &arrayBuffer), ErrorStillFree);
BYTE* buffer;
unsigned int bufferLength;
IfJsrtErrorSetGoLabel(ChakraRTInterface::JsGetArrayBufferStorage(arrayBuffer, &buffer, &bufferLength), ErrorStillFree);
if (bufferLength < lengthBytes)
{
fwprintf(stderr, _u("Array buffer size is insufficient to store the binary file.\n"));
}
else
{
JsValueRef arrayBuffer;
IfJsrtErrorSetGoLabel(ChakraRTInterface::JsCreateArrayBuffer(lengthBytes, &arrayBuffer), ErrorStillFree);
BYTE* buffer;
unsigned int bufferLength;
IfJsrtErrorSetGoLabel(ChakraRTInterface::JsGetArrayBufferStorage(arrayBuffer, &buffer, &bufferLength), ErrorStillFree);
if (bufferLength < lengthBytes)
{
fwprintf(stderr, _u("Array buffer size is insufficient to store the binary file.\n"));
}
else
if (memcpy_s(buffer, bufferLength, (BYTE*)fileContent, lengthBytes) == 0)
{
if (memcpy_s(buffer, bufferLength, (BYTE*)fileContent, lengthBytes) == 0)
{
returnValue = arrayBuffer;
}
returnValue = arrayBuffer;
}
}
ErrorStillFree:
if (isHeapAlloc)
{
HeapFree(GetProcessHeap(), 0, (void*)fileContent);
}
}
Expand Down Expand Up @@ -1365,7 +1420,7 @@ bool WScriptJsrt::PrintException(LPCSTR fileName, JsErrorCode jsErrorCode)

int line;
int column;

IfJsrtErrorFail(CreatePropertyIdFromString("line", &linePropertyId), false);
IfJsrtErrorFail(ChakraRTInterface::JsGetProperty(exception, linePropertyId, &lineProperty), false);
IfJsrtErrorFail(ChakraRTInterface::JsNumberToInt(lineProperty, &line), false);
Expand Down Expand Up @@ -1551,19 +1606,23 @@ HRESULT WScriptJsrt::ModuleMessage::Call(LPCSTR fileName)

if (FAILED(hr))
{
if (!HostConfigFlags::flags.MuteHostErrorMsgIsEnabled)
// check if have it registered
AutoString *data;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since data is a pointer, I don't think the AutoString destructor will run -- is that an issue?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shouldn't run by design and intention. See constructor. It takes over the ownership (there is a comment). Source code map lifetime == process lifetime.

if (!SourceMap::Find(specifierStr, &data))
{
fprintf(stderr, "Couldn't load file.\n");
if (!HostConfigFlags::flags.MuteHostErrorMsgIsEnabled)
{
fprintf(stderr, "Couldn't load file '%s'\n", specifierStr.GetString());
}
LoadScript(nullptr, *specifierStr, nullptr, "module", true, WScriptJsrt::FinalizeFree, false);
goto Error;
}

LoadScript(nullptr, *specifierStr, nullptr, "module", true, WScriptJsrt::FinalizeFree, false);
}
else
{
LoadScript(nullptr, *specifierStr, fileContent, "module", true, WScriptJsrt::FinalizeFree, true);
fileContent = data->GetString();
}
LoadScript(nullptr, *specifierStr, fileContent, "module", true, WScriptJsrt::FinalizeFree, true);
}
}
Error:
return errorCode;
}

Expand Down
1 change: 1 addition & 0 deletions bin/ch/WScriptJsrt.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ class WScriptJsrt

static JsValueRef CALLBACK LoadBinaryFileCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState);
static JsValueRef CALLBACK LoadTextFileCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState);
static JsValueRef CALLBACK RegisterModuleSourceCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState);
static JsValueRef CALLBACK FlagCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState);

static JsValueRef CALLBACK BroadcastCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState);
Expand Down
51 changes: 50 additions & 1 deletion bin/ch/stdafx.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,13 @@ class AutoString
data_wide(nullptr), errorCode(JsNoError), dontFree(false)
{ }

AutoString(AutoString &autoString):length(autoString.length),
data(autoString.data), data_wide(autoString.data_wide),
errorCode(JsNoError), dontFree(false)
{
autoString.dontFree = true; // take over the ownership
}

AutoString(JsValueRef value):length(0), data(nullptr),
data_wide(nullptr), errorCode(JsNoError), dontFree(false)
{
Expand Down Expand Up @@ -279,7 +286,49 @@ class AutoString
}

char* operator*() { return data; }
char** operator&() { return &data; }
};

struct FileNode
{
AutoString data;
AutoString path;
FileNode * next;
FileNode(AutoString &path_, AutoString &data_):
path(path_), data(data_), next(nullptr) {
path_.MakePersistent();
data_.MakePersistent();
}
};

class SourceMap
{
static FileNode * root;
public:
static void Add(AutoString &path, AutoString &data)
{
// SourceMap lifetime == process lifetime
FileNode * node = new FileNode(path, data);
if (root != nullptr)
{
node->next = root;
}
root = node;
}

static bool Find(AutoString &path, AutoString ** out)
{
FileNode * node = root;
while(node != nullptr)
{
if (strncmp(node->path.GetString(), path.GetString(), path.GetLength()) == 0)
{
*out = &(node->data);
return true;
}
node = node->next;
}
return false;
}
};

inline JsErrorCode CreatePropertyIdFromString(const char* str, JsPropertyIdRef *Id)
Expand Down
Loading