JsValueRef WScriptJsrt::AttachCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState) { LPCWSTR errorMessage = _u("WScript.Attach requires a function, like WScript.Attach(foo);"); JsValueType argumentType = JsUndefined; if (argumentCount != 2) { goto Error; } IfJsrtError(ChakraRTInterface::JsGetValueType(arguments[1], &argumentType)); if (argumentType != JsFunction) { goto Error; } QueueDebugOperation(arguments[1], [](WScriptJsrt::CallbackMessage& msg) { JsContextRef currentContext = JS_INVALID_REFERENCE; ChakraRTInterface::JsGetCurrentContext(¤tContext); JsRuntimeHandle currentRuntime = JS_INVALID_RUNTIME_HANDLE; ChakraRTInterface::JsGetRuntime(currentContext, ¤tRuntime); Debugger* debugger = Debugger::GetDebugger(currentRuntime); debugger->StartDebugging(currentRuntime); debugger->SourceRunDown(); return msg.CallFunction(""); }); Error: JsValueRef errorObject; JsValueRef errorMessageString; ERROR_MESSAGE_TO_STRING(errorCode, errorMessage, errorMessageString); if (errorCode != JsNoError) { errorCode = ChakraRTInterface::JsCreateError(errorMessageString, &errorObject); if (errorCode != JsNoError) { ChakraRTInterface::JsSetException(errorObject); } } return JS_INVALID_REFERENCE; }
HRESULT ExecuteTest(const char* fileName) { HRESULT hr = S_OK; LPCSTR fileContents = nullptr; JsRuntimeHandle runtime = JS_INVALID_RUNTIME_HANDLE; UINT lengthBytes = 0; if(strlen(fileName) >= 14 && strcmp(fileName + strlen(fileName) - 14, "ttdSentinal.js") == 0) { #if !ENABLE_TTD wprintf(_u("Sentinel js file is only ok when in TTDebug mode!!!\n")); return E_FAIL; #else if(!doTTDebug) { wprintf(_u("Sentinel js file is only ok when in TTDebug mode!!!\n")); return E_FAIL; } jsrtAttributes = static_cast<JsRuntimeAttributes>(jsrtAttributes | JsRuntimeAttributeEnableExperimentalFeatures); IfJsErrorFailLog(ChakraRTInterface::JsTTDCreateReplayRuntime(jsrtAttributes, ttUri, ttUriByteLength, Helpers::TTInitializeForWriteLogStreamCallback, Helpers::TTCreateStreamCallback, Helpers::TTReadBytesFromStreamCallback, Helpers::TTWriteBytesToStreamCallback, Helpers::TTFlushAndCloseStreamCallback, nullptr, &runtime)); chRuntime = runtime; JsContextRef context = JS_INVALID_REFERENCE; IfJsErrorFailLog(ChakraRTInterface::JsTTDCreateContext(runtime, true, &context)); IfJsErrorFailLog(ChakraRTInterface::JsSetCurrentContext(context)); IfFailGo(RunScript(fileName, fileContents, nullptr, nullptr)); unsigned int rcount = 0; IfJsErrorFailLog(ChakraRTInterface::JsSetCurrentContext(nullptr)); ChakraRTInterface::JsRelease(context, &rcount); AssertMsg(rcount == 0, "Should only have had 1 ref from replay code and one ref from current context??"); #endif } else { LPCOLESTR contentsRaw = nullptr; char fullPath[_MAX_PATH]; size_t len = 0; hr = Helpers::LoadScriptFromFile(fileName, fileContents, &lengthBytes); contentsRaw; lengthBytes; // Unused for now. IfFailGo(hr); if (HostConfigFlags::flags.GenerateLibraryByteCodeHeaderIsEnabled) { jsrtAttributes = (JsRuntimeAttributes)(jsrtAttributes | JsRuntimeAttributeSerializeLibraryByteCode); } #if ENABLE_TTD if (doTTRecord) { //Ensure we run with experimental features (as that is what Node does right now). jsrtAttributes = static_cast<JsRuntimeAttributes>(jsrtAttributes | JsRuntimeAttributeEnableExperimentalFeatures); IfJsErrorFailLog(ChakraRTInterface::JsTTDCreateRecordRuntime(jsrtAttributes, ttUri, ttUriByteLength, snapInterval, snapHistoryLength, Helpers::TTInitializeForWriteLogStreamCallback, Helpers::TTCreateStreamCallback, Helpers::TTReadBytesFromStreamCallback, Helpers::TTWriteBytesToStreamCallback, Helpers::TTFlushAndCloseStreamCallback, nullptr, &runtime)); chRuntime = runtime; JsContextRef context = JS_INVALID_REFERENCE; IfJsErrorFailLog(ChakraRTInterface::JsTTDCreateContext(runtime, true, &context)); #if ENABLE_TTD //We need this here since this context is created in record IfJsErrorFailLog(ChakraRTInterface::JsSetObjectBeforeCollectCallback(context, nullptr, WScriptJsrt::JsContextBeforeCollectCallback)); #endif IfJsErrorFailLog(ChakraRTInterface::JsSetCurrentContext(context)); } else { AssertMsg(!doTTDebug, "Should be handled in the else case above!!!"); IfJsErrorFailLog(ChakraRTInterface::JsCreateRuntime(jsrtAttributes, nullptr, &runtime)); chRuntime = runtime; if (HostConfigFlags::flags.DebugLaunch) { Debugger* debugger = Debugger::GetDebugger(runtime); debugger->StartDebugging(runtime); } JsContextRef context = JS_INVALID_REFERENCE; IfJsErrorFailLog(ChakraRTInterface::JsCreateContext(runtime, &context)); //Don't need collect callback since this is always in replay IfJsErrorFailLog(ChakraRTInterface::JsSetCurrentContext(context)); } #else IfJsErrorFailLog(ChakraRTInterface::JsCreateRuntime(jsrtAttributes, nullptr, &runtime)); chRuntime = runtime; if (HostConfigFlags::flags.DebugLaunch) { Debugger* debugger = Debugger::GetDebugger(runtime); debugger->StartDebugging(runtime); } JsContextRef context = JS_INVALID_REFERENCE; IfJsErrorFailLog(ChakraRTInterface::JsCreateContext(runtime, &context)); IfJsErrorFailLog(ChakraRTInterface::JsSetCurrentContext(context)); #endif #ifdef DEBUG ChakraRTInterface::SetCheckOpHelpersFlag(true); #endif #ifdef ENABLE_DEBUG_CONFIG_OPTIONS ChakraRTInterface::SetOOPCFGRegistrationFlag(false); #endif if (!WScriptJsrt::Initialize()) { IfFailGo(E_FAIL); } if (_fullpath(fullPath, fileName, _MAX_PATH) == nullptr) { IfFailGo(E_FAIL); } // canonicalize that path name to lower case for the profile storage // REVIEW: Assuming no utf8 characters here len = strlen(fullPath); for (size_t i = 0; i < len; i++) { fullPath[i] = (char)tolower(fullPath[i]); } if (HostConfigFlags::flags.GenerateLibraryByteCodeHeaderIsEnabled) { if (HostConfigFlags::flags.GenerateLibraryByteCodeHeader != nullptr && *HostConfigFlags::flags.GenerateLibraryByteCodeHeader != _u('\0')) { CHAR libraryName[_MAX_PATH]; CHAR ext[_MAX_EXT]; _splitpath_s(fullPath, NULL, 0, NULL, 0, libraryName, _countof(libraryName), ext, _countof(ext)); IfFailGo(CreateLibraryByteCodeHeader(fileContents, lengthBytes, HostConfigFlags::flags.GenerateLibraryByteCodeHeader, libraryName)); } else { fwprintf(stderr, _u("FATAL ERROR: -GenerateLibraryByteCodeHeader must provide the file name, i.e., -GenerateLibraryByteCodeHeader:<bytecode file name>, exiting\n")); IfFailGo(E_FAIL); } } else if (HostConfigFlags::flags.SerializedIsEnabled) { CreateAndRunSerializedScript(fileName, fileContents, fullPath); } else { IfFailGo(RunScript(fileName, fileContents, nullptr, fullPath)); } } Error: if (Debugger::debugger != nullptr) { Debugger::debugger->CompareOrWriteBaselineFile(fileName); Debugger::CloseDebugger(); } ChakraRTInterface::JsSetCurrentContext(nullptr); if (runtime != JS_INVALID_RUNTIME_HANDLE) { ChakraRTInterface::JsDisposeRuntime(runtime); } _flushall(); return hr; }
HRESULT ExecuteTest(const char* fileName) { HRESULT hr = S_OK; LPCWSTR fileContents = nullptr; JsRuntimeHandle runtime = JS_INVALID_RUNTIME_HANDLE; bool isUtf8 = false; LPCOLESTR contentsRaw = nullptr; UINT lengthBytes = 0; JsContextRef context = JS_INVALID_REFERENCE; char fullPath[_MAX_PATH]; size_t len = 0; hr = Helpers::LoadScriptFromFile(fileName, fileContents, &isUtf8, &contentsRaw, &lengthBytes); contentsRaw; lengthBytes; // Unused for now. IfFailGo(hr); if (HostConfigFlags::flags.GenerateLibraryByteCodeHeaderIsEnabled) { jsrtAttributes = (JsRuntimeAttributes)(jsrtAttributes | JsRuntimeAttributeSerializeLibraryByteCode); } IfJsErrorFailLog(ChakraRTInterface::JsCreateRuntime(jsrtAttributes, nullptr, &runtime)); if (HostConfigFlags::flags.DebugLaunch) { Debugger* debugger = Debugger::GetDebugger(runtime); debugger->StartDebugging(runtime); } IfJsErrorFailLog(ChakraRTInterface::JsCreateContext(runtime, &context)); IfJsErrorFailLog(ChakraRTInterface::JsSetCurrentContext(context)); #ifdef DEBUG ChakraRTInterface::SetCheckOpHelpersFlag(true); #endif if (!WScriptJsrt::Initialize()) { IfFailGo(E_FAIL); } if (_fullpath(fullPath, fileName, _MAX_PATH) == nullptr) { IfFailGo(E_FAIL); } // canonicalize that path name to lower case for the profile storage // REVIEW: Assuming no utf8 characters here len = strlen(fullPath); for (size_t i = 0; i < len; i++) { fullPath[i] = (char) tolower(fullPath[i]); } if (HostConfigFlags::flags.GenerateLibraryByteCodeHeaderIsEnabled) { if (isUtf8) { if (HostConfigFlags::flags.GenerateLibraryByteCodeHeader != nullptr && *HostConfigFlags::flags.GenerateLibraryByteCodeHeader != _u('\0')) { CHAR libraryName[_MAX_PATH]; CHAR ext[_MAX_EXT]; _splitpath_s(fullPath, NULL, 0, NULL, 0, libraryName, _countof(libraryName), ext, _countof(ext)); IfFailGo(CreateLibraryByteCodeHeader(fileContents, (BYTE*)contentsRaw, lengthBytes, HostConfigFlags::flags.GenerateLibraryByteCodeHeader, libraryName)); } else { fwprintf(stderr, _u("FATAL ERROR: -GenerateLibraryByteCodeHeader must provide the file name, i.e., -GenerateLibraryByteCodeHeader:<bytecode file name>, exiting\n")); IfFailGo(E_FAIL); } } else { fwprintf(stderr, _u("FATAL ERROR: GenerateLibraryByteCodeHeader flag can only be used on UTF8 file, exiting\n")); IfFailGo(E_FAIL); } } else if (HostConfigFlags::flags.SerializedIsEnabled) { if (isUtf8) { CreateAndRunSerializedScript(fileName, fileContents, fullPath); } else { fwprintf(stderr, _u("FATAL ERROR: Serialized flag can only be used on UTF8 file, exiting\n")); IfFailGo(E_FAIL); } } else { IfFailGo(RunScript(fileName, fileContents, nullptr, fullPath)); } Error: if (Debugger::debugger != nullptr) { Debugger::debugger->CompareOrWriteBaselineFile(fileName); Debugger::CloseDebugger(); } ChakraRTInterface::JsSetCurrentContext(nullptr); if (runtime != JS_INVALID_RUNTIME_HANDLE) { ChakraRTInterface::JsDisposeRuntime(runtime); } _flushall(); return hr; }