コード例 #1
0
        /// <summary>
        /// Determines whether an object has a property
        /// </summary>
        /// <remarks>
        /// Requires an active script context.
        /// </remarks>
        /// <param name="source">The JavaScript value</param>
        /// <param name="propertyName">The name of the property</param>
        /// <returns>Whether the object (or a prototype) has the property</returns>
        public static bool HasProperty(this JsValue source, string propertyName)
        {
            JsPropertyId propertyId = JsPropertyId.FromString(propertyName);
            bool         result     = source.HasProperty(propertyId);

            return(result);
        }
コード例 #2
0
        protected override bool InnerHasVariable(string variableName)
        {
            bool result = _dispatcher.Invoke(() =>
            {
                using (CreateJsScope())
                {
                    try
                    {
                        JsValue globalObj       = JsValue.GlobalObject;
                        JsPropertyId variableId = JsPropertyId.FromString(variableName);
                        bool variableExist      = globalObj.HasProperty(variableId);

                        if (variableExist)
                        {
                            JsValue variableValue = globalObj.GetProperty(variableId);
                            variableExist         = variableValue.ValueType != JsValueType.Undefined;
                        }

                        return(variableExist);
                    }
                    catch (OriginalException e)
                    {
                        throw WrapJsException(e);
                    }
                }
            });

            return(result);
        }
コード例 #3
0
        protected override object InnerCallFunction(string functionName, params object[] args)
        {
            object result = _dispatcher.Invoke(() =>
            {
                using (CreateJsScope())
                {
                    try
                    {
                        JsValue globalObj       = JsValue.GlobalObject;
                        JsPropertyId functionId = JsPropertyId.FromString(functionName);

                        bool functionExist = globalObj.HasProperty(functionId);
                        if (!functionExist)
                        {
                            throw new JsRuntimeException(
                                string.Format(CoreStrings.Runtime_FunctionNotExist, functionName));
                        }

                        JsValue resultValue;
                        JsValue functionValue = globalObj.GetProperty(functionId);

                        if (args.Length > 0)
                        {
                            JsValue[] processedArgs = MapToScriptType(args);

                            foreach (JsValue processedArg in processedArgs)
                            {
                                AddReferenceToValue(processedArg);
                            }

                            JsValue[] allProcessedArgs = new[] { globalObj }
                            .Concat(processedArgs)
                            .ToArray()
                            ;
                            resultValue = functionValue.CallFunction(allProcessedArgs);

                            foreach (JsValue processedArg in processedArgs)
                            {
                                RemoveReferenceToValue(processedArg);
                            }
                        }
                        else
                        {
                            resultValue = functionValue.CallFunction(globalObj);
                        }

                        return(MapToHostType(resultValue));
                    }
                    catch (OriginalJsException e)
                    {
                        throw ConvertJsExceptionToJsRuntimeException(e);
                    }
                }
            });

            return(result);
        }
コード例 #4
0
        /// <summary>
        /// Makes a mapping of value from the script type to a host type
        /// </summary>
        /// <param name="value">The source value</param>
        /// <returns>The mapped value</returns>
        public object MapToHostType(JsValue value)
        {
            JsValueType valueType = value.ValueType;
            object      result    = null;

            switch (valueType)
            {
            case JsValueType.Null:
                result = null;
                break;

            case JsValueType.Undefined:                     // Undefined is not mapped
                result = value;
                break;

            case JsValueType.Boolean:
                result = value.ToBoolean();
                break;

            case JsValueType.Number:
                result = NumericHelpers.CastDoubleValueToCorrectType(value.ToDouble());
                break;

            case JsValueType.String:
                result = value.ToString();
                break;

            case JsValueType.Function:
                JsPropertyId externalObjectPropertyId = JsPropertyId.FromString(ExternalObjectPropertyName);
                if (value.HasProperty(externalObjectPropertyId))
                {
                    JsValue externalObjectValue = value.GetProperty(externalObjectPropertyId);
                    result = externalObjectValue.HasExternalData ?
                             GCHandle.FromIntPtr(externalObjectValue.ExternalData).Target : null;
                }

                result ??= value.ConvertToObject();
                break;

            case JsValueType.Object:
            case JsValueType.Error:
            case JsValueType.Array:
            case JsValueType.Symbol:
            case JsValueType.ArrayBuffer:
            case JsValueType.TypedArray:
            case JsValueType.DataView:
                result = value.HasExternalData ?
                         GCHandle.FromIntPtr(value.ExternalData).Target : value.ConvertToObject();
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            return(result);
        }
コード例 #5
0
        protected override void InnerRemoveVariable(string variableName)
        {
            InvokeScript(() =>
            {
                JsValue globalObj       = JsValue.GlobalObject;
                JsPropertyId variableId = JsPropertyId.FromString(variableName);

                if (globalObj.HasProperty(variableId))
                {
                    globalObj.SetProperty(variableId, JsValue.Undefined, true);
                }
            });
        }
コード例 #6
0
        protected override object InnerCallFunction(string functionName, params object[] args)
        {
            object result = InvokeScript(() =>
            {
                JsValue globalObj       = JsValue.GlobalObject;
                JsPropertyId functionId = JsPropertyId.FromString(functionName);

                bool functionExist = globalObj.HasProperty(functionId);
                if (!functionExist)
                {
                    throw new JsRuntimeException(
                        string.Format(CoreStrings.Runtime_FunctionNotExist, functionName));
                }

                JsValue resultValue;
                JsValue functionValue = globalObj.GetProperty(functionId);

                if (args.Length > 0)
                {
                    JsValue[] processedArgs = MapToScriptType(args);

                    foreach (JsValue processedArg in processedArgs)
                    {
                        AddReferenceToValue(processedArg);
                    }

                    JsValue[] allProcessedArgs = new[] { globalObj }.Concat(processedArgs).ToArray();
                    resultValue = functionValue.CallFunction(allProcessedArgs);

                    foreach (JsValue processedArg in processedArgs)
                    {
                        RemoveReferenceToValue(processedArg);
                    }
                }
                else
                {
                    resultValue = functionValue.CallFunction(globalObj);
                }
                //modified by chuan.yin in 2017/4/29
                //return MapToHostType(resultValue);
                return(ConvertJsObjectToNetObject(resultValue));
            });

            return(result);
        }
コード例 #7
0
        protected override bool InnerHasVariable(string variableName)
        {
            bool result = InvokeScript(() =>
            {
                JsValue globalObj       = JsValue.GlobalObject;
                JsPropertyId variableId = JsPropertyId.FromString(variableName);
                bool variableExist      = globalObj.HasProperty(variableId);

                if (variableExist)
                {
                    JsValue variableValue = globalObj.GetProperty(variableId);
                    variableExist         = variableValue.ValueType != JsValueType.Undefined;
                }

                return(variableExist);
            });

            return(result);
        }
コード例 #8
0
        protected override void InnerRemoveVariable(string variableName)
        {
            _dispatcher.Invoke(() =>
            {
                using (CreateJsScope())
                {
                    try
                    {
                        JsValue globalObj       = JsValue.GlobalObject;
                        JsPropertyId variableId = JsPropertyId.FromString(variableName);

                        if (globalObj.HasProperty(variableId))
                        {
                            globalObj.SetProperty(variableId, JsValue.Undefined, true);
                        }
                    }
                    catch (OriginalException e)
                    {
                        throw WrapJsException(e);
                    }
                }
            });
        }
コード例 #9
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);
        }
コード例 #10
0
        protected override object InnerCallFunction(string functionName, params object[] args)
        {
            object result = _dispatcher.Invoke(() =>
            {
                using (new JsScope(_jsContext))
                {
                    try
                    {
                        JsValue globalObj       = JsValue.GlobalObject;
                        JsPropertyId functionId = JsPropertyId.FromString(functionName);

                        bool functionExist = globalObj.HasProperty(functionId);
                        if (!functionExist)
                        {
                            throw new WrapperRuntimeException(
                                string.Format(CoreStrings.Runtime_FunctionNotExist, functionName),
                                EngineName, EngineVersion
                                );
                        }

                        JsValue resultValue;
                        JsValue functionValue = globalObj.GetProperty(functionId);

                        int argCount = args.Length;
                        if (argCount > 0)
                        {
                            int processedArgCount = argCount + 1;
                            var processedArgs     = new JsValue[processedArgCount];
                            processedArgs[0]      = globalObj;

                            for (int argIndex = 0; argIndex < argCount; argIndex++)
                            {
                                JsValue processedArg = _typeMapper.MapToScriptType(args[argIndex]);
                                AddReferenceToValue(processedArg);

                                processedArgs[argIndex + 1] = processedArg;
                            }

                            try
                            {
                                resultValue = functionValue.CallFunction(processedArgs);
                            }
                            finally
                            {
                                for (int argIndex = 1; argIndex < processedArgCount; argIndex++)
                                {
                                    RemoveReferenceToValue(processedArgs[argIndex]);
                                }
                            }
                        }
                        else
                        {
                            resultValue = functionValue.CallFunction(globalObj);
                        }

                        return(_typeMapper.MapToHostType(resultValue));
                    }
                    catch (OriginalException e)
                    {
                        throw WrapJsException(e);
                    }
                }
            });

            return(result);
        }
コード例 #11
0
        static void Main(string[] args)
        {
            using (JsRuntime runtime = JsRuntime.Create())
            {
                JsContext context = runtime.CreateContext();
                context.AddRef();

                JsSourceContext sourceContext = JsSourceContext.FromIntPtr(IntPtr.Zero);
                var             moduleManager = new EsModuleManager(() => sourceContext++);
                var             scope         = new JsScope(context);

                try
                {
                    JsValue moduleNamespace;

                    // It's not working. Always returns a result equal to `undefined`.
                    JsValue resultValue = moduleManager.EvaluateModuleCode(
                        @"import * as geometry from './geometry/geometry.js';
new geometry.Square(15).area;",
                        "Files/main-with-return-value.js",
                        out moduleNamespace
                        );
                    WriteLine("Return value: {0}", resultValue.ConvertToString().ToString());

                    // It's works. We can return the result value by using the default export.
                    moduleManager.EvaluateModuleCode(
                        @"import * as geometry from './geometry/geometry.js';
export default new geometry.Square(20).area;",
                        "Files/main-with-default-export.js",
                        out moduleNamespace
                        );
                    JsPropertyId defaultPropertyId    = JsPropertyId.FromString("default");
                    JsValue      defaultPropertyValue = moduleNamespace.GetProperty(defaultPropertyId);
                    WriteLine("Default export: {0}", defaultPropertyValue.ConvertToString().ToString());

                    // It's works. We can return the result value by using the named export.
                    moduleManager.EvaluateModuleCode(
                        @"import * as geometry from './geometry/geometry.js';
export let squareArea = new geometry.Square(25).area;",
                        "Files/main-with-named-export.js",
                        out moduleNamespace
                        );
                    JsPropertyId squareAreaPropertyId    = JsPropertyId.FromString("squareArea");
                    JsValue      squareAreaPropertyValue = moduleNamespace.GetProperty(squareAreaPropertyId);
                    WriteLine("Named export: {0}", squareAreaPropertyValue.ConvertToString().ToString());
                }
                catch (JsException e)
                {
                    WriteLine("During working of JavaScript engine an error occurred.");
                    WriteLine();
                    Write(e.Message);

                    var scriptException = e as JsScriptException;
                    if (scriptException != null)
                    {
                        WriteLine();

                        JsValue     errorValue     = scriptException.Metadata.GetProperty("exception");
                        JsValueType errorValueType = errorValue.ValueType;

                        if (errorValueType == JsValueType.Error || errorValueType == JsValueType.Object)
                        {
                            JsValue      messageValue;
                            JsPropertyId stackPropertyId = JsPropertyId.FromString("stack");

                            if (errorValue.HasProperty(stackPropertyId))
                            {
                                messageValue = errorValue.GetProperty(stackPropertyId);
                            }
                            else
                            {
                                messageValue = errorValue.GetProperty("message");
                            }

                            WriteLine(messageValue.ToString());
                        }
                        else if (errorValueType == JsValueType.String)
                        {
                            WriteLine(errorValue.ToString());
                        }
                        else
                        {
                            WriteLine(errorValue.ConvertToString().ToString());
                        }
                    }
                }
                finally
                {
                    scope.Dispose();
                    moduleManager?.Dispose();
                    context.Release();
                }
            }
        }
コード例 #12
0
        private static JsRuntimeException ConvertJsExceptionToJsRuntimeException(
            OriginalJsException jsException)
        {
            string message        = jsException.Message;
            string category       = string.Empty;
            int    lineNumber     = 0;
            int    columnNumber   = 0;
            string sourceFragment = string.Empty;

            var jsScriptException = jsException as JsScriptException;

            if (jsScriptException != null)
            {
                category = "Script error";
                JsValue errorValue = jsScriptException.Error;

                JsPropertyId stackPropertyId = JsPropertyId.FromString("stack");
                if (errorValue.HasProperty(stackPropertyId))
                {
                    JsValue stackPropertyValue = errorValue.GetProperty(stackPropertyId);
                    message = stackPropertyValue.ConvertToString().ToString();
                }
                else
                {
                    JsValue messagePropertyValue = errorValue.GetProperty("message");
                    string  scriptMessage        = messagePropertyValue.ConvertToString().ToString();
                    if (!string.IsNullOrWhiteSpace(scriptMessage))
                    {
                        message = string.Format("{0}: {1}", message.TrimEnd('.'), scriptMessage);
                    }
                }

                JsPropertyId linePropertyId = JsPropertyId.FromString("line");
                if (errorValue.HasProperty(linePropertyId))
                {
                    JsValue linePropertyValue = errorValue.GetProperty(linePropertyId);
                    lineNumber = linePropertyValue.ConvertToNumber().ToInt32() + 1;
                }

                JsPropertyId columnPropertyId = JsPropertyId.FromString("column");
                if (errorValue.HasProperty(columnPropertyId))
                {
                    JsValue columnPropertyValue = errorValue.GetProperty(columnPropertyId);
                    columnNumber = columnPropertyValue.ConvertToNumber().ToInt32() + 1;
                }

                if (lineNumber <= 0 && columnNumber <= 0)
                {
                    Match errorStringMatch = _errorStringRegex.Match(message);
                    if (errorStringMatch.Success)
                    {
                        GroupCollection errorStringGroups = errorStringMatch.Groups;

                        lineNumber   = int.Parse(errorStringGroups["lineNumber"].Value);
                        columnNumber = int.Parse(errorStringGroups["columnNumber"].Value);
                    }
                }

                JsPropertyId sourcePropertyId = JsPropertyId.FromString("source");
                if (errorValue.HasProperty(sourcePropertyId))
                {
                    JsValue sourcePropertyValue = errorValue.GetProperty(sourcePropertyId);
                    sourceFragment = sourcePropertyValue.ConvertToString().ToString();
                }
            }
            else if (jsException is JsUsageException)
            {
                category = "Usage error";
            }
            else if (jsException is JsEngineException)
            {
                category = "Engine error";
            }
            else if (jsException is JsFatalException)
            {
                category = "Fatal error";
            }

            var jsEngineException = new JsRuntimeException(message, EngineName, EngineVersion)
            {
                ErrorCode      = ((uint)jsException.ErrorCode).ToString(CultureInfo.InvariantCulture),
                Category       = category,
                LineNumber     = lineNumber,
                ColumnNumber   = columnNumber,
                SourceFragment = sourceFragment
            };

            return(jsEngineException);
        }