/// <summary> /// http://www.ecma-international.org/ecma-262/5.1/#sec-13.2.1 /// </summary> /// <param name="thisArg"></param> /// <param name="arguments"></param> /// <returns></returns> public override JsValue Call(JsValue thisArg, JsValue[] arguments) { using (new StrictModeScope(Strict, true)) { // setup new execution context http://www.ecma-international.org/ecma-262/5.1/#sec-10.4.3 JsValue thisBinding; if (StrictModeScope.IsStrictModeCode) { thisBinding = thisArg; } else if (thisArg == Undefined.Instance || thisArg == Null.Instance) { thisBinding = Engine.Global; } else if (!thisArg.IsObject()) { thisBinding = TypeConverter.ToObject(Engine, thisArg); } else { thisBinding = thisArg; } var localEnv = LexicalEnvironment.NewDeclarativeEnvironment(Engine, Scope); Engine.EnterExecutionContext(localEnv, localEnv, thisBinding); try { Engine.DeclarationBindingInstantiation( DeclarationBindingType.FunctionCode, _functionDeclaration.FunctionDeclarations, _functionDeclaration.VariableDeclarations, this, arguments); var result = Engine.ExecuteStatement(_functionDeclaration.Body); if (result.Type == Completion.Throw) { JavaScriptException ex = new JavaScriptException(result.GetValueOrDefault()); ex.Location = result.Location; throw ex; } if (result.Type == Completion.Return) { return result.GetValueOrDefault(); } } finally { Engine.LeaveExecutionContext(); } return Undefined.Instance; } }
private static string GetErrorMessage(JsValue error) { if (error.IsObject()) { var oi = error.AsObject(); var message = oi.Get("message").AsString(); return message; } else return string.Empty; }
/// <summary> /// http://www.ecma-international.org/ecma-262/5.1/#sec-9.2 /// </summary> /// <param name="o"></param> /// <returns></returns> public static bool ToBoolean(JsValue o) { if (o.IsObject()) { return true; } if (o == Undefined.Instance || o == Null.Instance) { return false; } if (o.IsBoolean()) { return o.AsBoolean(); } if (o.IsNumber()) { var n = o.AsNumber(); if (n.Equals(0) || double.IsNaN(n)) { return false; } else { return true; } } if (o.IsString()) { var s = o.AsString(); if (String.IsNullOrEmpty(s)) { return false; } else { return true; } } return true; }
/// <summary> /// http://www.ecma-international.org/ecma-262/5.1/#sec-9.8 /// </summary> /// <param name="o"></param> /// <returns></returns> public static string ToString(JsValue o) { if (o.IsObject()) { var p = o.AsObject() as IPrimitiveInstance; if (p != null) { o = p.PrimitiveValue; } } if (o.IsString()) { return(o.AsString()); } if (o == Undefined.Instance) { return(Undefined.Text); } if (o == Null.Instance) { return(Null.Text); } if (o.IsBoolean()) { return(o.AsBoolean() ? "true" : "false"); } if (o.IsNumber()) { return(NumberPrototype.ToNumberString(o.AsNumber())); } return(ToString(ToPrimitive(o, Types.String))); }
public static Vector2?FromJsValue(JsValue obj) { if (obj == null || obj.IsNull() || obj.IsUndefined()) { return(null); } if (obj.IsNumber()) { var num = (float)obj.AsNumber(); return(new Vector2(num, num)); } if (obj.IsArray()) { var v0 = obj.AsArray()[0]; var v1 = obj.AsArray()[1]; var x = v0.IsNumber() ? (float)v0.AsNumber() : 0; var y = v1.IsNumber() ? (float)v1.AsNumber() : 0; return(new Vector2(x, y)); } if (obj.IsObject()) { var ob = obj.AsObject(); var v0 = ob.Get("x"); var v1 = ob.Get("y"); var x = v0.IsNumber() ? (float)v0.AsNumber() : 0; var y = v1.IsNumber() ? (float)v1.AsNumber() : 0; return(new Vector2(x, y)); } return(null); }
public static ObjectInstance ToObject(Engine engine, JsValue value) { if (value.IsObject()) { return(value.AsObject()); } if (value == Undefined.Instance) { //throw new JavaScriptException(engine.TypeError); return(null); } if (value == Null.Instance) { //throw new JavaScriptException(engine.TypeError); return(null); } if (value.IsBoolean()) { return(engine.Boolean.Construct(value.AsBoolean())); } if (value.IsNumber()) { return(engine.Number.Construct(value.AsNumber())); } if (value.IsString()) { return(engine.String.Construct(value.AsString())); } throw new JavaScriptException(engine.TypeError, value + " is not a object"); }
private static void RunEvalLoop() { try { if (File.Exists(HistoryFilePath)) { foreach (string line in File.ReadLines(HistoryFilePath).TakeLast(60)) { if (line != _removedString) { ReadLine.AddHistory(line); } } } } catch (Exception e) { CliConsole.WriteErrorLine($"Could not load cmd history from {HistoryFilePath} {e.Message}"); } ReadLine.AutoCompletionHandler = new AutoCompletionHandler(); while (true) { try { if (_terminal != Terminal.Cmder) { Console.ForegroundColor = ColorScheme.Text; } int bufferSize = 1024 * 16; string statement; using (Stream inStream = System.Console.OpenStandardInput(bufferSize)) { Console.SetIn(new StreamReader(inStream, Console.InputEncoding, false, bufferSize)); CliConsole.WriteLessImportant("nethermind> "); statement = _terminal == Terminal.Cygwin ? Console.ReadLine() : ReadLine.Read(); CleanStatement(statement); if (!File.Exists(HistoryFilePath)) { File.Create(HistoryFilePath).Dispose(); } if (!SecuredCommands.Any(sc => statement.Contains(sc))) { ReadLine.AddHistory(statement); using (var fileStream = File.AppendText(HistoryFilePath)) { fileStream.WriteLine(statement); } } else { ReadLine.AddHistory(_removedString); } } if (statement == "exit") { break; } JsValue result = _engine.Execute(statement); if (result.IsObject() && result.AsObject().Class == "Function") { CliConsole.WriteGood(result.ToString()); CliConsole.WriteLine(); } else if (!result.IsNull()) { string text = Serializer.Serialize(result.ToObject(), true); // File.AppendAllText("C:\\temp\\cli.txt", text); CliConsole.WriteGood(text); } else { CliConsole.WriteLessImportant("null"); CliConsole.WriteLine(); } // bool isNull = result.IsNull(); // if (!isNull) // { // CliConsole.WriteString(result); // } } catch (Exception e) { CliConsole.WriteException(e); } } }
private static JsValue ScalarToRawString(JsValue self2, JsValue[] args) { if (args.Length != 2) { throw new InvalidOperationException("scalarToRawString(document, lambdaToField) may be called on with two parameters only"); } JsValue firstParam = args[0]; if (firstParam.IsObject() == false || args[0].AsObject() is BlittableObjectInstance == false) { throw new InvalidOperationException("scalarToRawString(document, lambdaToField) may be called with a document first parameter only"); } JsValue secondParam = args[1]; if (args[1].IsObject() == false || secondParam.AsObject() is FunctionInstance == false) { throw new InvalidOperationException("scalarToRawString(document, lambdaToField) must be called with a second lambda argument"); } BlittableObjectInstance selfInstance = firstParam.AsObject() as BlittableObjectInstance; FunctionInstance lambda = secondParam.AsObject() as FunctionInstance; //TODO: expose this in Jint directly instead of reflection var funcDeclField = typeof(ScriptFunctionInstance).GetField("_functionDeclaration", BindingFlags.Instance | BindingFlags.NonPublic); var func = (IFunction)funcDeclField.GetValue(lambda); var ret = func.Body.Body.As <ReturnStatement[]>(); if (ret.Length != 1) { throw new InvalidOperationException("scalarToRawString(document, lambdaToField) lambda to field must contain a single return expression"); } StaticMemberExpression staticMemberExpression = ret[0].Argument.As <StaticMemberExpression>(); var prop = staticMemberExpression.Property; if (staticMemberExpression.Object is Identifier == false) { throw new InvalidOperationException("scalarToRawString(document, lambdaToField) lambda to field must contain a single return expression of a single field"); } var propName = prop.As <Identifier>().Name; if (selfInstance.OwnValues.TryGetValue(propName, out var existingValue)) { if (existingValue.Changed) { return(existingValue.Value); } } var propertyIndex = selfInstance.Blittable.GetPropertyIndex(propName); if (propertyIndex == -1) { return(new JsValue(new ObjectInstance(selfInstance.Engine) { Extensible = true })); } BlittableJsonReaderObject.PropertyDetails propDetails = new BlittableJsonReaderObject.PropertyDetails(); selfInstance.Blittable.GetPropertyByIndex(propertyIndex, ref propDetails); var value = propDetails.Value; switch (propDetails.Token & BlittableJsonReaderBase.TypesMask) { case BlittableJsonToken.Null: return(JsValue.Null); case BlittableJsonToken.Boolean: return(new JsValue((bool)propDetails.Value)); case BlittableJsonToken.Integer: return(new JsValue(new ObjectWrapper(selfInstance.Engine, value))); case BlittableJsonToken.LazyNumber: return(new JsValue(new ObjectWrapper(selfInstance.Engine, value))); case BlittableJsonToken.String: return(new JsValue(new ObjectWrapper(selfInstance.Engine, value))); case BlittableJsonToken.CompressedString: return(new JsValue(new ObjectWrapper(selfInstance.Engine, value))); default: throw new InvalidOperationException("scalarToRawString(document, lambdaToField) lambda to field must return either raw numeric or raw string types"); } }
public JsValue EvaluateBinaryExpression(BinaryExpression expression) { JsValue left = _engine.GetValue(EvaluateExpression(expression.Left)); JsValue right = _engine.GetValue(EvaluateExpression(expression.Right)); JsValue value; switch (expression.Operator) { case "+": var lprim = TypeConverter.ToPrimitive(left); var rprim = TypeConverter.ToPrimitive(right); if (lprim.IsString() || rprim.IsString()) { value = TypeConverter.ToString(lprim) + TypeConverter.ToString(rprim); } else { value = TypeConverter.ToNumber(lprim) + TypeConverter.ToNumber(rprim); } break; case "-": value = TypeConverter.ToNumber(left) - TypeConverter.ToNumber(right); break; case "*": if (left == Undefined.Instance || right == Undefined.Instance) { value = Undefined.Instance; } else { value = TypeConverter.ToNumber(left) * TypeConverter.ToNumber(right); } break; case "/": value = Divide(left, right); break; case "%": if (left == Undefined.Instance || right == Undefined.Instance) { value = Undefined.Instance; } else { value = TypeConverter.ToNumber(left) % TypeConverter.ToNumber(right); } break; case "==": value = Equal(left, right); break; case "!=": value = !Equal(left, right); break; case ">": value = Compare(right, left, false); if (value == Undefined.Instance) { value = false; } break; case ">=": value = Compare(left, right); if (value == Undefined.Instance || value.AsBoolean()) { value = false; } else { value = true; } break; case "<": value = Compare(left, right); if (value == Undefined.Instance) { value = false; } break; case "<=": value = Compare(right, left, false); if (value == Undefined.Instance || value.AsBoolean()) { value = false; } else { value = true; } break; case "===": return(StrictlyEqual(left, right)); case "!==": return(!StrictlyEqual(left, right)); case "&": return(TypeConverter.ToInt32(left) & TypeConverter.ToInt32(right)); case "|": return(TypeConverter.ToInt32(left) | TypeConverter.ToInt32(right)); case "^": return(TypeConverter.ToInt32(left) ^ TypeConverter.ToInt32(right)); case "<<": return(TypeConverter.ToInt32(left) << (int)(TypeConverter.ToUint32(right) & 0x1F)); case ">>": return(TypeConverter.ToInt32(left) >> (int)(TypeConverter.ToUint32(right) & 0x1F)); case ">>>": return((uint)TypeConverter.ToInt32(left) >> (int)(TypeConverter.ToUint32(right) & 0x1F)); case "instanceof": var f = right.TryCast <FunctionInstance>(); if (f == null) { throw new JavaScriptException(_engine.TypeError, "instanceof can only be used with a function object"); } value = f.HasInstance(left); break; case "in": if (!right.IsObject()) { throw new JavaScriptException(_engine.TypeError, "in can only be used with an object"); } value = right.AsObject().HasProperty(TypeConverter.ToString(left)); break; default: throw new NotImplementedException(); } return(value); }
private JsValue Sort(JsValue thisObj, JsValue[] arguments) { if (!thisObj.IsObject()) { ExceptionHelper.ThrowTypeError(_engine, "Array.prorotype.sort can only be applied on objects"); } var obj = ArrayOperations.For(thisObj.AsObject()); var compareArg = arguments.At(0); ICallable compareFn = null; if (!compareArg.IsUndefined()) { if (compareArg.IsNull() || !(compareArg is ICallable)) { ExceptionHelper.ThrowTypeError(_engine, "The comparison function must be either a function or undefined"); } compareFn = (ICallable)compareArg; } var len = obj.GetLength(); if (len <= 1) { return(obj.Target); } int Comparer(JsValue x, JsValue y) { if (ReferenceEquals(x, null)) { return(1); } if (ReferenceEquals(y, null)) { return(-1); } var xUndefined = x.IsUndefined(); var yUndefined = y.IsUndefined(); if (xUndefined && yUndefined) { return(0); } if (xUndefined) { return(1); } if (yUndefined) { return(-1); } if (compareFn != null) { var s = TypeConverter.ToNumber(compareFn.Call(Undefined, new[] { x, y })); if (s < 0) { return(-1); } if (s > 0) { return(1); } return(0); } var xString = TypeConverter.ToString(x); var yString = TypeConverter.ToString(y); var r = CompareOrdinal(xString, yString); return(r); } var array = new JsValue[len]; for (uint i = 0; i < (uint)array.Length; ++i) { var value = obj.TryGetValue(i, out var temp) ? temp : null; array[i] = value; } // don't eat inner exceptions try { System.Array.Sort(array, Comparer); } catch (InvalidOperationException e) { throw e.InnerException; } for (uint i = 0; i < (uint)array.Length; ++i) { if (!ReferenceEquals(array[i], null)) { obj.Set(i, array[i], updateLength: false, throwOnError: false); } else { obj.DeletePropertyOrThrow(i); } } return(obj.Target); }
public JsValue Serialize(JsValue value, JsValue replacer, JsValue space) { _stack = new Stack<object>(); // for JSON.stringify(), any function passed as the first argument will return undefined // if the replacer is not defined. The function is not called either. if (value.Is<ICallable>() && replacer == Undefined.Instance) { return Undefined.Instance; } if (replacer.IsObject()) { if (replacer.Is<ICallable>()) { _replacerFunction = replacer; } else { var replacerObj = replacer.AsObject(); if (replacerObj.Class == "Array") { _propertyList = new List<string>(); } foreach (var property in replacerObj.GetOwnProperties().Select(x => x.Value)) { JsValue v = _engine.GetValue(property); string item = null; if (v.IsString()) { item = v.AsString(); } else if (v.IsNumber()) { item = TypeConverter.ToString(v); } else if (v.IsObject()) { var propertyObj = v.AsObject(); if (propertyObj.Class == "String" || propertyObj.Class == "Number") { item = TypeConverter.ToString(v); } } if (item != null && !_propertyList.Contains(item)) { _propertyList.Add(item); } } } } if (space.IsObject()) { var spaceObj = space.AsObject(); if (spaceObj.Class == "Number") { space = TypeConverter.ToNumber(spaceObj); } else if (spaceObj.Class == "String") { space = TypeConverter.ToString(spaceObj); } } // defining the gap if (space.IsNumber()) { if (space.AsNumber() > 0) { _gap = new System.String(' ', (int)System.Math.Min(10, space.AsNumber())); } else { _gap = string.Empty; } } else if (space.IsString()) { var stringSpace = space.AsString(); _gap = stringSpace.Length <= 10 ? stringSpace : stringSpace.Substring(0, 10); } else { _gap = string.Empty; } var wrapper = _engine.Object.Construct(Arguments.Empty); wrapper.DefineOwnProperty("", new PropertyDescriptor(value, true, true, true), false); return Str("", wrapper); }
private LocalVariable GetLocalVariableJS(string key, JsValue value) { var result = new LocalVariable() { Name = key, TypeName = value.Type.ToString() }; if (value.IsArray()) { var trueValue = value.AsArray(); if (trueValue.GetLength() > 0) { var props = trueValue.GetOwnProperties(); foreach (var item in props) { var ch = GetLocalVariableJS(item.Key, item.Value.Value); result.Children.Add(ch); } } //result.Value=trueValue. } else if (value.IsBoolean()) { var trueValue = value.AsBoolean(); result.Value = trueValue.ToString(); } else if (value.IsDate()) { var trueValue = value.AsDate(); result.Value = trueValue.ToDateTime().ToString("yyyy-MM-dd HH:mm:ss"); } else if (value.IsNumber()) { var trueValue = value.AsNumber(); result.Value = trueValue.ToString(); } else if (value.IsString()) { var trueValue = value.AsString(); result.Value = trueValue; } else if (value.IsObject()) { var trueValue = value.AsObject(); //判断对象是否原生JS if (trueValue.GetType().Name == "ObjectInstance") { var props = trueValue.GetOwnProperties(); foreach (var item in props) { var ch = GetLocalVariableJS(item.Key, item.Value.Value); result.Children.Add(ch); } } else { var csharpValue = value.ToObject(); if (csharpValue != null) { //只处理DapperRow result = GetLocalVariableCSharp(key, csharpValue); //csharpValue. } } } return(result); }
private RavenJToken ToRavenJToken(JsValue v, string propertyKey, bool recursiveCall) { if (v.IsBoolean()) { return(new RavenJValue(v.AsBoolean())); } if (v.IsString()) { const string RavenDataByteArrayToBase64 = "raven-data:byte[];base64,"; var valueAsObject = v.ToObject(); var value = valueAsObject != null?valueAsObject.ToString() : null; if (value != null && value.StartsWith(RavenDataByteArrayToBase64)) { value = value.Remove(0, RavenDataByteArrayToBase64.Length); var byteArray = Convert.FromBase64String(value); return(new RavenJValue(byteArray)); } return(new RavenJValue(value)); } if (v.IsNumber()) { var num = v.AsNumber(); KeyValuePair <RavenJValue, JsValue> property; if (propertiesByValue.TryGetValue(propertyKey, out property)) { var originalValue = property.Key; if (originalValue.Type == JTokenType.Float || originalValue.Type == JTokenType.Integer) { // If the current value is exactly as the original value, we can return the original value before we made the JS conversion, // which will convert a Int64 to jsFloat. var originalJsValue = property.Value; if (originalJsValue.IsNumber() && Math.Abs(num - originalJsValue.AsNumber()) < double.Epsilon) { return(originalValue); } if (originalValue.Type == JTokenType.Integer) { return(new RavenJValue((long)num)); } return(new RavenJValue(num));//float } } // If we don't have the type, assume that if the number ending with ".0" it actually an integer. var integer = Math.Truncate(num); if (Math.Abs(num - integer) < double.Epsilon) { return(new RavenJValue((long)integer)); } return(new RavenJValue(num)); } if (v.IsNull()) { return(RavenJValue.Null); } if (v.IsUndefined()) { return(RavenJValue.Null); } if (v.IsArray()) { var jsArray = v.AsArray(); var rja = new RavenJArray(); foreach (var property in jsArray.Properties) { if (property.Key == "length") { continue; } var jsInstance = property.Value.Value; if (!jsInstance.HasValue) { continue; } var ravenJToken = ToRavenJToken(jsInstance.Value, propertyKey + "[" + property.Key + "]", recursiveCall); if (ravenJToken == null) { continue; } rja.Add(ravenJToken); } return(rja); } if (v.IsObject()) { return(ToRavenJObject(v, propertyKey, recursiveCall)); } if (v.IsRegExp()) { return(null); } throw new NotSupportedException(v.Type.ToString()); }
public static Color?FromJsValue(JsValue obj) { if (obj == null || obj.IsNull() || obj.IsUndefined()) { return(null); } var nativeObject = obj.ToObject(); if (nativeObject is Color c) { return(c); } if (obj.IsString()) { var s = obj.ToString(); ColorUtility.TryParseHtmlString(s, out var color); return(color); } if (obj.IsNumber()) { var num = (float)obj.AsNumber(); return(new Color(num, num, num, 1)); } if (obj.IsArray()) { var len = obj.AsArray().Length; if (len == 0) { return(Color.clear); } var v0 = obj.AsArray()[0]; var v1 = obj.AsArray()[1]; var v2 = obj.AsArray()[2]; var v3 = obj.AsArray()[3]; if (v0 != null && !v0.IsNumber() && !v0.IsNull() && !v0.IsUndefined()) { var start = FromJsValue(v0) ?? Color.clear; var end = FromJsValue(v2); if (end.HasValue) { var t = v1.IsNumber() ? (float)v1.AsNumber() : 0; return(Color.LerpUnclamped(start, end.Value, t)); } else { var t = v1.IsNumber() ? (float)v1.AsNumber() : 1; start.a = t; return(start); } } var r = v0.IsNumber() ? (float)v0.AsNumber() : 0; var g = v1.IsNumber() ? (float)v1.AsNumber() : 0; var b = v2.IsNumber() ? (float)v2.AsNumber() : 0; var a = v3.IsNumber() ? (float)v3.AsNumber() : 1; return(new Color(r, g, b, a)); } if (obj.IsObject()) { var ob = obj.AsObject(); var v0 = ob.Get("r"); var v1 = ob.Get("g"); var v2 = ob.Get("b"); var v3 = ob.Get("a"); var r = v0.IsNumber() ? (float)v0.AsNumber() : 0; var g = v1.IsNumber() ? (float)v1.AsNumber() : 0; var b = v2.IsNumber() ? (float)v2.AsNumber() : 0; var a = v3.IsNumber() ? (float)v3.AsNumber() : 1; return(new Color(r, g, b, a)); } return(null); }
public static bool CanConvert(this JsValue jsValue, Type targetType) { if (jsValue.IsNull() || jsValue.IsUndefined()) { return(targetType.IsClass); } if (jsValue.IsString() && (targetType == typeof(string) || targetType == typeof(bool))) { return(true); } if (jsValue.IsBoolean() && (targetType == typeof(bool) || targetType == typeof(bool?))) { return(true); } if (jsValue.IsNumber() && (targetType == typeof(int) || targetType == typeof(ulong) || targetType == typeof(double) || targetType == typeof(short) || targetType == typeof(short?) || targetType == typeof(int?) || targetType == typeof(double?) || targetType == typeof(string) || targetType == typeof(bool) || targetType == typeof(bool?))) { return(true); } if (jsValue.IsObject()) { var jsObj = jsValue.AsObject(); if (jsObj is FunctionInstance && (typeof(Delegate)).IsAssignableFrom(targetType)) { return(true); } if (jsObj is ClrObject clrObjectInstance) { if (clrObjectInstance.Target == null) { return(targetType.IsClass); } return(targetType.IsAssignableFrom(clrObjectInstance.Target.GetType())); } if (jsObj is ArrayInstance) { return(targetType.IsArray); } if (jsObj is ObjectInstance) { //if the target type is class that contains only public fields //it can be deserialized from js object. return(targetType.IsClass && targetType != typeof(string)); } } return(false); }
public static ObjectInstance ToObject(Engine engine, JsValue value) { if (value.IsObject()) { return value.AsObject(); } if (value == Undefined.Instance) { throw new JavaScriptException(engine.TypeError); } if (value == Null.Instance) { throw new JavaScriptException(engine.TypeError); } if (value.IsBoolean()) { return engine.Boolean.Construct(value.AsBoolean()); } if (value.IsNumber()) { return engine.Number.Construct(value.AsNumber()); } if (value.IsString()) { return engine.String.Construct(value.AsString()); } throw new JavaScriptException(engine.TypeError); }
public static Types GetPrimitiveType(JsValue value) { if (value.IsObject()) { var primitive = value.TryCast<IPrimitiveInstance>(); if (primitive != null) { return primitive.Type; } return Types.Object; } return value.Type; }
/// <summary> /// http://www.ecma-international.org/ecma-262/5.1/#sec-9.8 /// </summary> /// <param name="o"></param> /// <returns></returns> public static string ToString(JsValue o) { if (o.IsObject()) { var p = o.AsObject() as IPrimitiveInstance; if (p != null) { o = p.PrimitiveValue; } } if (o.IsString()) { return o.AsString(); } if (o == Undefined.Instance) { return Undefined.Text; } if (o == Null.Instance) { return Null.Text; } if (o.IsBoolean()) { return o.AsBoolean() ? "true" : "false"; } if (o.IsNumber()) { return NumberPrototype.ToNumberString(o.AsNumber()); } return ToString(ToPrimitive(o, Types.String)); }
/// <summary> /// http://www.ecma-international.org/ecma-262/5.1/#sec-9.3 /// </summary> /// <param name="o"></param> /// <returns></returns> public static double ToNumber(JsValue o) { // check number first as this is what is usually expected if (o.IsNumber()) { return o.AsNumber(); } if (o.IsObject()) { var p = o.AsObject() as IPrimitiveInstance; if (p != null) { o = p.PrimitiveValue; } } if (o == Undefined.Instance) { return double.NaN; } if (o == Null.Instance) { return 0; } if (o.IsBoolean()) { return o.AsBoolean() ? 1 : 0; } if (o.IsString()) { var s = o.AsString().Trim(); if (String.IsNullOrEmpty(s)) { return 0; } if ("+Infinity".Equals(s) || "Infinity".Equals(s)) { return double.PositiveInfinity; } if ("-Infinity".Equals(s)) { return double.NegativeInfinity; } // todo: use a common implementation with JavascriptParser try { if (!s.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) { var start = s[0]; if (start != '+' && start != '-' && start != '.' && !char.IsDigit(start)) { return double.NaN; } double n = Double.Parse(s, NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign | NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite | NumberStyles.AllowExponent, CultureInfo.InvariantCulture); if (s.StartsWith("-") && n.Equals(0)) { return -0.0; } return n; } int i = int.Parse(s.Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture); return i; } catch (OverflowException) { return s.StartsWith("-") ? double.NegativeInfinity : double.PositiveInfinity; } catch { return double.NaN; } } return ToNumber(ToPrimitive(o, Types.Number)); }
private JsValue AbstractWalkOperation(ObjectInstance thisObject, string prop) { JsValue value = thisObject.Get(prop); if (value.IsObject()) { var valueAsObject = value.AsObject(); if (valueAsObject.Class == "Array") { var valAsArray = value.AsArray(); var i = 0; var arrLen = valAsArray.GetLength(); while (i < arrLen) { var newValue = AbstractWalkOperation(valAsArray, TypeConverter.ToString(i)); if (newValue.IsUndefined()) { valAsArray.Delete(TypeConverter.ToString(i), false); } else { valAsArray.DefineOwnProperty ( TypeConverter.ToString(i), new PropertyDescriptor ( value: newValue, flags: PropertyFlag.ConfigurableEnumerableWritable ), false ); } i = i + 1; } } else { var keys = valueAsObject.GetOwnProperties(); foreach (var p in keys) { var newElement = AbstractWalkOperation(valueAsObject, p.Key); if (newElement.IsUndefined()) { valueAsObject.Delete(p.Key, false); } else { valueAsObject.DefineOwnProperty( p.Key, new PropertyDescriptor ( value: newElement, flags: PropertyFlag.ConfigurableEnumerableWritable ), false ); } } } } return(_reviver.Invoke(thisObject, new JsValue[] { prop, value })); }
public JsValue Serialize(JsValue value, JsValue replacer, JsValue space) { _stack = new Stack <object>(); // for JSON.stringify(), any function passed as the first argument will return undefined // if the replacer is not defined. The function is not called either. if (value is ICallable callable && ReferenceEquals(replacer, Undefined.Instance)) { return(Undefined.Instance); } if (replacer.IsObject()) { if (replacer is ICallable) { _replacerFunction = replacer; } else { var replacerObj = replacer.AsObject(); if (replacerObj.Class == ObjectClass.Array) { _propertyList = new List <JsValue>(); } foreach (var property in replacerObj.GetOwnProperties().Select(x => x.Value)) { JsValue v = _engine.GetValue(property, false); string item = null; if (v.IsString()) { item = v.ToString(); } else if (v.IsNumber()) { item = TypeConverter.ToString(v); } else if (v.IsObject()) { var propertyObj = v.AsObject(); if (propertyObj.Class == ObjectClass.String || propertyObj.Class == ObjectClass.Number) { item = TypeConverter.ToString(v); } } if (item != null && !_propertyList.Contains(item)) { _propertyList.Add(item); } } } } if (space.IsObject()) { var spaceObj = space.AsObject(); if (spaceObj.Class == ObjectClass.Number) { space = TypeConverter.ToNumber(spaceObj); } else if (spaceObj.Class == ObjectClass.String) { space = TypeConverter.ToJsString(spaceObj); } } // defining the gap if (space.IsNumber()) { var number = ((JsNumber)space)._value; if (number > 0) { _gap = new string(' ', (int)System.Math.Min(10, number)); } else { _gap = string.Empty; } } else if (space.IsString()) { var stringSpace = space.ToString(); _gap = stringSpace.Length <= 10 ? stringSpace : stringSpace.Substring(0, 10); } else { _gap = string.Empty; } var wrapper = _engine.Object.Construct(Arguments.Empty); wrapper.DefineOwnProperty(JsString.Empty, new PropertyDescriptor(value, PropertyFlag.ConfigurableEnumerableWritable)); return(Str(JsString.Empty, wrapper)); }
public object ConvertToObject(JsValue jsValue, Type targetType) { if (jsValue == _getEngine().Global) { return(_global); } if (jsValue.IsUndefined()) { return(null); } if (jsValue.IsObject()) { var obj = jsValue.AsObject(); if (targetType == typeof(string)) { return(obj.ToString()); } switch (obj) { case ClrObject clr: return(clr.Target); case ObjectInstance objInst: return(GetCreator(targetType)(objInst)); } return(jsValue); } if (jsValue.IsBoolean()) { var boolVal = jsValue.AsBoolean(); if (targetType == typeof(string)) { return(boolVal ? "true" : "false"); } return(boolVal); } if (jsValue.IsString()) { return(jsValue.AsString()); } if (jsValue.IsNumber()) { var dbl = jsValue.AsNumber(); if (targetType == typeof(sbyte)) { return((sbyte)dbl); } if (targetType == typeof(byte)) { return((byte)dbl); } if (targetType == typeof(int)) { return((int)dbl); } if (targetType == typeof(uint)) { return((uint)dbl); } if (targetType == typeof(short)) { return((short)dbl); } if (targetType == typeof(ushort)) { return((ushort)dbl); } if (targetType == typeof(long)) { return((long)dbl); } if (targetType == typeof(ulong)) { return((ulong)dbl); } if (targetType == typeof(float)) { return((float)dbl); } if (targetType == typeof(string)) { return(dbl.ToString(CultureInfo.InvariantCulture)); } return(dbl); } return(null); }
public JsValue Serialize(JsValue value, JsValue replacer, JsValue space) { _stack = new Stack <object>(); // for JSON.stringify(), any function passed as the first argument will return undefined // if the replacer is not defined. The function is not called either. if (value.Is <ICallable>() && replacer == Undefined.Instance) { return(Undefined.Instance); } if (replacer.IsObject()) { if (replacer.Is <ICallable>()) { _replacerFunction = replacer; } else { var replacerObj = replacer.AsObject(); if (replacerObj.Class == "Array") { _propertyList = new List <string>(); } foreach (var property in replacerObj.GetOwnProperties().Select(x => x.Value)) { JsValue v = _engine.GetValue(property); string item = null; if (v.IsString()) { item = v.AsString(); } else if (v.IsNumber()) { item = TypeConverter.ToString(v); } else if (v.IsObject()) { var propertyObj = v.AsObject(); if (propertyObj.Class == "String" || propertyObj.Class == "Number") { item = TypeConverter.ToString(v); } } if (item != null && !_propertyList.Contains(item)) { _propertyList.Add(item); } } } } if (space.IsObject()) { var spaceObj = space.AsObject(); if (spaceObj.Class == "Number") { space = TypeConverter.ToNumber(spaceObj); } else if (spaceObj.Class == "String") { space = TypeConverter.ToString(spaceObj); } } // defining the gap if (space.IsNumber()) { if (space.AsNumber() > 0) { _gap = new System.String(' ', (int)System.Math.Min(10, space.AsNumber())); } else { _gap = string.Empty; } } else if (space.IsString()) { var stringSpace = space.AsString(); _gap = stringSpace.Length <= 10 ? stringSpace : stringSpace.Substring(0, 10); } else { _gap = string.Empty; } var wrapper = _engine.Object.Construct(Arguments.Empty); wrapper.DefineOwnProperty("", new PropertyDescriptor(value, true, true, true), false); return(Str("", wrapper)); }
/// <summary> /// http://www.ecma-international.org/ecma-262/5.1/#sec-9.3 /// </summary> /// <param name="o"></param> /// <returns></returns> public static double ToNumber(JsValue o) { // check number first as this is what is usually expected if (o.IsNumber()) { return(o.AsNumber()); } if (o.IsObject()) { var p = o.AsObject() as IPrimitiveInstance; if (p != null) { o = p.PrimitiveValue; } } if (o == Undefined.Instance) { return(double.NaN); } if (o == Null.Instance) { return(0); } if (o.IsBoolean()) { return(o.AsBoolean() ? 1 : 0); } if (o.IsString()) { var s = StringPrototype.TrimEx(o.AsString()); if (String.IsNullOrEmpty(s)) { return(0); } if ("+Infinity".Equals(s) || "Infinity".Equals(s)) { return(double.PositiveInfinity); } if ("-Infinity".Equals(s)) { return(double.NegativeInfinity); } // todo: use a common implementation with JavascriptParser try { if (!s.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) { var start = s[0]; if (start != '+' && start != '-' && start != '.' && !char.IsDigit(start)) { return(double.NaN); } double n = Double.Parse(s, NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign | NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite | NumberStyles.AllowExponent, CultureInfo.InvariantCulture); if (s.StartsWith("-") && n.Equals(0)) { return(-0.0); } return(n); } int i = int.Parse(s.Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture); return(i); } catch (OverflowException) { return(s.StartsWith("-") ? double.NegativeInfinity : double.PositiveInfinity); } catch { return(double.NaN); } } return(ToNumber(ToPrimitive(o, Types.Number))); }
private JsValue Sort(JsValue thisObj, JsValue[] arguments) { if (!thisObj.IsObject()) { throw new JavaScriptException(Engine.TypeError, "Array.prorotype.sort can only be applied on objects"); } var obj = thisObj.AsObject(); var len = obj.Get("length"); var lenVal = TypeConverter.ToInt32(len); if (lenVal <= 1) { return(obj); } var compareArg = arguments.At(0); ICallable compareFn = null; if (compareArg != Undefined.Instance) { compareFn = compareArg.TryCast <ICallable>(x => { throw new JavaScriptException(Engine.TypeError, "The sort argument must be a function"); }); } Comparison <JsValue> comparer = (x, y) => { if (x == Undefined.Instance && y == Undefined.Instance) { return(0); } if (x == Undefined.Instance) { return(1); } if (y == Undefined.Instance) { return(-1); } if (compareFn != null) { var s = (int)TypeConverter.ToUint32(compareFn.Call(Undefined.Instance, new[] { x, y })); return(s); } var xString = TypeConverter.ToString(x); var yString = TypeConverter.ToString(y); var r = System.String.CompareOrdinal(xString, yString); return(r); }; var array = Enumerable.Range(0, lenVal).Select(i => obj.Get(i.ToString())).ToArray(); // don't eat inner exceptions try { System.Array.Sort(array, comparer); } catch (InvalidOperationException e) { throw e.InnerException; } foreach (var i in Enumerable.Range(0, lenVal)) { obj.Put(i.ToString(), array[i], false); } return(obj); }
private static object GetValue(JsValue jsValue) { if (jsValue.IsNull()) { return(null); } if (jsValue.IsString()) { return(jsValue.AsString()); } if (jsValue.IsBoolean()) { return(jsValue.AsBoolean()); } if (jsValue.IsNumber()) { return(jsValue.AsNumber()); } if (jsValue.IsDate()) { return(jsValue.AsDate()); } if (jsValue is ObjectWrapper ow) { var target = ow.Target; switch (target) { case LazyStringValue lsv: return(lsv); case LazyCompressedStringValue lcsv: return(lcsv); case LazyNumberValue lnv: return(lnv); //should be already blittable supported type. } ThrowInvalidObject(jsValue); } else if (jsValue.IsArray()) { var arr = jsValue.AsArray(); var array = new object[arr.GetLength()]; var i = 0; foreach ((var key, var val) in arr.GetOwnProperties()) { if (key == "length") { continue; } array[i++] = GetValue(val.Value); } return(array); } else if (jsValue.IsObject()) { return(jsValue.AsObject()); } if (jsValue.IsUndefined()) { return(null); } ThrowInvalidObject(jsValue); return(null); }
public bool IsPropertyReference() { // http://www.ecma-international.org/ecma-262/5.1/#sec-8.7 return((_baseValue.IsObject() && !_baseValue.Is <EnvironmentRecord>()) || HasPrimitiveBase()); }
public static JToken Map(JsValue value) { if (value == null || value.IsNull()) { return(JValue.CreateNull()); } if (value.IsUndefined()) { return(JValue.CreateUndefined()); } if (value.IsString()) { return(new JValue(value.AsString())); } if (value.IsBoolean()) { return(new JValue(value.AsBoolean())); } if (value.IsNumber()) { return(new JValue(value.AsNumber())); } if (value.IsDate()) { return(new JValue(value.AsDate().ToDateTime())); } if (value.IsRegExp()) { return(JValue.CreateString(value.AsRegExp().Value?.ToString())); } if (value.IsArray()) { var arr = value.AsArray(); var target = new JArray(); for (var i = 0; i < arr.GetLength(); i++) { target.Add(Map(arr.Get(i.ToString()))); } return(target); } if (value.IsObject()) { var obj = value.AsObject(); var target = new JObject(); foreach (var kvp in obj.GetOwnProperties()) { target[kvp.Key] = Map(kvp.Value.Value); } return(target); } throw new ArgumentException("Invalid json type.", nameof(value)); }
internal static bool IsFunction(JsValue jsValue) { return(jsValue.IsObject() && jsValue.AsObject() is Jint.Native.Function.FunctionInstance); }
/// <summary> /// http://www.ecma-international.org/ecma-262/5.1/#sec-13.2.1 /// </summary> /// <param name="thisArg"></param> /// <param name="arguments"></param> /// <returns></returns> public override JsValue Call(JsValue thisArg, JsValue[] arguments) { var scope = Engine.PoolStrictMode.Get(); scope.Setup(Strict, true); { // setup new execution context http://www.ecma-international.org/ecma-262/5.1/#sec-10.4.3 JsValue thisBinding; if (StrictModeScope.IsStrictModeCode) { thisBinding = thisArg; } else if (thisArg == Undefined.Instance || thisArg == Null.Instance) { thisBinding = Engine.Global; } else if (!thisArg.IsObject()) { thisBinding = TypeConverter.ToObject(Engine, thisArg); } else { thisBinding = thisArg; } var localEnv = LexicalEnvironment.NewDeclarativeEnvironment(Engine, Scope); Engine.EnterExecutionContext(localEnv, localEnv, thisBinding); try { Engine.DeclarationBindingInstantiation( DeclarationBindingType.FunctionCode, _functionDeclaration.FunctionDeclarations, _functionDeclaration.VariableDeclarations, this, arguments); var result = Engine.ExecuteStatement(_functionDeclaration.Body); if (result.Type == Completion.Throw) { JavaScriptException ex = new JavaScriptException(result.GetValueOrDefault()) .SetCallstack(Engine, result.Location); throw ex; } if (result.Type == Completion.Return) { scope.Teardown(); Engine.PoolStrictMode.Put(scope); return(result.GetValueOrDefault()); } } finally { Engine.LeaveExecutionContext(); } scope.Teardown(); Engine.PoolStrictMode.Put(scope); return(Undefined.Instance); } }
public JsValue EvaluateBinaryExpression(BinaryExpression expression) { var leftExpression = EvaluateExpression(expression.Left); JsValue left = _engine.GetValue(leftExpression); var rightExpression = EvaluateExpression(expression.Right); JsValue right = _engine.GetValue(rightExpression); JsValue value; switch (expression.Operator) { case BinaryOperator.Plus: var lprim = TypeConverter.ToPrimitive(left); var rprim = TypeConverter.ToPrimitive(right); if (lprim.IsString() || rprim.IsString()) { value = TypeConverter.ToString(lprim) + TypeConverter.ToString(rprim); } else { value = TypeConverter.ToNumber(lprim) + TypeConverter.ToNumber(rprim); } break; case BinaryOperator.Minus: value = TypeConverter.ToNumber(left) - TypeConverter.ToNumber(right); break; case BinaryOperator.Times: if (left == Undefined.Instance || right == Undefined.Instance) { value = Undefined.Instance; } else { value = TypeConverter.ToNumber(left) * TypeConverter.ToNumber(right); } break; case BinaryOperator.Divide: value = Divide(left, right); break; case BinaryOperator.Modulo: if (left == Undefined.Instance || right == Undefined.Instance) { value = Undefined.Instance; } else { value = TypeConverter.ToNumber(left) % TypeConverter.ToNumber(right); } break; case BinaryOperator.Equal: value = Equal(left, right); break; case BinaryOperator.NotEqual: value = !Equal(left, right); break; case BinaryOperator.Greater: value = Compare(right, left, false); if (value == Undefined.Instance) { value = false; } break; case BinaryOperator.GreaterOrEqual: value = Compare(left, right); if (value == Undefined.Instance || value.AsBoolean()) { value = false; } else { value = true; } break; case BinaryOperator.Less: value = Compare(left, right); if (value == Undefined.Instance) { value = false; } break; case BinaryOperator.LessOrEqual: value = Compare(right, left, false); if (value == Undefined.Instance || value.AsBoolean()) { value = false; } else { value = true; } break; case BinaryOperator.StrictlyEqual: return(StrictlyEqual(left, right)); case BinaryOperator.StricltyNotEqual: return(!StrictlyEqual(left, right)); case BinaryOperator.BitwiseAnd: return(TypeConverter.ToInt32(left) & TypeConverter.ToInt32(right)); case BinaryOperator.BitwiseOr: return(TypeConverter.ToInt32(left) | TypeConverter.ToInt32(right)); case BinaryOperator.BitwiseXOr: return(TypeConverter.ToInt32(left) ^ TypeConverter.ToInt32(right)); case BinaryOperator.LeftShift: return(TypeConverter.ToInt32(left) << (int)(TypeConverter.ToUint32(right) & 0x1F)); case BinaryOperator.RightShift: return(TypeConverter.ToInt32(left) >> (int)(TypeConverter.ToUint32(right) & 0x1F)); case BinaryOperator.UnsignedRightShift: return((uint)TypeConverter.ToInt32(left) >> (int)(TypeConverter.ToUint32(right) & 0x1F)); case BinaryOperator.InstanceOf: var f = right.TryCast <FunctionInstance>(); if (f == null) { throw new JavaScriptException(_engine.TypeError, "instanceof can only be used with a function object"); } value = f.HasInstance(left); break; case BinaryOperator.In: if (!right.IsObject()) { throw new JavaScriptException(_engine.TypeError, "in can only be used with an object"); } value = right.AsObject().HasProperty(TypeConverter.ToString(left)); break; default: throw new NotImplementedException(); } return(value); }
static bool IsObject(JsValue value) { return(value.IsObject() && value.IsArray() == false); }
private static JsValue ScalarToRawString(JsValue self2, JsValue[] args) { if (args.Length != 2) { throw new InvalidOperationException("scalarToRawString(document, lambdaToField) may be called on with two parameters only"); } JsValue firstParam = args[0]; if (firstParam.IsObject() && args[0].AsObject() is BlittableObjectInstance selfInstance) { JsValue secondParam = args[1]; if (secondParam.IsObject() && secondParam.AsObject() is ScriptFunctionInstance lambda) { var functionAst = lambda.GetFunctionAst(); var propName = functionAst.TryGetFieldFromSimpleLambdaExpression(); if (selfInstance.OwnValues.TryGetValue(propName, out var existingValue)) { if (existingValue.Changed) { return(existingValue.Value); } } var propertyIndex = selfInstance.Blittable.GetPropertyIndex(propName); if (propertyIndex == -1) { return(new JsValue(new ObjectInstance(selfInstance.Engine) { Extensible = true })); } BlittableJsonReaderObject.PropertyDetails propDetails = new BlittableJsonReaderObject.PropertyDetails(); selfInstance.Blittable.GetPropertyByIndex(propertyIndex, ref propDetails); var value = propDetails.Value; switch (propDetails.Token & BlittableJsonReaderBase.TypesMask) { case BlittableJsonToken.Null: return(JsValue.Null); case BlittableJsonToken.Boolean: return(new JsValue((bool)propDetails.Value)); case BlittableJsonToken.Integer: return(new JsValue(new ObjectWrapper(selfInstance.Engine, value))); case BlittableJsonToken.LazyNumber: return(new JsValue(new ObjectWrapper(selfInstance.Engine, value))); case BlittableJsonToken.String: return(new JsValue(new ObjectWrapper(selfInstance.Engine, value))); case BlittableJsonToken.CompressedString: return(new JsValue(new ObjectWrapper(selfInstance.Engine, value))); default: throw new InvalidOperationException("scalarToRawString(document, lambdaToField) lambda to field must return either raw numeric or raw string types"); } } else { throw new InvalidOperationException("scalarToRawString(document, lambdaToField) must be called with a second lambda argument"); } } else { throw new InvalidOperationException("scalarToRawString(document, lambdaToField) may be called with a document first parameter only"); } }
public static IJsonValue Map(JsValue value) { if (value == null || value.IsNull() || value.IsUndefined()) { return(JsonValue.Null); } if (value.IsString()) { return(JsonValue.Create(value.AsString())); } if (value.IsBoolean()) { return(JsonValue.Create(value.AsBoolean())); } if (value.IsNumber()) { return(JsonValue.Create(value.AsNumber())); } if (value.IsDate()) { return(JsonValue.Create(value.AsDate().ToString())); } if (value.IsRegExp()) { return(JsonValue.Create(value.AsRegExp().Value?.ToString())); } if (value.IsArray()) { var arr = value.AsArray(); var result = JsonValue.Array(); for (var i = 0; i < arr.GetLength(); i++) { result.Add(Map(arr.Get(i.ToString()))); } return(result); } if (value.IsObject()) { var obj = value.AsObject(); var result = JsonValue.Object(); foreach (var kvp in obj.GetOwnProperties()) { result[kvp.Key] = Map(kvp.Value.Value); } return(result); } throw new ArgumentException("Invalid json type.", nameof(value)); }
private object ToBlittableValue(JsValue v, string propertyKey, bool recursiveCall) { if (v.IsBoolean()) { return(v.AsBoolean()); } if (v.IsString()) { const string RavenDataByteArrayToBase64 = "raven-data:byte[];base64,"; var valueAsObject = v.ToObject(); var value = valueAsObject?.ToString(); if (value != null && value.StartsWith(RavenDataByteArrayToBase64)) { value = value.Remove(0, RavenDataByteArrayToBase64.Length); var byteArray = Convert.FromBase64String(value); return(Encoding.UTF8.GetString(byteArray)); } return(value); } if (v.IsNumber()) { var num = v.AsNumber(); KeyValuePair <object, JsValue> property; if (_propertiesByValue.TryGetValue(propertyKey, out property)) { var originalValue = property.Key; if (originalValue is float || originalValue is int) { // If the current value is exactly as the original value, we can return the original value before we made the JS conversion, // which will convert a Int64 to jsFloat. var jsValue = property.Value; if (jsValue.IsNumber() && Math.Abs(num - jsValue.AsNumber()) < double.Epsilon) { return(originalValue); } //We might have change the type of num from Integer to long in the script by design //Making sure the number isn't a real float before returning it as integer if (originalValue is int && (Math.Abs(num - Math.Floor(num)) <= double.Epsilon || Math.Abs(num - Math.Ceiling(num)) <= double.Epsilon)) { return((long)num); } return(num); //float } } // If we don't have the type, assume that if the number ending with ".0" it actually an integer. var integer = Math.Truncate(num); if (Math.Abs(num - integer) < double.Epsilon) { return((long)integer); } return(num); } if (v.IsNull() || v.IsUndefined()) { return(null); } if (v.IsArray()) { var jsArray = v.AsArray(); var array = new DynamicJsonArray(); foreach (var property in jsArray.GetOwnProperties()) { if (InheritedProperties.Contains(property.Key)) { continue; } var jsInstance = property.Value.Value; if (!jsInstance.HasValue) { continue; } var ravenJToken = ToBlittableValue(jsInstance.Value, propertyKey + "[" + property.Key + "]", recursiveCall); if (ravenJToken == null) { continue; } array.Add(ravenJToken); } return(array); } if (v.IsDate()) { return(v.AsDate().ToDateTime()); } if (v.IsObject()) { return(ToBlittable(v.AsObject(), propertyKey, recursiveCall)); } if (v.IsRegExp()) { return(null); } throw new NotSupportedException(v.Type.ToString()); }
/// <summary> /// Checks if object /// </summary> /// <param name="value">Value</param> /// <returns>True if object</returns> public static bool IsObject(JsValue value) { return(value.IsObject()); }
private JsValue Sort(JsValue thisObj, JsValue[] arguments) { if (!thisObj.IsObject()) { throw new JavaScriptException(Engine.TypeError, "Array.prorotype.sort can only be applied on objects"); } var obj = thisObj.AsObject(); var len = obj.Get("length"); var lenVal = TypeConverter.ToInt32(len); if (lenVal <= 1) { return obj; } var compareArg = arguments.At(0); ICallable compareFn = null; if (compareArg != Undefined.Instance) { compareFn = compareArg.TryCast<ICallable>(x => { throw new JavaScriptException(Engine.TypeError, "The sort argument must be a function"); }); } Comparison<JsValue> comparer = (x, y) => { if (x == Undefined.Instance && y == Undefined.Instance) { return 0; } if (x == Undefined.Instance) { return 1; } if (y == Undefined.Instance) { return -1; } if (compareFn != null) { var s = (int) TypeConverter.ToUint32(compareFn.Call(Undefined.Instance, new[] {x, y})); return s; } var xString = TypeConverter.ToString(x); var yString = TypeConverter.ToString(y); var r = System.String.CompareOrdinal(xString, yString); return r; }; var array = Enumerable.Range(0, lenVal).Select(i => obj.Get(i.ToString())).ToArray(); // don't eat inner exceptions try { System.Array.Sort(array, comparer); } catch (InvalidOperationException e) { throw e.InnerException; } foreach (var i in Enumerable.Range(0, lenVal)) { obj.Put(i.ToString(), array[i], false); } return obj; }
public static JsValue Show(JavaScriptUi ui, string title, JsValue fields, JsValue validate) { if (ui == null) { throw new ArgumentNullException(nameof(ui)); } using (var form = new UiForm()) { if (String.IsNullOrEmpty(title)) { form.Text = ui.Owner.Text; } else { form.Text = title; } form.Icon = ui.Owner.Icon; if (!fields.IsArray()) { throw new JavaScriptException("fields must be an array"); } var controls = new List <Field>(); fields.AsArray().ForEach((index, value) => { var container = form._container; while (container.RowStyles.Count <= index) { container.RowCount++; container.RowStyles.Add(new RowStyle(SizeType.AutoSize)); } var field = value.AsObject(); string name = field.Get("name").ConvertToString(); string label = field.Get("label").ConvertToString(); var type = ParseType(field.Get("type").ConvertToString()); ArrayInstance list = null; if (field.HasOwnProperty("list")) { list = field.Get("list").AsArray(); } Field control; switch (type) { case FieldType.Text: control = new TextField(name, label); break; case FieldType.CheckBox: control = new CheckBoxField(name, label); break; case FieldType.Numeric: control = new NumericField(name, label); break; case FieldType.Date: control = new DateField(name, label); break; case FieldType.DateTime: control = new DateTimeField(name, label); break; case FieldType.ComboBox: control = new ComboBoxField(name, label, list); break; default: throw new ArgumentOutOfRangeException(); } controls.Add(control); if (field.HasOwnProperty("value")) { control.SetValue(field.Get("value")); } if (control.ShowLabel) { var labelControl = new Label { AutoSize = true, Text = label, Dock = DockStyle.Fill, TextAlign = ContentAlignment.MiddleLeft }; container.SetRow(labelControl, index); container.Controls.Add(labelControl); } control.Control.Dock = DockStyle.Fill; control.Control.AutoSize = true; container.SetRow(control.Control, index); container.SetColumn(control.Control, 1); container.Controls.Add(control.Control); }); form._acceptButton.Click += (s, e) => { try { if (validate.IsObject()) { var values = BuildValues(ui.Engine, controls); var result = validate.Invoke(values); if (!result.ConvertToBoolean().GetValueOrDefault()) { return; } } form.DialogResult = DialogResult.OK; } catch (JavaScriptException exception) { JintDebugger.ExceptionForm.Show(form, exception); } catch (Exception exception) { MessageBox.Show( form, new StringBuilder() .AppendLine("An exception occurred while executing the script:") .AppendLine() .Append(exception.Message).Append(" (").Append(exception.GetType().FullName).AppendLine(")") .AppendLine() .AppendLine(exception.StackTrace) .ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error ); } }; var owner = ui.Owner; using (ui.PushOwner(form)) { if (form.ShowDialog(owner) == DialogResult.OK) { return(BuildValues(ui.Engine, controls)); } } } return(JsValue.Null); }