Esempio n. 1
0
            private void EmitNodeWriteAssign(IndirectVarUse node, CodeGenerator codeGenerator)
            {
                ChainBuilder chain = codeGenerator.ChainBuilder;

                // Note that for cases 1,3,4,5,6,9 EmitAssign is never called!!!

                // 2,7,8
                if (chain.IsMember)
                {
                    // 2,8
                    if (chain.Exists)
                    {
                        // 8: b[]->$a
                        chain.EmitSetObjectField();
                    }
                    else
                    {
                        // 2: $b->a
                        Debug.Assert(node.IsMemberOf is SimpleVarUse || node.IsMemberOf is FunctionCall);
                        if (node.IsMemberOf is FunctionCall)
                        {
                            codeGenerator.ChainBuilder.LoadAddressOfFunctionReturnValue = true;
                        }

                        assignmentCallback(codeGenerator, PhpTypeCode.Object);

                        SimpleVarUse svu = node.IsMemberOf as SimpleVarUse;
                        if (svu != null)
                        {
                            SimpleVarUseHelper.EmitLoadAddress_StoreBack(svu, codeGenerator);
                        }
                        // else do nothing
                    }
                    chain.End();
                }
                else
                {
                    // 7: $a
                    //codeGenerator.EmitVariableStoreAssign(this);
                    this.EmitStoreAssign(node, codeGenerator);
                }
            }
Esempio n. 2
0
            internal override PhpTypeCode EmitAssign(ItemUse node, CodeGenerator codeGenerator)
            {
                var         chain = codeGenerator.ChainBuilder;
                PhpTypeCode result;

                switch (access)
                {
                case AccessType.WriteAndReadRef:
                case AccessType.WriteAndReadUnknown:
                case AccessType.ReadAndWrite:
                case AccessType.ReadAndWriteAndReadRef:
                case AccessType.ReadAndWriteAndReadUnknown:
                case AccessType.Write:
                case AccessType.WriteRef:
                {
                    bool reference = access == AccessType.WriteRef;

                    // Note that some work was done in Emit() !
                    // In cases 3, 4, 5 EmitAssign is not called

                    if (node.IsMemberOf != null ||
                        (node.IsMemberOf == null && (node.Array is DirectStFldUse || node.Array is IndirectStFldUse || node.Array is ItemUse)))
                    {
                        // 2, 6, 7
                        chain.EmitSetArrayItem(indexTypeCode, node.Index, reference);
                        chain.End();
                    }
                    else
                    {
                        // Note: The value which should be stored is already loaded on the evaluation stack.
                        //				Push the destination array and index and call the operator
                        // 1: a_[x]_
                        Debug.Assert(node.Array is SimpleVarUse);
                        chain.IsArrayItem  = true;
                        chain.IsLastMember = true;
                        indexTypeCode      = codeGenerator.EmitArrayKey(chain, node.Index);
                        node.Array.Emit(codeGenerator);
                        chain.EmitSetItem(indexTypeCode, node.Index, reference);

                        // Store the changed variable into table of variables (do nothing in optimalized functions)
                        SimpleVarUseHelper.EmitLoadAddress_StoreBack((SimpleVarUse)node.Array, codeGenerator);
                    }

                    result = PhpTypeCode.Void;
                    break;
                }

                case AccessType.None:
                    // do nothing
                    result = PhpTypeCode.Void;
                    break;

                case AccessType.Read:
                    // do nothing
                    result = PhpTypeCode.Object;
                    break;

                case AccessType.ReadRef:
                    // Do nothing
                    result = PhpTypeCode.PhpReference;
                    break;

                default:
                    Debug.Fail(null);
                    result = PhpTypeCode.Invalid;
                    break;
                }

                return(result);
            }