/*
   FALCON - The Falcon Programming Language.
   FILE: vmmaps.h

   Map items used in VM and related stuff
   -------------------------------------------------------------------
   Author: Giancarlo Niccolai
   Begin: mer ott 20 2004

   -------------------------------------------------------------------
   (C) Copyright 2004: the FALCON developers (see list in AUTHORS file)

   See LICENSE file for licensing details.
*/

/** \file
   Map items used in VM and related stuff.
*/

#ifndef flc_vmmaps_H
#define flc_vmmaps_H

#include <falcon/setup.h>
#include <falcon/types.h>
#include <falcon/genericvector.h>
#include <falcon/genericmap.h>
#include <falcon/itemtraits.h>
#include <falcon/symbol.h>
#include <falcon/string.h>
#include <falcon/module.h>
#include <falcon/basealloc.h>

namespace Falcon {

class Symbol;
class Item;
class LiveModule;


/** Pair of the symbol and the module it is declared in.
   This is just a commodity class used to store the association between a certain symbol and the module
   it came from given the VM viewpoint (that is, the ID of the source module in the VM module list.

   The class may store either a global item (an item generated by an export request in the
   source module) or a well known item (an item generated via a setWKI request by the module),
   and it can never be both at the same time.
*/
class FALCON_DYN_CLASS SymModule: public BaseAlloc
{
   Item *m_item;
   const Symbol *m_symbol;
   LiveModule *m_lmod;
   int32 m_wkiid;

public:
   SymModule():
      m_item(0),
      m_symbol(0),
      m_lmod(0),
      m_wkiid( -1 )
   {}

   /** Creates an exported Global Item. */
   SymModule( Item *itm, LiveModule *mod, const Symbol *sym ):
      m_item( itm ),
      m_symbol( sym ),
      m_lmod( mod ),
      m_wkiid( -1 )
   {}

   /** Creates an exported Global Item.
      This shortcut initializes the item pointer atonomously.
   */
   SymModule( LiveModule *mod, const Symbol *sym );

   /** Creates an exported Well Known Item. */
   SymModule( int32 wiid, LiveModule *mod, const Symbol *sym ):
      m_item( 0 ),
      m_symbol( sym ),
      m_lmod( mod ),
      m_wkiid( wiid )
   {}

   /** Global item pointer.
      This pointers always points to a valid global variable in a vector inside LiveModule structure.
      As the global variable area never chages, the item pointer stays valid as long as the
      LiveModule in which it's stored is alive.
      \note If this SymModule refers to a WKI, the pointer is 0.
      \return a pointer to the referenced item.
   */
   Item *item() const { return m_item; }
   const Symbol *symbol() const { return m_symbol; }
   uint32 symbolId() const { return m_symbol->itemId(); }
   LiveModule *liveModule() const { return m_lmod; }

    /** Well known item id.
      To find an item in the well known item array, it is necessary to use a local ID,
      as the array grows as the VM finds wki in the module.
      \note if the SymModule refers to a globally exported item, this id is -1
      \return the id of the item in the WKI array.
   */
   int32 wkiid() const { return m_wkiid; }
};


class SymModuleTraits: public ElementTraits
{
public:
   virtual ~SymModuleTraits() {}
	virtual uint32 memSize() const;
	virtual void init( void *itemZone ) const;
	virtual void copy( void *targetZone, const void *sourceZone ) const;
	virtual int compare( const void *first, const void *second ) const;
	virtual void destroy( void *item ) const;
   virtual bool owning() const;
};


namespace traits
{
   extern SymModuleTraits &t_SymModule();
}

/** Map of symbol names and module where they are located.
   (const String *, SymModule )
*/
class FALCON_DYN_CLASS SymModuleMap: public Map
{
public:
   SymModuleMap();
};

/** Map of active modules in this VM.
   (const String *, LiveModule * )
*/
class FALCON_DYN_CLASS LiveModuleMap: public Map
{
public:
   LiveModuleMap();
};

}

#endif

/* end of vmmaps.h */
