Logo Search packages:      
Sourcecode: falconpl version File versions  Download package

module.h

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

   Falcon module extensions.
   -------------------------------------------------------------------
   Author: Giancarlo Niccolai
   Begin: mar ago 3 2004

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

   See LICENSE file for licensing details.
*/

#ifndef FLC_MODULE_H
#define FLC_MODULE_H

#include <falcon/setup.h>
#include <falcon/string.h>
#include <falcon/symbol.h>
#include <falcon/symtab.h>
#include <falcon/types.h>
#include <falcon/deptab.h>
#include <falcon/linemap.h>
#include <falcon/dll.h>
#include <falcon/strtable.h>
#include <falcon/service.h>
#include <falcon/genericmap.h>
#include <falcon/enginedata.h>
#include <falcon/basealloc.h>

namespace Falcon {

class String;
class Stream;

/** Module class abstraction.

   A module is uniquely individuated by its name; loading a module which has the same name of a
   previous one will make the other existing module to be discarded.

   When a module is added to the VM, it requests the module symbol table. The exported symbols
   are then loaded in the global VM symbol table.
   Only a module may be executed; when it is executed, it may load additional modules (the vm
   acts in its behalf) and then the VM creates the global context array.

   The array is filled with the items provided in the symbols of the symbol table, or with
   NIL were missing; if symbols are external, they are searched in the global VM symbol table
   (and again filled with the provided item or with NIL).

   A module may even exist without code. This is the case of pure C modules that register
   themselves using only C functions as symbol's initial items.

*/
00056 class FALCON_DYN_CLASS Module: public BaseAlloc
{
   volatile long m_refcount;

   /******************************
   * Anagraphic section
   *******************************/
   char m_version;
   char m_subversion;
   String m_name;
   String m_path;
   String m_language;
   uint32 m_modVersion;
   uint32 m_engineVersion;

   /******************************
   * Code section
   *******************************/
   byte *m_code;
   uint32 m_codeSize;
   uint32 m_entry;

   /******************************
   * Tables section
   *******************************/
   StringTable m_strTab;
   SymbolVector m_symbols;
   SymbolTable m_symtab;
   DependTable m_depend;
   /** The line map is a pointer as it can be absent or given after the generation step. */
00086    LineMap *m_lineInfo;

   /** Dynamic link loader attached with this module.
      If this module is created using a DLL, then it is necessary to close
      the DLL handle as soon as the module is disposed (or, at least,
      not before). For this reason, the loader that generated the module
      should be contained in the module itself.

      The loader provides internally a system to provide resource reference
      counting, so that if it insists on the same handler as other loaders
      (contained by other module instances), the corrct library handler count
      is kept (Actually, this service is usually available at kernel level on
      many OSs).

      Also, DllLoader instance contains usually a minimal representation for
      the DLL handler and points to a minimal set of non-virtual methods to
      manage it, so it has the same weight as a reference count or even a
      poiter to the an handler. This justifies the presence of this field
      also in modules that are not generated by DLLs, but are loaded from
      binary Falcon objects.
   */
00107    DllLoader *m_loader;

   /** Detach the loader for decref.
      If the module has been loaded through a DLL, decreffing it to death
      should unload the module. If this was the last instance of the module
      in memory, the return address of the DllLoader desctructor may not
      be available anymore when the destructor returns.

      For this reason, the decref() member calls this method and destroys
      autonomously the handler after having destroyed the module.
   */
   DllLoader *detachLoader();

   Map m_serviceMap;

   virtual ~Module();

public:

   static const uint32 c_noEntry;
   /** Variable parameter initializer semantic.
      Use the following functions to initialize the module.
      If a SymbolTable is not provided here, an empty one is immediately created.
   */
   Module();
   Module &name( const String &n ) { m_name.bufferize( n ); return *this; }
   Module &path( const String &p ) { m_path.bufferize( p ); return *this; }
   Module &code( byte *code ) { m_code = code; return *this; }
   Module &codeSize( uint32 cs ) { m_codeSize = cs; return *this; }
   Module &entry( uint32 entry ) { m_entry = entry; return *this; }
   Module &language( const String &lang ) { m_language = lang; return *this; }


   Module &version( uint32 version ) { m_modVersion = version; return *this; }
   Module &version( int major, int minor, int revision ) {
      m_modVersion = major << 16 | minor << 8 | revision;
      return *this;
   }

   Module &engineVersion( uint32 version ) { m_engineVersion = version; return *this; }
   Module &engineVersion( int major, int minor, int revision )  {
      m_engineVersion = major << 16 | minor << 8 | revision;
      return *this;
   }

   virtual char pcodeVersion() const;
   virtual char pcodeSubVersion() const;

   void incref();
   void decref();

   Symbol *findGlobalSymbol( const String &name ) const
   {
      return m_symtab.findByName( name );
   }

   const String &name() const { return m_name; }
   const String &path() const { return m_path; }
   const String &language() const { return m_language;}

   byte *code() const { return m_code; }
   uint32 codeSize() const { return m_codeSize; }
   uint32 entry() const { return m_entry; }

   String *addCString( const char *pos, uint32 size );

   /** Add a string to the module string table.
      If the string already exists, the previous entry is returned.
      \note If the string isn't found in the string table and is
         created on the spod, its exported status
         (international string) is copied from \b st.

      \param st the string to be added.
      \return A pointer to the string in the module string table.
   */
   String *addString( const String &st );

   /** Add a string to the module string table and eventually exports it.
      If the string already exists, the previous entry is returned.
      This method also set the "exported" bit of the returned string,
      so that the string can be directly used in exported intenrationalization
      tables.
      \param st the string to be added.
      \param exported set to true to make this string subject to
                      internationalization table exports.
      \return A pointer to the string in the module string table.
   */
   String *addString( const String &st, bool exported );

   /** Return a string given an ID in the string table.
      This function doesn't check for out-of-bounds access, so be careful.

      \param id the ID of the string in the string table (insertion order).
      \return A pointer to the string.
   */
00202    const String *getString( uint32 id ) const { return m_strTab.get(id); }

   Symbol *getSymbol( uint32 id ) const
   {
      if ( id > m_symbols.size() )
         return 0;
      return *(Symbol **) m_symbols.at(id);
   }

   /** Returns the module symbol table (const version).
      This holds the global variables that are available at module level.
      \return the global symbol table (const version).
   */
00215    const SymbolTable &symbolTable() const {
      return m_symtab;
   }

   /** Returns the module symbol table.
      This holds the global variables that are available at module level.
      \return the global symbol table.
   */
00223    SymbolTable &symbolTable() {
      return m_symtab;
   }


   /** Returns the symbol list (const version).
      The symbol list is a vector which contains the list of all the symbols in
      the module (including local, static, private, parameters and the like).
      Each Symbol contains an id that backreferences the position in the module
      symbol list so that

         symbols()[i]->id() == symbols[i];
      \return a reference to the symbol vector.
   */
00237    const SymbolVector &symbols() const {
      return m_symbols;
   }

   SymbolVector &symbols() {
      return m_symbols;
   }

   const DependTable &dependencies() const {
      return m_depend;
   }

   bool addDepend( String *dep );

   /** Adds a generic symbol to the module */
   void addSymbol( Symbol *sym );

   /** Shortcut to create a symbol.
      Creates a symbol and adds it to the module symbol vector.
      It is not added to the global symbol table, though. For that, use
      addGlobalSymbol().
      \note this function allows the creation of symbols having the same
         name of already existing  ones (useful i.e. for local/params).

      \param name the name of the symbol that must be created.
      \return the newly created symbol
   */
   Symbol *addSymbol( const String &name );

   Symbol *addExternalRef( const String &name ) {
      return addGlobalSymbol( addSymbol( name ) );
   }

   /** Shortcut to create a symbol as an external function.

      Binary modules may use this as a shortcut to create external
      function definitions.

      The function will also store the symbol int the global symbol
      table, and eventually add the string to the module string table
      if needed. In case the symbol is already used, it will return 0,
      else it will return the newly created symbol.

      If the symbol has to be set as a class method, or otherwise used
      internally by the module, then set the \b exp parameter to false,
      so that the symbol is not exported in the VM, sparing link time
      and memory.

      \param name the name of the symbol that must be created.
      \param func a function pointer to the external function.
      \param exp true if the symbol myst be exported (true by default)
      \return the newly created symbol
   */
   Symbol *addExtFunc( const String &name, ext_func_t func, bool exp = true );


   /** Shortcut to create a symbol and store it in the module symbol list.
      \return a newly allocated symbol which is already in the symbol list.
   */
   Symbol *addSymbol();


   /** Adds a symbol to the global symbol table.
      The function checks if the symbol is already in the module table;
      if not it adds it to the module table and sets the proper id.

      \return A pointer to the symbol.
   */
   Symbol *addGlobalSymbol( Symbol *sym );


   /** Adds a global variable symbol to the module
      @param name the name of the symbol
      @param exp true if the symbol is exported, false otherwise
      @return the newly created symbol
   */
   Symbol *addGlobal( const String &name, bool exp=true );

   /** Shortcut to add class properties that are to be considered variables.
      This method takes care to create the module strings needed to represent
      the class properties.
      \note The Symbol passed to this method must be
            one of the symbols held by this module.
      \param cls the symbol holding the ClassDef that must be operated on.
      \param prop the property name.
      \return the newly added VarDef (just for reference).
   */
   VarDef *addClassProperty( Symbol *cls, const String &prop );

   /** Adds methods to ClassDefs in symbols held by this module.

      This method takes care to create the module strings needed to represent
      the class properties.

      \note The Symbols passed to this method must be held by this module.
      \param cls the symbol holding the ClassDef that must be operated on
      \param prop the property name
      \param method the symbol that will be used as a method
      \return the newly added VarDef (just for reference)
   */
   VarDef *addClassMethod( Symbol *cls, const String &prop, Symbol *method );

   /** Shortcut to add external function methods to Classes in this module.

      This is a shortcut that creates a non-exported symbol represented by
      the class name, a dot, and the property name. This symbol is created
      in the module as non-exported, and then is fed into
      addClassMethod( Symbol *, const String, Symbol * ).

      \note The Symbols passed to this method must be held by this module.
      \param cls the symbol holding the ClassDef that must be operated on
      \param prop the property name
      \param func the function that will be used as a method
      \return the newly added VarDef (just for reference)
   */
   VarDef *addClassMethod( Symbol *cls, const String &prop, ext_func_t func );


   /** Adds an internal function to the module.
      As the functions and other callable are usually created during module load
      and added directly to the symbol table, this method serves only as a
      shortcut to define pseudo-functions. The most notable of them is the
      "__main__" function that starts at module entry point and never accepts
      parameters or locals

      The name parameter will be copied in a new string ar stored in the module string
      table. If the string already exists, that instance will be used as the symbol name.

      @param name the name of the symbol
      @param offset the position in the module code where the function is defined.
      @param exp true if the symbol is to be exported
      @return a pointer to the created symbol
   */
    Symbol *addFunction( const String &name, uint32 offset, bool exp=true );

   /** Adds a class definition to this module.
      This method creates a class which is pertinent to this modules and
      return the corresponding class symbol. The symbol may then be used
      to add properties to the class; every property must be a valid symbol
      that is already inserted in the same module of the class (at the moment,
      in future it may also be a symbol from another module).

    * @param name The name of the class
    * @param ctor_sym An optional symbol that is registered in the same module acting as a
                      constructor (pass zero if no constructor is needed).
    * @param exp true if the symbol is to be exported
    * @return The created class
    */
   Symbol *addClass( const String &name, Symbol *ctor_sym, bool exp=true );

   /** Adds a class definition with an external constructor to this module.
      This is a shortcut that creates a method in the module by getting the
      class name and adding a "._init". The created symbol is not exported, and
      is set as class constructor by calling addClass( name, Symbo *, bool ).

    * @param name The name of the class
    * @param ctor the external function that will be used as constructor.
    * @param exp true if the symbol is to be exported
    * @return The created class
    */
   Symbol *addClass( const String &name, ext_func_t ctor, bool exp=true );

   /** Adds a class definition without a constructor.

    * @param name The name of the class
    * @param exp true if the symbol is to be exported
    * @return The created class
    */
00405    Symbol *addClass( const String &name, bool exp=true ) {
      return addClass( name, static_cast<Symbol *>( 0 ), exp );
   }

   /** Adds a singleton object to this module.
      This method creates a singleton object, that is a private class which
      is instantiated at link time in an unique, eventually exported object.
      The given name is the name by which the object will be known; the private
      class is given the special name "%[object name]", where "[object name]" is
      the \b name parameter.

      If both the name and the "%" prefixed name are currently unassigned, a new
      symbol containing the singletone instance declaration is returned. On failure,
      0 is returned.

      The class giving form to this singleton can be retrieved using the Symbol::instanceOf()
      method. That symbol can then be used to add methods and properties to the singleton, or
      to derive the private class from other classes.

      \param name the name of the singleton to be created
      \param ctor_sym the constructor of the base class, or 0 for none
      \param exp true to export the singleton. The class is always private; to export it
         get it with Symbol::instanceOf() and export it with Symbol::exported().
      \return the symbol of the singleton object on success, zero on failure.
   */
   Symbol *addSingleton( const String &name, Symbol *ctor_sym, bool exp = true );

   /** Adds a singleton object to this module.
      This is like addSingleton( const String &, Symbol *, bool ), but this version
      of the function takes an external function as a constructor and assigns it a name
      that coresponds to the class name followed by "._init". If the constructor name,
      the class name or the instance name are not free, the method returns false.

      \param name the name of the singleton to be created
      \param ctor the constructor of the base class; cannot be zero (use the other version instead)
      \param exp true to export the singleton. The class is always private; to export it
         get it with Symbol::instanceOf() and export it with Symbol::exported().
      \return the symbol of the singleton object on success, zero on failure.
   */
   Symbol *addSingleton( const String &name, ext_func_t ctor, bool exp = true );

   /** Returns the line number that generated a certain code portion.
      Given a Program Counter index, this funtion returns the code
      line that originally generated the part of the code to which the
      Program Counter is pointing to, if this information is available.

      The function will return zero if the information cannot be retreived
      (i.e. be cause debug informations have been stripped).
      \param pc a code position for which the original code line must be discovered.
      \return the code line that generated the coed at PC position, or 0 if line
             info are missing.
   */
   uint32 getLineAt( uint32 pc ) const;

   /** Adds a line information to the module.
      The line informations are used in debug and error reporting to provide
      the users with the line number of the source falcon script that generated
      a certain code portion in the bytecode.

      The the assembler calls this function each time a new line generates new code.

      \param pc the current code position.
      \param line the line that generated the code starting at PC.
   */
   void addLineInfo( uint32 pc, uint32 line );

   /** Adds pre-compiled line informations to the module.
      The line informations are used in debug and error reporting to provide
      the users with the line number of the source falcon script that generated
      a certain code portion in the bytecode.

      Generators knowing the line informations (i.e. the code generator) can
      create a ready-to-use line information map, that can then be inserted
      into the same module where the target code will find place.

      The given line map is then owned by the module, and it will destroyed
      at module destruction; so the creator must give off its ownership.

      If the module already had some line infrmations, they are destroyed.

      \param infos a map containing line informations relative to the code
               used in this module.
   */
   void setLineInfo( LineMap *infos );

   /** Access the DllLoader attached with this module.
      The internal dll loader is created the first time this
      mehtod gets called. This is to avoid application-only
      modules to have a Dll loader attached.

      \see m_loader
      \return the dynamic code loader that is used by this module.
   */
   DllLoader &dllLoader();


   /** Write the module to a stream.

      The module is written to a stream (that does not requires seeking
      capabilities, like i.e. stdout). If skipCode
      is true, the code member of the module (m_code) is not written and when
      the operation reaches the point where the code should be written, it skips
      forward of m_codeSize bytes. If skipCode is false (default), the m_code
      member is regularily written.
      The code is usually skipped by the compiler and assembler if they have the
      byte code handy in another place (i.e. stored on a seekable temporary
      stream). In that case, importing the bytecode in the module just to
      serialize it would be a waste.

      The very last things to be written are 4 bytes representing the de-endianized
      code size and then the bytecode itself. This allow a caller that sets
      skipCode=true to write those data right after save() has returned
      successfully.

      \param os an output stream with seek capabilities
      \param skipCode true if the caller doesn't want to save the bytecode.
      \throw std::ostream::failure in case the stream reports a write error
   */
   virtual bool save( Stream *os, bool skipCode=false ) const;

   /** Reads the module from a stream.
      This method may only load a Falcon binary module; it has no capability to compile
      a source module or to load a native module in DLL or shared object format.

      This method is used as a convenience by the module loader or by other agents when they
      discover that the module is a native Falcon module.

      For this reason, the 4 bytes containing the Falcon module intestation should be skipped
      (read) by the caller \b before calling this method. In case they are not, i.e. because
      the caller knows the module being right without reading the header, then it should
      call this function with skipHeader set to false.

      The skipHeader parameter only refers to the first 4 bytes of the module file, which
      contain a signature, the version and the subversion of the module; the whole header
      may be much longer and depends on the module version.

      \param is an input stream
      \param skipHeader wheter to skip or read the first 4 module bytes.
   */
   virtual bool load( Stream *is, bool skipHeader=true );

   const StringTable &stringTable() const { return m_strTab; }
   StringTable &stringTable() { return m_strTab; }

   /** Adds a Main symbol as a function in the entry point if possbile.
   */
   void addMain();

   /** Creates an istance for a certain service.
      Returns 0 if the module does not provide the required service.
      The caller will have to delete the service.
   */
   Service *getService( const String &name ) const;

   /** Publishes a service on the module.
      \param sp the ServiceProvider (function pointer) that will create the service on request.
      \return true if possible, false if the service was already registered.
   */
   bool publishService( Service *sp );

   /** Return a map of the provided services.
      Should be used only in the vm.
   */
00568    const Map &getServiceMap() const { return m_serviceMap; }

   /** Adds a constant to the module.
      This object will become a constant item in the VM.
      \param exp true if the symbol is to be exported.
      \param value the value that the constant will assume in the vm.
      \param name the name of the symbol in the vm.
   */
   Symbol *addConstant( const String &name, int64 value, bool exp = true );

   /** Adds a constant to the module.
      This object will become a constant item in the VM.
      \param exp true if the symbol is to be exported.
      \param value the value that the constant will assume in the vm.
      \param name the name of the symbol in the vm.
   */
   Symbol *addConstant( const String &name, numeric value, bool exp = true );

   /** Adds a constant to the module.
      This object will become a constant item in the VM.
      \param exp true if the symbol is to be exported.
      \param value the value that the constant will assume in the vm.
      \param name the name of the symbol in the vm.
   */
   Symbol *addConstant( const String &name, const String &value, bool exp = true );

   /** Get the version declared by this module */
   void getModuleVersion( int &major, int &minor, int &revision ) const;

   /** Get the version of the engine libraries under which this module has been compiled. */
   void getEngineVersion( int &major, int &minor, int &revision ) const;

   /** Save internationalization infos on required file.
      Creates an XML file staring with ?xml tag.
      Shouldn't be called if it's table has no international strintgs.
   */
   bool saveTableTemplate( Stream *stream, const String &encoding ) const;
};

}

//====================================================
// Module declaration and service macros
//

// module init and declaration
#define DEFALUT_FALCON_MODULE_INIT falcon_module_init

#define FALCON_MODULE_DECL \
   FALCON_MODULE_TYPE DEFALUT_FALCON_MODULE_INIT

// Module string table service functions
#ifndef FAL_STR
   #define FAL_STR( id )   vm->moduleString( id )
#endif

#endif

/* end of module.h */

Generated by  Doxygen 1.6.0   Back to index