コード例 #1
0
        private static void EmitInvokeCommand(CodeBlockBuilder tryBlock, TypeSet.VkHandleMethod method, Func <IEnumerable <Action <ExpressionBuilder> >, Action <ExpressionBuilder> > commandExpression, Func <TypeSet.VkMethodParam, string> argumentNameSelector, string commandResultVariable)
        {
            foreach (var fixedArgument in method.Parameters.Where(x => !string.IsNullOrEmpty(x.FixedName)))
            {
                tryBlock.EmitStatement($"fixed({fixedArgument.FixedType} {fixedArgument.FixedName} = {fixedArgument.Name})");
            }

            var arguments = method.Parameters.Select(argumentNameSelector).Select(Variable);

            if (method.IsPassthroughResult)
            {
                tryBlock.EmitAssignment(Variable("result"), commandExpression(arguments));
            }
            else if (method.HasVkResult)
            {
                tryBlock.EmitAssignment(Variable(commandResultVariable), commandExpression(arguments));
            }
            else
            {
                tryBlock.EmitCallExpression(commandExpression(arguments));
            }

            if (method.HasVkResult)
            {
                tryBlock.EmitIfBlock(StaticCall("SharpVkException", "IsError", Variable(commandResultVariable)), ifBlock =>
                {
                    ifBlock.EmitThrow(StaticCall("SharpVkException", "Create", Variable(commandResultVariable)));
                });
            }
        }
コード例 #2
0
ファイル: MethodEmitter.cs プロジェクト: yaram/SharpVk
        public static void EmitMarshalAction(CodeBlockBuilder codeBlock, Generation.AssignAction action, Action <ExpressionBuilder> targetExpression)
        {
            switch (action.Type)
            {
            case AssignActionType.Assign:
                codeBlock.EmitAssignment(targetExpression, action.ValueExpression);
                break;

            case AssignActionType.Alloc:
                if (action.LengthExpression != null)
                {
                    codeBlock.EmitAssignment(targetExpression,
                                             Cast(action.MemberType + "*", StaticCall("Interop.HeapUtil", $"Allocate<{action.MemberType}>", action.LengthExpression)));
                }
                else
                {
                    codeBlock.EmitAssignment(targetExpression,
                                             Cast(action.MemberType + "*", StaticCall("Interop.HeapUtil", $"Allocate<{action.MemberType}>")));
                }
                break;

            case AssignActionType.AllocAndAssign:
                codeBlock.EmitAssignment(targetExpression,
                                         Cast(action.MemberType + "*", StaticCall("Interop.HeapUtil", $"Allocate<{action.MemberType}>")));
                codeBlock.EmitAssignment(Deref(targetExpression), action.ValueExpression);
                break;

            case AssignActionType.MarshalToAddressOf:
                codeBlock.EmitCall(action.ValueExpression, "MarshalTo", AddressOf(targetExpression));
                break;

            case AssignActionType.MarshalTo:
                codeBlock.EmitAssignment(targetExpression,
                                         Cast(action.MemberType + "*", StaticCall("Interop.HeapUtil", $"Allocate<{action.MemberType}>")));
                codeBlock.EmitCall(action.ValueExpression, "MarshalTo", targetExpression);
                break;

            case AssignActionType.MarshalFrom:
                codeBlock.EmitAssignment(targetExpression,
                                         StaticCall(action.MemberType, "MarshalFrom", action.ValueExpression));
                break;

            case AssignActionType.MarshalFromAddressOf:
                codeBlock.EmitAssignment(targetExpression,
                                         StaticCall(action.MemberType, "MarshalFrom", AddressOf(action.ValueExpression)));
                break;

            case AssignActionType.FixedLengthMarshalTo:
                codeBlock.EmitStaticCall("Interop.HeapUtil", "MarshalTo", action.ValueExpression, action.LengthExpression, targetExpression);
                break;
            }
        }
コード例 #3
0
ファイル: MethodEmitter.cs プロジェクト: yaram/SharpVk
        private static void EmitActions(CodeBlockBuilder body, List <MethodAction> actions)
        {
            foreach (var action in actions.OfType <DeclarationAction>())
            {
                body.EmitVariableDeclaration(action.MemberType, action.MemberName, Default(action.MemberType));
            }

            foreach (var action in actions.OrderBy(x => x.Priority))
            {
                if (action is AssignAction assignAction)
                {
                    if (assignAction.IsLoop)
                    {
                        void BuildAssignBlock(CodeBlockBuilder ifBlock)
                        {
                            var fieldPointerName = assignAction.FieldPointerName ?? "fieldPointer";

                            if (assignAction.IsArray)
                            {
                                ifBlock.EmitVariableDeclaration("var", fieldPointerName, NewArray(assignAction.MemberType, Cast("uint", assignAction.LengthExpression)));
                            }
                            else
                            {
                                string allocationType = assignAction.MemberType.EndsWith("*")
                                                            ? "IntPtr"
                                                            : assignAction.MemberType;

                                ifBlock.EmitVariableDeclaration("var", fieldPointerName, Cast(assignAction.MemberType + "*", Call(StaticCall("Interop.HeapUtil", $"AllocateAndClear<{allocationType}>", assignAction.LengthExpression), "ToPointer")));
                            }

                            ifBlock.EmitForLoop(init => init.EmitVariableDeclaration("int", assignAction.IndexName, Literal(0)),
                                                LessThan(Variable(assignAction.IndexName), Cast("uint", assignAction.LengthExpression)),
                                                after => after.EmitStatement(assignAction.IndexName + "++"),
                                                loop =>
                            {
                                EmitMarshalAction(loop, assignAction, Index(Variable(fieldPointerName), Variable(assignAction.IndexName)));
                            });

                            ifBlock.EmitAssignment(assignAction.TargetExpression, Variable(fieldPointerName));
                        }

                        if (assignAction.NullCheckExpression != null)
                        {
                            body.EmitIfBlock(assignAction.NullCheckExpression,
                                             BuildAssignBlock,
                                             elseBlock =>
                            {
                                elseBlock.EmitAssignment(assignAction.TargetExpression, Null);
                            });
                        }
                        else
                        {
                            BuildAssignBlock(body);
                        }
                    }
                    else
                    {
                        EmitMarshalAction(body, assignAction, assignAction.TargetExpression);
                    }
                }
                else if (action is InvokeAction invokeAction)
                {
                    var paramNames = (invokeAction.Parameters ?? Enumerable.Empty <Action <ExpressionBuilder> >().ToArray());

                    Action <ExpressionBuilder> invokeExpression = null;

                    if (invokeAction.LookupDelegate)
                    {
                        if (invokeAction.DelegateName != null)
                        {
                            body.EmitVariableDeclaration(invokeAction.DelegateName, "commandDelegate", Call(Variable("commandCache"), $"GetCommandDelegate<{invokeAction.DelegateName}>", Literal(invokeAction.MethodName), Literal(invokeAction.LookupScope)));
                        }

                        invokeExpression = DelegateCall(Variable("commandDelegate"), paramNames);
                    }
                    else if (invokeAction.TypeName == null)
                    {
                        invokeExpression = Call(This, invokeAction.MethodName, paramNames);
                    }
                    else
                    {
                        invokeExpression = StaticCall(invokeAction.TypeName, invokeAction.MethodName, paramNames);
                    }

                    if (invokeAction.ReturnName != null)
                    {
                        if (invokeAction.ReturnType != null)
                        {
                            body.EmitVariableDeclaration(invokeAction.ReturnType, invokeAction.ReturnName, invokeExpression);
                        }
                        else
                        {
                            body.EmitAssignment(Variable(invokeAction.ReturnName), invokeExpression);
                        }
                    }
                    else
                    {
                        body.EmitCallExpression(invokeExpression);
                    }
                }
                else if (action is OptionalAction optionalAction)
                {
                    if (optionalAction.ElseActions.Any())
                    {
                        body.EmitIfBlock(optionalAction.CheckExpression,
                                         ifBlock => EmitActions(ifBlock, optionalAction.Actions),
                                         elseBlock => EmitActions(elseBlock, optionalAction.ElseActions));
                    }
                    else
                    {
                        body.EmitIfBlock(optionalAction.CheckExpression,
                                         ifBlock => EmitActions(ifBlock, optionalAction.Actions));
                    }
                }
                else if (action is ValidateAction validationAction)
                {
                    body.EmitIfBlock(StaticCall("SharpVkException", "IsError", Variable(validationAction.VariableName)),
                                     ifBlock =>
                    {
                        ifBlock.EmitThrow(StaticCall("SharpVkException", "Create", Variable(validationAction.VariableName)));
                    });
                }
            }
        }