示例#1
0
 public override bool TryOptimize(CompilerTarget target, out AstExpr expr)
 {
     //Do not optimize the macros arguments! They should be passed to the macro in their original form.
     //  the macro should decide whether or not to apply AST-optimization to the arguments or not.
     expr = null;
     return false;
 }
示例#2
0
        public override bool TryOptimize(CompilerTarget target, out AstExpr expr)
        {
            Subject = _GetOptimizedNode(target, Subject);
            Type = (AstTypeExpr) _GetOptimizedNode(target, Type);

            expr = null;

            var constType = Type as AstConstantTypeExpression;
            if (constType == null)
                return false;

            //Constant cast
            var constSubject = Subject as AstConstant;
            if (constSubject != null)
                return _tryOptimizeConstCast(target, constSubject, constType, out expr);

            //Redundant cast
            AstTypecast castSubject;
            AstConstantTypeExpression sndCastType;
            if ((castSubject = Subject as AstTypecast) != null &&
                (sndCastType = castSubject.Type as AstConstantTypeExpression) != null)
            {
                if (Engine.StringsAreEqual(sndCastType.TypeExpression, constType.TypeExpression))
                {
                    //remove the outer cast.
                    expr = castSubject;
                    return true;
                }
            }

            return false;
        }
示例#3
0
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if (Elements.Count == 0)
            {
                target.Emit(Position,OpCode.newobj, 0, "Hash");
            }
            else
            {
                foreach (var element in Elements)
                {
                    if (element is AstConstant)
                        throw new PrexoniteException(
                            String.Concat(
                                "Hashes are built from key-value pairs, not constants like ",
                                element,
                                ". [File: ",
                                File,
                                ", Line: ",
                                Line,
                                "]"));
                    element.EmitCode(target,stackSemantics);
                }

                if(stackSemantics == StackSemantics.Effect)
                    return;

                target.EmitStaticGetCall(Position, Elements.Count, "Hash", "Create", false);
            }
        }
示例#4
0
文件: AstNull.cs 项目: SealedSun/prx
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if(stackSemantics == StackSemantics.Effect)
                return;

            target.EmitNull(Position);
        }
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if(stackSemantics == StackSemantics.Effect)
                return;

            target.Emit(Position,OpCode.ldr_type, TypeExpression);
        }
示例#6
0
 private void _reportUnresolved(CompilerTarget target)
 {
     target.Loader.ReportMessage(
         Message.Error(
             string.Format(Resources.AstUnresolved_The_symbol__0__has_not_been_resolved_, Id), Position,
             MessageClasses.SymbolNotResolved));
 }
示例#7
0
文件: AstUsing.cs 项目: SealedSun/prx
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if(stackSemantics == StackSemantics.Value)
                throw new NotSupportedException("Using blocks do not produce values and can thus not be used as expressions.");

            if (_resourceExpression == null)
                throw new PrexoniteException("AstUsing requires Expression to be initialized.");

            var tryNode = new AstTryCatchFinally(Position, this);
            var vContainer = _block.CreateLabel("container");
            target.Function.Variables.Add(vContainer);
            //Try block => Container = {Expression}; {Block};
            var setCont = target.Factory.Call(Position, EntityRef.Variable.Local.Create(vContainer),PCall.Set);
            setCont.Arguments.Add(_resourceExpression);

            var getCont = target.Factory.Call(Position, EntityRef.Variable.Local.Create(vContainer));

            var tryBlock = tryNode.TryBlock;
            tryBlock.Add(setCont);
            tryBlock.AddRange(_block);

            //Finally block => dispose( Container );
            var dispose = target.Factory.Call(Position, EntityRef.Command.Create(Engine.DisposeAlias));
            dispose.Arguments.Add(getCont);

            tryNode.FinallyBlock.Add(dispose);

            //Emit code!
            tryNode.EmitEffectCode(target);
        }
示例#8
0
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            var labelNs = @"Or\" + Guid.NewGuid().ToString("N");
            var trueLabel = @"True\" + labelNs;
            var falseLabel = @"False\" + labelNs;
            var evalLabel = @"Eval\" + labelNs;

            EmitCode(target, trueLabel, falseLabel);

            if (stackSemantics == StackSemantics.Value)
            {
                target.EmitLabel(Position, falseLabel);
                target.EmitConstant(Position, false);
                target.EmitJump(Position, evalLabel);
                target.EmitLabel(Position, trueLabel);
                target.EmitConstant(Position, true);
                target.EmitLabel(Position, evalLabel);
            }
            else
            {
                Debug.Assert(stackSemantics == StackSemantics.Effect);
                target.EmitLabel(Position, falseLabel);
                target.EmitLabel(Position, trueLabel);
            }
        }
示例#9
0
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            //Jumps need special treatment for label resolution

            if (Instruction.Arguments == -1)
            {
                switch (Instruction.OpCode)
                {
                    case OpCode.jump:
                        target.EmitJump(Position, Instruction.Id);
                        break;
                    case OpCode.jump_t:
                        target.EmitJumpIfTrue(Position, Instruction.Id);
                        break;
                    case OpCode.jump_f:
                        target.EmitJumpIfFalse(Position, Instruction.Id);
                        break;
                    case OpCode.leave:
                        target.EmitLeave(Position, Instruction.Id);
                        break;
                    default:
                        goto emitNormally;
                }
            }
            else
                goto emitNormally;

            return;
            emitNormally:
            target.Emit(Position, Instruction);
        }
示例#10
0
        public override bool TryOptimize(CompilerTarget target, out AstExpr expr)
        {
            //Optimize condition
            _OptimizeNode(target, ref Condition);
            // Invert condition when unary logical not
            AstIndirectCall unaryCond;
            while (Condition.IsCommandCall(Commands.Core.Operators.LogicalNot.DefaultAlias, out unaryCond))
            {
                Condition = unaryCond.Arguments[0];
                IsNegative = !IsNegative;
            }

            //Constant conditions
            if (Condition is AstConstant)
            {
                var constCond = (AstConstant) Condition;
                PValue condValue;
                if (
                    !constCond.ToPValue(target).TryConvertTo(
                        target.Loader, PType.Bool, out condValue))
                    expr = null;
                else if (((bool) condValue.Value) ^ IsNegative)
                    expr = IfExpression;
                else
                    expr = ElseExpression;
                return expr != null;
            }

            expr = null;
            return false;
        }
示例#11
0
文件: AstThrow.cs 项目: SealedSun/prx
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if (Expression == null)
                throw new PrexoniteException("Expression must be assigned.");

            Expression.EmitValueCode(target);
            target.Emit(Position,OpCode.@throw);

            if (stackSemantics == StackSemantics.Value)
                target.Emit(Position,OpCode.ldc_null);
        }
示例#12
0
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if (Key == null)
                throw new PrexoniteException("AstKeyValuePair.Key must be initialized.");
            if (Value == null)
                throw new ArgumentNullException("target");

            var call = target.Factory.Call(Position, EntityRef.Command.Create(Engine.PairAlias));
            call.Arguments.Add(Key);
            call.Arguments.Add(Value);
            call.EmitCode(target, stackSemantics);
        }
示例#13
0
        /// <summary>
        ///     Creates a new macro expansion session for the specified compiler target.
        /// </summary>
        /// <param name = "target">The target to expand macros in.</param>
        public MacroSession([NotNull] CompilerTarget target)
        {
            if(target == null)
                throw new ArgumentNullException("target");

            _target = target;
            _astFactory = _target.Factory;
            
            _globalSymbols = SymbolStore.Create(_target.Loader.TopLevelSymbols);
            _outerVariables = new ReadOnlyCollectionView<string>(_target.OuterVariables);

            _buildCommandToken = target.Loader.RequestBuildCommands();
        }
示例#14
0
        public override bool TryOptimize(CompilerTarget target, out AstExpr expr)
        {
            expr = null;

            var isConstant = true;
            var buffer = new StringBuilder(TypeId);
            buffer.Append("(");

            //Optimize arguments
            AstExpr oArg;
            foreach (var arg in Arguments.ToArray())
            {
                oArg = _GetOptimizedNode(target, arg);
                if (!ReferenceEquals(oArg, arg))
                {
                    Arguments.Remove(arg);
                    Arguments.Add(oArg);
                }

                var constValue = oArg as AstConstant;
                var constType = oArg as AstConstantTypeExpression;

                if (constValue == null && constType == null)
                {
                    isConstant = false;
                }
                else if (isConstant)
                {
                    if (constValue != null)
                    {
                        buffer.Append('"');
                        buffer.Append(
                            StringPType.Escape(
                                constValue.ToPValue(target).CallToString(target.Loader)));
                        buffer.Append('"');
                    }
                    else //if(constType != null)
                        buffer.Append(constType.TypeExpression);
                    buffer.Append(",");
                }
            }
            if (!isConstant)
                return false;

            buffer.Remove(buffer.Length - 1, 1); //remove , or (
            if (Arguments.Count != 0)
                buffer.Append(")"); //Add ) if necessary

            expr = new AstConstantTypeExpression(File, Line, Column, buffer.ToString());
            return true;
        }
示例#15
0
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if(stackSemantics == StackSemantics.Effect)
                return;

            if (Expression == null)
                throw new PrexoniteException("CreateCoroutine node requires an Expression.");

            Expression.EmitValueCode(target);
            foreach (var argument in _arguments)
                argument.EmitValueCode(target);

            target.Emit(Position,OpCode.newcor, _arguments.Count);
        }
示例#16
0
        /// <summary>
        ///     Emits code responsible for changing the variables identity.
        /// </summary>
        /// <param name = "target">The target to compile to</param>
        private void _emitNewDeclareCode(CompilerTarget target)
        {
            _ensureValid();
            //create command call
            //  unbind(->variable)
            var unlinkCall = new AstIndirectCall(Position, PCall.Get,
                                                 new AstReference(Position, EntityRef.Command.Create(Engine.UnbindAlias)));
            var targetRef = new AstReference(Position, EntityRef.Variable.Local.Create(Id));
            unlinkCall.Arguments.Add(targetRef);

            //Optimize call and emit code
            var call = (AstExpr) unlinkCall;
            _OptimizeNode(target, ref call);
            call.EmitEffectCode(target);
        }
示例#17
0
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if(stackSemantics == StackSemantics.Effect)
                return;

            Subject.EmitValueCode(target);
            var constType = Type as AstConstantTypeExpression;
            if (constType != null)
                target.Emit(Position,OpCode.cast_const, constType.TypeExpression);
            else
            {
                Type.EmitValueCode(target);
                target.Emit(Position,OpCode.cast_arg);
            }
        }
示例#18
0
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if (stackSemantics == StackSemantics.Effect)
                return;

            PFunction targetFunction;
            MetaEntry sharedNamesEntry;
            if (target.Loader.ParentApplication.TryGetFunction(_implementation.Id, _implementation.ModuleName, out targetFunction)
                && (!targetFunction.Meta.TryGetValue(PFunction.SharedNamesKey, out sharedNamesEntry)
                    || !sharedNamesEntry.IsList
                        || sharedNamesEntry.List.Length == 0))
                target.Emit(Position,OpCode.ldr_func, _implementation.Id, target.ToInternalModule(_implementation.ModuleName));
            else
                target.Emit(Position,OpCode.newclo, _implementation.Id, target.ToInternalModule(_implementation.ModuleName));
        }
示例#19
0
        protected override void EmitGetCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            var constType = TypeExpr as AstConstantTypeExpression;

            var justEffect = stackSemantics == StackSemantics.Effect;
            if (constType != null)
            {
                EmitArguments(target);
                target.EmitStaticGetCall(Position, Arguments.Count, constType.TypeExpression, _memberId, justEffect);
            }
            else
            {
                TypeExpr.EmitValueCode(target);
                target.EmitConstant(Position, _memberId);
                EmitArguments(target);
                target.EmitGetCall(Position, Arguments.Count + 1, PType.StaticCallFromStackId, justEffect);
            }
        }
示例#20
0
        public override bool TryOptimize(CompilerTarget target, out AstExpr expr)
        {
            expr = null;

            _typeExpr = (AstTypeExpr) _GetOptimizedNode(target, _typeExpr);

            //Optimize arguments
            for (var i = 0; i < _arguments.Count; i++)
            {
                var arg = _arguments[i];
                var oArg = _GetOptimizedNode(target, arg);
                if (ReferenceEquals(oArg, arg))
                    continue;
                _arguments[i] = oArg;
            }

            return false;
        }
示例#21
0
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if(stackSemantics == StackSemantics.Effect)
                return;

            if (Constant == null)
                target.EmitNull(Position);
            else
                switch (Type.GetTypeCode(Constant.GetType()))
                {
                    case TypeCode.Boolean:
                        target.EmitConstant(Position, (bool) Constant);
                        break;
                    case TypeCode.Int16:
                    case TypeCode.Byte:
                    case TypeCode.Int32:
                    case TypeCode.UInt16:
                    case TypeCode.UInt32:
                        target.EmitConstant(Position, (int) Constant);
                        break;
                    case TypeCode.Single:
                    case TypeCode.Double:
                        target.EmitConstant(Position, (double) Constant);
                        break;
                    case TypeCode.String:
                        target.EmitConstant(Position, (string) Constant);
                        break;
                    default:
                        var moduleName = Constant as ModuleName;

                        if (moduleName != null)
                        {
                            target.EmitConstant(Position, moduleName);
                        }
                        else
                        {
                            throw new PrexoniteException(
                                "Prexonite does not support constants of type " +
                                    Constant.GetType().Name + ".");
                        }
                        break;
                }
        }
示例#22
0
 public override bool TryOptimize(CompilerTarget target, out AstExpr expr)
 {
     foreach (var arg in Elements.ToArray())
     {
         if (arg == null)
             throw new PrexoniteException(
                 "Invalid (null) argument in ListLiteral node (" + ToString() +
                     ") detected at position " + Elements.IndexOf(arg) + ".");
         var oArg = _GetOptimizedNode(target, arg);
         if (!ReferenceEquals(oArg, arg))
         {
             var idx = Elements.IndexOf(arg);
             Elements.Insert(idx, oArg);
             Elements.RemoveAt(idx + 1);
         }
     }
     expr = null;
     return false;
 }
示例#23
0
        public override bool TryOptimize(CompilerTarget target, out AstExpr expr)
        {
            expr = null;

            //Optimize arguments
            for (var i = 0; i < Arguments.Count; i++)
            {
                var arg = Arguments[i];
                if (arg == null)
                    throw new PrexoniteException(
                        "Invalid (null) argument in GetSet node (" + ToString() +
                            ") detected at position " + Arguments.IndexOf(arg) + ".");
                var oArg = _GetOptimizedNode(target, arg);
                if (!ReferenceEquals(oArg, arg))
                    Arguments[i] = oArg;
            }

            return false;
        }
示例#24
0
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if(stackSemantics == StackSemantics.Value)
                throw new NotSupportedException("Return nodes cannot be used with value stack semantics. (They don't produce any values)");

            var warned = false;
            if (target.Function.Meta[Coroutine.IsCoroutineKey].Switch)
                _warnInCoroutines(target, ref warned);

            if (Expression != null)
            {
                _OptimizeNode(target, ref Expression);
                if (ReturnVariant == ReturnVariant.Exit)
                {
                    _emitTailCallExit(target);
                    return;
                }
            }
            switch (ReturnVariant)
            {
                case ReturnVariant.Exit:
                    target.Emit(Position,OpCode.ret_exit);
                    break;
                case ReturnVariant.Set:
                    if (Expression == null)
                        throw new PrexoniteException("Return assignment requires an expression.");
                    Expression.EmitValueCode(target);
                    target.Emit(Position,OpCode.ret_set);
                    break;
                case ReturnVariant.Continue:
                    if (Expression != null)
                    {
                        Expression.EmitValueCode(target);
                        target.Emit(Position,OpCode.ret_set);
                        _warnInCoroutines(target, ref warned);
                    }
                    target.Emit(Position,OpCode.ret_continue);
                    break;
                case ReturnVariant.Break:
                    target.Emit(Position,OpCode.ret_break);
                    break;
            }
        }
示例#25
0
 public static bool TryCreateConstant(
     CompilerTarget target,
     ISourcePosition position,
     PValue value,
     out AstExpr expr)
 {
     expr = null;
     if (value.Type is ObjectPType)
         target.Loader.Options.ParentEngine.CreateNativePValue(value.Value);
     if (value.Type is IntPType 
         || value.Type is RealPType 
         || value.Type is BoolPType 
         || value.Type is StringPType 
         || value.Type is NullPType 
         || _isModuleName(value))
         expr = new AstConstant(position.File, position.Line, position.Column, value.Value);
     else //Cannot represent value in a constant instruction
         return false;
     return true;
 }
示例#26
0
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            //instantiate macro for the current target
            MacroSession session = null;

            try
            {
                //Acquire current macro session
                session = target.AcquireMacroSession();

                //Expand macro
                var justEffect = stackSemantics == StackSemantics.Effect;
                var node = session.ExpandMacro(this, justEffect);

                //Emit generated code
                node.EmitCode(target, stackSemantics);
            }
            finally
            {
                if (session != null)
                    target.ReleaseMacroSession(session);
            }
        }
示例#27
0
        public override bool TryOptimize(CompilerTarget target, out AstExpr expr)
        {
            expr = null;

            //Optimize arguments
            for (var i = 0; i < _expressions.Count; i++)
            {
                var arg = _expressions[i];
                if (arg == null)
                    throw new PrexoniteException(
                        "Invalid (null) argument in GetSet node (" + ToString() +
                            ") detected at position " + _expressions.IndexOf(arg) + ".");
                var oArg = _GetOptimizedNode(target, arg);
                if (!ReferenceEquals(oArg, arg))
                    _expressions[i] = oArg;
            }

            var nonNullExpressions = _expressions.Where(_exprIsNotNull).ToArray();
            _expressions.Clear();
            _expressions.AddRange(nonNullExpressions);

            if (_expressions.Count == 1)
            {
                var pExpr = _expressions[0];
                expr = pExpr is AstPlaceholder ? ((AstPlaceholder) pExpr).IdFunc() : pExpr;
                return true;
            }
            else if (_expressions.Count == 0)
            {
                expr = new AstNull(File, Line, Column);
                return true;
            }
            else
            {
                return false;
            }
        }
示例#28
0
 protected override void DoEmitCode(CompilerTarget target, string trueLabel,
     string falseLabel)
 {
     var labelNs = @"Or\" + Guid.NewGuid().ToString("N");
     var nextLabel = @"Next\" + labelNs;
     foreach (var expr in Conditions)
     {
         var and = expr as AstLogicalAnd;
         if (and != null)
         {
             and.EmitCode(target, trueLabel, nextLabel);
             //ResolveOperator pending jumps to Next
             target.EmitLabel(Position, nextLabel);
             target.FreeLabel(nextLabel);
             //Future references of to nextLabel will be resolved in the next iteration
         }
         else
         {
             expr.EmitValueCode(target);
             target.EmitJumpIfTrue(Position, trueLabel);
         }
     }
     target.EmitJump(Position, falseLabel);
 }
示例#29
0
        private bool _optimizeConditionalReturnExpression(CompilerTarget target)
        {
            var cond = Expression as AstConditionalExpression;
            if (cond == null)
                return false;

            //  return  if( cond )
            //              expr1
            //          else
            //              expr2
            var retif = new AstCondition(Position, target.CurrentBlock, cond.Condition, cond.IsNegative);

            var ret1 = new AstReturn(File, Line, Column, ReturnVariant)
                {
                    Expression = cond.IfExpression
                };
            retif.IfBlock.Add(ret1);

            var ret2 = new AstReturn(File, Line, Column, ReturnVariant)
                {
                    Expression = cond.ElseExpression
                };
            //not added to the condition

            retif.EmitEffectCode(target); //  if( cond )
            //      return expr1
            ret2.EmitEffectCode(target); //  return expr2

            //ret1 and ret2 will continue optimizing
            return true;
        }
示例#30
0
     private static bool _isStacklessRecursionPossible(CompilerTarget target,
 AstIndirectCall symbol)
     {
         var refNode = symbol.Subject as AstReference;
         if (refNode == null)
             return false;
         EntityRef.Function funcRef;
         if (!refNode.Entity.TryGetFunction(out funcRef))
             return false;
         if (funcRef.Id != target.Function.Id)
             return false;
         if (funcRef.ModuleName != target.Function.ParentApplication.Module.Name)
             return false;
         if (target.Function.Variables.Contains(PFunction.ArgumentListId))
             //must not use argument list
             return false;
         if (symbol.Arguments.Count > target.Function.Parameters.Count)
             //must not supply more arguments than mapped
             return false;
         return true;
     }
示例#31
0
    void OnGUI()
    {
        // Choose the compiler
        m_Compiler = (CompilerTarget)EditorGUILayout.Popup(Content.compilerContent, (int)m_Compiler, Content.compileOptions);
        if (m_Compiler == CompilerTarget.Custom)
        {
            EditorGUILayout.BeginHorizontal();
            m_CompilerPath = EditorGUILayout.TextField(m_CompilerPath);
            if (GUILayout.Button("..."))
            {
#if UNITY_STANDALONE_WIN
                m_CompilerPath = EditorUtility.OpenFilePanel("Mali Offline Compiler", "", "exe");
#else
                m_CompilerPath = EditorUtility.OpenFilePanel("Mali Offline Compiler", "", "");
#endif
            }
            EditorGUILayout.EndHorizontal();
        }

        // Select the shader
        Shader s = EditorGUILayout.ObjectField(Content.targetContent, m_Target, typeof(Shader), true) as Shader;

        // Go through and setup the data needed to compile a shader
        // we only do this once when a shader is selected.
        ProcessShader(s);

        // Display the keywords
        {
            GUILayout.Label(Content.allKeywords, EditorStyles.boldLabel);

            EditorGUILayout.BeginVertical(GUILayout.MaxHeight(40.0f));
            m_KeywordScroll = EditorGUILayout.BeginScrollView(m_KeywordScroll);
            EditorGUILayout.BeginHorizontal();
            for (int i = 0; i < m_Keywords.Count; i++)
            {
                GUILayout.Label(m_Keywords[i], EditorStyles.label);
            }

            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndScrollView();
            EditorGUILayout.EndVertical();
        }

        // Select Pass to investigate
        GUILayout.Label("Pass:"******"Pass Name:");
            GUILayout.Label(info.name);
            EditorGUILayout.EndHorizontal();
            GUILayout.Label("Pass Keywords:");
            m_PassKeywordScroll = EditorGUILayout.BeginScrollView(m_PassKeywordScroll);
            EditorGUILayout.BeginVertical();
            for (int i = 0; i < m_SelectedKeywords.Count; i++)
            {
                string[] options = info.keywords[i].ToArray();

                if (options.Length == 0)
                {
                    continue;
                }

                if (options[0].Length == 0)
                {
                    options[0] = k_NA;
                }

                m_SelectedKeywords[i] = EditorGUILayout.Popup(info.keywordHint[i], Mathf.Clamp(m_SelectedKeywords[i], 0, options.Length), options);
            }

            EditorGUILayout.EndVertical();
            EditorGUILayout.EndScrollView();
        }

        // Report section
        {
            m_ReportScroll = EditorGUILayout.BeginScrollView(m_ReportScroll);
            EditorGUILayout.BeginVertical();

            string value = null;
            for (int i = 0; i < k_ReportOrder.Length; i++)
            {
                if (m_Report.TryGetValue(k_ReportOrder[i], out value))
                {
                    EditorGUILayout.BeginHorizontal();
                    GUILayout.Label(Content.shaderTypes[i]);
                    if (GUILayout.Button("Copy text"))
                    {
                        EditorGUIUtility.systemCopyBuffer = value;
                    }

                    EditorGUILayout.EndHorizontal();

                    GUILayout.Box(value, EditorStyles.helpBox);
                }
            }

            EditorGUILayout.EndVertical();
            EditorGUILayout.EndScrollView();
        }
        EditorGUILayout.EndVertical();
        EditorGUILayout.BeginHorizontal();

        GUI.enabled = info != defaultPassInfo;
        if (GUILayout.Button("Compile & Report"))
        {
            CompileAndReport();
        }

        GUI.enabled = true;

        if (GUILayout.Button("Refresh Shader"))
        {
            // preprocess the shader
            ProcessShader(s, true);
        }

        if (GUILayout.Button("Clear Report"))
        {
            m_Report.Clear();
        }

        EditorGUILayout.EndHorizontal();
    }