static public void Register(string name, object fn, int argcnt, Type rettype) { FunctionDesc desc = new FunctionDesc(); Utils.Assumes(argcnt <= 3); desc.fn_ = fn; desc.argcnt_ = argcnt; desc.rettype_ = externalType2ColumnType(rettype); set_.Add(name, desc); }
public override bool Equals(object obj) { FunctionDesc other = obj as FunctionDesc; if (other != null) { return(Name == other.Name && Ns == other.Ns && (Arity == other.Arity || Arity == -1 || other.Arity == -1)); } return(false); }
public void Add(string ns, string name, int arity, XPath2ResultType resultType, XPathFunctionDelegate action, bool overwriteExistingEntry = true) { var key = new FunctionDesc(name, ns, arity); if (_funcTable.ContainsKey(key) && overwriteExistingEntry) { _funcTable[key] = new XPathFunctionDef(name, action, resultType); } else { _funcTable.Add(key, new XPathFunctionDef(name, action, resultType)); } }
public void Resolve(string assemblyName, string dllName) { // create assembly and module AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly( new AssemblyName(assemblyName), AssemblyBuilderAccess.Save ); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName, dllName); // create Inanity.Object type TypeBuilder inanityObjectTypeBuilder = moduleBuilder.DefineType( "Inanity.Object", TypeAttributes.Public | TypeAttributes.Abstract, null, // parent new Type[] { typeof(IDisposable) } ); inanityObjectTypeBuilder.DefineField( "ptr", typeof(UIntPtr), FieldAttributes.Family ); ConstructorBuilder inanityObjectConstructorBuilder = inanityObjectTypeBuilder.DefineDefaultConstructor(MethodAttributes.Family); { MethodBuilder disposeMethod = inanityObjectTypeBuilder.DefineMethod( "Dispose", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig, typeof(void), new Type[] { } ); disposeMethod.SetImplementationFlags(MethodImplAttributes.InternalCall); } inanityObjectTypeBuilder.CreateType(); // create type bulders for all classes foreach (string fullClassName in classes.Keys) { classes[fullClassName].typeBuilder = moduleBuilder.DefineType( fullClassName, TypeAttributes.Public | (classes[fullClassName].constructor == null ? TypeAttributes.Abstract : 0) ); } // lambda for resolving types Func <string, Type> resolveType = delegate(string typeName) { switch (typeName) { case "void": return(typeof(void)); case "bool": return(typeof(bool)); case "int32": return(typeof(Int32)); case "uint32": return(typeof(UInt32)); case "int64": return(typeof(Int64)); case "uint64": return(typeof(UInt64)); case "float": return(typeof(float)); case "double": return(typeof(double)); case "string": return(typeof(string)); case "object": return(typeof(object)); default: { ClassDesc classDesc; if (!classes.TryGetValue(typeName, out classDesc)) { throw new Exception("Cannot resolve type " + typeName); } return(classDesc.typeBuilder); } } }; // set parents, create constructors and methods foreach (string className in classes.Keys) { ClassDesc classDesc = classes[className]; TypeBuilder typeBuilder = classDesc.typeBuilder; // set parent { TypeBuilder parentTypeBuilder; if (classDesc.parentClassName != null) { if (!classes.TryGetValue(classDesc.parentClassName, out classDesc.parentClassDesc)) { throw new Exception("Parent class " + classDesc.parentClassName + " is not registered"); } parentTypeBuilder = classDesc.parentClassDesc.typeBuilder; } else { parentTypeBuilder = inanityObjectTypeBuilder; } typeBuilder.SetParent(parentTypeBuilder); } // set constructor { ConstructorDesc constructorDesc = classDesc.constructor; if (constructorDesc != null) { Type[] argumentTypes = constructorDesc.argumentTypes.Select(resolveType).ToArray(); // define extern thunk method MethodBuilder methodBuilder = typeBuilder.DefineMethod( "__c", MethodAttributes.Private, CallingConventions.HasThis, typeof(void), argumentTypes ); methodBuilder.SetImplementationFlags(MethodImplAttributes.InternalCall); classDesc.constructorThunkMethodBuilder = methodBuilder; // define constructor ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.HasThis, argumentTypes ); classDesc.constructorBuilder = constructorBuilder; } else { classDesc.constructorBuilder = typeBuilder.DefineDefaultConstructor(MethodAttributes.Family); } } // add methods foreach (string methodName in classDesc.methods.Keys) { MethodDesc methodDesc = classDesc.methods[methodName]; MethodBuilder methodBuilder = typeBuilder.DefineMethod( methodName, MethodAttributes.Public | MethodAttributes.Final, CallingConventions.HasThis, resolveType(methodDesc.returnType), methodDesc.argumentTypes.Select(resolveType).ToArray() ); methodBuilder.SetImplementationFlags(MethodImplAttributes.InternalCall); } // add static methods foreach (string staticMethodName in classDesc.staticMethods.Keys) { FunctionDesc functionDesc = classDesc.staticMethods[staticMethodName]; MethodBuilder methodBuilder = typeBuilder.DefineMethod( staticMethodName, MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Static, CallingConventions.Standard, resolveType(functionDesc.returnType), functionDesc.argumentTypes.Select(resolveType).ToArray() ); methodBuilder.SetImplementationFlags(MethodImplAttributes.InternalCall); } } // emit code for constructors foreach (ClassDesc classDesc in classes.Values) { ConstructorDesc constructorDesc = classDesc.constructor; if (constructorDesc == null) { continue; } Type[] argumentTypes = constructorDesc.argumentTypes.Select(resolveType).ToArray(); ILGenerator ilGenerator = classDesc.constructorBuilder.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Call, classDesc.parentClassDesc != null ? classDesc.parentClassDesc.constructorBuilder : inanityObjectConstructorBuilder ); ilGenerator.Emit(OpCodes.Ldarg_0); for (int i = 0; i < argumentTypes.Length; ++i) { ilGenerator.Emit(OpCodes.Ldarg, i + 1); } ilGenerator.Emit(OpCodes.Call, classDesc.constructorThunkMethodBuilder); ilGenerator.Emit(OpCodes.Ret); } // create types foreach (ClassDesc classDesc in classes.Values) { classDesc.typeBuilder.CreateType(); } // save assembly assemblyBuilder.Save(dllName); }