Exemple #1
0
        /// <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;
            }
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        /// <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);
        }