/// <summary> /// Initializes a JS engine /// </summary> private static void Initialize() { if (_initialized) { return; } lock (_initializationSynchronizer) { if (_initialized) { return; } if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { try { AssemblyResolver.Initialize(); } catch (InvalidOperationException e) { throw CoreErrorHelpers.WrapEngineLoadException(e, EngineName, EngineVersion); } } _initialized = true; } }
private static WrapperEngineLoadException WrapDllNotFoundException( DllNotFoundException originalDllNotFoundException) { string originalMessage = originalDllNotFoundException.Message; string description; string message; bool isMonoRuntime = Utils.IsMonoRuntime(); if ((isMonoRuntime && originalMessage == DllName.Universal) || originalMessage.ContainsQuotedValue(DllName.Universal)) { const string buildInstructionsUrl = "https://github.com/Microsoft/ChakraCore/wiki/Building-ChakraCore#{0}"; const string manualInstallationInstructionsUrl = "https://github.com/Taritsyn/JavaScriptEngineSwitcher/wiki/ChakraCore#{0}"; Architecture osArchitecture = RuntimeInformation.OSArchitecture; var stringBuilderPool = StringBuilderPool.Shared; StringBuilder descriptionBuilder = stringBuilderPool.Rent(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { descriptionBuilder.AppendFormat(CoreStrings.Engine_AssemblyNotFound, DllName.ForWindows); descriptionBuilder.Append(" "); if (osArchitecture == Architecture.X64 || osArchitecture == Architecture.X86) { descriptionBuilder.AppendFormat(CoreStrings.Engine_NuGetPackageInstallationRequired, Utils.Is64BitProcess() ? "JavaScriptEngineSwitcher.ChakraCore.Native.win-x64" : "JavaScriptEngineSwitcher.ChakraCore.Native.win-x86" ); } else if (osArchitecture == Architecture.Arm) { descriptionBuilder.AppendFormat(CoreStrings.Engine_NuGetPackageInstallationRequired, "JavaScriptEngineSwitcher.ChakraCore.Native.win-arm"); } else { descriptionBuilder.AppendFormat(CoreStrings.Engine_NoNuGetPackageForProcessorArchitecture, "JavaScriptEngineSwitcher.ChakraCore.Native.win*", osArchitecture.ToString().ToLowerInvariant() ); descriptionBuilder.Append(" "); descriptionBuilder.AppendFormat(Strings.Engine_BuildNativeAssemblyForCurrentProcessorArchitecture, DllName.ForWindows, string.Format(buildInstructionsUrl, "windows") ); } } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { descriptionBuilder.AppendFormat(CoreStrings.Engine_AssemblyNotFound, DllName.ForLinux); descriptionBuilder.Append(" "); if (isMonoRuntime) { descriptionBuilder.AppendFormat(Strings.Engine_ManualInstallationUnderMonoRequired, "JavaScriptEngineSwitcher.ChakraCore.Native.linux-*", string.Format(manualInstallationInstructionsUrl, "linux") ); } else { if (osArchitecture == Architecture.X64) { descriptionBuilder.AppendFormat(CoreStrings.Engine_NuGetPackageInstallationRequired, "JavaScriptEngineSwitcher.ChakraCore.Native.linux-x64"); } else { descriptionBuilder.AppendFormat(CoreStrings.Engine_NoNuGetPackageForProcessorArchitecture, "JavaScriptEngineSwitcher.ChakraCore.Native.linux-*", osArchitecture.ToString().ToLowerInvariant() ); descriptionBuilder.Append(" "); descriptionBuilder.AppendFormat(Strings.Engine_BuildNativeAssemblyForCurrentProcessorArchitecture, DllName.ForLinux, string.Format(buildInstructionsUrl, "linux") ); } } } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { descriptionBuilder.AppendFormat(CoreStrings.Engine_AssemblyNotFound, DllName.ForOsx); descriptionBuilder.Append(" "); if (isMonoRuntime) { descriptionBuilder.AppendFormat(Strings.Engine_ManualInstallationUnderMonoRequired, "JavaScriptEngineSwitcher.ChakraCore.Native.osx-*", string.Format(manualInstallationInstructionsUrl, "os-x") ); } else { if (osArchitecture == Architecture.X64) { descriptionBuilder.AppendFormat(CoreStrings.Engine_NuGetPackageInstallationRequired, "JavaScriptEngineSwitcher.ChakraCore.Native.osx-x64"); } else { descriptionBuilder.AppendFormat(CoreStrings.Engine_NoNuGetPackageForProcessorArchitecture, "JavaScriptEngineSwitcher.ChakraCore.Native.osx-*", osArchitecture.ToString().ToLowerInvariant() ); descriptionBuilder.Append(" "); descriptionBuilder.AppendFormat(Strings.Engine_BuildNativeAssemblyForCurrentProcessorArchitecture, DllName.ForOsx, string.Format(buildInstructionsUrl, "os-x") ); } } } else { descriptionBuilder.Append(CoreStrings.Engine_OperatingSystemNotSupported); } description = descriptionBuilder.ToString(); stringBuilderPool.Return(descriptionBuilder); message = CoreErrorHelpers.GenerateEngineLoadErrorMessage(description, EngineName); } else { description = originalMessage; message = CoreErrorHelpers.GenerateEngineLoadErrorMessage(description, EngineName, true); } var wrapperEngineLoadException = new WrapperEngineLoadException(message, EngineName, EngineVersion, originalDllNotFoundException) { Description = description }; return(wrapperEngineLoadException); }
private static WrapperException WrapJsException(OriginalException originalException, string defaultDocumentName = null) { WrapperException wrapperException; JsErrorCode errorCode = originalException.ErrorCode; string description = originalException.Message; string message = description; string type = string.Empty; string documentName = defaultDocumentName ?? string.Empty; int lineNumber = 0; int columnNumber = 0; string callStack = string.Empty; string sourceFragment = string.Empty; var originalScriptException = originalException as OriginalScriptException; if (originalScriptException != null) { JsValue metadataValue = originalScriptException.Metadata; if (metadataValue.IsValid) { JsValue errorValue = metadataValue.GetProperty("exception"); JsValueType errorValueType = errorValue.ValueType; if (errorValueType == JsValueType.Error || errorValueType == JsValueType.Object) { JsPropertyId innerErrorPropertyId = JsPropertyId.FromString("innerException"); if (errorValue.HasProperty(innerErrorPropertyId)) { JsValue innerErrorValue = errorValue.GetProperty(innerErrorPropertyId); JsPropertyId metadataPropertyId = JsPropertyId.FromString("metadata"); if (innerErrorValue.HasProperty(metadataPropertyId)) { errorValue = innerErrorValue; metadataValue = innerErrorValue.GetProperty(metadataPropertyId); } } JsValue messagePropertyValue = errorValue.GetProperty("message"); string localDescription = messagePropertyValue.ConvertToString().ToString(); if (!string.IsNullOrWhiteSpace(localDescription)) { description = localDescription; } JsValue namePropertyValue = errorValue.GetProperty("name"); type = namePropertyValue.ValueType == JsValueType.String ? namePropertyValue.ToString() : string.Empty; JsPropertyId descriptionPropertyId = JsPropertyId.FromString("description"); if (errorValue.HasProperty(descriptionPropertyId)) { JsValue descriptionPropertyValue = errorValue.GetProperty(descriptionPropertyId); localDescription = descriptionPropertyValue.ConvertToString().ToString(); if (!string.IsNullOrWhiteSpace(localDescription)) { description = localDescription; } } if (type == JsErrorType.Syntax) { errorCode = JsErrorCode.ScriptCompile; } else { JsPropertyId numberPropertyId = JsPropertyId.FromString("number"); if (errorValue.HasProperty(numberPropertyId)) { JsValue numberPropertyValue = errorValue.GetProperty(numberPropertyId); int errorNumber = numberPropertyValue.ValueType == JsValueType.Number ? numberPropertyValue.ToInt32() : 0; errorCode = (JsErrorCode)errorNumber; } } JsPropertyId urlPropertyId = JsPropertyId.FromString("url"); if (metadataValue.HasProperty(urlPropertyId)) { JsValue urlPropertyValue = metadataValue.GetProperty(urlPropertyId); string url = urlPropertyValue.ValueType == JsValueType.String ? urlPropertyValue.ToString() : string.Empty; if (url != "undefined") { documentName = url; } } JsPropertyId linePropertyId = JsPropertyId.FromString("line"); if (metadataValue.HasProperty(linePropertyId)) { JsValue linePropertyValue = metadataValue.GetProperty(linePropertyId); lineNumber = linePropertyValue.ValueType == JsValueType.Number ? linePropertyValue.ToInt32() + 1 : 0; } JsPropertyId columnPropertyId = JsPropertyId.FromString("column"); if (metadataValue.HasProperty(columnPropertyId)) { JsValue columnPropertyValue = metadataValue.GetProperty(columnPropertyId); columnNumber = columnPropertyValue.ValueType == JsValueType.Number ? columnPropertyValue.ToInt32() + 1 : 0; } string sourceLine = string.Empty; JsPropertyId sourcePropertyId = JsPropertyId.FromString("source"); if (metadataValue.HasProperty(sourcePropertyId)) { JsValue sourcePropertyValue = metadataValue.GetProperty(sourcePropertyId); sourceLine = sourcePropertyValue.ValueType == JsValueType.String ? sourcePropertyValue.ToString() : string.Empty; sourceFragment = TextHelpers.GetTextFragmentFromLine(sourceLine, columnNumber); } JsPropertyId stackPropertyId = JsPropertyId.FromString("stack"); if (errorValue.HasProperty(stackPropertyId)) { JsValue stackPropertyValue = errorValue.GetProperty(stackPropertyId); string messageWithTypeAndCallStack = stackPropertyValue.ValueType == JsValueType.String ? stackPropertyValue.ToString() : string.Empty; string messageWithType = errorValue.ConvertToString().ToString(); string rawCallStack = messageWithTypeAndCallStack .TrimStart(messageWithType) .TrimStart("Error") .TrimStart(new char[] { '\n', '\r' }) ; string callStackWithSourceFragment = string.Empty; ErrorLocationItem[] callStackItems = CoreErrorHelpers.ParseErrorLocation(rawCallStack); if (callStackItems.Length > 0) { ErrorLocationItem firstCallStackItem = callStackItems[0]; firstCallStackItem.SourceFragment = sourceFragment; documentName = firstCallStackItem.DocumentName; lineNumber = firstCallStackItem.LineNumber; columnNumber = firstCallStackItem.ColumnNumber; callStack = CoreErrorHelpers.StringifyErrorLocationItems(callStackItems, true); callStackWithSourceFragment = CoreErrorHelpers.StringifyErrorLocationItems(callStackItems); } message = CoreErrorHelpers.GenerateScriptErrorMessage(type, description, callStackWithSourceFragment); } else { message = CoreErrorHelpers.GenerateScriptErrorMessage(type, description, documentName, lineNumber, columnNumber, sourceFragment); } } else if (errorValueType == JsValueType.String) { message = errorValue.ToString(); description = message; } else { message = errorValue.ConvertToString().ToString(); description = message; } } WrapperScriptException wrapperScriptException; if (errorCode == JsErrorCode.ScriptCompile) { wrapperScriptException = new WrapperCompilationException(message, EngineName, EngineVersion, originalScriptException); } else if (errorCode == JsErrorCode.ScriptTerminated) { message = CoreStrings.Runtime_ScriptInterrupted; description = message; wrapperScriptException = new WrapperInterruptedException(message, EngineName, EngineVersion, originalScriptException) { CallStack = callStack }; } else { wrapperScriptException = new WrapperRuntimeException(message, EngineName, EngineVersion, originalScriptException) { CallStack = callStack }; } wrapperScriptException.Type = type; wrapperScriptException.DocumentName = documentName; wrapperScriptException.LineNumber = lineNumber; wrapperScriptException.ColumnNumber = columnNumber; wrapperScriptException.SourceFragment = sourceFragment; wrapperException = wrapperScriptException; } else { if (originalException is OriginalUsageException) { wrapperException = new WrapperUsageException(message, EngineName, EngineVersion, originalException); } else if (originalException is OriginalEngineException) { wrapperException = new WrapperEngineException(message, EngineName, EngineVersion, originalException); } else if (originalException is OriginalFatalException) { wrapperException = new WrapperFatalException(message, EngineName, EngineVersion, originalException); } else { wrapperException = new WrapperException(message, EngineName, EngineVersion, originalException); } } wrapperException.Description = description; return(wrapperException); }
/// <summary> /// Constructs an instance of adapter for the ChakraCore JS engine /// </summary> /// <param name="settings">Settings of the ChakraCore JS engine</param> public ChakraCoreJsEngine(ChakraCoreSettings settings) { #if NETFULL Initialize(); #endif ChakraCoreSettings chakraCoreSettings = settings ?? new ChakraCoreSettings(); JsRuntimeAttributes attributes = JsRuntimeAttributes.AllowScriptInterrupt; if (chakraCoreSettings.DisableBackgroundWork) { attributes |= JsRuntimeAttributes.DisableBackgroundWork; } if (chakraCoreSettings.DisableEval) { attributes |= JsRuntimeAttributes.DisableEval; } if (chakraCoreSettings.DisableExecutablePageAllocation) { attributes |= JsRuntimeAttributes.DisableExecutablePageAllocation; } if (chakraCoreSettings.DisableFatalOnOOM) { attributes |= JsRuntimeAttributes.DisableFatalOnOOM; } if (chakraCoreSettings.DisableNativeCodeGeneration) { attributes |= JsRuntimeAttributes.DisableNativeCodeGeneration; } if (chakraCoreSettings.EnableExperimentalFeatures) { attributes |= JsRuntimeAttributes.EnableExperimentalFeatures; } #if NETSTANDARD1_3 _dispatcher = new ScriptDispatcher(); #else _dispatcher = new ScriptDispatcher(chakraCoreSettings.MaxStackSize); #endif _promiseContinuationCallback = PromiseContinuationCallback; try { _dispatcher.Invoke(() => { _jsRuntime = JsRuntime.Create(attributes, null); _jsRuntime.MemoryLimit = settings.MemoryLimit; _jsContext = _jsRuntime.CreateContext(); if (_jsContext.IsValid) { _jsContext.AddRef(); } }); } catch (DllNotFoundException e) { throw WrapDllNotFoundException(e); } catch (Exception e) { throw CoreErrorHelpers.WrapEngineLoadException(e, EngineName, EngineVersion, true); } finally { if (!_jsContext.IsValid) { Dispose(); } } }
private static JsValue CreateErrorFromWrapperException(WrapperException exception) { var originalException = exception.InnerException as JsException; JsErrorCode errorCode = originalException != null ? originalException.ErrorCode : JsErrorCode.NoError; string description = exception.Description; JsValue innerErrorValue = JsErrorHelpers.CreateError(description); innerErrorValue.SetProperty("description", JsValue.FromString(description), true); JsValue metadataValue = JsValue.CreateObject(); var scriptException = exception as WrapperScriptException; if (scriptException != null) { string type = scriptException.Type; string documentName = scriptException.DocumentName; int lineNumber = scriptException.LineNumber; if (lineNumber > 0) { lineNumber--; } int columnNumber = scriptException.ColumnNumber; if (columnNumber > 0) { columnNumber--; } string sourceFragment = scriptException.SourceFragment; innerErrorValue.SetProperty("name", JsValue.FromString(type), true); var runtimeException = scriptException as WrapperRuntimeException; if (runtimeException != null) { var errorNumber = (int)errorCode; string callStack = runtimeException.CallStack; string messageWithTypeAndCallStack = CoreErrorHelpers.GenerateScriptErrorMessage(type, description, callStack); innerErrorValue.SetProperty("number", JsValue.FromInt32(errorNumber), true); if (!string.IsNullOrWhiteSpace(callStack)) { innerErrorValue.SetProperty("stack", JsValue.FromString(messageWithTypeAndCallStack), true); } } else { innerErrorValue.SetProperty("url", JsValue.FromString(documentName), true); innerErrorValue.SetProperty("line", JsValue.FromInt32(lineNumber), true); innerErrorValue.SetProperty("column", JsValue.FromInt32(columnNumber), true); innerErrorValue.SetProperty("source", JsValue.FromString(sourceFragment), true); } metadataValue.SetProperty("url", JsValue.FromString(documentName), true); metadataValue.SetProperty("line", JsValue.FromInt32(lineNumber), true); metadataValue.SetProperty("column", JsValue.FromInt32(columnNumber), true); metadataValue.SetProperty("source", JsValue.FromString(sourceFragment), true); } innerErrorValue.SetProperty("metadata", metadataValue, true); JsValue errorValue = JsErrorHelpers.CreateError(description); errorValue.SetProperty("innerException", innerErrorValue, true); return(errorValue); }