/// <summary> /// Creates a REST call from a given method. /// If the method has no marker, a null is returned /// </summary> /// <param name="methodBase">The method base.</param> /// <returns></returns> public static RestCall FromMethod(MethodBase methodBase) { var httpGet = methodBase.GetCustomAttribute<HttpGetAttribute>(); if (httpGet != null) return new RestCall("GET", httpGet.UriTemplate); return null; }
private static Function EmitFunction(Module module, MethodBase method) { var methodInfo = method as MethodInfo; var methodConstructor = method as ConstructorInfo; var declaringType = method.DeclaringType; if (methodInfo == null && methodConstructor == null) throw new CudaSharpException("Unknown MethodBase type " + method.GetType().FullName); if (declaringType == null) throw new CudaSharpException("Could not find the declaring type of " + method.Name.StripNameToValidPtx()); var parameters = method.GetParameters().Select(p => p.ParameterType); if (methodConstructor != null) parameters = new[] { declaringType.MakeByRefType() }.Concat(parameters); if (methodInfo != null && methodInfo.IsStatic == false) { if (declaringType.IsValueType == false) throw new CudaSharpException("Cannot compile object instance methods (did you forget to mark the method as static?)"); parameters = new[] { declaringType.MakeByRefType() }.Concat(parameters); } var llvmParameters = parameters.Select(t => ConvertType(module, t)).ToArray(); var funcType = new FunctionType(ConvertType(module, methodInfo == null ? typeof(void) : methodInfo.ReturnType), llvmParameters); var intrinsic = method.GetCustomAttribute<Gpu.BuiltinAttribute>(); if (intrinsic != null) { var name = intrinsic.Intrinsic; var preExisting = module.GetFunction(name); if (preExisting != null) return preExisting; return module.CreateFunction(name, funcType); } var function = module.CreateFunction(methodConstructor == null ? method.Name.StripNameToValidPtx() : declaringType.Name.StripNameToValidPtx() + "_ctor", funcType); var block = new Block("entry", module.Context, function); var writer = new InstructionBuilder(module.Context, block); var opcodes = method.Disassemble().ToList(); FindBranchTargets(opcodes, module.Context, function); var body = method.GetMethodBody(); var efo = new EmitFuncObj(module, function, body, writer, null, new Stack<Value>(), body == null ? null : new Value[body.LocalVariables.Count], new Value[llvmParameters.Length]); PrintHeader(efo); foreach (var opcode in opcodes) { if (EmitFunctions.ContainsKey(opcode.Opcode) == false) throw new CudaSharpException("Unsupported CIL instruction " + opcode.Opcode); var func = EmitFunctions[opcode.Opcode]; efo.Argument = opcode.Parameter; func(efo); } return function; }
public static MethodTranslationInfo FromMethodInfo(MethodBase methodInfo, ClassTranslationInfo classTranslationInfo) { var result = new MethodTranslationInfo { _scriptName = methodInfo.Name, _classTi = classTranslationInfo }; var scriptNameAttribute = methodInfo.GetCustomAttribute<ScriptNameAttribute>(); if (scriptNameAttribute != null) result._scriptName = scriptNameAttribute.Name.Trim(); if (string.IsNullOrEmpty(result._scriptName)) throw new Exception("Method name is empty"); return result; }
internal static bool TryGetReflectedCode(MethodBase b, out string code) { var att = b.GetCustomAttribute<CompiledReflectedDefinitionAttribute>(false); if (att != null) { var c = att.Code; c = c.Replace("\\r", "\r").Replace("\\n", "\n"); code = c; return true; } else { code = null; return false; } }
protected void ScanMethod(MethodBase aMethod, bool aIsPlug, string sourceItem) { var xParams = aMethod.GetParameters(); var xParamTypes = new Type[xParams.Length]; // Dont use foreach, enum generaly keeps order but // isn't guaranteed. //string xMethodFullName = LabelName.GenerateFullName(aMethod); for (int i = 0; i < xParams.Length; i++) { xParamTypes[i] = xParams[i].ParameterType; Queue(xParamTypes[i], aMethod, "Parameter"); } var xIsDynamicMethod = aMethod.DeclaringType == null; // Queue Types directly related to method if (!aIsPlug) { // Don't queue declaring types of plugs if (!xIsDynamicMethod) { // dont queue declaring types of dynamic methods either, those dont have a declaring type Queue(aMethod.DeclaringType, aMethod, "Declaring Type"); } } if (aMethod is SysReflection.MethodInfo) { Queue(((SysReflection.MethodInfo) aMethod).ReturnType, aMethod, "Return Type"); } if (aMethod.GetFullName().IndexOf("CreateComparer", StringComparison.OrdinalIgnoreCase)!=-1) { ; } // Scan virtuals #region Virtuals scan if (!xIsDynamicMethod && aMethod.IsVirtual) { // For virtuals we need to climb up the type tree // and find the top base method. We then add that top // node to the mVirtuals list. We don't need to add the // types becuase adding DeclaringType will already cause // all ancestor types to be added. var xVirtMethod = aMethod; var xVirtType = aMethod.DeclaringType; MethodBase xNewVirtMethod; while (true) { xVirtType = xVirtType.BaseType; if (xVirtType == null) { // We've reached object, can't go farther xNewVirtMethod = null; } else { xNewVirtMethod = xVirtType.GetMethod(aMethod.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, xParamTypes, null); if (xNewVirtMethod != null) { if (!xNewVirtMethod.IsVirtual) { // This can happen if a virtual "replaces" a non virtual // above it that is not virtual. xNewVirtMethod = null; } } } // We dont bother to add these to Queue, because we have to do a // full downlevel scan if its a new base virtual anyways. if (xNewVirtMethod == null) { // If its already in the list, we mark it null // so we dont do a full downlevel scan. if (mVirtuals.Contains(xVirtMethod)) { xVirtMethod = null; } break; } xVirtMethod = xNewVirtMethod; } // New virtual base found, we need to downscan it // If it was already in mVirtuals, then ScanType will take // care of new additions. if (xVirtMethod != null) { Queue(xVirtMethod, aMethod, "Virtual Base"); mVirtuals.Add(xVirtMethod); // List changes as we go, cant be foreach for (int i = 0; i < mItemsList.Count; i++) { if (mItemsList[i] is Type) { var xType = (Type) mItemsList[i]; if (xType.IsSubclassOf(xVirtMethod.DeclaringType) || (xVirtMethod.DeclaringType.IsInterface && xVirtMethod.DeclaringType.IsAssignableFrom(xType))) { var xNewMethod = xType.GetMethod(aMethod.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, xParamTypes, null); if (xNewMethod != null) { // We need to check IsVirtual, a non virtual could // "replace" a virtual above it? if (xNewMethod.IsVirtual) { Queue(xNewMethod, aMethod, "Virtual Downscan"); } } } } } } } #endregion MethodBase xPlug = null; // Plugs may use plugs, but plugs won't be plugged over themself var inl = aMethod.GetCustomAttribute<InlineAttribute>(); if (!aIsPlug && !xIsDynamicMethod) { // Check to see if method is plugged, if it is we don't scan body xPlug = mPlugManager.ResolvePlug(aMethod, xParamTypes); if (xPlug != null) { //ScanMethod(xPlug, true, "Plug method"); if (inl == null) { Queue(xPlug, aMethod, "Plug method"); } } } if (xPlug == null) { bool xNeedsPlug = false; if ((aMethod.Attributes & MethodAttributes.PinvokeImpl) != 0) { // pinvoke methods dont have an embedded implementation xNeedsPlug = true; } else { var xImplFlags = aMethod.GetMethodImplementationFlags(); // todo: prob even more if (((xImplFlags & MethodImplAttributes.Native) != 0) || ((xImplFlags & MethodImplAttributes.InternalCall) != 0)) { // native implementations cannot be compiled xNeedsPlug = true; } } if (xNeedsPlug) { throw new Exception("Native code encountered, plug required. Please see https://github.com/CosmosOS/Cosmos/wiki/Plugs). " + LabelName.GenerateFullName(aMethod) + "." + Environment.NewLine + " Called from :" + Environment.NewLine + sourceItem); } //TODO: As we scan each method, we could update or put in a new list // that has the resolved plug so we don't have to reresolve it again // later for compilation. // Scan the method body for more type and method refs //TODO: Dont queue new items if they are plugged // or do we need to queue them with a resolved ref in a new list? if (inl != null) { return; // cancel inline } List<ILOpCode> xOpCodes; xOpCodes = mReader.ProcessMethod(aMethod); if (xOpCodes != null) { ProcessInstructions(xOpCodes); foreach (var xOpCode in xOpCodes) { if (xOpCode is ILOpCodes.OpMethod) { Queue(((ILOpCodes.OpMethod) xOpCode).Value, aMethod, "Call", sourceItem); } else if (xOpCode is ILOpCodes.OpType) { Queue(((ILOpCodes.OpType) xOpCode).Value, aMethod, "OpCode Value"); } else if (xOpCode is ILOpCodes.OpField) { var xOpField = (ILOpCodes.OpField) xOpCode; //TODO: Need to do this? Will we get a ILOpCodes.OpType as well? Queue(xOpField.Value.DeclaringType, aMethod, "OpCode Value"); if (xOpField.Value.IsStatic) { //TODO: Why do we add static fields, but not instance? // AW: instance fields are "added" always, as part of a type, but for static fields, we need to emit a datamember Queue(xOpField.Value, aMethod, "OpCode Value"); } } else if (xOpCode is ILOpCodes.OpToken) { var xTokenOp = (ILOpCodes.OpToken) xOpCode; if (xTokenOp.ValueIsType) { Queue(xTokenOp.ValueType, aMethod, "OpCode Value"); } if (xTokenOp.ValueIsField) { Queue(xTokenOp.ValueField.DeclaringType, aMethod, "OpCode Value"); if (xTokenOp.ValueField.IsStatic) { //TODO: Why do we add static fields, but not instance? // AW: instance fields are "added" always, as part of a type, but for static fields, we need to emit a datamember Queue(xTokenOp.ValueField, aMethod, "OpCode Value"); } } } } } } }
private static string GetCallerCommand(MethodBase caller) { if (caller == null) return "nullCallerMethod!?"; string name = string.Empty; var atrCom = (CommandMethodAttribute)caller.GetCustomAttribute(typeof(CommandMethodAttribute)); if (atrCom != null) { name = atrCom.GlobalName; } else { name = caller.Name; } return name; }
public void Resolve(IDictionary<Identifier, IReferencable> referencables) { if (referencables.ContainsKey(identifier)) { IsResolved = true; IReferencable referencable = referencables[identifier]; var method = referencable as Method; if (method == null) { throw new InvalidOperationException("Cannot resolve to '" + referencable.GetType().FullName + "'"); } ReturnType = method.ReturnType; if (ReturnType != null && !ReturnType.IsResolved) { ReturnType.Resolve(referencables); } declaration = method.declaration; if (declaration != null && declaration.IsDefined(typeof (ObsoleteAttribute))) { ObsoleteReason = declaration.GetCustomAttribute<ObsoleteAttribute>().Message; } if (!Summary.IsResolved) { Summary.Resolve(referencables); } if (!Remarks.IsResolved) { Remarks.Resolve(referencables); } foreach (MethodParameter para in Parameters) { if ((para.Reference != null) && (!para.Reference.IsResolved)) { para.Reference.Resolve(referencables); } } } else { ConvertToExternalReference(); } }
static string GetCacheRegion(MethodBase method) { var cachingAttribute = method.GetCustomAttribute<CacheRegionAttribute>(false); if (cachingAttribute == null) { cachingAttribute = method.DeclaringType.GetCustomAttribute<CacheRegionAttribute>(false); } if (cachingAttribute == null) { return "ThinkCache"; } return cachingAttribute.CacheRegion; }
private void TraceMethod( MethodBase method ) { Contract.Assert( method != null ); #if !WINDOWS_PHONE bool isMethodBuilder = method is MethodBuilder || method is ConstructorBuilder; #endif if ( !isMethodBuilder ) { try { method.GetParameters(); } catch ( NotSupportedException ) { // For internal MethodBuilderInstantiationType isMethodBuilder = true; } } /* * <instr_method> <callConv> <type> [ <typeSpec> :: ] <methodName> ( <parameters> ) */ // <callConv> if ( !method.IsStatic ) { this._trace.Write( "instance " ); } var unamanagedCallingConvention = default( CallingConvention? ); // TODO: Back to NLiblet #if !WINDOWS_PHONE if ( !isMethodBuilder ) #endif { // TODO: C++/CLI etc... var dllImport = method.GetCustomAttribute<DllImportAttribute>(); if ( dllImport != null ) { unamanagedCallingConvention = dllImport.CallingConvention; } } WriteCallingConventions( this._trace, method.CallingConvention, unamanagedCallingConvention ); var asMethodInfo = method as MethodInfo; if ( asMethodInfo != null ) { WriteType( this._trace, asMethodInfo.ReturnType ); this._trace.Write( " " ); } if ( method.DeclaringType == null ) { // '[' '.module' name1 ']' this._trace.Write( "[.module" ); this._trace.Write( asMethodInfo.Module.Name ); this._trace.Write( "]::" ); } #if !WINDOWS_PHONE else if ( this._isInDynamicMethod || !isMethodBuilder ) // declaring type of the method should be omitted for same type. #else else #endif { WriteType( this._trace, method.DeclaringType ); this._trace.Write( "::" ); } this._trace.Write( method.Name ); this._trace.Write( "(" ); #if !WINDOWS_PHONE if ( !isMethodBuilder ) #endif { var parameters = method.GetParameters(); for ( int i = 0; i < parameters.Length; i++ ) { if ( i == 0 ) { this._trace.Write( " " ); } else { this._trace.Write( ", " ); } if ( parameters[ i ].IsOut ) { this._trace.Write( "out " ); } else if ( parameters[ i ].ParameterType.IsByRef ) { this._trace.Write( "ref " ); } WriteType( this._trace, parameters[ i ].ParameterType.IsByRef ? parameters[ i ].ParameterType.GetElementType() : parameters[ i ].ParameterType ); this._trace.Write( " " ); this._trace.Write( parameters[ i ].Name ); } if ( 0 < parameters.Length ) { this._trace.Write( " " ); } } this._trace.Write( ")" ); }
/// <summary> /// Process a plugged method. /// </summary> /// <param name="aMethod">The method to process.</param> /// <returns>A new ILChunk marked as plugged with common attribites loaded. Null if any errors occur.</returns> public ILChunk ProcessPluggedMethod(MethodBase aMethod) { ILChunk result = null; PluggedMethodAttribute plugAttr = (PluggedMethodAttribute)aMethod.GetCustomAttribute(typeof(PluggedMethodAttribute)); //Resolve the ASMPlugPath to be relative to the assembly file that the method came from string ASMPlugPath = plugAttr.ASMFilePath; //Null path will result in no load attempt //Allows multiple methods to be plugged by the same ASM file if (ASMPlugPath == null) { result = new ILChunk() { Plugged = true, PlugASMFilePath = null, Method = aMethod }; ProcessCommonMethodAttributes(aMethod, result); return result; } string assemblyPath = aMethod.DeclaringType.Assembly.Location; assemblyPath = Path.GetDirectoryName(assemblyPath); ASMPlugPath = Path.Combine(assemblyPath, ASMPlugPath); if (ASMPlugPath.EndsWith("\\")) { ASMPlugPath = ASMPlugPath.Substring(0, ASMPlugPath.Length - 1); } result = new ILChunk() { Plugged = true, PlugASMFilePath = ASMPlugPath, Method = aMethod }; ProcessCommonMethodAttributes(aMethod, result); return result; }
/// <summary> /// Processes attributes that are common to both plugged and unplugged methods. /// </summary> /// <param name="aMethod">The method to process attributes of.</param> /// <param name="aChunk">The ILChunk to load attributes' info into.</param> private void ProcessCommonMethodAttributes(MethodBase aMethod, ILChunk aChunk) { SequencePriorityAttribute seqPriorityAttr = (SequencePriorityAttribute)aMethod.GetCustomAttribute(typeof(SequencePriorityAttribute)); if (seqPriorityAttr != null) { aChunk.SequencePriority = seqPriorityAttr.Priority; } else { aChunk.SequencePriority = 0; } NoGCAttribute noGCAttr = (NoGCAttribute)aMethod.GetCustomAttribute(typeof(NoGCAttribute)); if (noGCAttr != null) { aChunk.ApplyGC = false; } NoDebugAttribute noDebugAttr = (NoDebugAttribute)aMethod.GetCustomAttribute(typeof(NoDebugAttribute)); if (noDebugAttr != null) { aChunk.NoDebugOps = true; } KernelMainMethodAttribute kernelMainMethodAttr = (KernelMainMethodAttribute)aMethod.GetCustomAttribute(typeof(KernelMainMethodAttribute)); if (kernelMainMethodAttr != null) { aChunk.IsMainMethod = true; } CallStaticConstructorsMethodAttribute callStaticConstructorsMethodAttr = (CallStaticConstructorsMethodAttribute)aMethod.GetCustomAttribute(typeof(CallStaticConstructorsMethodAttribute)); if (callStaticConstructorsMethodAttr != null) { aChunk.IsCallStaticConstructorsMethod = true; } AddExceptionHandlerInfoMethodAttribute addExceptionHandlerInfoMethodAttr = (AddExceptionHandlerInfoMethodAttribute)aMethod.GetCustomAttribute(typeof(AddExceptionHandlerInfoMethodAttribute)); if (addExceptionHandlerInfoMethodAttr != null) { aChunk.IsAddExceptionHandlerInfoMethod = true; } ExceptionsHandleLeaveMethodAttribute exceptionsHandleLeaveMethodAttr = (ExceptionsHandleLeaveMethodAttribute)aMethod.GetCustomAttribute(typeof(ExceptionsHandleLeaveMethodAttribute)); if (exceptionsHandleLeaveMethodAttr != null) { aChunk.IsExceptionsHandleLeaveMethod = true; } ExceptionsHandleEndFinallyMethodAttribute exceptionsHandleEndFinallyMethodAttr = (ExceptionsHandleEndFinallyMethodAttribute)aMethod.GetCustomAttribute(typeof(ExceptionsHandleEndFinallyMethodAttribute)); if (exceptionsHandleEndFinallyMethodAttr != null) { aChunk.IsExceptionsHandleEndFinallyMethod = true; } ThrowExceptionMethodAttribute throwExceptionMethodAttr = (ThrowExceptionMethodAttribute)aMethod.GetCustomAttribute(typeof(ThrowExceptionMethodAttribute)); if (throwExceptionMethodAttr != null) { aChunk.IsExceptionsThrowMethod = true; } ThrowNullReferenceExceptionMethodAttribute throwNullReferenceExceptionMethodAttr = (ThrowNullReferenceExceptionMethodAttribute)aMethod.GetCustomAttribute(typeof(ThrowNullReferenceExceptionMethodAttribute)); if (throwNullReferenceExceptionMethodAttr != null) { aChunk.IsExceptionsThrowNullReferenceMethod = true; } ThrowArrayTypeMismatchExceptionMethodAttribute throwArrayTypeMismatchExceptionMethodAttr = (ThrowArrayTypeMismatchExceptionMethodAttribute)aMethod.GetCustomAttribute(typeof(ThrowArrayTypeMismatchExceptionMethodAttribute)); if (throwArrayTypeMismatchExceptionMethodAttr != null) { aChunk.IsExceptionsThrowArrayTypeMismatchMethod = true; } ThrowIndexOutOfRangeExceptionMethodAttribute throwIndexOutOfRangeExceptionMethodAttr = (ThrowIndexOutOfRangeExceptionMethodAttribute)aMethod.GetCustomAttribute(typeof(ThrowIndexOutOfRangeExceptionMethodAttribute)); if (throwIndexOutOfRangeExceptionMethodAttr != null) { aChunk.IsExceptionsThrowIndexOutOfRangeMethod = true; } HandleExceptionMethodAttribute handleExceptionMethodAttr = (HandleExceptionMethodAttribute)aMethod.GetCustomAttribute(typeof(HandleExceptionMethodAttribute)); if (handleExceptionMethodAttr != null) { aChunk.IsExceptionsHandleExceptionMethod = true; } NewObjMethodAttribute newObjMethodAttr = (NewObjMethodAttribute)aMethod.GetCustomAttribute(typeof(NewObjMethodAttribute)); if (newObjMethodAttr != null) { aChunk.IsNewObjMethod = true; } NewArrMethodAttribute newArrMethodAttr = (NewArrMethodAttribute)aMethod.GetCustomAttribute(typeof(NewArrMethodAttribute)); if (newArrMethodAttr != null) { aChunk.IsNewArrMethod = true; } IncrementRefCountMethodAttribute incrementRefCountMethodAttr = (IncrementRefCountMethodAttribute)aMethod.GetCustomAttribute(typeof(IncrementRefCountMethodAttribute)); if (incrementRefCountMethodAttr != null) { aChunk.IsIncrementRefCountMethod = true; } DecrementRefCountMethodAttribute decrementRefCountMethodAttr = (DecrementRefCountMethodAttribute)aMethod.GetCustomAttribute(typeof(DecrementRefCountMethodAttribute)); if (decrementRefCountMethodAttr != null) { aChunk.IsDecrementRefCountMethod = true; } HaltMethodAttribute haltMethodAttr = (HaltMethodAttribute)aMethod.GetCustomAttribute(typeof(HaltMethodAttribute)); if (haltMethodAttr != null) { aChunk.IsHaltMethod = true; } ArrayConstructorMethodAttribute arrayConstructorMethodAttr = (ArrayConstructorMethodAttribute)aMethod.GetCustomAttribute(typeof(ArrayConstructorMethodAttribute)); if (arrayConstructorMethodAttr != null) { aChunk.IsArrayConstructorMethod = true; } }