ACPI_STATUS AcpiExStoreObjectToObject ( ACPI_OPERAND_OBJECT *SourceDesc, ACPI_OPERAND_OBJECT *DestDesc, ACPI_OPERAND_OBJECT **NewDesc, ACPI_WALK_STATE *WalkState) { ACPI_OPERAND_OBJECT *ActualSrcDesc; ACPI_STATUS Status = AE_OK; ACPI_FUNCTION_TRACE_PTR (ExStoreObjectToObject, SourceDesc); ActualSrcDesc = SourceDesc; if (!DestDesc) { /* * There is no destination object (An uninitialized node or * package element), so we can simply copy the source object * creating a new destination object */ Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, NewDesc, WalkState); return_ACPI_STATUS (Status); } if (SourceDesc->Common.Type != DestDesc->Common.Type) { /* * The source type does not match the type of the destination. * Perform the "implicit conversion" of the source to the current type * of the target as per the ACPI specification. * * If no conversion performed, ActualSrcDesc = SourceDesc. * Otherwise, ActualSrcDesc is a temporary object to hold the * converted object. */ Status = AcpiExConvertToTargetType (DestDesc->Common.Type, SourceDesc, &ActualSrcDesc, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } if (SourceDesc == ActualSrcDesc) { /* * No conversion was performed. Return the SourceDesc as the * new object. */ *NewDesc = SourceDesc; return_ACPI_STATUS (AE_OK); } } /* * We now have two objects of identical types, and we can perform a * copy of the *value* of the source object. */ switch (DestDesc->Common.Type) { case ACPI_TYPE_INTEGER: DestDesc->Integer.Value = ActualSrcDesc->Integer.Value; /* Truncate value if we are executing from a 32-bit ACPI table */ AcpiExTruncateFor32bitTable (DestDesc); break; case ACPI_TYPE_STRING: Status = AcpiExStoreStringToString (ActualSrcDesc, DestDesc); break; case ACPI_TYPE_BUFFER: Status = AcpiExStoreBufferToBuffer (ActualSrcDesc, DestDesc); break; case ACPI_TYPE_PACKAGE: Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, &DestDesc, WalkState); break; default: /* * All other types come here. */ ACPI_WARNING ((AE_INFO, "Store into type %s not implemented", AcpiUtGetObjectTypeName (DestDesc))); Status = AE_NOT_IMPLEMENTED; break; } if (ActualSrcDesc != SourceDesc) { /* Delete the intermediate (temporary) source object */ AcpiUtRemoveReference (ActualSrcDesc); } *NewDesc = DestDesc; return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiDsStoreObjectToLocal ( UINT16 Opcode, UINT32 Index, ACPI_OPERAND_OBJECT *SrcDesc, ACPI_WALK_STATE *WalkState) { ACPI_STATUS Status; ACPI_OPERAND_OBJECT **Entry; FUNCTION_TRACE ("DsMethodDataSetValue"); ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%d Idx=%d Obj=%p\n", Opcode, Index, SrcDesc)); /* Parameter validation */ if (!SrcDesc) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Get a pointer to the requested method stack entry */ Status = AcpiDsMethodDataGetEntry (Opcode, Index, WalkState, &Entry); if (ACPI_FAILURE (Status)) { goto Cleanup; } if (*Entry == SrcDesc) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n", SrcDesc)); goto Cleanup; } /* * If there is an object already in this slot, we either * have to delete it, or if this is an argument and there * is an object reference stored there, we have to do * an indirect store! */ if (*Entry) { /* * Check for an indirect store if an argument * contains an object reference (stored as an Node). * We don't allow this automatic dereferencing for * locals, since a store to a local should overwrite * anything there, including an object reference. * * If both Arg0 and Local0 contain RefOf (Local4): * * Store (1, Arg0) - Causes indirect store to local4 * Store (1, Local0) - Stores 1 in local0, overwriting * the reference to local4 * Store (1, DeRefof (Local0)) - Causes indirect store to local4 * * Weird, but true. */ if ((Opcode == AML_ARG_OP) && (VALID_DESCRIPTOR_TYPE (*Entry, ACPI_DESC_TYPE_NAMED))) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Arg (%p) is an ObjRef(Node), storing in %p\n", SrcDesc, *Entry)); /* Detach an existing object from the Node */ AcpiNsDetachObject ((ACPI_NAMESPACE_NODE *) *Entry); /* * Store this object into the Node * (do the indirect store) */ Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) *Entry, SrcDesc, SrcDesc->Common.Type); return_ACPI_STATUS (Status); } #ifdef ACPI_ENABLE_IMPLICIT_CONVERSION /* * Perform "Implicit conversion" of the new object to the type of the * existing object */ Status = AcpiExConvertToTargetType ((*Entry)->Common.Type, &SrcDesc, WalkState); if (ACPI_FAILURE (Status)) { goto Cleanup; } #endif /* * Delete the existing object * before storing the new one */ AcpiDsMethodDataDeleteValue (Opcode, Index, WalkState); } /* * Install the ObjStack descriptor (*SrcDesc) into * the descriptor for the Arg or Local. * Install the new object in the stack entry * (increments the object reference count by one) */ Status = AcpiDsMethodDataSetEntry (Opcode, Index, SrcDesc, WalkState); if (ACPI_FAILURE (Status)) { goto Cleanup; } /* Normal exit */ return_ACPI_STATUS (AE_OK); /* Error exit */ Cleanup: return_ACPI_STATUS (Status); }