Dear Eric,
Using a simple test.prg:
function Main()
? "Hello world"
return nil
if you compile it: harbour test.prg /n
you get this test.c
/*
* Harbour 3.2.0dev (r2004201301)
* Microsoft Visual C 19.21.27702 (64-bit)
* Generated C source from "test.prg"
*/
#include "hbvmpub.h"
#include "hbinit.h"
HB_FUNC( MAIN );
HB_FUNC_EXTERN( QOUT );
HB_INIT_SYMBOLS_BEGIN( hb_vm_SymbolInit_TEST )
{ "MAIN", {HB_FS_PUBLIC | HB_FS_FIRST | HB_FS_LOCAL}, {HB_FUNCNAME( MAIN )}, NULL },
{ "QOUT", {HB_FS_PUBLIC}, {HB_FUNCNAME( QOUT )}, NULL }
HB_INIT_SYMBOLS_EX_END( hb_vm_SymbolInit_TEST, "test.prg", 0x0, 0x0003 )
#if defined( HB_PRAGMA_STARTUP )
#pragma startup hb_vm_SymbolInit_TEST
#elif defined( HB_DATASEG_STARTUP )
#define HB_DATASEG_BODY HB_DATASEG_FUNC( hb_vm_SymbolInit_TEST )
#include "hbiniseg.h"
#endif
HB_FUNC( MAIN )
{
static const HB_BYTE pcode[] =
{
36,3,0,176,1,0,106,12,72,101,108,108,111,32,
119,111,114,108,100,0,20,1,36,5,0,100,110,7
};
hb_vmExecute( pcode, symbols );
}
From the above output, this is what we name the "local symbol table":
HB_INIT_SYMBOLS_BEGIN( hb_vm_SymbolInit_TEST )
{ "MAIN", {HB_FS_PUBLIC | HB_FS_FIRST | HB_FS_LOCAL}, {HB_FUNCNAME( MAIN )}, NULL },
{ "QOUT", {HB_FS_PUBLIC}, {HB_FUNCNAME( QOUT )}, NULL }
HB_INIT_SYMBOLS_EX_END( hb_vm_SymbolInit_TEST, "test.prg", 0x0, 0x0003 )
It is a C structure that contains the symbols used in test.prg. Each PRG that we compile, generates a "local symbol table"
This was learned and imported from clipper.exe way of working.
All the "local symbol tables" need to be referenced and accessible from a "global symbol table": One table that can access all of them. Again
this way of working was learned and imported from Clipper.
When Harbour boots, all the local symbol tables must be stepped through to build the "global symbol table". Again this is done
in a similar way as Clipper did it, but using modern C compilers segments management techniques. This code in each C/OBJ does
the "magic":
#if defined( HB_PRAGMA_STARTUP )
#pragma startup hb_vm_SymbolInit_TEST
#elif defined( HB_DATASEG_STARTUP )
#define HB_DATASEG_BODY HB_DATASEG_FUNC( hb_vm_SymbolInit_TEST )
#include "hbiniseg.h"
#endif
Once that the global symbol table is built, besides being used by Harbour, we can "do" several things with it. We will
review it on a next msg.
best regards