public JsObject CreatePromise(out JsFunction resolve, out JsFunction reject) { var promiseHandle = m_engine.JsCreatePromise(out JavaScriptValueSafeHandle resolveHandle, out JavaScriptValueSafeHandle rejectHandle); resolve = CreateValue <JsFunction>(resolveHandle); reject = CreateValue <JsFunction>(rejectHandle); return(CreateValue <JsObject>(promiseHandle)); }
/// <summary> /// Tests whether the prototype property of a constructor appears anywhere in the prototype chain of an object. /// </summary> /// <param name="obj"></param> /// <param name="constructor"></param> /// <returns></returns> public bool InstanceOf(JsObject obj, JsFunction constructor) { if (IsDisposed) { throw new ObjectDisposedException(nameof(BaristaContext)); } return(Engine.JsInstanceOf(obj.Handle, constructor.Handle)); }
public bool TryCreatePrototypeFunction(BaristaContext context, Type typeToConvert, out JsFunction ctor) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (typeToConvert == null) { throw new ArgumentNullException(nameof(typeToConvert)); } if (m_prototypes.ContainsKey(typeToConvert)) { ctor = m_prototypes[typeToConvert]; return(true); } var reflector = new ObjectReflector(typeToConvert); JsFunction superCtor = null; var baseType = reflector.GetBaseType(); if (baseType != null && !baseType.IsSameOrSubclass(typeof(JsValue)) && TryCreatePrototypeFunction(context, baseType, out JsFunction fnSuper)) { superCtor = fnSuper; } var objectName = BaristaObjectAttribute.GetBaristaObjectNameFromType(typeToConvert); //Get all the property descriptors for the specified type. var staticPropertyDescriptors = context.CreateObject(); var instancePropertyDescriptors = context.CreateObject(); //Get static and instance properties. ProjectProperties(context, staticPropertyDescriptors, reflector.GetProperties(false)); ProjectProperties(context, instancePropertyDescriptors, reflector.GetProperties(true)); //Get static and instance indexer properties. ProjectIndexerProperties(context, staticPropertyDescriptors, reflector.GetIndexerProperties(false)); ProjectIndexerProperties(context, instancePropertyDescriptors, reflector.GetIndexerProperties(true)); //Get static and instance methods. ProjectMethods(context, staticPropertyDescriptors, reflector, reflector.GetUniqueMethodsByName(false)); ProjectMethods(context, instancePropertyDescriptors, reflector, reflector.GetUniqueMethodsByName(true)); //Get static and instance events. ProjectEvents(context, staticPropertyDescriptors, reflector, reflector.GetEventTable(false)); ProjectEvents(context, instancePropertyDescriptors, reflector, reflector.GetEventTable(true)); //Get the [[iterator]] property. ProjectIEnumerable(context, instancePropertyDescriptors, reflector); JsFunction fnCtor; var publicConstructors = reflector.GetConstructors(); if (publicConstructors.Any()) { fnCtor = context.CreateFunction(new BaristaFunctionDelegate((calleeObj, isConstructCall, thisObj, args) => { if (thisObj == null) { var ex = context.CreateTypeError($"Failed to construct '{objectName}': 'this' must be specified."); context.CurrentScope.SetException(ex); return(context.Undefined); } if (superCtor != null) { superCtor.Call(thisObj); } context.Object.DefineProperties(thisObj, instancePropertyDescriptors); //If this isn't a construct call, don't attempt to set the bean if (!isConstructCall) { return(thisObj); } //Set our native object. JsExternalObject externalObject = null; //!!Special condition -- if there's exactly one argument, and if it matches the enclosing type, //don't invoke the type's constructor, rather, just wrap the object with the JsObject. if (args.Length == 1 && args[0].GetType() == typeToConvert) { externalObject = context.CreateExternalObject(args[0]); } else { try { var bestConstructor = reflector.GetConstructorBestMatch(args); if (bestConstructor == null) { var ex = context.CreateTypeError($"Failed to construct '{objectName}': Could not find a matching constructor for the provided arguments."); context.CurrentScope.SetException(ex); return(context.Undefined); } //Convert the args into the native args of the constructor. var constructorParams = bestConstructor.GetParameters(); var convertedArgs = ConvertArgsToParamTypes(context, args, constructorParams); var newObj = bestConstructor.Invoke(convertedArgs); externalObject = context.CreateExternalObject(newObj); } catch (Exception ex) { context.CurrentScope.SetException(context.CreateError(ex.Message)); return(context.Undefined); } } thisObj.SetBean(externalObject); return(thisObj); }), objectName); } else { fnCtor = context.CreateFunction(new BaristaFunctionDelegate((calleeObj, isConstructCall, thisObj, args) => { var ex = context.CreateTypeError($"Failed to construct '{objectName}': This object cannot be constructed."); context.CurrentScope.SetException(ex); return(context.Undefined); }), objectName); } //We've got everything we need. fnCtor.Prototype = context.Object.Create(superCtor == null ? context.Object.Prototype : superCtor.Prototype); context.Object.DefineProperties(fnCtor, staticPropertyDescriptors); m_prototypes.Add(typeToConvert, fnCtor); ctor = fnCtor; return(true); }
public JsObject CreatePromise(out JsFunction resolve, out JsFunction reject) { return(ValueFactory.CreatePromise(out resolve, out reject)); }
public void Enqueue(JsFunction promise) { m_taskQueue.Enqueue(promise); }
/// <summary> /// Returns a new JavaScriptValue for the specified handle querying for the handle's value type. /// </summary> /// <remarks> /// Use the valueType parameter carefully. If the resulting type does not match the handle type unexpected issues may occur. /// </remarks> /// <returns>The JavaScript Value that represents the handle</returns> public JsValue CreateValue(JavaScriptValueSafeHandle valueHandle, JsValueType?valueType = null) { if (valueHandle == JavaScriptValueSafeHandle.Invalid) { return(null); } return(m_valuePool.GetOrAdd(valueHandle, () => { if (valueType.HasValue == false) { valueType = m_engine.JsGetValueType(valueHandle); } JsValue result; switch (valueType.Value) { case JsValueType.Array: result = new JsArray(m_engine, Context, valueHandle); break; case JsValueType.ArrayBuffer: result = new JsArrayBuffer(m_engine, Context, valueHandle); break; case JsValueType.Boolean: result = new JsBoolean(m_engine, Context, valueHandle); break; case JsValueType.DataView: result = new JsDataView(m_engine, Context, valueHandle); break; case JsValueType.Error: result = new JsError(m_engine, Context, valueHandle); break; case JsValueType.Function: result = new JsFunction(m_engine, Context, valueHandle); break; case JsValueType.Null: result = new JsNull(m_engine, Context, valueHandle); break; case JsValueType.Number: result = new JsNumber(m_engine, Context, valueHandle); break; case JsValueType.Object: result = new JsObject(m_engine, Context, valueHandle); break; case JsValueType.String: result = new JsString(m_engine, Context, valueHandle); break; case JsValueType.Symbol: result = new JsSymbol(m_engine, Context, valueHandle); break; case JsValueType.TypedArray: result = new JsTypedArray(m_engine, Context, valueHandle); break; case JsValueType.Undefined: result = new JsUndefined(m_engine, Context, valueHandle); break; default: throw new NotImplementedException($"Error Creating JavaScript Value: The JavaScript Value Type '{valueType}' is unknown, invalid, or has not been implemented."); } result.BeforeCollect += JsValueBeforeCollectCallback; return result; })); }