Example #1
0
        internal override PhpTypeCode Emit(CodeGenerator codeGenerator)
        {
            Debug.Assert(access == AccessType.Read || access == AccessType.None);
            Statistics.AST.AddNode("Class.Concat." + expressions.Count);

            PhpTypeCode result;

            //
            // For low numbers call specialized methods
            switch (expressions.Count)
            {
                case 1:
                    result = expressions[0].Emit(codeGenerator);

                    if (result != PhpTypeCode.PhpBytes && result != PhpTypeCode.String)
                    {
                        var lbl = codeGenerator.IL.DefineLabel();
                        codeGenerator.EmitBoxing(result);
                        codeGenerator.IL.Emit(OpCodes.Dup);
                        codeGenerator.IL.Emit(OpCodes.Isinst,typeof(PhpBytes));

                        // IF (STACK)
                        codeGenerator.IL.Emit(OpCodes.Brtrue_S,lbl);                      
                        if (true)
                        {
                            codeGenerator.IL.Emit(OpCodes.Call, Methods.Convert.ObjectToString);
                        }
                        
                        // ELSE                        
                        codeGenerator.IL.MarkLabel(lbl, true);

                        //END IF

                        result = PhpTypeCode.Object;
                    }
                    break;

                case 2:
                    result = EmitConcat(codeGenerator, expressions[0], expressions[1]);
                    break;

                default:

                    codeGenerator.EmitObjectArrayPopulation(expressions);
                    codeGenerator.IL.Emit(OpCodes.Call, Methods.Operators.Concat.ObjectArray);

                    result = PhpTypeCode.Object;    // string, PhpBytes
                    break;
            }

            switch (access)
            {
                case AccessType.Read:
                    // do nothing
                    break;

                case AccessType.None:
                    // pop result from stack
                    codeGenerator.IL.Emit(OpCodes.Pop);
                    result = PhpTypeCode.Void;
                    break;
            }

            return result;
        }