private bool AddOrUpdateConstructor(bool isInstance, IMethod orig) { var holder = _type as IHasConstructors; if (holder == null) { return(false); } var cstr = holder.Constructors.FirstOrDefault(c => isInstance ? !c.Modifier.HasFlag(Modifier.Static) : c.Modifier == Modifier.Static); if (cstr == null) { holder.Constructors.Add(cstr = new ConstructorImpl(null)); } cstr.Visibility = orig.Visibility; foreach (var parm in orig.Parameters) { var myParm = new ParameterImpl(parm.Name, parm.Type); cstr.Parameters.Add(myParm); } if (!isInstance) { cstr.Modifier = Modifier.Static; } return(true); }
private object CreateInstance(IJintVisitor visitor, JsInstance[] parameters) { ConstructorImpl constructorImpl = this.m_overloads.ResolveOverload(parameters, (Type[])null); if (constructorImpl == null) { throw new JintException(string.Format("No matching overload found {0}({1})", (object)this.reflectedType.FullName, (object)string.Join(",", Array.ConvertAll <JsInstance, string>(parameters, (Converter <JsInstance, string>)(p => p.ToString()))))); } return(constructorImpl(visitor.Global, parameters)); }
/// <summary> /// Finds a best matched constructor and uses it to create a native object instance /// </summary> /// <param name="visitor">Execution visitor</param> /// <param name="parameters">Parameters for a constructor</param> /// <returns>A newly created native object</returns> object CreateInstance(Jint.Expressions.IJintVisitor visitor, JsInstance[] parameters) { ConstructorImpl impl = m_overloads.ResolveOverload(parameters, null); if (impl == null) { throw new JintException( String.Format("No matching overload found {0}({1})", reflectedType.FullName, String.Join(",", Array.ConvertAll <JsInstance, string>(parameters, p => p.ToString())) ) ); } return(impl(visitor.Global, parameters)); }
public ConstructorImpl WrapConstructor(ConstructorInfo info, bool passGlobal) { if (info == null) { throw new ArgumentNullException(nameof(info)); } lock (this.ctorCache) { ConstructorImpl constructorImpl; if (this.ctorCache.TryGetValue(info, out constructorImpl)) { return(constructorImpl); } } LinkedList <ParameterInfo> linkedList = new LinkedList <ParameterInfo>((IEnumerable <ParameterInfo>)info.GetParameters()); DynamicMethod dynamicMethod = new DynamicMethod("clrConstructor", typeof(object), new Type[2] { typeof(IGlobal), typeof(JsInstance[]) }, this.GetType()); ILGenerator ilGenerator = dynamicMethod.GetILGenerator(); ilGenerator.DeclareLocal(typeof(int)); if (passGlobal && linkedList.First != null && typeof(IGlobal).IsAssignableFrom(linkedList.First.Value.ParameterType)) { linkedList.RemoveFirst(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Isinst, typeof(IGlobal)); } ilGenerator.Emit(OpCodes.Ldarg_1); ilGenerator.Emit(OpCodes.Ldlen); ilGenerator.Emit(OpCodes.Stloc_0); int num = 0; foreach (ParameterInfo parameterInfo in linkedList) { ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.EmitCall(OpCodes.Call, typeof(IGlobal).GetProperty("Marshaller").GetGetMethod(), (Type[])null); Label label1 = ilGenerator.DefineLabel(); Label label2 = ilGenerator.DefineLabel(); ilGenerator.Emit(OpCodes.Ldloc_0); ilGenerator.Emit(OpCodes.Ldc_I4, num); ilGenerator.Emit(OpCodes.Ble, label1); ilGenerator.Emit(OpCodes.Ldarg_1); ilGenerator.Emit(OpCodes.Ldc_I4, num); ilGenerator.Emit(OpCodes.Ldelem, typeof(JsInstance)); ilGenerator.Emit(OpCodes.Br, label2); ilGenerator.MarkLabel(label1); ilGenerator.Emit(OpCodes.Ldsfld, typeof(JsUndefined).GetField("Instance")); ilGenerator.MarkLabel(label2); if (parameterInfo.ParameterType.IsByRef) { Type elementType = parameterInfo.ParameterType.GetElementType(); LocalBuilder localBuilder = ilGenerator.DeclareLocal(elementType); ilGenerator.Emit(OpCodes.Call, typeof(Marshaller).GetMethod("MarshalJsValue").MakeGenericMethod(elementType)); ilGenerator.Emit(OpCodes.Stloc, localBuilder.LocalIndex); ilGenerator.Emit(OpCodes.Ldloca, localBuilder.LocalIndex); } else { ilGenerator.Emit(OpCodes.Call, typeof(Marshaller).GetMethod("MarshalJsValue").MakeGenericMethod(parameterInfo.ParameterType)); } ++num; } ilGenerator.Emit(OpCodes.Newobj, info); if (info.DeclaringType.IsValueType) { ilGenerator.Emit(OpCodes.Box, info.DeclaringType); } ilGenerator.Emit(OpCodes.Ret); ConstructorImpl constructorImpl1 = (ConstructorImpl)dynamicMethod.CreateDelegate(typeof(ConstructorImpl)); lock (this.ctorCache) this.ctorCache[info] = constructorImpl1; return(constructorImpl1); }