public bool ToBoolean(JavaScriptValue value) { if (value == null) throw new ArgumentNullException(nameof(value)); var eng = GetEngineAndClaimContext(); bool result; if (value.Type == JavaScriptValueType.Boolean) { Errors.ThrowIfIs(api_.JsBooleanToBool(value.handle_, out result)); } else { JavaScriptValueSafeHandle tempBool; Errors.ThrowIfIs(api_.JsConvertValueToBoolean(value.handle_, out tempBool)); using (tempBool) { Errors.ThrowIfIs(api_.JsBooleanToBool(tempBool, out result)); } } return result; }
public double ToDouble(JavaScriptValue value) { if (value == null) throw new ArgumentNullException(nameof(value)); var eng = GetEngineAndClaimContext(); double result; if (value.Type == JavaScriptValueType.Number) { Errors.ThrowIfIs(api_.JsNumberToDouble(value.handle_, out result)); } else { JavaScriptValueSafeHandle tempVal; Errors.ThrowIfIs(api_.JsConvertValueToNumber(value.handle_, out tempVal)); using (tempVal) { Errors.ThrowIfIs(api_.JsNumberToDouble(tempVal, out result)); } } return result; }
public bool SimpleEquals(JavaScriptValue other) { var eng = GetEngineAndClaimContext(); bool result; Errors.ThrowIfIs(api_.JsEquals(this.handle_, other.handle_, out result)); return result; }
public bool StrictEquals(JavaScriptValue other) { var eng = GetEngine(); bool result; Errors.ThrowIfIs(api_.JsStrictEquals(this.handle_, other.handle_, out result)); return result; }
static JavaScriptValue Echo(JavaScriptEngine engine, bool construct, JavaScriptValue thisValue, IEnumerable<JavaScriptValue> arguments) { Console.WriteLine(arguments.First().ToString(), (object[])arguments.Skip(1).ToArray()); return engine.UndefinedValue; }
// todo: replace with a dynamic method thunk private MethodInfo GetBestFitMethod(IEnumerable<MethodInfo> methodCandidates, JavaScriptValue thisObj, JavaScriptValue[] argsArray) { JavaScriptObject @this = thisObj as JavaScriptObject; if (@this == null) return null; var external = @this.ExternalObject; if (external == null) return null; MethodInfo most = null; int arity = -1; foreach (var candidate in methodCandidates) { //if (candidate.DeclaringType != external.GetType()) // continue; var paramCount = candidate.GetParameters().Length; if (argsArray.Length == paramCount) { return candidate; } else if (argsArray.Length < paramCount) { if (paramCount > arity) { arity = paramCount; most = candidate; } } } return most; }
public void DeleteValueAtIndex(JavaScriptValue index) { if (index == null) throw new ArgumentNullException(nameof(index)); GetEngineAndClaimContext(); // unused but the call is needed to claim the context Errors.ThrowIfIs(api_.JsDeleteIndexedProperty(handle_, index.handle_)); }
public unsafe string ToString(JavaScriptValue value) { if (value == null) throw new ArgumentNullException(nameof(value)); var eng = GetEngineAndClaimContext(); if (value.Type == JavaScriptValueType.String) { void* str; uint len; Errors.ThrowIfIs(api_.JsStringToPointer(value.handle_, out str, out len)); if (len > int.MaxValue) throw new OutOfMemoryException("Exceeded maximum string length."); return Marshal.PtrToStringUni(new IntPtr(str), unchecked((int)len)); } else if (value.Type == JavaScriptValueType.Symbol) { // Presently, JsRT doesn't have a way for the host to query the description of a Symbol // Using JsConvertValueToString resulted in putting the runtime into an exception state // Thus, detect the condition and just return a known string. return "(Symbol)"; } else { JavaScriptValueSafeHandle tempStr; Errors.ThrowIfIs(api_.JsConvertValueToString(value.handle_, out tempStr)); using (tempStr) { void* str; uint len; Errors.ThrowIfIs(api_.JsStringToPointer(tempStr, out str, out len)); if (len > int.MaxValue) throw new OutOfMemoryException("Exceeded maximum string length."); return Marshal.PtrToStringUni(new IntPtr(str), unchecked((int)len)); } } }
public object ToObject(JavaScriptValue val) { switch (val.Type) { case JavaScriptValueType.Boolean: return val.IsTruthy; case JavaScriptValueType.Number: return ToDouble(val); case JavaScriptValueType.String: return ToString(val); case JavaScriptValueType.Undefined: return null; case JavaScriptValueType.Array: JavaScriptArray arr = val as JavaScriptArray; Debug.Assert(arr != null); return arr.Select(v => ToObject(v)).ToArray(); case JavaScriptValueType.ArrayBuffer: var ab = val as JavaScriptArrayBuffer; Debug.Assert(ab != null); return ab.GetUnderlyingMemory(); case JavaScriptValueType.DataView: var dv = val as JavaScriptDataView; Debug.Assert(dv != null); return dv.GetUnderlyingMemory(); case JavaScriptValueType.TypedArray: var ta = val as JavaScriptTypedArray; Debug.Assert(ta != null); return ta.GetUnderlyingMemory(); case JavaScriptValueType.Object: var obj = val as JavaScriptObject; var external = obj.ExternalObject; return external ?? obj; // Unsupported marshaling types case JavaScriptValueType.Function: case JavaScriptValueType.Date: case JavaScriptValueType.Symbol: default: throw new NotSupportedException("Unsupported type marshaling value from JavaScript to host: " + val.Type); } }
public void SetGlobalVariable(string name, JavaScriptValue value) { if (value == null) throw new ArgumentNullException(nameof(value)); GlobalObject.SetPropertyByName(name, value); }
public void SetException(JavaScriptValue exception) { if (exception == null) throw new ArgumentNullException(nameof(exception)); ClaimContext(); Errors.ThrowIfIs(api_.JsSetException(exception.handle_)); }
public JavaScriptValue this[JavaScriptValue index] { get { return GetValueAtIndex(index); } set { SetValueAtIndex(index, value); } }
// todo: replace with a dynamic method thunk private MethodInfo GetBestFitMethod(IEnumerable <MethodInfo> methodCandidates, JavaScriptValue thisObj, JavaScriptValue[] argsArray) { JavaScriptObject @this = thisObj as JavaScriptObject; if (@this == null) { return(null); } var external = @this.ExternalObject; if (external == null) { return(null); } MethodInfo most = null; int arity = -1; foreach (var candidate in methodCandidates) { //if (candidate.DeclaringType != external.GetType()) // continue; var paramCount = candidate.GetParameters().Length; if (argsArray.Length == paramCount) { return(candidate); } else if (argsArray.Length < paramCount) { if (paramCount > arity) { arity = paramCount; most = candidate; } } } return(most); }
public void DeleteValueAtIndex(JavaScriptValue index) { if (index == null) throw new ArgumentNullException(nameof(index)); Errors.ThrowIfIs(api_.JsDeleteIndexedProperty(handle_, index.handle_)); }
public void SetValueAtIndex(JavaScriptValue index, JavaScriptValue value) { if (index == null) throw new ArgumentNullException(nameof(index)); var eng = GetEngine(); if (value == null) value = eng.NullValue; Errors.ThrowIfIs(api_.JsSetIndexedProperty(handle_, index.handle_, value.handle_)); }
public JavaScriptValue GetValueAtIndex(JavaScriptValue index) { if (index == null) throw new ArgumentNullException(nameof(index)); var eng = GetEngine(); JavaScriptValueSafeHandle result; Errors.ThrowIfIs(api_.JsGetIndexedProperty(handle_, index.handle_, out result)); return eng.CreateValueFromHandle(result); }
public void SetPropertyBySymbol(JavaScriptSymbol symbol, JavaScriptValue value) { var eng = GetEngine(); IntPtr propId; Errors.ThrowIfIs(api_.JsGetPropertyIdFromSymbol(symbol.handle_, out propId)); Errors.ThrowIfIs(api_.JsSetProperty(handle_, propId, value.handle_, false)); }
public void SetPropertyByName(string propertyName, JavaScriptValue value) { var eng = GetEngine(); IntPtr propId; Errors.ThrowIfIs(api_.JsGetPropertyIdFromName(propertyName, out propId)); Errors.ThrowIfIs(api_.JsSetProperty(handle_, propId, value.handle_, false)); }