private JsObject JsDictionaryObject(JsValue v) { JsObject obj = new JsObject(this._context, v.Ptr); int len = v.Length * 2; for (int i = 0; i < len; i += 2) { var key = (JsValue)Marshal.PtrToStructure(new IntPtr(v.Ptr.ToInt64() + (16 * i)), typeof(JsValue)); var value = (JsValue)Marshal.PtrToStructure(new IntPtr(v.Ptr.ToInt64() + (16 * (i + 1))), typeof(JsValue)); obj[(string)FromJsValue(key)] = FromJsValue(value); } return obj; }
public object FromJsValue(JsValue v) { #if DEBUG_TRACE_API Console.WriteLine("Converting Js value to .net"); #endif switch (v.Type) { case JsValueType.Empty: case JsValueType.Null: return null; case JsValueType.Boolean: return v.I32 != 0; case JsValueType.Integer: return v.I32; case JsValueType.Index: return (UInt32)v.I64; case JsValueType.Number: return v.Num; case JsValueType.String: return Marshal.PtrToStringUni(v.Ptr); case JsValueType.Date: /* // The formula (v.num * 10000) + 621355968000000000L was taken from a StackOverflow // question and should be OK. Then why do we need to compensate by -26748000000000L // (a value determined from the failing tests)?! return new DateTime((long)(v.Num * 10000) + 621355968000000000L - 26748000000000L); */ //var msFromJsTime = v.I64 % 1000; return EPOCH_LocalTime.AddMilliseconds(v.I64);// + new TimeSpan(7, 0, 0); //return EPOCH_LocalTime.AddMilliseconds(v.I64);// + new TimeSpan(7, 0, 0); //return EPOCH.AddMilliseconds(v.I64); //return EPOCH.AddMilliseconds(v.Num); //return new DateTime((long)(v.Num * 10000) + 621355968000000000L - 26748000000000L); case JsValueType.Array: { int len = v.Length; var r = new object[len]; for (int i = 0; i < len; i++) { var vi = (JsValue)Marshal.PtrToStructure(new IntPtr(v.Ptr.ToInt64() + (16 * i)), typeof(JsValue)); r[i] = FromJsValue(vi); } return r; } case JsValueType.UnknownError: if (v.Ptr != IntPtr.Zero) return new JsException(Marshal.PtrToStringUni(v.Ptr)); return new JsInteropException("unknown error without reason"); case JsValueType.StringError: return new JsException(Marshal.PtrToStringUni(v.Ptr)); case JsValueType.Managed: return _context.KeepAliveGet(v.Index); case JsValueType.JsTypeWrap: //auto unwrap return this._context.GetObjectProxy(v.Index).WrapObject; case JsValueType.ManagedError: Exception inner = _context.KeepAliveGet(v.Index) as Exception; string msg = null; if (v.Ptr != IntPtr.Zero) { msg = Marshal.PtrToStringUni(v.Ptr); } else { if (inner != null) { msg = inner.Message; } } return new JsException(msg, inner); #if NET40 case JsValueType.Wrapped: return new JsObject(_context, v.Ptr); #else case JsValueType.Dictionary: return JsDictionaryObject(v); #endif case JsValueType.Wrapped: return new JsObject(_context, v.Ptr); case JsValueType.Error: return JsException.Create(this, (JsError)Marshal.PtrToStructure(v.Ptr, typeof(JsError))); case JsValueType.Function: var fa = new JsValue[2]; for (int i = 0; i < 2; i++) { fa[i] = (JsValue)Marshal.PtrToStructure(new IntPtr(v.Ptr.ToInt64() + (16 * i)), typeof(JsValue)); } return new JsFunction(_context, fa[0].Ptr, fa[1].Ptr); default: throw new InvalidOperationException("unknown type code: " + v.Type); } }
static extern JsValue jscontext_set_property_value(HandleRef engine, IntPtr ptr, [MarshalAs(UnmanagedType.LPWStr)] string name, JsValue value);
static extern JsValue jscontext_set_variable(HandleRef engine, [MarshalAs(UnmanagedType.LPWStr)] string name, JsValue value);
internal static extern void jsvalue_dispose(JsValue value);
static extern JsValue jscontext_invoke_property(HandleRef engine, IntPtr ptr, [MarshalAs(UnmanagedType.LPWStr)] string name, JsValue args);
internal static extern JsValue jscontext_invoke(HandleRef engine, IntPtr funcPtr, IntPtr thisPtr, JsValue args);
private JsValue KeepAliveSetPropertyValue(int contextId, int slot, string name, JsValue value) { #if DEBUG_TRACE_API Console.WriteLine("set prop " + contextId + " " + slot); #endif JsContext context; if (!_aliveContexts.TryGetValue(contextId, out context)) { throw new Exception("fail"); } return context.KeepAliveSetPropertyValue(slot, name, value); }
private JsValue KeepAliveInvoke(int contextId, int slot, JsValue args) { JsContext context; if (!_aliveContexts.TryGetValue(contextId, out context)) { throw new Exception("fail"); } return context.KeepAliveInvoke(slot, args); }
internal static extern void ResultSetJsValue(IntPtr callingArgsPtr, JsValue jsvalue);
static extern void jsvalue_dispose(ref JsValue value);