/// <summary> /// Recursively retrieves named properties. Returns true if all property names were found. /// If a value along the chain is not an object, false is returned and that value is the result. /// </summary> public bool TryGetNested(out JS.Value result, params string[] propertyNames) { var searchScope = Pointer; var temp = new Rooted <JS.Value>(Context, JS.Value.Undefined); for (int i = 0, l = propertyNames.Length; i < l; i++) { var name = propertyNames[i]; temp = searchScope.GetProperty(Context, name); if (i == (l - 1)) { result = temp.Value; return(true); } if (temp.Value.ValueType != JSValueType.OBJECT) { result = temp.Value; return(false); } searchScope = temp.Value.AsObject; } throw new Exception("Unexpected"); }
public static unsafe Rooted <JS.Value> ManagedToNativeException(JSContextPtr cx, Exception managedException) { var errorRoot = NewError(cx, managedException.Message); var errorObj = errorRoot.Value.AsObject; var existingStackRoot = new Rooted <JS.Value>(cx); JSAPI.GetProperty( cx, &errorObj, "stack", existingStackRoot ); var existingStackText = existingStackRoot.Value.ToManagedString(cx); JSAPI.SetProperty( cx, &errorObj, "stack", new JSString( cx, managedException.StackTrace + "\n//---- JS-to-native boundary ----//\n" + existingStackText ) ); if (managedException.InnerException != null) { var inner = ManagedToNativeException(cx, managedException.InnerException); JSAPI.SetProperty(cx, &errorObj, "innerException", inner); } return(errorRoot); }
public unsafe Rooted <Value> InvokeFunction( JSContextPtr context, JSHandleObject thisReference, params Value[] arguments ) { fixed(Value *pThis = &this) fixed(Value * pArgs = arguments) { var argsPtr = new ValueArrayPtr((uint)arguments.Length, (IntPtr)pArgs); var resultRoot = new Rooted <Value>(context, Undefined); if (JSAPI.CallFunctionValue( context, thisReference, pThis, ref argsPtr, resultRoot )) { return(resultRoot); } resultRoot.Dispose(); return(null); } }
/// <summary> /// Wraps existing reference and roots it. /// </summary> /// <param name="context"></param> /// <param name="str"></param> public JSString( JSContextPtr context, JSStringPtr str ) { if (context.IsZero) { throw new ArgumentNullException("context"); } Context = context; Root = new Rooted <JSStringPtr>(Context, str); }
public void MarshalArray() { using (var tc = new TestContext()) { var clrArray = new object[] { 1, 1.5, "a" }; var jsArray = new Rooted <JS.Value>( tc, JSMarshal.ManagedToNative(tc, clrArray) ); var roundTripArray = JSMarshal.NativeToManaged(tc, jsArray); Assert.AreEqual("1,1.5,a", jsArray.Value.ToManagedString(tc)); Assert.AreEqual(clrArray, roundTripArray); } }
public JSObjectReference( JSContextPtr context, JSObjectPtr obj ) { if (context.IsZero) { throw new ArgumentNullException("context"); } Context = context; Root = new Rooted <JSObjectPtr>(Context, obj); }
public Rooted <JS.Value> Evaluate(JSHandleObject scope, string scriptSource, string filename = null, uint lineNumber = 0) { var resultRoot = new Rooted <JS.Value>(this, JS.Value.Undefined); if (JSAPI.EvaluateScript( this, scope, scriptSource, filename, lineNumber, resultRoot )) { return(resultRoot); } resultRoot.Dispose(); return(null); }
/// <summary> /// Value becomes (or is) rooted by the object. /// It's your responsibility to root it if you need it to outlive the object. /// </summary> public JS.Value this[uint index] { get { var temp = new Rooted <JS.Value>(Context); if (!JSAPI.GetElement(Context, Root, index, temp)) { throw new Exception("Operation failed"); } return(temp.Value); } set { var temp = new Rooted <JS.Value>(Context, value); if (!JSAPI.SetElement(Context, Root, index, temp)) { throw new Exception("Operation failed"); } } }
// [TestCase] // FIXME: Cloning scripts doesn't work public void ExecuteCrossCompartment() { using (var tc = new TestContext()) { tc.Context.ReportUncaughtExceptions = false; var scriptRoot = new Rooted <JSScriptPtr>(tc); var options = new JSCompileOptions(); options.canLazilyParse = false; options.defineOnScope = false; options.sourceIsLazy = false; options.noScriptRval = true; Assert.IsTrue(JSAPI.CompileScript( tc, tc.Global, "function fn() { return global_v; }; global_v = 3;", options, scriptRoot )); if (tc.Context.Exception.IsPending) { throw tc.Context.Exception.GetManaged(); } tc.Leave(); using (var tc2 = new TestContext(tc.Runtime)) { var eres = (bool)JSAPI.CloneAndExecuteScript(tc2, tc2.Global, scriptRoot); if (tc2.Context.Exception.IsPending) { throw tc2.Context.Exception.GetManaged(); } Assert.IsTrue(eres); Assert.AreEqual(3, tc2.Global["global_v"].ToManaged(tc2)); tc2.Global["global_v"] = new JS.Value(5); var invokeResult = tc2.Global["fn"].InvokeFunction(tc2, JSHandleObject.Zero); Assert.AreEqual(5, invokeResult.Value.ToManaged(tc2)); } } }
// [TestCase] // FIXME: Cloning functions doesn't work public void CloneFunction() { using (var tc = new TestContext()) { tc.Context.ReportUncaughtExceptions = false; var funRoot = new Rooted <JSFunctionPtr>(tc); Assert.IsTrue(JSAPI.CompileFunction( tc, tc.Global, "test", 0, null, "return global_v;", JSCompileOptions.Default, funRoot )); if (tc.Context.Exception.IsPending) { throw tc.Context.Exception.GetManaged(); } tc.Leave(); using (var tc2 = new TestContext(tc.Runtime)) { var funRoot2 = new Rooted <JSObjectPtr>(tc2); funRoot2.Value = JSAPI.CloneFunctionObject(tc2, funRoot, tc2.Global); if (tc2.Context.Exception.IsPending) { throw tc2.Context.Exception.GetManaged(); } Assert.IsTrue(funRoot2.Value.IsNonzero); tc2.Global["global_v"] = new JS.Value(5); var invokeResult = funRoot2.Value.InvokeFunction(tc2, JSHandleObject.Zero); Assert.AreEqual(5, invokeResult.Value.ToManaged(tc2)); } } }
public void CompileThenExecuteFunction() { using (var tc = new TestContext()) { var funRoot = new Rooted <JSFunctionPtr>(tc); Assert.IsTrue(JSAPI.CompileFunction( tc, tc.Global, "test", 0, null, "return global_v;", JSCompileOptions.Default, funRoot )); Assert.IsTrue(funRoot.Value.IsNonzero); tc.Global["global_v"] = new JS.Value(5); var invokeResult = funRoot.Value.InvokeFunction(tc, JSHandleObject.Zero); Assert.AreEqual(5, invokeResult.Value.ToManaged(tc)); } }
public unsafe void ArrayReadTest() { using (var tc = new TestContext()) { var evalResult = tc.Context.Evaluate(tc.Global, "[1, 2, 3, 4]"); var obj = evalResult.Value.AsObject; Assert.IsTrue(JSAPI.IsArrayObject(tc, &obj)); var arrayHandle = (JSHandleObject)evalResult; uint length; Assert.IsTrue(JSAPI.GetArrayLength(tc, arrayHandle, out length)); Assert.AreEqual(4, length); var elementRoot = new Rooted <JS.Value>(tc); Assert.IsTrue(JSAPI.GetElement(tc, arrayHandle, 0, elementRoot)); Assert.AreEqual(1, elementRoot.Value.ToManaged(tc)); Assert.IsTrue(JSAPI.GetElement(tc, arrayHandle, 3, elementRoot)); Assert.AreEqual(4, elementRoot.Value.ToManaged(tc)); } }
public void CompileThenExecuteScript() { using (var tc = new TestContext()) { var scriptRoot = new Rooted <JSScriptPtr>(tc); Assert.IsTrue(JSAPI.CompileScript( tc, tc.Global, "function fn() { return global_v; }; global_v = 3;", JSCompileOptions.Default, scriptRoot )); Assert.IsTrue(scriptRoot.Value.IsNonzero); Assert.IsTrue(tc.Global["global_v"].IsNullOrUndefined); Assert.IsTrue(JSAPI.ExecuteScript(tc, tc.Global, scriptRoot)); Assert.AreEqual(3, tc.Global["global_v"].ToManaged(tc)); tc.Global["global_v"] = new JS.Value(5); var invokeResult = tc.Global["fn"].InvokeFunction(tc, JSHandleObject.Zero); Assert.AreEqual(5, invokeResult.Value.ToManaged(tc)); } }
public StatusEffects clone() { Rooted rooted = new Rooted(); rooted.duration = this.duration; return rooted; }
public JSObjectReference(Rooted <JSObjectPtr> objRoot) : this(objRoot.Context, objRoot.Value) { }
/// <summary> /// If valueRoot does not contain an object value, this will throw. /// </summary> public JSObjectReference(Rooted <JS.Value> valueRoot) : this(valueRoot.Context, valueRoot.Value.AsObject) { }
public JSString(Rooted <JSStringPtr> strRoot) : this(strRoot.Context, strRoot.Value) { }
/// <summary> /// If valueRoot does not contain an object value, this will throw. /// </summary> public JSArray(Rooted <JS.Value> valueRoot) : this(valueRoot.Context, valueRoot.Value.AsObject) { }
public JSArray(Rooted <JSObjectPtr> objRoot) : this(objRoot.Context, objRoot.Value) { }
/// <summary> /// If valueRoot does not contain a string value, this will throw. /// </summary> public JSString(Rooted <JS.Value> valueRoot) : this(valueRoot.Context, valueRoot.Value.AsString) { }