diff --git a/bin/ch/ChakraRtInterface.cpp b/bin/ch/ChakraRtInterface.cpp
index 2d8feacef01..d806527c696 100644
--- a/bin/ch/ChakraRtInterface.cpp
+++ b/bin/ch/ChakraRtInterface.cpp
@@ -77,6 +77,7 @@ bool ChakraRTInterface::LoadChakraDll(ArgInfo* argInfo, HINSTANCE *outLibrary)
m_jsApiHooks.pfJsrtCreateRuntime = (JsAPIHooks::JsrtCreateRuntimePtr)GetChakraCoreSymbol(library, "JsCreateRuntime");
m_jsApiHooks.pfJsrtCreateContext = (JsAPIHooks::JsrtCreateContextPtr)GetChakraCoreSymbol(library, "JsCreateContext");
m_jsApiHooks.pfJsrtSetRuntimeMemoryLimit = (JsAPIHooks::JsrtSetRuntimeMemoryLimitPtr)GetChakraCoreSymbol(library, "JsSetRuntimeMemoryLimit");
+ m_jsApiHooks.pfJsrtGetContextUrl = (JsAPIHooks::JsrtGetContextUrlPtr)GetChakraCoreSymbol(library, "JsGetContextUrl");
m_jsApiHooks.pfJsrtSetCurrentContext = (JsAPIHooks::JsrtSetCurrentContextPtr)GetChakraCoreSymbol(library, "JsSetCurrentContext");
m_jsApiHooks.pfJsrtGetCurrentContext = (JsAPIHooks::JsrtGetCurrentContextPtr)GetChakraCoreSymbol(library, "JsGetCurrentContext");
m_jsApiHooks.pfJsrtDisposeRuntime = (JsAPIHooks::JsrtDisposeRuntimePtr)GetChakraCoreSymbol(library, "JsDisposeRuntime");
diff --git a/bin/ch/ChakraRtInterface.h b/bin/ch/ChakraRtInterface.h
index 30ce885c89d..50101744199 100644
--- a/bin/ch/ChakraRtInterface.h
+++ b/bin/ch/ChakraRtInterface.h
@@ -9,6 +9,7 @@ struct JsAPIHooks
typedef JsErrorCode (WINAPI *JsrtCreateRuntimePtr)(JsRuntimeAttributes attributes, JsThreadServiceCallback threadService, JsRuntimeHandle *runtime);
typedef JsErrorCode (WINAPI *JsrtCreateContextPtr)(JsRuntimeHandle runtime, JsContextRef *newContext);
typedef JsErrorCode (WINAPI *JsrtSetRuntimeMemoryLimitPtr)(JsRuntimeHandle runtime, size_t memoryLimit);
+ typedef JsErrorCode (WINAPI *JsrtGetContextUrlPtr)(JsContextRef context, char** url);
typedef JsErrorCode (WINAPI *JsrtSetCurrentContextPtr)(JsContextRef context);
typedef JsErrorCode (WINAPI *JsrtGetCurrentContextPtr)(JsContextRef* context);
typedef JsErrorCode (WINAPI *JsrtDisposeRuntimePtr)(JsRuntimeHandle runtime);
@@ -100,6 +101,7 @@ struct JsAPIHooks
JsrtCreateRuntimePtr pfJsrtCreateRuntime;
JsrtCreateContextPtr pfJsrtCreateContext;
JsrtSetRuntimeMemoryLimitPtr pfJsrtSetRuntimeMemoryLimit;
+ JsrtGetContextUrlPtr pfJsrtGetContextUrl;
JsrtSetCurrentContextPtr pfJsrtSetCurrentContext;
JsrtGetCurrentContextPtr pfJsrtGetCurrentContext;
JsrtDisposeRuntimePtr pfJsrtDisposeRuntime;
@@ -270,6 +272,7 @@ class ChakraRTInterface
static JsErrorCode WINAPI JsCreateRuntime(JsRuntimeAttributes attributes, JsThreadServiceCallback threadService, JsRuntimeHandle *runtime) { return HOOK_JS_API(CreateRuntime(attributes, threadService, runtime)); }
static JsErrorCode WINAPI JsCreateContext(JsRuntimeHandle runtime, JsContextRef *newContext) { return HOOK_JS_API(CreateContext(runtime, newContext)); }
static JsErrorCode WINAPI JsSetRuntimeMemoryLimit(JsRuntimeHandle runtime, size_t memory) { return HOOK_JS_API(SetRuntimeMemoryLimit(runtime, memory)); }
+ static JsErrorCode WINAPI JsGetContextUrl(JsContextRef context, char** url) { return HOOK_JS_API(GetContextUrl(context, url)); }
static JsErrorCode WINAPI JsSetCurrentContext(JsContextRef context) { return HOOK_JS_API(SetCurrentContext(context)); }
static JsErrorCode WINAPI JsGetCurrentContext(JsContextRef* context) { return HOOK_JS_API(GetCurrentContext(context)); }
static JsErrorCode WINAPI JsDisposeRuntime(JsRuntimeHandle runtime) { return HOOK_JS_API(DisposeRuntime(runtime)); }
diff --git a/bin/ch/WScriptJsrt.cpp b/bin/ch/WScriptJsrt.cpp
index c0355545dc1..343a2b56706 100644
--- a/bin/ch/WScriptJsrt.cpp
+++ b/bin/ch/WScriptJsrt.cpp
@@ -126,6 +126,76 @@ JsValueRef __stdcall WScriptJsrt::QuitCallback(JsValueRef callee, bool isConstru
ExitProcess(exitCode);
}
+JsValueRef __stdcall WScriptJsrt::GetDirectoryCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState)
+{
+ HRESULT hr = E_FAIL;
+ JsErrorCode errorCode = JsNoError;
+ LPCWSTR errorMessage = _u("Internal error.");
+ JsValueRef returnValue = JS_INVALID_REFERENCE;
+ JsContextRef calleeContext = JS_INVALID_REFERENCE;
+ AutoString url;
+
+ IfJsrtErrorSetGo(ChakraRTInterface::JsGetContextOfObject(callee, &calleeContext));
+ IfJsrtErrorSetGo(ChakraRTInterface::JsGetContextUrl(calleeContext, &url));
+ char drive[8], dir[256], filename[256], ext[256];
+ IfJsrtErrorSetGo(_splitpath_s(*url, drive, 8, dir, 256, filename, 256, ext, 256) ? JsErrorInvalidArgument : JsNoError);
+ char fullDir[256];
+ _makepath_s(fullDir, 256, drive, dir, nullptr, nullptr);
+ size_t len = strlen(fullDir);
+ IfJsrtErrorSetGo(ChakraRTInterface::JsPointerToStringUtf8(fullDir, len, &returnValue));
+
+Error:
+ if (errorCode != JsNoError)
+ {
+ JsValueRef errorObject;
+ JsValueRef errorMessageString;
+
+ if (wcscmp(errorMessage, _u("")) == 0) {
+ errorMessage = ConvertErrorCodeToMessage(errorCode);
+ }
+
+ ERROR_MESSAGE_TO_STRING(errCode, errorMessage, errorMessageString);
+
+ ChakraRTInterface::JsCreateError(errorMessageString, &errorObject);
+ ChakraRTInterface::JsSetException(errorObject);
+ }
+
+ return returnValue;
+}
+
+JsValueRef __stdcall WScriptJsrt::GetFileNameCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState)
+{
+ HRESULT hr = E_FAIL;
+ JsErrorCode errorCode = JsNoError;
+ LPCWSTR errorMessage = _u("Internal error.");
+ JsValueRef returnValue = JS_INVALID_REFERENCE;
+ JsContextRef calleeContext = JS_INVALID_REFERENCE;
+ AutoString url;
+
+ IfJsrtErrorSetGo(ChakraRTInterface::JsGetContextOfObject(callee, &calleeContext));
+ IfJsrtErrorSetGo(ChakraRTInterface::JsGetContextUrl(calleeContext, &url));
+ size_t len = strlen(*url);
+ IfJsrtErrorSetGo(ChakraRTInterface::JsPointerToStringUtf8(*url, len, &returnValue));
+
+Error:
+ if (errorCode != JsNoError)
+ {
+ JsValueRef errorObject;
+ JsValueRef errorMessageString;
+
+ if (wcscmp(errorMessage, _u("")) == 0) {
+ errorMessage = ConvertErrorCodeToMessage(errorCode);
+ }
+
+ ERROR_MESSAGE_TO_STRING(errCode, errorMessage, errorMessageString);
+
+ ChakraRTInterface::JsCreateError(errorMessageString, &errorObject);
+ ChakraRTInterface::JsSetException(errorObject);
+ }
+
+ return returnValue;
+}
+
JsValueRef __stdcall WScriptJsrt::LoadScriptFileCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState)
{
return LoadScriptFileHelper(callee, arguments, argumentCount, false);
@@ -322,7 +392,7 @@ JsErrorCode WScriptJsrt::LoadModuleFromString(LPCSTR fileName, LPCSTR fileConten
JsValueRef errorObject = JS_INVALID_REFERENCE;
// ParseModuleSource is sync, while additional fetch & evaluation are async.
- errorCode = ChakraRTInterface::JsParseModuleSource(requestModule, dwSourceCookie, (LPBYTE)fileContent,
+ errorCode = ChakraRTInterface::JsParseModuleSource(requestModule, dwSourceCookie, (LPBYTE)fileContent,
(unsigned int)strlen(fileContent), JsParseModuleSourceFlags_DataIsUTF8, &errorObject);
if ((errorCode != JsNoError) && errorObject != JS_INVALID_REFERENCE)
{
@@ -711,6 +781,8 @@ bool WScriptJsrt::Initialize()
IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "Echo", EchoCallback));
IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "Quit", QuitCallback));
+ IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "GetFileName", GetFileNameCallback));
+ IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "GetDirectory", GetDirectoryCallback));
IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "LoadScriptFile", LoadScriptFileCallback));
IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "LoadScript", LoadScriptCallback));
IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "LoadModule", LoadModuleCallback));
@@ -1017,7 +1089,7 @@ JsErrorCode WScriptJsrt::FetchImportedModule(_In_ JsModuleRecord referencingModu
return errorCode;
}
-// Callback from chakraCore when the module resolution is finished, either successfuly or unsuccessfully.
+// Callback from chakraCore when the module resolution is finished, either successfuly or unsuccessfully.
JsErrorCode WScriptJsrt::NotifyModuleReadyCallback(_In_opt_ JsModuleRecord referencingModule, _In_opt_ JsValueRef exceptionVar)
{
if (exceptionVar != nullptr)
diff --git a/bin/ch/WScriptJsrt.h b/bin/ch/WScriptJsrt.h
index 4044fb50bc5..2f815fc9382 100644
--- a/bin/ch/WScriptJsrt.h
+++ b/bin/ch/WScriptJsrt.h
@@ -91,6 +91,8 @@ class WScriptJsrt
static bool CreateNamedFunction(const char*, JsNativeFunction callback, JsValueRef* functionVar);
static JsValueRef __stdcall EchoCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState);
static JsValueRef __stdcall QuitCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState);
+ static JsValueRef __stdcall GetDirectoryCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState);
+ static JsValueRef __stdcall GetFileNameCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState);
static JsValueRef __stdcall LoadScriptFileCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState);
static JsValueRef __stdcall LoadScriptCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState);
static JsValueRef __stdcall LoadModuleCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState);
diff --git a/lib/Jsrt/ChakraCommon.h b/lib/Jsrt/ChakraCommon.h
index a598b54614f..f32107507f0 100644
--- a/lib/Jsrt/ChakraCommon.h
+++ b/lib/Jsrt/ChakraCommon.h
@@ -930,6 +930,19 @@ typedef UINT32 DWORD;
_In_ JsRuntimeHandle runtime,
_Out_ JsContextRef *newContext);
+ ///
+ /// Gets the source url of the context
+ ///
+ /// The context the url belongs to.
+ /// The url of the context
+ ///
+ /// The code JsNoError if the operation succeeded, a failure code otherwise.
+ ///
+ CHAKRA_API
+ JsGetContextUrl(
+ _In_ JsContextRef context,
+ _Out_ char** url);
+
///
/// Gets the current script context on the thread.
///
diff --git a/lib/Jsrt/Jsrt.cpp b/lib/Jsrt/Jsrt.cpp
index 39b8009d491..4d3fd84afd2 100644
--- a/lib/Jsrt/Jsrt.cpp
+++ b/lib/Jsrt/Jsrt.cpp
@@ -745,6 +745,24 @@ CHAKRA_API JsCreateContext(_In_ JsRuntimeHandle runtimeHandle, _Out_ JsContextRe
return CreateContextCore(runtimeHandle, false /*createUnderTimeTravel*/, newContext);
}
+
+CHAKRA_API JsGetContextUrl(_In_ JsContextRef context, _Out_ char **url)
+{
+ PARAM_NOT_NULL(context);
+ PARAM_NOT_NULL(url);
+
+ BEGIN_JSRT_NO_EXCEPTION
+ {
+ *url = ((JsrtContext*)context)->GetScriptContext()->GetCurrentUrl();
+ if (!*url)
+ {
+ RETURN_NO_EXCEPTION(JsErrorInvalidContext);
+ }
+ }
+ END_JSRT_NO_EXCEPTION
+}
+
+
CHAKRA_API JsGetCurrentContext(_Out_ JsContextRef *currentContext)
{
PARAM_NOT_NULL(currentContext);
diff --git a/lib/Jsrt/JsrtCommonExports.inc b/lib/Jsrt/JsrtCommonExports.inc
index 9bc6d7530aa..b7447e3f915 100644
--- a/lib/Jsrt/JsrtCommonExports.inc
+++ b/lib/Jsrt/JsrtCommonExports.inc
@@ -5,6 +5,7 @@
JsAddRef
JsRelease
JsCreateContext
+ JsGetContextUrl
JsGetCurrentContext
JsSetCurrentContext
JsGetContextOfObject
diff --git a/lib/Runtime/Base/ScriptContext.cpp b/lib/Runtime/Base/ScriptContext.cpp
index b2e41e5b7c6..f0c5c2dc771 100644
--- a/lib/Runtime/Base/ScriptContext.cpp
+++ b/lib/Runtime/Base/ScriptContext.cpp
@@ -33,6 +33,7 @@
#ifdef ENABLE_BASIC_TELEMETRY
#include "ScriptContextTelemetry.h"
#endif
+#include "Codex/Utf8Helper.h"
namespace Js
{
@@ -491,6 +492,27 @@ namespace Js
PERF_COUNTER_DEC(Basic, ScriptContext);
}
+ char* ScriptContext::GetCurrentUrl()
+ {
+ Js::JavascriptStackWalker walker(this);
+ char* url = nullptr;;
+ walker.WalkUntil((ushort)10, [&](Js::JavascriptFunction* func, ushort frameIndex) -> bool
+ {
+ FunctionBody* body = func->GetFunctionBody();
+ if (body)
+ {
+ SourceContextInfo* info = body->GetSourceContextInfo();
+ if (info)
+ {
+ utf8::WideStringToNarrowDynamic(info->url, &url);
+ return true;
+ }
+ }
+ return false;
+ });
+ return url;
+ }
+
void ScriptContext::SetUrl(BSTR bstrUrl)
{
// Assumption: this method is never called multiple times
diff --git a/lib/Runtime/Base/ScriptContext.h b/lib/Runtime/Base/ScriptContext.h
index 7b453fc7b1e..34c7acf1293 100644
--- a/lib/Runtime/Base/ScriptContext.h
+++ b/lib/Runtime/Base/ScriptContext.h
@@ -920,6 +920,7 @@ namespace Js
#ifdef ENABLE_DOM_FAST_PATH
DOMFastPathIRHelperMap* EnsureDOMFastPathIRHelperMap();
#endif
+ char* GetCurrentUrl();
char16 const * GetUrl() const { return url; }
void SetUrl(BSTR bstr);
#ifdef RUNTIME_DATA_COLLECTION