public void Emit(CodeGenerator generator) { _targetObject.Emit(generator); _value.Emit(generator); generator.CastType(_value.ObjectType, _field.FieldType); generator.Emit(OpCodes.Stfld, _field); }
public void EndSetMembers(CodeGenerator generator, ArgBuilder targetObject) { generator.Ldarg(targetObject); generator.Load(null); generator.If(Cmp.EqualTo); generator.Pop(); LocalBuilder dataRow = generator.DeclareLocal(typeof(DataRow)); generator.Ldloc(locDataTable); generator.Call(typeof(DataTable).GetMethod("NewRow")); generator.Stloc(dataRow); LocalBuilder locCurrent = generator.DeclareLocal(typeof(string)); LocalBuilder locEnumerator = generator.DeclareLocal(typeof(Dictionary<string, object>.KeyCollection.Enumerator)); generator.Ldloc(locMemberValues); generator.Call(typeof(Dictionary<string, object>).GetMethod("get_Keys")); generator.Call(typeof(Dictionary<string, object>.KeyCollection).GetMethod("GetEnumerator")); generator.Stloc(locEnumerator); MethodInfo getCurrentMethod = typeof(Dictionary<string, object>.KeyCollection.Enumerator).GetMethod("get_Current"); MethodInfo moveNextMethod = typeof(Dictionary<string, object>.KeyCollection.Enumerator).GetMethod("MoveNext"); generator.ForEach(locCurrent, typeof(string), typeof(Dictionary<string, object>.KeyCollection.Enumerator), locEnumerator, getCurrentMethod); generator.Ldloc(dataRow); generator.Ldloc(locCurrent); generator.Ldloc(locMemberValues); generator.Ldloc(locCurrent); generator.Call(typeof(Dictionary<string, object>).GetMethod("get_Item")); generator.Call(typeof(DataRow).GetMethod("set_Item", new Type[] { typeof(string), typeof(object) })); generator.EndForEach(moveNextMethod); generator.Ldloc(dataRow); generator.EndIf(); }
public JsonFormatClassReaderDelegate GenerateClassReader(ClassDataContract classContract) { _ilg = new CodeGenerator(); bool memberAccessFlag = classContract.RequiresMemberAccessForRead(null); try { BeginMethod(_ilg, "Read" + DataContract.SanitizeTypeName(classContract.StableName.Name) + "FromJson", typeof(JsonFormatClassReaderDelegate), memberAccessFlag); } catch (SecurityException securityException) { if (memberAccessFlag) { classContract.RequiresMemberAccessForRead(securityException); } else { throw; } } InitArgs(); CreateObject(classContract); _ilg.Call(_contextArg, XmlFormatGeneratorStatics.AddNewObjectMethod, _objectLocal); InvokeOnDeserializing(classContract); if (classContract.IsISerializable) ReadISerializable(classContract); else ReadClass(classContract); if (Globals.TypeOfIDeserializationCallback.IsAssignableFrom(classContract.UnderlyingType)) { _ilg.Call(_objectLocal, JsonFormatGeneratorStatics.OnDeserializationMethod, null); } InvokeOnDeserialized(classContract); if (!InvokeFactoryMethod(classContract)) { _ilg.Load(_objectLocal); // Do a conversion back from DateTimeOffsetAdapter to DateTimeOffset after deserialization. // DateTimeOffsetAdapter is used here for deserialization purposes to bypass the ISerializable implementation // on DateTimeOffset; which does not work in partial trust. if (classContract.UnderlyingType == Globals.TypeOfDateTimeOffsetAdapter) { _ilg.ConvertValue(_objectLocal.LocalType, Globals.TypeOfDateTimeOffsetAdapter); _ilg.Call(XmlFormatGeneratorStatics.GetDateTimeOffsetMethod); _ilg.ConvertValue(Globals.TypeOfDateTimeOffset, _ilg.CurrentMethod.ReturnType); } //Copy the KeyValuePairAdapter<K,T> to a KeyValuePair<K,T>. else if (classContract.IsKeyValuePairAdapter) { _ilg.Call(classContract.GetKeyValuePairMethodInfo); _ilg.ConvertValue(Globals.TypeOfKeyValuePair.MakeGenericType(classContract.KeyValuePairGenericArguments), _ilg.CurrentMethod.ReturnType); } else { _ilg.ConvertValue(_objectLocal.LocalType, _ilg.CurrentMethod.ReturnType); } } return (JsonFormatClassReaderDelegate)_ilg.EndMethod(); }
/// <summary> /// Emits the literal. The common code for all literals. /// </summary> internal override PhpTypeCode Emit(CodeGenerator/*!*/ codeGenerator) { ILEmitter il = codeGenerator.IL; // loads the value: il.LoadLiteral(Value); switch (access) { case AccessType.Read: return ValueTypeCode; case AccessType.None: il.Emit(OpCodes.Pop); return ValueTypeCode; case AccessType.ReadUnknown: case AccessType.ReadRef: // created by evaluation a function called on literal, e.g. $x =& sin(10); codeGenerator.EmitBoxing(ValueTypeCode); il.Emit(OpCodes.Newobj, Constructors.PhpReference_Object); return PhpTypeCode.PhpReference; } Debug.Fail("Invalid access type"); return PhpTypeCode.Invalid; }
/// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/> internal override PhpTypeCode Emit(CodeGenerator codeGenerator) { Statistics.AST.AddNode("ListEx"); Debug.Assert(access == AccessType.Read || access == AccessType.None); Debug.Assert(RValue != null); // the root of the lists structure must have RValue assigned. list(whatever) = RValue codeGenerator.EmitBoxing(RValue.Emit(codeGenerator)); // put object on the top of the stack LocalBuilder o1 = codeGenerator.IL.GetTemporaryLocal(Types.Object[0]); // temporary variable for object to be copied EmitAssignList(codeGenerator, LValues, o1); // assign particular elements of the list, using the array from the stack // return temporary local codeGenerator.IL.ReturnTemporaryLocal(o1); // the original top of the stack is replaced with the instance of array or null if (access == AccessType.Read) { return PhpTypeCode.PhpArray; // return the top of the stack (null or array) } else { codeGenerator.IL.Emit(OpCodes.Pop); // remove the top of the stack, not used return PhpTypeCode.Void; } }
public override ConvertHandler GetConvertHandler(Type inputType, Type outputType, object inputObject, object outputObject, Dictionary<string, string> mappingNames, List<string> ignoreList, Dictionary<int, string> mappingOrders, bool mappingSpecifiedOnly) { Dictionary<string, string> distToSrc = new Dictionary<string, string>(); Dictionary<string, MemberInfo> members = new Dictionary<string, MemberInfo>(); foreach (string sourceName in mappingNames.Keys) { MemberInfo sourceMember = ConvertorGeneratorHelper.GetMemberInfo(inputType, sourceName); Check.Require(sourceMember != null, string.Format("member named {0} could not be found in {1}", sourceName, outputType.FullName)); distToSrc.Add(mappingNames[sourceName], sourceName); members.Add(mappingNames[sourceName], sourceMember); } if (!mappingSpecifiedOnly) { Dictionary<string, MemberInfo> sourceMembers = ConvertorGeneratorHelper.GetMembers(inputType); foreach (string sourceName in sourceMembers.Keys) { if (!ignoreList.Contains(sourceName) && !distToSrc.ContainsKey(sourceName)) { distToSrc.Add(sourceName, sourceName); members.Add(sourceName, sourceMembers[sourceName]); } } } CodeGenerator gen = new CodeGenerator(); gen.BeginMethod("m" + Guid.NewGuid().ToString("N"), typeof(ConvertHandler)); ArgBuilder inputObjectArg = new ArgBuilder(0, inputType); ArgBuilder outputObjectArg = new ArgBuilder(1, outputType); int currentCount = 0; int memberCount = members.Count; string[] keys = new string[memberCount]; distToSrc.Keys.CopyTo(keys, 0); List<string> keyList = new List<string>(keys); MemberSetterGenerator.BeginSetMembers(gen, outputObjectArg); while (currentCount < memberCount) { currentCount++; string targetName = ConvertorGeneratorHelper.GetCurrentKey(mappingOrders, currentCount, keyList).Replace("_", ""); if (string.IsNullOrEmpty(targetName)) { continue; } string sourceName = distToSrc[targetName].Replace("_",""); if (MemberGetterGenerator.ContainsMember(sourceName, inputType, inputObject) && MemberSetterGenerator.ContainsMember(targetName, outputType, outputObject)) { Type targetType = ConvertorGeneratorHelper.GetMemberType(members[targetName]); LocalBuilder memberValue = gen.DeclareLocal(targetType, "memberValue"); MemberGetterGenerator.GetMemberValue(gen, inputObjectArg, sourceName, ref memberValue); MemberSetterGenerator.SetMemberValue(gen, outputObjectArg, targetName, memberValue); } } gen.Ldarg(outputObjectArg); MemberSetterGenerator.EndSetMembers(gen, outputObjectArg); return (ConvertHandler)gen.EndMethod(); }
public void SetMemberValue(CodeGenerator generator, ArgBuilder targetObject, string memberName, LocalBuilder memberValue) { generator.Ldarg(targetObject); generator.Load(memberName); generator.Ldloc(memberValue); // Type originalType = memberValue.LocalType.IsEnum ? typeof(int) : memberValue.LocalType; if (memberValue.LocalType.IsValueType) { generator.Box(memberValue.LocalType.IsEnum ? typeof(int) : memberValue.LocalType); } //���ֵΪ�գ����ܵ���ToString generator.Load(null); generator.If(Cmp.NotEqualTo); generator.Ldloc(memberValue); // Type originalType = memberValue.LocalType.IsEnum ? typeof(int) : memberValue.LocalType; if (memberValue.LocalType.IsValueType) { generator.Box(memberValue.LocalType.IsEnum ? typeof(int) : memberValue.LocalType); } generator.Call(typeof(object).GetMethod("ToString", Type.EmptyTypes)); generator.Else(); generator.LoadDefaultValue(memberValue.LocalType); if (memberValue.LocalType.IsValueType) { generator.Box(memberValue.LocalType.IsEnum ? typeof(int) : memberValue.LocalType); } generator.EndIf(); generator.Call(typeof(NameValueCollection).GetMethod("Add", new Type[] { typeof(string), typeof(string) })); }
public void Emit(CodeGenerator generator) { _value.Emit(generator); if (ObjectType.IsValueType) { generator.Emit(OpCodes.Box, ObjectType); } }
public void BeginSetMembers(CodeGenerator generator, ArgBuilder targetObject) { locMemberValues = generator.DeclareLocal(typeof(Dictionary<string, object>), "memberValues"); locDataTable = generator.DeclareLocal(typeof(DataTable), "dataTable"); generator.New(typeof(Dictionary<string, object>).GetConstructor(Type.EmptyTypes)); generator.Stloc(locMemberValues); generator.New(typeof(DataTable).GetConstructor(Type.EmptyTypes)); generator.Stloc(locDataTable); }
public void GetMemberValue(CodeGenerator generator, ArgBuilder targetObject, string memberName, ref LocalBuilder memberValue) { LocalBuilder locValue = generator.DeclareLocal(typeof(string)); Type targetType = memberValue.LocalType; Type originalType = ConvertorGeneratorHelper.GetOriginalType(targetType); generator.Ldarg(targetObject); generator.Load(memberName); generator.Call(typeof(NameValueCollection).GetMethod("get_Item", new Type[] { typeof(string) })); generator.Stloc(locValue); if (targetType.IsAssignableFrom(typeof(string))) { generator.Ldloc(locValue); generator.Stloc(memberValue); return; } else { generator.Ldloc(locValue); generator.Call(typeof(string).GetMethod("IsNullOrEmpty")); generator.Load(true); generator.If(Cmp.NotEqualTo); if (targetType == typeof(Guid)) { generator.Ldloc(locValue); generator.New(typeof(Guid).GetConstructor(new Type[] { typeof(string) })); generator.Stloc(memberValue); } else { MethodInfo parseMethod = targetType.GetMethod("Parse", new Type[] { typeof(string) }); if (parseMethod != null) { generator.Ldloc(locValue); generator.Call(parseMethod); generator.Stloc(memberValue); } else { generator.Ldloc(locValue); generator.Load(originalType); generator.Call(typeof(Convert).GetMethod("ChangeType", new Type[] { typeof(object), typeof(Type) })); if (targetType.IsValueType) { generator.UnboxAny(targetType); } generator.Stloc(memberValue); } } generator.Else(); generator.LoadDefaultValue(targetType); generator.Stloc(memberValue); generator.EndIf(); } }
/// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/> internal override PhpTypeCode Emit(CodeGenerator/*!*/ codeGenerator) { PhpTypeCode result; // emits inclusion and Main() call: result = EmitDynamicInclusion(codeGenerator); // return value conversion: codeGenerator.EmitReturnValueHandling(this, false, ref result); return result; }
public void SetMemberValue(CodeGenerator generator, ArgBuilder targetObject, string memberName, LocalBuilder memberValue) { generator.Ldarg(targetObject); generator.Load(memberName); generator.Ldloc(memberValue); if (memberValue.LocalType.IsValueType) { generator.Box(memberValue.LocalType.IsEnum ? typeof(int) : memberValue.LocalType); } generator.Call(typeof(IDictionary).GetMethod("Add")); }
/// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/> internal override PhpTypeCode Emit(CodeGenerator/*!*/ codeGenerator) { Statistics.AST.AddNode("IndirectVarUse"); PhpTypeCode result = PhpTypeCode.Invalid; switch (codeGenerator.SelectAccess(access)) { // This case occurs everytime we want to get current variable value // All we do is push the value onto the IL stack case AccessType.Read: // Push value onto a IL stack result = EmitNodeRead(codeGenerator); break; // This case occurs when the varible is written ($a = $b, then $a has Write mark) // We only prepare the stack for storing, the work will be done later, // by EmitAssign() case AccessType.Write: result = EmitNodeWrite(codeGenerator); break; case AccessType.None: EmitNodeRead(codeGenerator); codeGenerator.IL.Emit(OpCodes.Pop); result = PhpTypeCode.Void; break; case AccessType.ReadRef: // if the selector is set to the ReadRef, the chain is emitted as if it was written // (chained nodes are marked as ReadAndWrite): if (codeGenerator.AccessSelector == AccessType.ReadRef) codeGenerator.AccessSelector = AccessType.Write; result = EmitNodeReadRef(codeGenerator); Debug.Assert(result == PhpTypeCode.PhpReference); break; case AccessType.ReadUnknown: result = EmitNodeReadUnknown(codeGenerator); break; case AccessType.WriteRef: EmitNodeWriteRef(codeGenerator); result = PhpTypeCode.PhpReference; break; default: result = PhpTypeCode.Invalid; Debug.Fail(); break; } return result; }
public void Emit(CodeGenerator generator) { _returnValue.Emit(generator); if (ObjectType == _returnValue.ObjectType) { generator.Emit(OpCodes.Ret); } else { generator.CastType(_returnValue.ObjectType, ObjectType) .Emit(OpCodes.Ret); } }
/// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/> internal override PhpTypeCode Emit(CodeGenerator codeGenerator) { Debug.Assert(access == AccessType.Read || access == AccessType.None); ILEmitter il = codeGenerator.IL; // count integer and string keys: int int_count = 0; int string_count = 0; DetermineCapacities(out int_count, out string_count); // array = new PhpArray(<int_count>, <string_count>); il.Emit(OpCodes.Ldc_I4, int_count); il.Emit(OpCodes.Ldc_I4, string_count); il.Emit(OpCodes.Newobj, Constructors.PhpArray.Int32_Int32); if (codeGenerator.Context.Config.Compiler.Debug) { il.Emit(OpCodes.Nop); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Nop); } foreach (Item item in items) { // CALL array.SetArrayItemRef(z, p); // CALL array.SetArrayItem(x, PhpVariable.Copy(y, CopyReason.Assigned)); // CALL array.SetArrayItem(PhpVariable.Copy(x, CopyReason.Assigned)) // CALL array.AddToEnd(x) il.Emit(OpCodes.Dup); PhpTypeCode index_type_code = item.EmitIndex(codeGenerator); item.EmitValue(codeGenerator); codeGenerator.EmitSetArrayItem(index_type_code, item.Index, item is RefItem, true); } switch (this.access) { case AccessType.Read: // keep array on the stack return PhpTypeCode.PhpArray; case AccessType.None: // pop array from the stack il.Emit(OpCodes.Pop); return PhpTypeCode.Void; } Debug.Fail(); return PhpTypeCode.Invalid; }
public void SetMemberValue(CodeGenerator generator, ArgBuilder targetObject, string memberName, LocalBuilder memberValue) { generator.Ldarg(targetObject); if (memberValue.LocalType.FullName.StartsWith("System.Nullable`1[")) { generator.Ldloc(memberValue); generator.Load(null); generator.If(Cmp.EqualTo); generator.LoadMember(typeof(DBNull).GetField("Value")); generator.Stloc(memberValue); generator.EndIf(); } generator.Load(null); generator.If(Cmp.EqualTo); PropertyInfo columns = typeof(DataTable).GetProperty("Columns"); generator.Ldloc(locDataTable); generator.LoadMember(columns); generator.Load(memberName); generator.Ldtoken(CommonUtils.GetOriginalTypeOfNullableType(memberValue.LocalType.IsEnum ? typeof(int) : memberValue.LocalType)); generator.Call(typeof(Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(RuntimeTypeHandle) })); generator.Call(typeof(DataColumnCollection).GetMethod("Add", new Type[] { typeof(string), typeof(Type) })); generator.Pop(); generator.Ldloc(locMemberValues); generator.Load(memberName); generator.Ldloc(memberValue); if (memberValue.LocalType.IsValueType) { generator.Box(memberValue.LocalType.IsEnum ? typeof(int) : memberValue.LocalType); } generator.Call(typeof(Dictionary<string, object>).GetMethod("Add")); generator.Else(); generator.Ldarg(targetObject); generator.Load(memberName); generator.Ldloc(memberValue); if (memberValue.LocalType.IsValueType) { generator.Box(memberValue.LocalType); } generator.Call(typeof(DataRow).GetMethod("set_Item", new Type[] { typeof(string), typeof(object) })); generator.EndIf(); }
/// <summary> /// Emits dynamic inclusion. /// </summary> private PhpTypeCode EmitDynamicInclusion(CodeGenerator/*!*/ codeGenerator) { // do not generate dynamic auto inclusions: if (InclusionTypesEnum.IsAutoInclusion(inclusionType)) return PhpTypeCode.Void; ILEmitter il = codeGenerator.IL; // CALL context.DynamicInclude(<file name>,<relative includer source path>,variables,self,includer); codeGenerator.EmitLoadScriptContext(); codeGenerator.EmitConversion(fileNameEx, PhpTypeCode.String); il.Emit(OpCodes.Ldstr, codeGenerator.SourceUnit.SourceFile.RelativePath.ToString()); codeGenerator.EmitLoadRTVariablesTable(); codeGenerator.EmitLoadSelf(); codeGenerator.EmitLoadClassContext(); il.LoadLiteral(inclusionType); il.Emit(OpCodes.Call, Methods.ScriptContext.DynamicInclude); return PhpTypeCode.Object; }
/// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/> internal override PhpTypeCode Emit(CodeGenerator/*!*/ codeGenerator) { #if !SILVERLIGHT Debug.Assert(access == AccessType.Read || access == AccessType.None); Statistics.AST.AddNode("ShellEx"); // CALL Execution.ShellExec(<(string) command>); codeGenerator.EmitConversion(command, PhpTypeCode.String); codeGenerator.IL.Emit(OpCodes.Call, Methods.ShellExec); if (access == AccessType.None) { codeGenerator.IL.Emit(OpCodes.Pop); return PhpTypeCode.Void; } #endif // ShellExec returns a string containing the standard output of executed command return PhpTypeCode.String; }
internal override PhpTypeCode Emit(CodeGenerator/*!*/ codeGenerator) { ILEmitter il = codeGenerator.IL; LinqBuilder builder = new LinqBuilder(codeGenerator); builder.DefineContextType(); builder.EmitNewLinqContext(); codeGenerator.LinqBuilder = builder; LinqOpChain chain = body.BuildChain(); var typecode = chain.Emit(codeGenerator); // the result is IEnumerable<object>, let's wrap it and pass out il.Emit(OpCodes.Call, Methods.ClrObject_WrapRealObject); builder.BakeContextType(); return PhpTypeCode.Object; }
public void Emit(CodeGenerator generator) { switch (_index) { case 0: generator.Emit(OpCodes.Ldarg_0); break; case 1: generator.Emit(OpCodes.Ldarg_1); break; case 2: generator.Emit(OpCodes.Ldarg_2); break; case 3: generator.Emit(OpCodes.Ldarg_3); break; default: generator.Emit(OpCodes.Ldarg, _index); break; } }
public void Emit(CodeGenerator generator) { switch (_localBuilder.LocalIndex) { case 0: generator.Emit(OpCodes.Ldloc_0); break; case 1: generator.Emit(OpCodes.Ldloc_1); break; case 2: generator.Emit(OpCodes.Ldloc_2); break; case 3: generator.Emit(OpCodes.Ldloc_3); break; default: generator.Emit(OpCodes.Ldloc, _localBuilder.LocalIndex); break; } }
/// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/> /// <remarks> /// Nothing is expected on the evaluation stack. Nothing is left on the evaluation stack. /// </remarks> internal override void Emit(CodeGenerator/*!*/ codeGenerator) { Statistics.AST.AddNode("EchoStmt"); codeGenerator.MarkSequencePoint(position.FirstLine, position.FirstColumn, position.LastLine, position.LastColumn + 2); foreach (Expression parameter in parameters) { // skip empty evaluated expression if (parameter.HasValue && ( parameter.Value == null || (parameter.Value is string && ((string)parameter.Value) == string.Empty) || Convert.ObjectToPhpBytes(parameter.Value).Length == 0 )) { continue; } // emit the echo of parameter expression codeGenerator.EmitEcho(parameter); } }
internal JsonFormatCollectionWriterDelegate GenerateCollectionWriter(CollectionDataContract collectionContract) { _ilg = new CodeGenerator(); bool memberAccessFlag = collectionContract.RequiresMemberAccessForWrite(null); try { BeginMethod(_ilg, "Write" + DataContract.SanitizeTypeName(collectionContract.StableName.Name) + "ToJson", typeof(JsonFormatCollectionWriterDelegate), memberAccessFlag); } catch (SecurityException securityException) { if (memberAccessFlag) { collectionContract.RequiresMemberAccessForWrite(securityException); } else { throw; } } InitArgs(collectionContract.UnderlyingType); WriteCollection(collectionContract); return (JsonFormatCollectionWriterDelegate)_ilg.EndMethod(); }
public void Emit(CodeGenerator generator) { _array.Emit(generator); switch (_index) { case 0: generator.Emit(OpCodes.Ldc_I4_0); break; case 1: generator.Emit(OpCodes.Ldc_I4_1); break; case 2: generator.Emit(OpCodes.Ldc_I4_2); break; case 3: generator.Emit(OpCodes.Ldc_I4_3); break; default: generator.Emit(OpCodes.Ldc_I4, _index); break; } generator.Emit(OpCodes.Ldelem, ObjectType); }
internal JsonFormatClassWriterDelegate GenerateClassWriter(ClassDataContract classContract) { _ilg = new CodeGenerator(); bool memberAccessFlag = classContract.RequiresMemberAccessForWrite(null, JsonGlobals.JsonSerializationPatterns); try { BeginMethod(_ilg, "Write" + DataContract.SanitizeTypeName(classContract.StableName.Name) + "ToJson", typeof(JsonFormatClassWriterDelegate), memberAccessFlag); } catch (SecurityException securityException) { if (memberAccessFlag) { classContract.RequiresMemberAccessForWrite(securityException, JsonGlobals.JsonSerializationPatterns); } else { throw; } } InitArgs(classContract.UnderlyingType); _memberNamesArg = _ilg.GetArg(4); WriteClass(classContract); return (JsonFormatClassWriterDelegate)_ilg.EndMethod(); }
internal JsonFormatClassWriterDelegate GenerateClassWriter(ClassDataContract classContract) { ilg = new CodeGenerator(); bool memberAccessFlag = classContract.RequiresMemberAccessForWrite(null); try { BeginMethod(ilg, "Write" + classContract.StableName.Name + "ToJson", typeof(JsonFormatClassWriterDelegate), memberAccessFlag); } catch (SecurityException securityException) { if (memberAccessFlag && securityException.PermissionType.Equals(typeof(ReflectionPermission))) { classContract.RequiresMemberAccessForWrite(securityException); } else { throw; } } InitArgs(classContract.UnderlyingType); memberNamesArg = ilg.GetArg(4); DemandSerializationFormatterPermission(classContract); DemandMemberAccessPermission(memberAccessFlag); if (classContract.IsReadOnlyContract) { ThrowIfCannotSerializeReadOnlyTypes(classContract); } WriteClass(classContract); return (JsonFormatClassWriterDelegate)ilg.EndMethod(); }
void BeginMethod(CodeGenerator ilg, string methodName, Type delegateType, bool allowPrivateMemberAccess) { #if USE_REFEMIT ilg.BeginMethod(methodName, delegateType, allowPrivateMemberAccess); #else MethodInfo signature = delegateType.GetMethod("Invoke"); ParameterInfo[] parameters = signature.GetParameters(); Type[] paramTypes = new Type[parameters.Length]; for (int i = 0; i < parameters.Length; i++) paramTypes[i] = parameters[i].ParameterType; DynamicMethod dynamicMethod = new DynamicMethod(methodName, signature.ReturnType, paramTypes, typeof(JsonFormatWriterGenerator).Module, allowPrivateMemberAccess); ilg.BeginMethod(dynamicMethod, delegateType, methodName, paramTypes, allowPrivateMemberAccess); #endif }
/// <summary> /// Stores a reference on the top of the stack to a specified variable. /// </summary> internal void StoreLocalRefAssign(CodeGenerator codeGenerator, VariablesTable.Entry variable, LocalBuilder variableName) { ILEmitter il = codeGenerator.IL; Debug.Assert(variable == null ^ variableName == null); if (variable != null) { Debug.Assert(variable.IsPhpReference); variable.Variable.EmitStore(il); } else { // temp = STACK LocalBuilder temp = il.GetTemporaryLocal(Types.PhpReference[0], true); il.Stloc(temp); // CALL Operators.SetVariableRef(<local variables table>,<name>,temp); codeGenerator.EmitLoadScriptContext(); codeGenerator.EmitLoadRTVariablesTable(); il.Ldloc(variableName); il.Ldloc(temp); il.Emit(OpCodes.Call, Methods.Operators.SetVariableRef); } }
///// <summary> ///// Prepares local variable for a store operation. ///// </summary> //internal void StoreLocalPrepare(CodeGenerator codeGenerator, VariablesTable.Entry variable, LocalBuilder variableName) //{ // Debug.Assert(variable == null ^ variableName == null); //} /// <summary> /// Unsets a specified variable. /// </summary> internal void UnsetLocal(CodeGenerator codeGenerator, VariablesTable.Entry variable, LocalBuilder variableName) { ILEmitter il = codeGenerator.IL; Debug.Assert(variable == null ^ variableName == null); if (variable != null) { if (variable.IsPhpReference) { // <variable> = new PhpReference(); il.Emit(OpCodes.Newobj, Constructors.PhpReference_Void); variable.Variable.EmitStore(il); } else { il.Emit(OpCodes.Ldnull); variable.Variable.EmitStore(il); } } else { // CALL Operators.SetVariable(<local variables table>,<name>,null); codeGenerator.EmitLoadScriptContext(); codeGenerator.EmitLoadRTVariablesTable(); il.Ldloc(variableName); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Call, Methods.Operators.SetVariable); } }
/// <summary> /// Loads a specified reference local variable. /// </summary> internal void LoadLocalRef(CodeGenerator codeGenerator, VariablesTable.Entry variable, LocalBuilder variableName) { ILEmitter il = codeGenerator.IL; Debug.Assert(variable == null ^ variableName == null); if (variable != null) { Debug.Assert(variable.IsPhpReference); variable.Variable.EmitLoad(il); } else { codeGenerator.EmitLoadScriptContext(); codeGenerator.EmitLoadRTVariablesTable(); il.Ldloc(variableName); il.Emit(OpCodes.Call, Methods.Operators.GetVariableRef); } }