/// <summary> /// added by chuan.yin in 2017/4/27 /// </summary> /// <param name="value"></param> /// <returns></returns> private object MapToNetObject(JsValue value) { if (value.ValueType == JsValueType.Object) { var descstr = value.ConvertToString().ToString(); if (descstr == "[object Object]") { //json对象 var result = new Dictionary <string, object>(); var names = value.GetOwnPropertyNames(); if (names.ValueType == JsValueType.String) { result.Add(names.ToString(), ConvertJsObjectToNetObject(value.GetProperty(names.ToString()))); } else if (names.ValueType == JsValueType.Array) { var arrIndex = ToArray(names); foreach (var key in arrIndex) { result.Add(key.ToString(), ConvertJsObjectToNetObject(value.GetProperty(key.ToString()))); } } return(result); } else if (descstr.ToLower().Contains("gmt")) { var result = DateTime.MinValue; string format = "ddd MMM dd yyyy HH:mm:ss 'GMT'K"; bool validFormat = DateTime.TryParseExact(descstr.Split('(')[0].Trim(), format, CultureInfo.InvariantCulture, DateTimeStyles.None, out result); if (validFormat) { return(result); } else { return(descstr); } } else { return(value); } } else { return(value); } }
/// <summary> /// Gets an object's property /// </summary> /// <remarks> /// Requires an active script context. /// </remarks> /// <param name="source">The JavaScript value</param> /// <param name="name">The name of the property</param> /// <returns>The value of the property</returns> public static JsValue GetProperty(this JsValue source, string name) { JsPropertyId id = JsPropertyId.FromString(name); JsValue resultValue = source.GetProperty(id); return(resultValue); }
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); }
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); }
/// <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); }
/// <summary> /// Creates a new script exception from the error metadata /// </summary> /// <param name="metadata">JavaScript object representing the error metadata</param> /// <returns>Instance of the <see cref="JsScriptException"/> class</returns> public static JsScriptException CreateScriptExceptionFromMetadata(JsValue metadata) { JsValue namePropertyValue = metadata.GetProperty("name"); string type = namePropertyValue.ValueType == JsValueType.String ? namePropertyValue.ToString() : string.Empty; JsErrorCode errorCode = type == "SyntaxError" ? JsErrorCode.ScriptCompile : JsErrorCode.ScriptException; return(CreateScriptExceptionFromMetadata(errorCode, metadata)); }
private JToken VisitObject(JsValue value) { var jsonObject = new JObject(); var properties = Visit(value.GetOwnPropertyNames()).ToObject <string[]>(); foreach (var property in properties) { var propertyId = JsPropertyId.FromString(property); var propertyValue = value.GetProperty(propertyId); jsonObject.Add(property, Visit(propertyValue)); } return(jsonObject); }
public static IEnumerable <JsValue> EnumerateArrayValues(this JsValue val) { if (val.ValueType != JsValueType.Array) { throw new InvalidOperationException("Can't enumerate non array value"); } var lenId = JsPropertyId.FromString("length"); var len = val.GetProperty(lenId).ToInt32(); for (var i = 0; i < len; i++) { yield return(val.GetIndexedProperty(JsValue.FromInt(i))); } }
private JToken VisitArray(JsValue value) { var array = new JArray(); var propertyId = JsPropertyId.FromString("length"); var length = value.GetProperty(propertyId).ToInt32(); for (var i = 0; i < length; ++i) { var index = JsValue.FromInt(i); var element = value.GetIndexedProperty(index); array.Add(Visit(element)); } return(array); }
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); }
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); }
public static IEnumerable <KeyValuePair <string, JsValue> > EnumerateProperties(this JsValue _this) => from nameVal in EnumerateArrayValues(_this.GetOwnPropertyNames()) let name = nameVal.ToString() let propId = JsPropertyId.FromString(name) let val = _this.GetProperty(propId) select new KeyValuePair <string, JsValue>(name, val);
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); }
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); }
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(); } } }
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); }