public bool IsMatch(JsValueType expectJsType, Type expectCsType, bool isByRef, bool isOut) { var jsType = this.valueType; if (jsType == JsValueType.JsObject) { if (!isByRef) { return(false); } if (isOut) { return(true); } jsType = PuertsDLL.GetJsValueType(isolate, value, true); } if ((expectJsType & jsType) != jsType) { return(false); } if (jsType == JsValueType.NativeObject) { if (csType == null) { var typeId = NativeValueApi.GetValueFromArgument.GetTypeId(isolate, value, isByRef); if (typeId >= 0) { csType = JsEnv.jsEnvs[jsEnvIdx].TypeRegister.GetType(typeId); } } return(csType != null && expectCsType != null && expectCsType.IsAssignableFrom(csType)); } return(true); }
public bool IsMatch(JsValueType expectJsType, Type expectCsType, bool isByRef, bool isOut) { var jsType = this.valueType; if (jsType == JsValueType.JsObject) { if (!isByRef) { return(false); } if (isOut) { return(true); } jsType = PuertsDLL.GetJsValueType(isolate, value, true); } if ((expectJsType & jsType) != jsType) { return(false); } if (jsType == JsValueType.NativeObject) { if (obj == null) { obj = JsEnv.jsEnvs[jsEnvIdx].GeneralGetterManager.AnyTranslator(isolate, NativeValueApi.GetValueFromArgument, value, isByRef); } return(expectCsType != null && expectCsType.IsAssignableFrom(obj.GetType())); } return(true); }
/// <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> private object MapToHostType(IeJsValue value) { JsValueType valueType = value.ValueType; IeJsValue processedValue; object result; switch (valueType) { case JsValueType.Null: result = null; break; case JsValueType.Undefined: result = Undefined.Value; break; case JsValueType.Boolean: processedValue = value.ConvertToBoolean(); result = processedValue.ToBoolean(); break; case JsValueType.Number: processedValue = value.ConvertToNumber(); result = NumericHelpers.CastDoubleValueToCorrectType(processedValue.ToDouble()); break; case JsValueType.String: processedValue = value.ConvertToString(); result = processedValue.ToString(); break; case JsValueType.Object: case JsValueType.Function: case JsValueType.Error: case JsValueType.Array: #if NETSTANDARD1_3 result = ToObject(value); #else processedValue = value.ConvertToObject(); object obj = processedValue.ToObject(); if (!TypeConverter.IsPrimitiveType(obj.GetType())) { var hostObj = obj as HostObject; result = hostObj != null ? hostObj.Target : obj; } else { result = obj; } #endif break; default: throw new ArgumentOutOfRangeException(); } return(result); }
public ArgumentHelper(int jsEnvIdx, IntPtr isolate, IntPtr info, int index) { this.jsEnvIdx = jsEnvIdx; this.isolate = isolate; value = PuertsDLL.GetArgumentValue(info, index); valueType = PuertsDLL.GetJsValueType(isolate, value, false); obj = null; }
public bool IsMatch(JsValueType expectJsType, Type expectCsType, bool isByRef, bool isOut) { if (this.valueType == JsValueType.Invalid) { this.valueType = PuertsDLL.GetJsValueType(isolate, value, false); } var jsType = this.valueType; if (jsType == JsValueType.JsObject) { if (isByRef) { if (isOut) { return(true); } jsType = PuertsDLL.GetJsValueType(isolate, value, true); } else if ((expectJsType & jsType) == jsType) { return(true); } else { return(false); } } if ((expectJsType & jsType) != jsType) { return(false); } if (jsType == JsValueType.NativeObject) { if (expectCsType.IsArray) { if (obj == null) { obj = JsEnv.jsEnvs[jsEnvIdx].GeneralGetterManager.AnyTranslator(isolate, NativeValueApi.GetValueFromArgument, value, isByRef); } return(expectCsType != null && expectCsType.IsAssignableFrom(obj.GetType())); } else { if (csType == null) { var typeId = NativeValueApi.GetValueFromArgument.GetTypeId(isolate, value, isByRef); if (typeId >= 0) { csType = JsEnv.jsEnvs[jsEnvIdx].TypeRegister.GetType(typeId); } } return(csType != null && expectCsType != null && expectCsType.IsAssignableFrom(csType)); } } return(true); }
public ArgumentHelper(int jsEnvIdx, IntPtr isolate, IntPtr info, int index) { this.jsEnvIdx = jsEnvIdx; this.isolate = isolate; value = PuertsDLL.GetArgumentValue(info, index); valueType = JsValueType.Invalid; obj = null; csType = null; }
public static JsValueType GetJsTypeMask(Type type) { if (type.IsByRef) { return(GetJsTypeMask(type.GetElementType())); } Type underlyingType = Nullable.GetUnderlyingType(type); if (underlyingType != null) { return(GetJsTypeMask(underlyingType) | JsValueType.NullOrUndefined); } if (type.IsEnum) { return(GetJsTypeMask(Enum.GetUnderlyingType(type))); } JsValueType mash = 0; if (primitiveTypeMap.ContainsKey(type)) { mash = primitiveTypeMap[type]; } else if (type.IsArray) { mash = JsValueType.NativeObject | JsValueType.NullOrUndefined; } else if (type == typeof(DateTime)) { mash = JsValueType.Date; } else if (type == typeof(ArrayBuffer)) { mash = JsValueType.ArrayBuffer; } else if (!type.IsAbstract() && typeof(Delegate).IsAssignableFrom(type)) { mash = JsValueType.Function | JsValueType.NativeObject | JsValueType.NullOrUndefined; } else if (type.IsValueType()) { mash = JsValueType.NativeObject /* | JsValueType.JsObject*/; //TODO: 支持js对象到C#对象静默转换 } else { mash = JsValueType.NativeObject | JsValueType.NullOrUndefined; /*if ((type.IsClass() && type.GetConstructor(System.Type.EmptyTypes) != null)) * { * mash = mash | JsValueType.JsObject; * }*/ } return(mash); }
/// <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: result = Undefined.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 = 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> /// Makes a mapping of value from the script type to a .net type /// added by chuan.yin in 2017/4/27 /// </summary> /// <param name="value">The source value</param> /// <returns>The mapped value</returns> private object ConvertJsObjectToNetObject(JsValue value) { JsValueType valueType = value.ValueType; JsValue processedValue; object result; switch (valueType) { case JsValueType.Null: result = null; break; case JsValueType.Undefined: result = Undefined.Value; break; case JsValueType.Boolean: processedValue = value.ConvertToBoolean(); result = processedValue.ToBoolean(); break; case JsValueType.Number: processedValue = value.ConvertToNumber(); result = NumericHelpers.CastDoubleValueToCorrectType(processedValue.ToDouble()); break; case JsValueType.String: processedValue = value.ConvertToString(); result = processedValue.ToString(); break; case JsValueType.Object: result = MapToNetObject(value); break; case JsValueType.Function: case JsValueType.Error: case JsValueType.Array: result = ToArray(value); break; case JsValueType.Symbol: case JsValueType.ArrayBuffer: case JsValueType.TypedArray: case JsValueType.DataView: result = ToObject(value); break; default: throw new ArgumentOutOfRangeException(); } return(result); }
/// <summary> /// Checks whether the value can have references /// </summary> /// <param name="value">The value</param> /// <returns>Result of check (true - may have; false - may not have)</returns> private static bool CanHaveReferences(JsValue value) { JsValueType valueType = value.ValueType; switch (valueType) { case JsValueType.Null: case JsValueType.Undefined: case JsValueType.Boolean: return(false); default: return(true); } }
public bool IsMatchParams(JsValueType expectJsType, Type expectCsType, int start, int end) { if (!IsMatch(expectJsType, expectCsType, false, false)) { return(false); } for (int i = start + 1; i < end; i++) { var argHelper = new Puerts.ArgumentHelper(jsEnvIdx, isolate, info, i); if (!argHelper.IsMatch(expectJsType, expectCsType, false, false)) { return(false); } } return(true); }
public static JavaScriptValueType ToApiValueType(this JsValueType type) { switch (type) { case JsValueType.JsArray: return(JavaScriptValueType.Array); case JsValueType.JsArrayBuffer: return(JavaScriptValueType.ArrayBuffer); case JsValueType.JsBoolean: return(JavaScriptValueType.Boolean); case JsValueType.JsDataView: return(JavaScriptValueType.DataView); case JsValueType.JsFunction: return(JavaScriptValueType.Function); case JsValueType.JsNumber: return(JavaScriptValueType.Number); case JsValueType.JsError: case JsValueType.JsNull: case JsValueType.JsObject: return(JavaScriptValueType.Object); case JsValueType.JsString: return(JavaScriptValueType.String); case JsValueType.JsSymbol: return(JavaScriptValueType.Symbol); case JsValueType.JsTypedArray: return(JavaScriptValueType.TypedArray); case JsValueType.JsUndefined: default: return(JavaScriptValueType.Undefined); } }
public static ParameterGenInfo FromParameterInfo(ParameterInfo parameterInfo) { bool isParams = parameterInfo.IsDefined(typeof(ParamArrayAttribute), false); JsValueType ExpectJsType = isParams ? GeneralGetterManager.GetJsTypeMask(parameterInfo.ParameterType.GetElementType()) : GeneralGetterManager.GetJsTypeMask(parameterInfo.ParameterType); var result = new ParameterGenInfo() { IsOut = !parameterInfo.IsIn && parameterInfo.IsOut && parameterInfo.ParameterType.IsByRef, IsByRef = parameterInfo.ParameterType.IsByRef, TypeName = Utils.RemoveRefAndToConstraintType(parameterInfo.ParameterType).GetFriendlyName(), ExpectJsType = Utils.ToCode(ExpectJsType), IsParams = isParams, }; if (result.IsParams) { result.TypeName = Utils.RemoveRefAndToConstraintType(parameterInfo.ParameterType.GetElementType()).GetFriendlyName(); } result.ExpectCsType = ((ExpectJsType & JsValueType.NativeObject) == JsValueType.NativeObject) ? string.Format("typeof({0})", result.TypeName) : "null"; Utils.FillEnumInfo(result, parameterInfo.ParameterType); return(result); }
static string ToCode(JsValueType ExpectJsType) { return(string.Join(" | ", ExpectJsType.ToString().Split(',').Select(s => "Puerts.JsValueType." + s.Trim()).ToArray())); }
internal static extern JsErrorCode JsGetValueType(JsValue value, out JsValueType type);
internal static extern JsErrorCode JsGetValueType(EdgeJsValue value, out JsValueType type);
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(); } } }
public void OnReturnMessage(bool isException, JsValueType tag, object value) { ReadMessage(new ReturnMessage { IsException = isException, Value = new JsValue(tag, value) }); }
public JsValue(JsValueType tag, object value) { this.Tag = tag; this.Object = value; }
public void Read(NetworkReader reader) { Tag = (JsValueType)reader.ReadByte(); switch (Tag) { case JsValueType.Null: case JsValueType.Void: Object = null; break; case JsValueType.Bool: Object = reader.ReadBoolean(); break; case JsValueType.Int: Object = reader.ReadInt32(); break; case JsValueType.Double: Object = reader.ReadDouble(); break; case JsValueType.String: Object = reader.ReadString(); break; case JsValueType.Object: case JsValueType.JsObject: case JsValueType.Delegate: Object = reader.ReadInt32(); break; default: throw new InvalidDataException(); } }
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); }
private void SimulateAction(SessionHelper session, Type nativeType, string name, JsValueType retType, ref int remoteId, params int[] args) { var action = session.DefineFunctionMessage(nativeType.GetMethod(name)); session.InvokeFunctionMessage(action.Name, 0); var id = ++remoteId; session.OnReturnMessage(false, JsValueType.JsObject, id); JsValue[] wrapped = args.Select(x => new JsValue(x)).ToArray(); session.InvokeDelegateMessage(id, wrapped); session.OnReturnMessage(false, retType, null); }
public static extern JsErrorCode JsGetValueType(JsValueRef value, out JsValueType type);