diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 9e9806d7f4..8b3f21ad14 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,310 @@ 2002-12-01 13:30 UTC+0100 Foo Bar */ + * generate Clipper compatible error messages for EG_NO[VAR]METHOD + and EG_NOFUNC. Please do not change it. If you want previous Harbour + error messages for EG_NO[VAR]METHOD then please change __msgNoMethod + in classy.c + + * harbour/source/vm/arrays.c + * minor modification + +2006-06-14 13:30 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbapiitm.h + + added missing declaration of hb_itemPutPtrGC() + +2006-06-14 13:05 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/config/linux/dir.cf + * harbour/config/linux/gcc.cf + * formatting + + * harbour/config/linux/global.cf + * harbour/config/linux/install.cf + * added -ldl to linked library list and RANLIB executing after library + creation + + * harbour/contrib/ole/ole2.c + * added #include "hbapicls.h" + + + harbour/include/hbapicls.h + * harbour/include/hbapi.h + + added HB_IT_ENUM item + + added collect member to HB_IT_POINTER structure for POINTER items + inspected by GC + * changed the order of HB_CODEBLOCK members to safe few bytes on + alignment + * removed counters from HB_CODEBLOCK and HB_BASEARRAY structure + + added hb_xRefInc(), hb_xRefDec(), hb_xRefFree(), hb_xRefCount(), + hb_xRefResize() functions. They are internal Harbour VM functions + and covered by internal API macro. Should not be used by 3-rd + party code because we may change them in the future or even remove. + + added hb_gcRefInc(), hb_gcRefDec(), hb_gcRefFree(), hb_gcRefCount() + functions. These are also internal function which corresponds to the + above hb_x*() ones. + - removed hb_arrayRelease() function. This function is not longer + necessary and it should never be public function - it was implemented + in very dangerous way. + - removed hb_codeblockDelete() function. + - removed hb_memvarValueDecGarbageRef() + + added USHORT usLen parameter to hb_codeblockMacroNew() - when sets + to non 0 value it informs that PCODE should be copied to dynamically + allocated buffer. + * moved all classes/object functions to separate file: hbapicls.h + + added hb_retptrGC() + + added internal function hb_memvarGetItem() + + * harbour/include/hbapiitm.h + - removed hb_itemForwardValue() and added macro which translates + hb_itemForwardValue() to hb_itemMove() + + added hb_itemUnShareString() and hb_itemReSizeString() functions + + added hb_itemSetNil() macro + + * harbour/include/hbdefs.h + * some cleanups in macro definitions + + * harbour/include/hbexprb.c + * indenting + + * harbour/include/hbvm.h + * harbour/include/hbinit.h + + added hb_vmProcessSymbolsExt(), hb_vmRegisterSymbols(), + hb_vmFreeSymbols(), hb_vmBeginSymbolGroup(), + hb_vmInitSymbolGroup(), hb_vmExitSymbolGroup() + * changed hb_vmProcessSymbols() to return address of register symbol + table. For normal code it's the same address as given in parameter + so it does not break backward binary compatibility. + * changed symbol init macros to work correctly with modified address + of symbol table + + * harbour/include/hbsetup.h + * added support for HB_USE_PROFILER macro. Now profiler code is + is disable in HVM by default + * commented out HB_ASORT_OPT_ITEMCOPY - it's not longer used - see note. + + * harbour/include/hbstack.h + * added missing parenthesis in hb_stackItem() macro + + * harbour/include/hbtypes.h + * updated VM_PROCESS_DLL_SYMBOLS definition + + added VM_PROCESS_SYMBOLS_EXT + - removed HB_ARRAYRELEASE + + * harbour/include/hbver.h + * changed revision number to 2 + + * harbour/include/hbvmpub.h + - remove pFunPtr from HB_DYNS and cover profiler member by + #ifndef HB_NO_PROFILER + + added HB_PCODEFUNC structure + + added HB_FS_PCODEFUNC, HB_FS_DYNCODE and HB_FS_LOCAL - the last one + is not used yet. + + * harbour/include/hbxvm.h + * added some multipcode functions for some speed optimization in -gc3 + output + + * harbour/include/hbapicdp.h + * harbour/source/codepage/cpbg866.c + * harbour/source/codepage/cpbgiso.c + * harbour/source/codepage/cpbgwin.c + * harbour/source/codepage/cpeldos.c + * harbour/source/codepage/cpelwin.c + * harbour/source/codepage/cpesdos.c + * harbour/source/codepage/cpesmwi.c + * harbour/source/codepage/cpeswin.c + * harbour/source/codepage/cpgedos.c + * harbour/source/codepage/cpgewin.c + * harbour/source/codepage/cphu852.c + * harbour/source/codepage/cphuiso.c + * harbour/source/codepage/cphuwin.c + * harbour/source/codepage/cppl852.c + * harbour/source/codepage/cppliso.c + * harbour/source/codepage/cpplmaz.c + * harbour/source/codepage/cpplwin.c + * harbour/source/codepage/cppt850.c + * harbour/source/codepage/cpptiso.c + * harbour/source/codepage/cpru866.c + * harbour/source/codepage/cprukoi.c + * harbour/source/codepage/cpruwin.c + * harbour/source/codepage/cpsl437.c + * harbour/source/codepage/cpsl852.c + * harbour/source/codepage/cpsliso.c + * harbour/source/codepage/cpslwin.c + * harbour/source/codepage/cpsrwin.c + * harbour/source/common/hbfhnd.c + * harbour/source/common/hbstr.c + * harbour/source/common/hbver.c + * harbour/source/compiler/gencli.c + * harbour/source/rtl/fstemp.c + * harbour/source/rtl/hbgtcore.c + * harbour/source/rtl/langapi.c + * harbour/source/rtl/gtalleg/gtalleg.c + * harbour/source/rtl/gtalleg/ssf.h + * harbour/source/rtl/gtcgi/gtcgi.c + * harbour/source/rtl/gtcrs/gtcrs.c + * harbour/source/rtl/gtdos/gtdos.c + * harbour/source/rtl/gtos2/gtos2.c + * harbour/source/rtl/gtpca/gtpca.c + * harbour/source/rtl/gtsln/gtsln.c + * harbour/source/rtl/gtstd/gtstd.c + * harbour/source/rtl/gtwin/gtwin.c + * harbour/source/rtl/gtwvt/gtwvt.c + * harbour/source/rtl/gtxwc/gtxwc.c + * cleaned the code to avoid warnings for some non ANSI C constructions + + * harbour/source/compiler/cmdcheck.c + * formatting + + * harbour/source/compiler/gencc.c + * added some multipcode optimizations + + * formatting + * keep function name set by compiler for static initstatics + + * harbour/source/compiler/harbour.c + * extend init statics name with the number of used static variables + * formatting + + * harbour/source/compiler/hbusage.c + + added my name to developers list - I hope that there is enough + of my code in Harbour (BTW for quite long time) ;-) + + * harbour/source/rdd/dbcmd.c + - removed DBF2TEXT() function + + * harbour/source/rdd/dbf1.c + * harbour/source/rdd/dbffpt/dbffpt1.c + * generate RT error when someone tries to create DBF with memo fields + without MEMO RDD linked. + + * harbour/source/rtl/errorapi.c + * replace all hb_vmDo() with hb_vmSend() + + * harbour/source/rtl/math.c + * use hb_errPutArgs() to pass parameters to error object + + * harbour/source/rtl/philes.c + * harbour/source/rtl/space.c + * harbour/source/rtl/strpeek.c + * some minor optimizations + + * harbour/source/vm/arrays.c + - removed hb_arrayRelease() function. + * changed hb_arrayReleaseGarbage() to be safe for recursive call + * updated to use GC counters + + * harbour/source/vm/arrayshb.c + * use stack function/macros instead of direct accessing HB_STACK members + + * harbour/source/vm/asort.c + * removed unused HB_ASORT_OPT_ITEMCOPY + + * harbour/source/vm/classes.c + * added class code from HVM + % added fast overloaded operator detection and execution + + added hb_objHasOperator(), hb_objOperatorCall() + + added separated overloading of "=" and "==" operators + * operate on PHB_SYMB not PHB_FUNC - support for pure PCODE function + without any machine code + * use stack function/macros instead of direct accessing HB_STACK members + * separated profiler code + * some code cleaning + + * harbour/source/vm/codebloc.c + + added USHORT usLen parameter to hb_codeblockMacroNew() - when sets + to non 0 value it informs that PCODE should be copied to dynamically + allocated buffer. + * updated to use GC counters + - removed hb_codeblockDelete() function. + * changed hb_codeblockDeleteGarbage() to be safe for recursive call + - removed restoring statics base in hb_codeblockEvaluate() + + * harbour/source/vm/debug.c + * cleaned and optimized some code + + * harbour/source/vm/dynlibhb.c + + added support for loading and unloading dynamic libraries with PCODE + + added support for dynamic libraries in Linux (.so) + + added HB_LIBERROR() - returns error string with last error in + HB_LIBLOAD() - now works only in Linux + + * harbour/source/vm/dynsym.c + * separated profiler code + + use pDynSym->pSymbol->value.pFunPtr instead of pDynSym->pFunPtr + + * harbour/source/vm/estack.c + + added #include "hbapicls.h" + + added hb_stackPushReturn(), hb_stackPopReturn() + + * harbour/source/vm/eval.c + * harbour/source/vm/extend.c + * use stack function/macros instead of direct accessing HB_STACK members + + added hb_retptrGC() + + * harbour/source/vm/fm.c + + added hb_xRefInc(), hb_xRefDec(), hb_xRefFree(), hb_xRefCount(), + hb_xRefResize() functions. They are internal Harbour VM functions + and covered by internal API macro. Should not be used by 3-rd + party code because we may change them in the future or even remove. + + * harbour/source/vm/garbage.c + + added hb_gcRefInc(), hb_gcRefDec(), hb_gcRefFree(), hb_gcRefCount() + functions. These are also internal function which corresponds to the + above hb_x*() ones. + * changed Step 3 of GC pass and execution of clean-up function to be + safe for recursive calls and additional activity. + Ryszard see my note and s_pDeletedBlock + + added GC inspected HB_IT_POINTER items. + + * harbour/source/vm/hvm.c + * separated profiler code + * separated class code from HVM + + added support for loading and unloading libraries with PCODE modules + + added support for pure PCODE functions + + added support for string item resizing and preallocating string buffer + + added some new multipcode functions for -gc3 optimization + + added hb_vmProcessSymbolsExt(), hb_vmRegisterSymbols(), + hb_vmFreeSymbols(), hb_vmBeginSymbolGroup(), + hb_vmInitSymbolGroup(), hb_vmExitSymbolGroup() + * changed hb_vmProcessSymbols() to return address of register symbol + table. For normal code it's the same address as given in parameter + so it does not break backward binary compatibility. + + use new code for operator overloading + * changed FOR EACH to dynamically check iteration scope in + hb_vmEnumNext()/hb_vmEnumPrev() and remove max number of iteration + stored on HVM stack + * temporary use hb_itemUnRefOnce() instead of hb_itemUnRefRefer() as + workaround for possible GPF. I'd like Ryszard will chose the final + version + + * harbour/source/vm/itemapi.c + + added support for preallocating string buffer size + + added hb_itemUnShareString() and hb_itemReSizeString() + * updated string items to use counters allocated with each + memory block by xh_xgrab()/hb_xalloc() + * updated codeblock and array items to use GC reference counters + + added GC inspected HB_IT_POINTER items. + * generate RT error in hb_itemUnreOnce() for enumerator items + out of scope + + added hb_itemPutPtrGC() + + * harbour/source/vm/macro.c + * use pDynSym->pSymbol->value.pFunPtr instead of pDynSym->pFunPtr + + * harbour/source/vm/maindllp.c + * updated usage of hb_vmProcessSymbols() + * added hb_vmProcessSymbolsExt() + + * harbour/source/vm/memvars.c + + added hb_memvarGetItem() + - removed hb_memvarValueDecGarbageRef() + + * harbour/source/vm/proc.c + + added #include "hbapicls.h" + + * harbour/source/vm/pvalue.c + * do not access stack structure directly but use hb_stack*() + functions (macros) * harbour/source/vm/runner.c * synced with xHarbour diff --git a/harbour/config/linux/dir.cf b/harbour/config/linux/dir.cf index 08f9ed936f..63132daa76 100644 --- a/harbour/config/linux/dir.cf +++ b/harbour/config/linux/dir.cf @@ -11,4 +11,4 @@ DIR_RULE =\ fi \ done -endif # ! compiling a specific program module \ No newline at end of file +endif # ! compiling a specific program module diff --git a/harbour/config/linux/gcc.cf b/harbour/config/linux/gcc.cf index 071e4fc43c..d987a3c457 100644 --- a/harbour/config/linux/gcc.cf +++ b/harbour/config/linux/gcc.cf @@ -23,7 +23,7 @@ CPPFLAGS = -I. -I$(HB_INC_COMPILE) # We are under linux CFLAGS = -DHB_OS_LINUX -Wall -W -fsigned-char -# uncomment this if you want to farce relocateable code for .so libs +# uncomment this if you want to force relocateable code for .so libs # it's necessary on some platforms but can reduce performance #CFLAGS += -fPIC @@ -106,12 +106,12 @@ endif endif -LINKLIBS += -lm -Wl,--end-group +LINKLIBS += -lm -ldl -Wl,--end-group LDFLAGS = $(LINKPATHS) AR = ar ARFLAGS = $(A_USR) -AR_RULE = $(AR) $(ARFLAGS) cr $@ $(^F) || $(RM) $@ +AR_RULE = $(AR) $(ARFLAGS) cr $@ $(^F) && $(RANLIB) $@ || ( $(RM) $@ && false ) include $(TOP)$(ROOT)config/rules.cf diff --git a/harbour/config/linux/global.cf b/harbour/config/linux/global.cf index 6ad9db0432..3062491d48 100644 --- a/harbour/config/linux/global.cf +++ b/harbour/config/linux/global.cf @@ -37,6 +37,7 @@ CP = cp -f MV = mv -f MD = mkdir MDP = mkdir -p +RANLIB = ranlib dirbase:: @[ -d $(ARCH_DIR) ] || $(MDP) $(ARCH_DIR) diff --git a/harbour/config/linux/install.cf b/harbour/config/linux/install.cf index 239603d970..0c71da1194 100644 --- a/harbour/config/linux/install.cf +++ b/harbour/config/linux/install.cf @@ -18,4 +18,3 @@ INSTALL_RULE =\ fi \ done \ fi - diff --git a/harbour/contrib/ole/ole2.c b/harbour/contrib/ole/ole2.c index fa030db199..ce598bf126 100644 --- a/harbour/contrib/ole/ole2.c +++ b/harbour/contrib/ole/ole2.c @@ -80,6 +80,7 @@ #include "hbvm.h" #include "hbapiitm.h" +#include "hbapicls.h" #include "hbdate.h" static far VARIANTARG RetVal; diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index 4b12a255ae..160668dab4 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -74,27 +74,28 @@ HB_EXTERN_BEGIN /* items types and type checking macros */ -#define HB_IT_NIL ( ( HB_TYPE ) 0x0000 ) -#define HB_IT_POINTER ( ( HB_TYPE ) 0x0001 ) -#define HB_IT_INTEGER ( ( HB_TYPE ) 0x0002 ) -#define HB_IT_LONG ( ( HB_TYPE ) 0x0008 ) -#define HB_IT_DOUBLE ( ( HB_TYPE ) 0x0010 ) -#define HB_IT_DATE ( ( HB_TYPE ) 0x0020 ) -#define HB_IT_LOGICAL ( ( HB_TYPE ) 0x0080 ) -#define HB_IT_SYMBOL ( ( HB_TYPE ) 0x0100 ) -#define HB_IT_ALIAS ( ( HB_TYPE ) 0x0200 ) -#define HB_IT_STRING ( ( HB_TYPE ) 0x0400 ) -#define HB_IT_MEMOFLAG ( ( HB_TYPE ) 0x0800 ) +#define HB_IT_NIL ( ( HB_TYPE ) 0x00000 ) +#define HB_IT_POINTER ( ( HB_TYPE ) 0x00001 ) +#define HB_IT_INTEGER ( ( HB_TYPE ) 0x00002 ) +#define HB_IT_LONG ( ( HB_TYPE ) 0x00008 ) +#define HB_IT_DOUBLE ( ( HB_TYPE ) 0x00010 ) +#define HB_IT_DATE ( ( HB_TYPE ) 0x00020 ) +#define HB_IT_LOGICAL ( ( HB_TYPE ) 0x00080 ) +#define HB_IT_SYMBOL ( ( HB_TYPE ) 0x00100 ) +#define HB_IT_ALIAS ( ( HB_TYPE ) 0x00200 ) +#define HB_IT_STRING ( ( HB_TYPE ) 0x00400 ) +#define HB_IT_MEMOFLAG ( ( HB_TYPE ) 0x00800 ) #define HB_IT_MEMO ( HB_IT_MEMOFLAG | HB_IT_STRING ) -#define HB_IT_BLOCK ( ( HB_TYPE ) 0x1000 ) -#define HB_IT_BYREF ( ( HB_TYPE ) 0x2000 ) -#define HB_IT_MEMVAR ( ( HB_TYPE ) 0x4000 ) -#define HB_IT_ARRAY ( ( HB_TYPE ) 0x8000 ) +#define HB_IT_BLOCK ( ( HB_TYPE ) 0x01000 ) +#define HB_IT_BYREF ( ( HB_TYPE ) 0x02000 ) +#define HB_IT_MEMVAR ( ( HB_TYPE ) 0x04000 ) +#define HB_IT_ARRAY ( ( HB_TYPE ) 0x08000 ) +#define HB_IT_ENUM ( ( HB_TYPE ) 0x10000 ) #define HB_IT_OBJECT HB_IT_ARRAY #define HB_IT_NUMERIC ( ( HB_TYPE ) ( HB_IT_INTEGER | HB_IT_LONG | HB_IT_DOUBLE ) ) #define HB_IT_NUMINT ( ( HB_TYPE ) ( HB_IT_INTEGER | HB_IT_LONG ) ) #define HB_IT_ANY ( ( HB_TYPE ) 0xFFFFFFFF ) -#define HB_IT_COMPLEX ( ( HB_TYPE ) ( HB_IT_STRING | HB_IT_BLOCK | HB_IT_ARRAY | HB_IT_MEMVAR | HB_IT_BYREF ) ) +#define HB_IT_COMPLEX ( ( HB_TYPE ) ( HB_IT_BLOCK | HB_IT_ARRAY | HB_IT_POINTER | HB_IT_MEMVAR | HB_IT_ENUM | HB_IT_STRING ) ) #define HB_IT_GCITEM ( ( HB_TYPE ) ( HB_IT_BLOCK | HB_IT_ARRAY | HB_IT_POINTER | HB_IT_BYREF ) ) #if 0 @@ -119,27 +120,28 @@ HB_EXTERN_BEGIN * x86 machines they can safe few CPU cycles. [druzus] */ -#define HB_IS_NIL( p ) HB_IS_OF_TYPE( p, HB_IT_NIL ) -#define HB_IS_ARRAY( p ) HB_IS_OF_TYPE( p, HB_IT_ARRAY ) -#define HB_IS_BLOCK( p ) HB_IS_OF_TYPE( p, HB_IT_BLOCK ) -#define HB_IS_DATE( p ) HB_IS_OF_TYPE( p, HB_IT_DATE ) -#define HB_IS_DOUBLE( p ) HB_IS_OF_TYPE( p, HB_IT_DOUBLE ) -#define HB_IS_INTEGER( p ) HB_IS_OF_TYPE( p, HB_IT_INTEGER ) -#define HB_IS_LOGICAL( p ) HB_IS_OF_TYPE( p, HB_IT_LOGICAL ) -#define HB_IS_LONG( p ) HB_IS_OF_TYPE( p, HB_IT_LONG ) -#define HB_IS_SYMBOL( p ) HB_IS_OF_TYPE( p, HB_IT_SYMBOL ) -#define HB_IS_POINTER( p ) HB_IS_OF_TYPE( p, HB_IT_POINTER ) -#define HB_IS_MEMVAR( p ) HB_IS_OF_TYPE( p, HB_IT_MEMVAR ) -#define HB_IS_MEMO( p ) HB_IS_OF_TYPE( p, HB_IT_MEMO ) -#define HB_IS_STRING( p ) ( ( HB_ITEM_TYPE( p ) & ~( HB_IT_BYREF | HB_IT_MEMOFLAG ) ) == HB_IT_STRING ) -#define HB_IS_BYREF( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_BYREF ) != 0 ) -#define HB_IS_NUMERIC( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_NUMERIC ) != 0 ) -#define HB_IS_NUMINT( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_NUMINT ) != 0 ) -#define HB_IS_COMPLEX( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_COMPLEX ) != 0 ) -#define HB_IS_GCITEM( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_GCITEM ) != 0 ) -#define HB_IS_BADITEM( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_COMPLEX ) != 0 && ( HB_ITEM_TYPE( p ) & ~( HB_IT_COMPLEX | HB_IT_MEMOFLAG ) ) != 0 ) -#define HB_IS_OBJECT( p ) ( HB_IS_ARRAY( p ) && HB_OBJ_CLASS( p ) != 0 ) -#define HB_IS_NUMBER( p ) HB_IS_NUMERIC( p ) +#define HB_IS_NIL( p ) HB_IS_OF_TYPE( p, HB_IT_NIL ) +#define HB_IS_ARRAY( p ) HB_IS_OF_TYPE( p, HB_IT_ARRAY ) +#define HB_IS_BLOCK( p ) HB_IS_OF_TYPE( p, HB_IT_BLOCK ) +#define HB_IS_DATE( p ) HB_IS_OF_TYPE( p, HB_IT_DATE ) +#define HB_IS_DOUBLE( p ) HB_IS_OF_TYPE( p, HB_IT_DOUBLE ) +#define HB_IS_INTEGER( p ) HB_IS_OF_TYPE( p, HB_IT_INTEGER ) +#define HB_IS_LOGICAL( p ) HB_IS_OF_TYPE( p, HB_IT_LOGICAL ) +#define HB_IS_LONG( p ) HB_IS_OF_TYPE( p, HB_IT_LONG ) +#define HB_IS_SYMBOL( p ) HB_IS_OF_TYPE( p, HB_IT_SYMBOL ) +#define HB_IS_POINTER( p ) HB_IS_OF_TYPE( p, HB_IT_POINTER ) +#define HB_IS_MEMVAR( p ) HB_IS_OF_TYPE( p, HB_IT_MEMVAR ) +#define HB_IS_MEMO( p ) HB_IS_OF_TYPE( p, HB_IT_MEMO ) +#define HB_IS_ENUM( p ) HB_IS_OF_TYPE( p, HB_IT_ENUM ) +#define HB_IS_STRING( p ) ( ( HB_ITEM_TYPE( p ) & ~( HB_IT_BYREF | HB_IT_MEMOFLAG ) ) == HB_IT_STRING ) +#define HB_IS_BYREF( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_BYREF ) != 0 ) +#define HB_IS_NUMERIC( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_NUMERIC ) != 0 ) +#define HB_IS_NUMINT( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_NUMINT ) != 0 ) +#define HB_IS_COMPLEX( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_COMPLEX ) != 0 ) +#define HB_IS_GCITEM( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_GCITEM ) != 0 ) +#define HB_IS_BADITEM( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_COMPLEX ) != 0 && ( HB_ITEM_TYPE( p ) & ~( HB_IT_COMPLEX | HB_IT_MEMOFLAG ) ) != 0 ) +#define HB_IS_OBJECT( p ) ( HB_IS_ARRAY( p ) && HB_OBJ_CLASS( p ) != 0 ) +#define HB_IS_NUMBER( p ) HB_IS_NUMERIC( p ) #elif 0 @@ -148,54 +150,56 @@ HB_EXTERN_BEGIN * they are the safest one in buggy code which may produce wrong item * signatures but also they can be slower on some machines */ -#define HB_IS_NIL( p ) ( HB_ITEM_TYPE( p ) == HB_IT_NIL ) -#define HB_IS_ARRAY( p ) ( HB_ITEM_TYPE( p ) == HB_IT_ARRAY ) -#define HB_IS_BLOCK( p ) ( HB_ITEM_TYPE( p ) == HB_IT_BLOCK ) -#define HB_IS_DATE( p ) ( HB_ITEM_TYPE( p ) == HB_IT_DATE ) -#define HB_IS_DOUBLE( p ) ( HB_ITEM_TYPE( p ) == HB_IT_DOUBLE ) -#define HB_IS_INTEGER( p ) ( HB_ITEM_TYPE( p ) == HB_IT_INTEGER ) -#define HB_IS_LOGICAL( p ) ( HB_ITEM_TYPE( p ) == HB_IT_LOGICAL ) -#define HB_IS_LONG( p ) ( HB_ITEM_TYPE( p ) == HB_IT_LONG ) -#define HB_IS_SYMBOL( p ) ( HB_ITEM_TYPE( p ) == HB_IT_SYMBOL ) -#define HB_IS_POINTER( p ) ( HB_ITEM_TYPE( p ) == HB_IT_POINTER ) -#define HB_IS_MEMO( p ) ( HB_ITEM_TYPE( p ) == HB_IT_MEMO ) -#define HB_IS_MEMVAR( p ) ( HB_ITEM_TYPE( p ) == ( HB_IT_MEMVAR | HB_IT_BYREF ) ) -#define HB_IS_STRING( p ) ( ( HB_ITEM_TYPE( p ) & ~HB_IT_MEMOFLAG ) == HB_IT_STRING ) -#define HB_IS_BYREF( p ) ( ( HB_ITEM_TYPE( p ) & ~HB_IT_MEMVAR ) == HB_IT_BYREF ) -#define HB_IS_NUMERIC( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_NUMERIC ) != 0 ) -#define HB_IS_NUMINT( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_NUMINT ) != 0 ) -#define HB_IS_COMPLEX( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_COMPLEX ) != 0 ) -#define HB_IS_GCITEM( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_GCITEM ) != 0 ) -#define HB_IS_BADITEM( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_COMPLEX ) != 0 && ( HB_ITEM_TYPE( p ) & ~( HB_IT_COMPLEX | HB_IT_MEMOFLAG ) ) != 0 ) -#define HB_IS_OBJECT( p ) ( HB_IS_ARRAY( p ) && HB_OBJ_CLASS( p ) != 0 ) -#define HB_IS_NUMBER( p ) HB_IS_NUMERIC( p ) +#define HB_IS_NIL( p ) ( HB_ITEM_TYPE( p ) == HB_IT_NIL ) +#define HB_IS_ARRAY( p ) ( HB_ITEM_TYPE( p ) == HB_IT_ARRAY ) +#define HB_IS_BLOCK( p ) ( HB_ITEM_TYPE( p ) == HB_IT_BLOCK ) +#define HB_IS_DATE( p ) ( HB_ITEM_TYPE( p ) == HB_IT_DATE ) +#define HB_IS_DOUBLE( p ) ( HB_ITEM_TYPE( p ) == HB_IT_DOUBLE ) +#define HB_IS_INTEGER( p ) ( HB_ITEM_TYPE( p ) == HB_IT_INTEGER ) +#define HB_IS_LOGICAL( p ) ( HB_ITEM_TYPE( p ) == HB_IT_LOGICAL ) +#define HB_IS_LONG( p ) ( HB_ITEM_TYPE( p ) == HB_IT_LONG ) +#define HB_IS_SYMBOL( p ) ( HB_ITEM_TYPE( p ) == HB_IT_SYMBOL ) +#define HB_IS_POINTER( p ) ( HB_ITEM_TYPE( p ) == HB_IT_POINTER ) +#define HB_IS_MEMO( p ) ( HB_ITEM_TYPE( p ) == HB_IT_MEMO ) +#define HB_IS_MEMVAR( p ) ( HB_ITEM_TYPE( p ) == ( HB_IT_MEMVAR | HB_IT_BYREF ) ) +#define HB_IS_ENUM( p ) ( HB_ITEM_TYPE( p ) == ( HB_IT_ENUM | HB_IT_BYREF ) ) +#define HB_IS_STRING( p ) ( ( HB_ITEM_TYPE( p ) & ~HB_IT_MEMOFLAG ) == HB_IT_STRING ) +#define HB_IS_BYREF( p ) ( ( HB_ITEM_TYPE( p ) & ~HB_IT_MEMVAR ) == HB_IT_BYREF ) +#define HB_IS_NUMERIC( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_NUMERIC ) != 0 ) +#define HB_IS_NUMINT( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_NUMINT ) != 0 ) +#define HB_IS_COMPLEX( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_COMPLEX ) != 0 ) +#define HB_IS_GCITEM( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_GCITEM ) != 0 ) +#define HB_IS_BADITEM( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_COMPLEX ) != 0 && ( HB_ITEM_TYPE( p ) & ~( HB_IT_COMPLEX | HB_IT_MEMOFLAG ) ) != 0 ) +#define HB_IS_OBJECT( p ) ( HB_IS_ARRAY( p ) && HB_OBJ_CLASS( p ) != 0 ) +#define HB_IS_NUMBER( p ) HB_IS_NUMERIC( p ) #else /* * these ones are can be the most efficiently optimized on some CPUs */ -#define HB_IS_NIL( p ) ( HB_ITEM_TYPE( p ) == HB_IT_NIL ) -#define HB_IS_ARRAY( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_ARRAY ) != 0 ) -#define HB_IS_BLOCK( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_BLOCK ) != 0 ) -#define HB_IS_DATE( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_DATE ) != 0 ) -#define HB_IS_DOUBLE( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_DOUBLE ) != 0 ) -#define HB_IS_INTEGER( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_INTEGER ) != 0 ) -#define HB_IS_LOGICAL( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_LOGICAL ) != 0 ) -#define HB_IS_LONG( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_LONG ) != 0 ) -#define HB_IS_SYMBOL( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_SYMBOL ) != 0 ) -#define HB_IS_POINTER( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_POINTER ) != 0 ) -#define HB_IS_MEMO( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_MEMOFLAG ) != 0 ) -#define HB_IS_STRING( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_STRING ) != 0 ) -#define HB_IS_MEMVAR( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_MEMVAR ) != 0 ) -#define HB_IS_BYREF( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_BYREF ) != 0 ) -#define HB_IS_NUMERIC( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_NUMERIC ) != 0 ) -#define HB_IS_NUMINT( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_NUMINT ) != 0 ) -#define HB_IS_COMPLEX( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_COMPLEX ) != 0 ) -#define HB_IS_GCITEM( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_GCITEM ) != 0 ) -#define HB_IS_BADITEM( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_COMPLEX ) != 0 && ( HB_ITEM_TYPE( p ) & ~( HB_IT_COMPLEX | HB_IT_MEMOFLAG ) ) != 0 ) -#define HB_IS_OBJECT( p ) ( HB_IS_ARRAY( p ) && HB_OBJ_CLASS( p ) != 0 ) -#define HB_IS_NUMBER( p ) HB_IS_NUMERIC( p ) +#define HB_IS_NIL( p ) ( HB_ITEM_TYPE( p ) == HB_IT_NIL ) +#define HB_IS_ARRAY( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_ARRAY ) != 0 ) +#define HB_IS_BLOCK( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_BLOCK ) != 0 ) +#define HB_IS_DATE( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_DATE ) != 0 ) +#define HB_IS_DOUBLE( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_DOUBLE ) != 0 ) +#define HB_IS_INTEGER( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_INTEGER ) != 0 ) +#define HB_IS_LOGICAL( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_LOGICAL ) != 0 ) +#define HB_IS_LONG( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_LONG ) != 0 ) +#define HB_IS_SYMBOL( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_SYMBOL ) != 0 ) +#define HB_IS_POINTER( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_POINTER ) != 0 ) +#define HB_IS_MEMO( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_MEMOFLAG ) != 0 ) +#define HB_IS_STRING( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_STRING ) != 0 ) +#define HB_IS_MEMVAR( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_MEMVAR ) != 0 ) +#define HB_IS_ENUM( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_ENUM ) != 0 ) +#define HB_IS_BYREF( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_BYREF ) != 0 ) +#define HB_IS_NUMERIC( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_NUMERIC ) != 0 ) +#define HB_IS_NUMINT( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_NUMINT ) != 0 ) +#define HB_IS_COMPLEX( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_COMPLEX ) != 0 ) +#define HB_IS_GCITEM( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_GCITEM ) != 0 ) +#define HB_IS_BADITEM( p ) ( ( HB_ITEM_TYPE( p ) & HB_IT_COMPLEX ) != 0 && ( HB_ITEM_TYPE( p ) & ~( HB_IT_COMPLEX | HB_IT_MEMOFLAG ) ) != 0 ) +#define HB_IS_OBJECT( p ) ( HB_IS_ARRAY( p ) && HB_OBJ_CLASS( p ) != 0 ) +#define HB_IS_NUMBER( p ) HB_IS_NUMERIC( p ) #endif @@ -265,42 +269,42 @@ struct hb_struLong HB_LONG value; }; +struct hb_struPointer +{ + void * value; + BOOL collect; +}; + struct hb_struMemvar { struct _HB_VALUE ** itemsbase; LONG value; }; -struct hb_struPointer -{ - void * value; -}; - struct hb_struRefer { union { - struct _HB_CODEBLOCK * block; /* codeblock */ - struct _HB_ITEM * itemPtr; /* item pointer */ - struct _HB_ITEM ** itemsbase; /* static variables */ - struct _HB_ITEM ** *itemsbasePtr; /* local variables */ + struct _HB_CODEBLOCK * block; /* codeblock */ + struct _HB_ITEM * itemPtr; /* item pointer */ + struct _HB_ITEM ** itemsbase; /* static variables */ + struct _HB_ITEM ** *itemsbasePtr; /* local variables */ } BasePtr; - LONG offset; /* 0 for static variables */ + LONG offset; /* 0 for static variables */ LONG value; - union { - struct _HB_ITEM * itemPtr; /* item pointer */ - } ValuePtr; +}; + +struct hb_struEnum +{ + struct _HB_ITEM * basePtr; /* base item pointer */ + struct _HB_ITEM * valuePtr; /* value item pointer */ + LONG offset; }; struct hb_struString { ULONG length; + ULONG allocated; /* size of memory block allocated for string value, 0 for static strings */ char * value; - SHORT bStatic; /* it is a static string from pcode or from a C string */ - union - { - char value[1]; - HB_COUNTER * pulHolders; /* number of holders of this string */ - } u; }; struct hb_struSymbol @@ -317,18 +321,19 @@ typedef struct _HB_ITEM HB_TYPE type; union { - struct hb_struArray asArray; - struct hb_struBlock asBlock; - struct hb_struDate asDate; - struct hb_struDouble asDouble; - struct hb_struInteger asInteger; - struct hb_struLogical asLogical; - struct hb_struLong asLong; - struct hb_struMemvar asMemvar; - struct hb_struPointer asPointer; - struct hb_struRefer asRefer; - struct hb_struString asString; - struct hb_struSymbol asSymbol; + struct hb_struArray asArray; + struct hb_struBlock asBlock; + struct hb_struDate asDate; + struct hb_struDouble asDouble; + struct hb_struInteger asInteger; + struct hb_struLogical asLogical; + struct hb_struLong asLong; + struct hb_struPointer asPointer; + struct hb_struMemvar asMemvar; + struct hb_struRefer asRefer; + struct hb_struEnum asEnum; + struct hb_struString asString; + struct hb_struSymbol asSymbol; } item; } HB_ITEM, * PHB_ITEM, * HB_ITEM_PTR; @@ -336,7 +341,6 @@ typedef struct _HB_BASEARRAY { PHB_ITEM pItems; /* pointer to the array items */ ULONG ulLen; /* number of items in the array */ - HB_COUNTER ulHolders; /* number of holders of this array */ USHORT * puiClsTree; /* remember array of super called ID Tree */ USHORT uiClass; /* offset to the classes base if it is an object */ USHORT uiPrevCls; /* for fixing after access super */ @@ -346,12 +350,11 @@ typedef struct _HB_BASEARRAY typedef struct _HB_CODEBLOCK { BYTE * pCode; /* codeblock pcode */ - PHB_ITEM pLocals; /* table with referenced local variables */ - USHORT uiLocals; /* number of referenced local variables */ PHB_SYMB pSymbols; /* codeblocks symbols */ PHB_SYMB pDefSymb; /* symbol where the codeblock was created */ - HB_COUNTER ulCounter; /* numer of references to this codeblock */ - BOOL dynBuffer; /* is pcode buffer allocated dynamically */ + PHB_ITEM pLocals; /* table with referenced local variables */ + USHORT uiLocals; /* number of referenced local variables */ + SHORT dynBuffer; /* is pcode buffer allocated dynamically, SHORT used instead of BOOL intentionally to force optimal alignment */ } HB_CODEBLOCK, * PHB_CODEBLOCK, * HB_CODEBLOCK_PTR; typedef struct _HB_VALUE @@ -435,6 +438,7 @@ extern HB_EXPORT LONGLONG hb_parnll( int iParam, ... ); /* retrieve a numeric #define hb_retnint( iNumber ) hb_itemPutNInt( hb_stackReturnItem(), iNumber ) #define hb_retnintlen( lNumber, iWidth ) hb_itemPutNIntLen( hb_stackReturnItem(), lNumber, iWidth ) #define hb_retptr( pointer ) hb_itemPutPtr( hb_stackReturnItem(), pointer ) +#define hb_retptrGC( pointer ) hb_itemPutPtrGC( hb_stackReturnItem(), pointer ) #else @@ -460,6 +464,7 @@ extern HB_EXPORT void hb_retnllen( long lNumber, int iWidth ); /* returns a lo extern HB_EXPORT void hb_retnintlen( HB_LONG lNumber, int iWidth ); /* returns a long long number, with specific width */ extern HB_EXPORT void hb_reta( ULONG ulLen ); /* returns an array with a specific length */ extern HB_EXPORT void hb_retptr( void * ptr ); /* returns a pointer */ +extern HB_EXPORT void hb_retptrGC( void * ptr ); /* returns a pointer to an allocated memory, collected by GC */ #ifndef HB_LONG_LONG_OFF extern HB_EXPORT void hb_retnll( LONGLONG lNumber );/* returns a long long number */ extern HB_EXPORT void hb_retnlllen( LONGLONG lNumber, int iWidth ); /* returns a long long number, with specific width */ @@ -489,6 +494,32 @@ extern HB_EXPORT void * hb_xrealloc( void * pMem, ULONG ulSize ); /* reallocat extern HB_EXPORT ULONG hb_xsize( void * pMem ); /* returns the size of an allocated memory block */ extern HB_EXPORT ULONG hb_xquery( USHORT uiMode ); /* Query different types of memory information */ +#ifdef _HB_API_INTERNAL_ +extern void hb_xRefInc( void * pMem ); /* increment reference counter */ +extern BOOL hb_xRefDec( void * pMem ); /* decrement reference counter, return TRUE when 0 reached */ +extern void hb_xRefFree( void * pMem ); /* decrement reference counter and free the block when 0 reached */ +extern HB_COUNTER hb_xRefCount( void * pMem ); /* return number of references */ +extern void * hb_xRefResize( void * pMem, ULONG ulSave, ULONG ulSize ); /* reallocates memory, create copy if reference counter greater then 1 */ + +#if 0 + +/* + * I used this macros only to test some speed overhead, + * They may not be supported in the future so please do + * not create any code which needs them. [druzus] + */ + +#define hb_xRefInc( p ) (++(*HB_COUNTER_PTR( p ))) +#define hb_xRefDec( p ) (--(*HB_COUNTER_PTR( p ))==0) +#define hb_xRefFree( p ) do { \ + if( hb_xRefDec( p ) ) \ + hb_xfree( (p) ); \ + } while( 0 ) + +#endif + +#endif + /* #if UINT_MAX == ULONG_MAX */ /* it fails on 64bit platforms where int has 32 bit and long has 64 bit. we need these functions only when max(size_t) < max(long) @@ -505,6 +536,32 @@ extern HB_EXPORT void * hb_xmemcpy( void * pDestArg, void * pSourceArg, ULONG ul extern HB_EXPORT void * hb_xmemset( void * pDestArg, int iFill, ULONG ulLen ); /* set more than memset() can */ #endif +/* garbage collector */ +#define HB_GARBAGE_FUNC( hbfunc ) void hbfunc( void * Cargo ) /* callback function for cleaning garbage memory pointer */ +typedef HB_GARBAGE_FUNC( HB_GARBAGE_FUNC_ ); +typedef HB_GARBAGE_FUNC_ * HB_GARBAGE_FUNC_PTR; + +extern PHB_ITEM hb_gcGripGet( HB_ITEM_PTR pItem ); +extern void hb_gcGripDrop( HB_ITEM_PTR pItem ); + +extern void * hb_gcAlloc( ULONG ulSize, HB_GARBAGE_FUNC_PTR pFunc ); /* allocates a memory controlled by the garbage collector */ +extern void hb_gcFree( void *pAlloc ); /* deallocates a memory allocated by the garbage collector */ +extern void * hb_gcLock( void *pAlloc ); /* do not release passed memory block */ +extern void * hb_gcUnlock( void *pAlloc ); /* passed block is allowed to be released */ +#ifdef _HB_API_INTERNAL_ +extern void hb_gcRefInc( void * pAlloc ); /* increment reference counter */ +extern BOOL hb_gcRefDec( void * pAlloc ); /* decrement reference counter, return TRUE when 0 reached */ +extern void hb_gcRefFree( void * pAlloc ); /* decrement reference counter and free the block when 0 reached */ +extern HB_COUNTER hb_gcRefCount( void * pAlloc ); /* return number of references */ +#endif +extern void hb_gcCollect( void ); /* checks if a single memory block can be released */ +extern void hb_gcCollectAll( void ); /* checks if all memory blocks can be released */ +extern void hb_gcReleaseAll( void ); /* release all memory blocks unconditionally */ +extern void hb_gcItemRef( HB_ITEM_PTR pItem ); /* checks if passed item refers passed memory block pointer */ +extern void hb_vmIsLocalRef( void ); /* hvm.c - mark all local variables as used */ +extern void hb_vmIsStaticRef( void ); /* hvm.c - mark all static variables as used */ +extern void hb_memvarsIsMemvarRef( void ); /* memvars.c - mark all memvar variables as used */ + /* array management */ extern HB_EXPORT BOOL hb_arrayNew( PHB_ITEM pItem, ULONG ulLen ); /* creates a new array */ extern HB_EXPORT ULONG hb_arrayLen( PHB_ITEM pArray ); /* retrieves the array len */ @@ -516,7 +573,6 @@ extern HB_EXPORT BOOL hb_arrayIns( PHB_ITEM pArray, ULONG ulIndex ); /* in extern HB_EXPORT BOOL hb_arrayDel( PHB_ITEM pArray, ULONG ulIndex ); /* delete an array item, without changing length */ extern HB_EXPORT BOOL hb_arraySize( PHB_ITEM pArray, ULONG ulLen ); /* sets the array total length */ extern HB_EXPORT BOOL hb_arrayLast( PHB_ITEM pArray, PHB_ITEM pResult ); /* retrieve last item in an array */ -extern HB_EXPORT BOOL hb_arrayRelease( PHB_ITEM pArray ); /* releases an array - don't call it - use ItemRelease() !!! */ extern HB_EXPORT BOOL hb_arraySet( PHB_ITEM pArray, ULONG ulIndex, PHB_ITEM pItem ); /* sets an array element */ extern HB_EXPORT BOOL hb_arrayGet( PHB_ITEM pArray, ULONG ulIndex, PHB_ITEM pItem ); /* retrieves an item */ /* hb_arrayGetItemPtr() is dangerous */ @@ -606,23 +662,6 @@ extern HB_EXPORT double hb_get_le_uint64( BYTE * ptr ); extern HB_EXPORT void hb_put_le_uint64( BYTE * ptr, double d ); #endif -/* class management */ -extern void hb_clsReleaseAll( void ); /* releases all defined classes */ -extern BOOL hb_clsIsParent( USHORT uiClass, char * szParentName ); /* is a class handle inherited from szParentName Class ? */ - -/* object management */ -extern char * hb_objGetClsName( PHB_ITEM pObject ); /* retrieves an object class name */ -extern char * hb_objGetRealClsName( PHB_ITEM pObject, char * szString ); /* retrieves an object class name for a specific message */ -extern PHB_FUNC hb_objGetMethod( PHB_ITEM pObject, PHB_SYMB pSymMsg ); /* returns the method pointer of a object class */ -extern BOOL hb_objHasMsg( PHB_ITEM pObject, char * szString ); /* returns TRUE/FALSE whether szString is an existing message for object */ -extern void hb_objSendMsg( PHB_ITEM pObj, char *sMsg, ULONG ulArg, ... ); -extern USHORT hb_objGetClass( PHB_ITEM pItem ); - -/* profiler for object management */ -extern void * hb_mthRequested( void ); /* profiler from classes.c */ -extern void hb_mthAddTime( void *, ULONG ); /* profiler from classes.c */ - - /* dynamic symbol table management */ extern HB_EXPORT PHB_DYNS hb_dynsymGet( char * szName ); /* finds and creates a dynamic symbol if not found */ extern HB_EXPORT PHB_DYNS hb_dynsymGetCase( char * szName ); /* finds and creates a dynamic symbol if not found - case sensitive */ @@ -659,9 +698,8 @@ extern HB_EXPORT BOOL hb_winmainArgGet( HANDLE * phInstance, HANDLE * phPrevInst /* Codeblock management */ extern HB_EXPORT void * hb_codeblockId( PHB_ITEM pItem ); /* retrieves the codeblock unique ID */ -extern HB_CODEBLOCK_PTR hb_codeblockNew( const BYTE * pBuffer, USHORT uiLocals, const BYTE * pLocalPosTable, PHB_SYMB pSymbols ); /* create a code-block */ +extern HB_CODEBLOCK_PTR hb_codeblockNew( const BYTE * pBuffer, USHORT uiLocals, const BYTE * pLocalPosTable, PHB_SYMB pSymbols, USHORT usLen ); /* create a code-block */ extern HB_CODEBLOCK_PTR hb_codeblockMacroNew( BYTE * pBuffer, USHORT usLen ); -extern void hb_codeblockDelete( HB_ITEM_PTR pItem ); /* delete a codeblock */ extern PHB_ITEM hb_codeblockGetVar( PHB_ITEM pItem, LONG iItemPos ); /* get local variable referenced in a codeblock */ extern PHB_ITEM hb_codeblockGetRef( HB_CODEBLOCK_PTR pCBlock, PHB_ITEM pRefer ); /* get local variable passed by reference */ extern void hb_codeblockEvaluate( HB_ITEM_PTR pItem ); /* evaluate a codeblock */ @@ -673,7 +711,6 @@ extern void hb_memvarsRelease( void ); /* clear all PUBLIC and PRIVATE var extern void hb_memvarsFree( void ); /* release the memvar API system */ extern void hb_memvarValueIncRef( HB_HANDLE hValue ); /* increase the reference count of a global value */ extern void hb_memvarValueDecRef( HB_HANDLE hValue ); /* decrease the reference count of a global value */ -extern void hb_memvarValueDecGarbageRef( HB_HANDLE hValue ); /* decrease the reference count of a detached local variable */ extern void hb_memvarSetValue( PHB_SYMB pMemvarSymb, HB_ITEM_PTR pItem ); /* copy an item into a symbol */ extern ERRCODE hb_memvarGet( HB_ITEM_PTR pItem, PHB_SYMB pMemvarSymb ); /* copy an symbol value into an item */ extern void hb_memvarGetValue( HB_ITEM_PTR pItem, PHB_SYMB pMemvarSymb ); /* copy an symbol value into an item, with error trapping */ @@ -685,6 +722,9 @@ extern char * hb_memvarGetStrValuePtr( char * szVarName, ULONG *pulLen ); extern void hb_memvarCreateFromItem( PHB_ITEM pMemvar, BYTE bScope, PHB_ITEM pValue ); extern int hb_memvarScope( char * szVarName, ULONG ulLength ); /* retrieve scope of a dynamic variable symbol */ extern PHB_ITEM hb_memvarDetachLocal( HB_ITEM_PTR pLocal ); /* Detach a local variable from the eval stack */ +#ifdef _HB_API_INTERNAL_ +extern PHB_ITEM hb_memvarGetItem( PHB_SYMB pMemvarSymb ); +#endif /* console I/O subsystem */ extern void hb_conInit( void ); /* initialize the console API system */ @@ -753,29 +793,6 @@ extern void hb_macroPushAliasedValue( HB_ITEM_PTR pAlias, HB_ITEM_PTR pVar, BY extern char * hb_macroGetType( HB_ITEM_PTR pItem ); /* determine the type of an expression */ extern char * hb_macroExpandString( char *szString, ULONG ulLength, BOOL *pbNewString ); /* expands valid '&' operator */ -/* garbage collector */ -#define HB_GARBAGE_FUNC( hbfunc ) void hbfunc( void * Cargo ) /* callback function for cleaning garbage memory pointer */ -typedef HB_GARBAGE_FUNC( HB_GARBAGE_FUNC_ ); -typedef HB_GARBAGE_FUNC_ * HB_GARBAGE_FUNC_PTR; - -extern HB_ITEM_PTR hb_gcGripGet( HB_ITEM_PTR pItem ); -extern void hb_gcGripDrop( HB_ITEM_PTR pItem ); - -extern void * hb_gcAlloc( ULONG ulSize, HB_GARBAGE_FUNC_PTR pFunc ); /* allocates a memory controlled by the garbage collector */ -extern void hb_gcFree( void *pAlloc ); /* deallocates a memory allocated by the garbage collector */ -extern void * hb_gcLock( void *pAlloc ); /* do not release passed memory block */ -extern void * hb_gcUnlock( void *pAlloc ); /* passed block is allowed to be released */ -extern void hb_gcCollect( void ); /* checks if a single memory block can be released */ -extern void hb_gcCollectAll( void ); /* checks if all memory blocks can be released */ -extern void hb_gcReleaseAll( void ); /* release all memory blocks unconditionally */ -extern void hb_gcItemRef( HB_ITEM_PTR pItem ); /* checks if passed item refers passed memory block pointer */ -extern void hb_vmIsLocalRef( void ); /* hvm.c - mark all local variables as used */ -extern void hb_vmIsStaticRef( void ); /* hvm.c - mark all static variables as used */ -extern void hb_memvarsIsMemvarRef( void ); /* memvars.c - mark all memvar variables as used */ -extern void hb_clsIsClassRef( void ); /* classes.c - mark all class internals as used */ -extern HB_GARBAGE_FUNC( hb_codeblockDeleteGarbage ); /* clear a codeblock before releasing by the GC */ -extern HB_GARBAGE_FUNC( hb_arrayReleaseGarbage ); /* clear an array before releasing by the GC */ - /* idle states */ extern void hb_releaseCPU( void ); extern void hb_idleState( void ); /* services a single idle state */ diff --git a/harbour/include/hbapicdp.h b/harbour/include/hbapicdp.h index 28b9339f2e..ad3dd7d306 100644 --- a/harbour/include/hbapicdp.h +++ b/harbour/include/hbapicdp.h @@ -70,7 +70,7 @@ HB_EXTERN_BEGIN } #define HB_CODEPAGE_ANNOUNCE( id ) HB_FUNC( HB_CODEPAGE_##id ) {} -#define HB_CODEPAGE_INIT( id ) HB_CODEPAGE_ANNOUNCE( id ); \ +#define HB_CODEPAGE_INIT( id ) HB_CODEPAGE_ANNOUNCE( id ) \ HB_CALL_ON_STARTUP_BEGIN( hb_codepage_Init_##id ) \ hb_cdpRegister( &s_codepage ); \ HB_CALL_ON_STARTUP_END( hb_codepage_Init_##id ) diff --git a/harbour/include/hbapicls.h b/harbour/include/hbapicls.h new file mode 100644 index 0000000000..c8a010089e --- /dev/null +++ b/harbour/include/hbapicls.h @@ -0,0 +1,117 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * Harbour class API + * + * Copyright 2006 Przemyslaw Czerpak + * www - http://www.harbour-project.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +#ifndef HB_APICLS_H_ +#define HB_APICLS_H_ + +#include "hbapi.h" + +HB_EXTERN_BEGIN + +#define HB_OO_OP_PLUS 0 +#define HB_OO_OP_MINUS 1 +#define HB_OO_OP_MULT 2 +#define HB_OO_OP_DIVIDE 3 +#define HB_OO_OP_MOD 4 +#define HB_OO_OP_POWER 5 +#define HB_OO_OP_INC 6 +#define HB_OO_OP_DEC 7 +#define HB_OO_OP_EQUAL 8 +#define HB_OO_OP_EXACTEQUAL 9 +#define HB_OO_OP_NOTEQUAL 10 +#define HB_OO_OP_LESS 11 +#define HB_OO_OP_LESSEQUAL 12 +#define HB_OO_OP_GREATER 13 +#define HB_OO_OP_GREATEREQUAL 14 +#define HB_OO_OP_ASSIGN 15 +#define HB_OO_OP_INSTRING 16 +#define HB_OO_OP_NOT 17 +#define HB_OO_OP_AND 18 +#define HB_OO_OP_OR 19 +#define HB_OO_OP_ARRAYINDEX 20 +#define HB_OO_OP_ENUMNEXT 21 +#define HB_OO_OP_ENUMPREV 22 +#define HB_OO_OP_ENUMINDEX 23 +#define HB_OO_OP_ENUMBASE 24 +#define HB_OO_OP_ENUMVALUE 25 + +#define HB_OO_MAX_OPERATOR 25 + +/* class management */ +extern void hb_clsInit( void ); /* initialize Classy/OO system at HVM startup */ +extern void hb_clsReleaseAll( void ); /* releases all defined classes */ +extern void hb_clsIsClassRef( void ); /* classes.c - mark all class internals as used */ +/* has this function to be public? */ +extern BOOL hb_clsIsParent( USHORT uiClass, char * szParentName ); /* is a class handle inherited from szParentName Class ? */ + +/* object management */ +extern BOOL hb_objHasOperator( PHB_ITEM pObject, USHORT uiOperator ); +extern BOOL hb_objOperatorCall( USHORT uiOperator, HB_ITEM_PTR pResult, PHB_ITEM pObject, PHB_ITEM pMsgArg ); + +extern USHORT hb_objGetClass( PHB_ITEM pItem ); /* get object class handle */ +extern char * hb_objGetClsName( PHB_ITEM pObject ); /* retrieves an object class name */ +extern char * hb_objGetRealClsName( PHB_ITEM pObject, char * szString ); /* retrieves an object class name for a specific message */ +extern PHB_SYMB hb_objGetMethod( PHB_ITEM pObject, PHB_SYMB pSymMsg, BOOL * pfPopSuper ); /* returns the method pointer of an object class */ +extern void hb_objPopSuperCast( PHB_ITEM pObject ); /* clean super casting if necessary */ +extern BOOL hb_objHasMsg( PHB_ITEM pObject, char * szString ); /* returns TRUE/FALSE whether szString is an existing message for object */ +extern void hb_objSendMsg( PHB_ITEM pObj, char *sMsg, ULONG ulArg, ... ); + +#ifndef HB_NO_PROFILER +/* profiler for object management */ +extern BOOL hb_bProfiler; /* profiler activity status */ +extern void * hb_mthRequested( void ); /* profiler from classes.c */ +extern void hb_mthAddTime( void *, ULONG ); /* profiler from classes.c */ +#endif + +HB_EXTERN_END + +#endif /* HB_APICLS_H_ */ diff --git a/harbour/include/hbapiitm.h b/harbour/include/hbapiitm.h index f20e646995..5482f0a28a 100644 --- a/harbour/include/hbapiitm.h +++ b/harbour/include/hbapiitm.h @@ -134,13 +134,14 @@ extern HB_EXPORT PHB_ITEM hb_itemPutNLLLen( PHB_ITEM pItem, LONGLONG lNumber, extern HB_EXPORT PHB_ITEM hb_itemParamPtr ( USHORT uiParam, long lMask ); extern HB_EXPORT int hb_itemStrCmp ( PHB_ITEM pFirst, PHB_ITEM pSecond, BOOL bForceExact ); /* our string compare */ extern HB_EXPORT void hb_itemCopy ( PHB_ITEM pDest, PHB_ITEM pSource ); /* copies an item to one place to another respecting its containts */ -extern HB_EXPORT void hb_itemForwardValue( PHB_ITEM pDest, PHB_ITEM pSource ); /* copies the value of an item without incrementing of reference counters */ -extern HB_EXPORT void hb_itemMove ( PHB_ITEM pDest, PHB_ITEM pSource ); +extern HB_EXPORT void hb_itemMove ( PHB_ITEM pDest, PHB_ITEM pSource ); /* moves the value of an item without incrementing of reference counters, source is cleared */ extern HB_EXPORT void hb_itemClear ( PHB_ITEM pItem ); extern HB_EXPORT PHB_ITEM hb_itemUnRef ( PHB_ITEM pItem ); /* de-references passed variable */ extern HB_EXPORT PHB_ITEM hb_itemUnRefOnce( PHB_ITEM pItem ); /* de-references passed variable, one step*/ extern HB_EXPORT PHB_ITEM hb_itemUnRefRefer( PHB_ITEM pItem ); /* de-references passed variable, leaving the last reference */ extern HB_EXPORT PHB_ITEM hb_itemUnShare ( PHB_ITEM pItem ); /* un-share given string item */ +extern HB_EXPORT PHB_ITEM hb_itemUnShareString( PHB_ITEM pItem ); /* un-share given string item - the pItem have to be valid unrefed string item */ +extern HB_EXPORT PHB_ITEM hb_itemReSizeString( PHB_ITEM pItem, ULONG ulSize ); /* Resize string buffer of given string item - the pItem have to be valid unrefed string item */ extern HB_EXPORT PHB_ITEM hb_itemClone ( PHB_ITEM pItem ); /* clone the given item */ extern HB_EXPORT char * hb_itemStr ( PHB_ITEM pNumber, PHB_ITEM pWidth, PHB_ITEM pDec ); /* convert a number to a string */ extern HB_EXPORT char * hb_itemString ( PHB_ITEM pItem, ULONG * ulLen, BOOL * bFreeReq ); /* Convert any scalar to a string */ @@ -149,6 +150,35 @@ extern HB_EXPORT PHB_ITEM hb_itemValToStr ( PHB_ITEM pItem ); /* Convert any s extern HB_EXPORT char * hb_itemPadConv ( PHB_ITEM pItem, ULONG * pulSize, BOOL * bFreeReq ); extern HB_EXPORT void hb_itemSwap ( PHB_ITEM pItem1, PHB_ITEM pItem2 ); +#if defined( _HB_API_INTERNAL_ ) + +# define hb_itemSetNil( item ) do { \ + if( HB_IS_COMPLEX( item ) ) \ + hb_itemClear( item ); \ + else \ + (item)->type = HB_IT_NIL; \ + } while( 0 ) + +#if 0 +# define hb_itemRawMove( dst, src ) do { \ + memcpy( (dst), (src), sizeof( HB_ITEM ) ); \ + (src)->type = HB_IT_NIL; \ + } while( 0 ) +#else +# define hb_itemRawMove( dst, src ) hb_itemMove( (dst), (src) ) +#endif + +#else + +# define hb_itemSetNil( item ) hb_itemClear( (item) ) + +# define hb_itemRawMove( dst, src ) hb_itemMove( (dst), (src) ) + +#endif + +/* xHarbour compatible function */ +#define hb_itemForwardValue( dst, src ) hb_itemMove( (dst), (src) ) + HB_EXTERN_END #endif /* HB_APIITM_H_ */ diff --git a/harbour/include/hbdefs.h b/harbour/include/hbdefs.h index 70b9423439..4ee7853db5 100644 --- a/harbour/include/hbdefs.h +++ b/harbour/include/hbdefs.h @@ -404,18 +404,22 @@ # define HB_LL( num ) num##LL #endif -#if HB_LONG_MAX > HB_LL( 10000000000 ) -# define HB_LONG_LENGTH( l ) ( ( (l) <= -1000000000 || (l) >= HB_LL( 10000000000 ) ) ? 20 : 10 ) -#else -# define HB_LONG_LENGTH( l ) ( ( (l) <= -1000000000 ) ? 20 : 10 ) -#endif - #if HB_INT_MIN <= -1000000000 # define HB_INT_LENGTH( i ) ( ( (i) <= -1000000000 ) ? 20 : 10 ) #else # define HB_INT_LENGTH( i ) 10 #endif +#if !defined( HB_LONG_LONG_OFF ) +# if HB_LONG_MAX > HB_LL( 10000000000 ) +# define HB_LONG_LENGTH( l ) ( ( (l) <= -1000000000 || (l) >= HB_LL( 10000000000 ) ) ? 20 : 10 ) +# endif +#endif + +#if !defined HB_LONG_LENGTH +# define HB_LONG_LENGTH( l ) ( ( (l) <= -1000000000 ) ? 20 : 10 ) +#endif + /* NOTE: Yes, -999999999.0 is right instead of -1000000000.0 [vszakats] */ /* This comment is from hb_vmNeg() - if it's true only in this case then the limit should be changed and this function fixed */ @@ -433,6 +437,11 @@ typedef UINT32 HB_TYPE; /* type of reference counter */ typedef unsigned long HB_COUNTER; +#if ULONG_MAX <= UINT32_MAX +# define HB_COUNTER_SIZE 4 +#else +# define HB_COUNTER_SIZE 8 +#endif /* type for memory pointer diff */ #if defined( _WIN64 ) @@ -584,11 +593,22 @@ typedef unsigned long HB_COUNTER; # if !defined( HB_STRICT_ALIGNMENT ) # define HB_STRICT_ALIGNMENT # endif +#endif + +#if defined( HB_STRICT_ALIGNMENT ) # if !defined( HB_ALLOC_ALIGNMENT ) || ( HB_ALLOC_ALIGNMENT + 1 == 1 ) # define HB_ALLOC_ALIGNMENT 8 # endif #endif +#if defined( HB_ALLOC_ALIGNMENT ) && HB_COUNTER_SIZE < HB_ALLOC_ALIGNMENT + 0 +# define HB_COUNTER_OFFSET HB_ALLOC_ALIGNMENT +#else +# define HB_COUNTER_OFFSET HB_COUNTER_SIZE +#endif + +#define HB_COUNTER_PTR( p ) ((HB_COUNTER*) ((BYTE *) (p)-HB_COUNTER_OFFSET)) + /* * These macros are necessary for architectures which need * strict alignment for pointers. @@ -601,6 +621,8 @@ typedef unsigned long HB_COUNTER; # define HB_PUT_LONG( p, v ) HB_PUT_BE_UINT32( p, ( UINT32 ) ( v ) ) # define HB_GET_LONG( p ) HB_GET_BE_UINT32( p ) # endif +# define HB_PUT_UINT32( p, v ) HB_PUT_BE_UINT32( p, ( UINT32 ) ( v ) ) +# define HB_GET_UINT32( p ) HB_GET_BE_UINT32( p ) #else # if defined( HB_ARCH_64BIT ) # define HB_PUT_LONG( p, v ) HB_PUT_LE_UINT64( p, ( UINT64 ) ( v ) ) @@ -609,6 +631,8 @@ typedef unsigned long HB_COUNTER; # define HB_PUT_LONG( p, v ) HB_PUT_LE_UINT32( p, ( UINT32 ) ( v ) ) # define HB_GET_LONG( p ) HB_GET_LE_UINT32( p ) # endif +# define HB_PUT_UINT32( p, v ) HB_PUT_LE_UINT32( p, ( UINT32 ) ( v ) ) +# define HB_GET_UINT32( p ) HB_GET_LE_UINT32( p ) #endif #if !defined( HB_STRICT_ALIGNMENT ) diff --git a/harbour/include/hbexprb.c b/harbour/include/hbexprb.c index 8eefebd9b1..8ed6b17597 100644 --- a/harbour/include/hbexprb.c +++ b/harbour/include/hbexprb.c @@ -1285,14 +1285,14 @@ static HB_EXPR_FUNC( hb_compExprUseArrayAt ) { BOOL bRemoveRef = FALSE; /* #ifndef HB_C52_STRICT */ - if( HB_SUPPORT_ARRSTR ) - /* to manage strings as bytes arrays, they must be pushed by reference */ - /* arrays also are passed by reference */ - if( pSelf->value.asList.pExprList->ExprType == HB_ET_VARIABLE ) - { - pSelf->value.asList.pExprList->ExprType = HB_ET_VARREF; - bRemoveRef = TRUE; - } + if( HB_SUPPORT_ARRSTR ) + /* to manage strings as bytes arrays, they must be pushed by reference */ + /* arrays also are passed by reference */ + if( pSelf->value.asList.pExprList->ExprType == HB_ET_VARIABLE ) + { + pSelf->value.asList.pExprList->ExprType = HB_ET_VARREF; + bRemoveRef = TRUE; + } /* #endif */ HB_EXPR_USE( pSelf->value.asList.pExprList, HB_EA_PUSH_PCODE ); @@ -1300,11 +1300,11 @@ static HB_EXPR_FUNC( hb_compExprUseArrayAt ) HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_ARRAYPOP ); /* #ifndef HB_C52_STRICT */ - if( HB_SUPPORT_ARRSTR ) - if( bRemoveRef ) - { - pSelf->value.asList.pExprList->ExprType = HB_ET_VARIABLE; - } + if( HB_SUPPORT_ARRSTR ) + if( bRemoveRef ) + { + pSelf->value.asList.pExprList->ExprType = HB_ET_VARIABLE; + } /* #endif */ } @@ -3356,6 +3356,7 @@ static HB_EXPR_FUNC( hb_compExprUsePlus ) case HB_EA_LVALUE: hb_compErrorLValue( pSelf ); break; + case HB_EA_PUSH_PCODE: { HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); diff --git a/harbour/include/hbinit.h b/harbour/include/hbinit.h index 84fd3e5193..b0c942d666 100644 --- a/harbour/include/hbinit.h +++ b/harbour/include/hbinit.h @@ -57,7 +57,8 @@ HB_EXTERN_BEGIN -extern HB_EXPORT void hb_vmProcessSymbols( PHB_SYMB pSymbols, USHORT uiSymbols ); /* statics symbols initialization */ +extern HB_EXPORT PHB_SYMB hb_vmProcessSymbols( PHB_SYMB pSymbols, USHORT uiSymbols ); /* old module symbols initialization */ +extern HB_EXPORT PHB_SYMB hb_vmProcessSymbolsExt( PHB_SYMB pSymbols, USHORT uiSymbols, char * szModuleName, ULONG ulID, USHORT uiPcodeMin, USHORT uiPcodeMax ); /* module symbols initialization with extended information */ #if defined(_MSC_VER) && !defined(_WIN64) && \ !defined(__LCC__) && !defined(__POCC__) && !defined(__XCC__) && \ @@ -87,13 +88,14 @@ extern HB_EXPORT void hb_vmProcessSymbols( PHB_SYMB pSymbols, USHORT uiSymbols ) #if defined(HARBOUR_STRICT_ANSI_C) #define HB_INIT_SYMBOLS_BEGIN( func ) \ - static HB_SYMB symbols[] = { + static HB_SYMB symbols_table[] = { #define HB_INIT_SYMBOLS_END( func ) \ }; \ + static PHB_SYMB symbols = symbols_table; \ void func( void ) \ { \ - hb_vmProcessSymbols( symbols, (USHORT) ( sizeof( symbols ) / sizeof( HB_SYMB ) ) ); \ + symbols = hb_vmProcessSymbols( symbols_table, (USHORT) ( sizeof( symbols_table ) / sizeof( HB_SYMB ) ) ); \ } #define HB_CALL_ON_STARTUP_BEGIN( func ) \ @@ -110,13 +112,14 @@ extern HB_EXPORT void hb_vmProcessSymbols( PHB_SYMB pSymbols, USHORT uiSymbols ) #endif #define HB_INIT_SYMBOLS_BEGIN( func ) \ - static HB_SYMB symbols[] = { + static HB_SYMB symbols_table[] = { #define HB_INIT_SYMBOLS_END( func ) \ }; \ + static PHB_SYMB symbols = symbols_table; \ static void __attribute__ ((constructor)) func( void ) \ { \ - hb_vmProcessSymbols( symbols, (USHORT) ( sizeof( symbols ) / sizeof( HB_SYMB ) ) ); \ + symbols = hb_vmProcessSymbols( symbols_table, (USHORT) ( sizeof( symbols_table ) / sizeof( HB_SYMB ) ) ); \ } #define HB_CALL_ON_STARTUP_BEGIN( func ) \ @@ -131,13 +134,14 @@ extern HB_EXPORT void hb_vmProcessSymbols( PHB_SYMB pSymbols, USHORT uiSymbols ) typedef int (* HB_$INITSYM)( void ); #define HB_INIT_SYMBOLS_BEGIN( func ) \ - static HB_SYMB symbols[] = { + static HB_SYMB symbols_table[] = { #define HB_INIT_SYMBOLS_END( func ) \ }; \ + static PHB_SYMB symbols = symbols_table; \ static int func( void ) \ { \ - hb_vmProcessSymbols( symbols, (USHORT) ( sizeof( symbols ) / sizeof( HB_SYMB ) ) ); \ + symbols = hb_vmProcessSymbols( symbols_table, (USHORT) ( sizeof( symbols_table ) / sizeof( HB_SYMB ) ) ); \ return 0; \ } @@ -160,21 +164,11 @@ extern HB_EXPORT void hb_vmProcessSymbols( PHB_SYMB pSymbols, USHORT uiSymbols ) #endif #define HB_INIT_SYMBOLS_BEGIN( func ) \ - static HB_SYMB symbols[] = { + static HB_SYMB symbols_table[] = { - /* this allows any macros to be preprocessed first - so that token pasting is handled correctly */ #define HB_INIT_SYMBOLS_END( func ) \ - _HB_INIT_SYMBOLS_END( func ) - - #define _HB_INIT_SYMBOLS_END( func ) \ }; \ - static int func( void ) \ - { \ - hb_vmProcessSymbols( symbols, (USHORT) ( sizeof( symbols ) / sizeof( HB_SYMB ) ) ); \ - return 0; \ - } \ - static int hb_vm_auto_##func = func(); + static PHB_SYMB symbols = hb_vmProcessSymbols( symbols_table, (USHORT) ( sizeof( symbols_table ) / sizeof( HB_SYMB ) ) ); \ #define HB_CALL_ON_STARTUP_BEGIN( func ) \ static int func( void ) \ @@ -202,13 +196,14 @@ extern HB_EXPORT void hb_vmProcessSymbols( PHB_SYMB pSymbols, USHORT uiSymbols ) #endif #define HB_INIT_SYMBOLS_BEGIN( func ) \ - static HB_SYMB symbols[] = { + static HB_SYMB symbols_table[] = { #define HB_INIT_SYMBOLS_END( func ) \ }; \ + static PHB_SYMB symbols = symbols_table; \ static void func( void ) \ { \ - hb_vmProcessSymbols( symbols, (USHORT) ( sizeof( symbols ) / sizeof( HB_SYMB ) ) ); \ + symbols = hb_vmProcessSymbols( symbols_table, (USHORT) ( sizeof( symbols_table ) / sizeof( HB_SYMB ) ) ); \ } #define HB_CALL_ON_STARTUP_BEGIN( func ) \ diff --git a/harbour/include/hbsetup.h b/harbour/include/hbsetup.h index 14d8182d96..7023db53c8 100644 --- a/harbour/include/hbsetup.h +++ b/harbour/include/hbsetup.h @@ -125,6 +125,16 @@ #define HB_FM_STATISTICS #endif + +/* *********************************************************************** + * Enable profiler support in HVM + * By default this is turned off. Define HB_USE_PROFILER to turn it on. + */ + +#ifndef HB_USE_PROFILER + #define HB_NO_PROFILER +#endif + /* *********************************************************************** * Use native Windows memory allocation functions (HB_OS_WIN_32) * This option can disabled compiler memory allocation optimization @@ -207,7 +217,16 @@ * Using this option makes sorting *much* faster, but if you have a * problem, or the low level stuff changes, turn it off. [vszakats] */ -#define HB_ASORT_OPT_ITEMCOPY +/* + * It's not longer used - current code which uses hb_itemSwap() should + * give similar performance (probably a little bit worser due to some small + * function call overhead) but it's ready for automatic GC activation and + * I'd like to keep it. + * If the current performance is not enough then I can change sorting + * algorithm used inside ASORT and with cost of some additional memory + * improve the speed but it's not my priority now. [druzus] + */ +/* #define HB_ASORT_OPT_ITEMCOPY */ /* *********************************************************************** * You can select here faster but less secure behaviour of STOD() function diff --git a/harbour/include/hbstack.h b/harbour/include/hbstack.h index 25d721d6db..c6192f4021 100644 --- a/harbour/include/hbstack.h +++ b/harbour/include/hbstack.h @@ -97,7 +97,7 @@ typedef struct #define hb_stackTopItem( ) ( * hb_stack.pPos ) #define hb_stackBaseItem( ) ( * hb_stack.pBase ) #define hb_stackSelfItem( ) ( * ( hb_stack.pBase + 1 ) ) -#define hb_stackItem( iItemPos ) ( * ( hb_stack.pItems + iItemPos ) ) +#define hb_stackItem( iItemPos ) ( * ( hb_stack.pItems + ( iItemPos ) ) ) #define hb_stackReturnItem( ) ( &hb_stack.Return ) @@ -117,11 +117,27 @@ typedef struct if( HB_IS_COMPLEX( * hb_stack.pPos ) ) \ hb_itemClear( * hb_stack.pPos ); \ } while ( 0 ) + #define hb_stackPush( ) do { \ if( ++hb_stack.pPos == hb_stack.pEnd ) \ hb_stackIncrease(); \ ( * hb_stack.pPos )->type = HB_IT_NIL; \ } while ( 0 ) + +#define hb_stackPopReturn( ) do { \ + if( HB_IS_COMPLEX( &hb_stack.Return ) ) \ + hb_itemClear( &hb_stack.Return ); \ + if( --hb_stack.pPos < hb_stack.pItems ) \ + hb_errInternal( HB_EI_STACKUFLOW, NULL, NULL, NULL ); \ + hb_itemRawMove( &hb_stack.Return, * hb_stack.pPos ); \ + } while ( 0 ) + +#define hb_stackPushReturn( ) do { \ + hb_itemRawMove( * hb_stack.pPos, &hb_stack.Return ); \ + if( ++hb_stack.pPos == hb_stack.pEnd ) \ + hb_stackIncrease(); \ + ( * hb_stack.pPos )->type = HB_IT_NIL; \ + } while ( 0 ) #else extern HB_ITEM_PTR hb_stackItemFromTop( int nFromTop ); diff --git a/harbour/include/hbtypes.h b/harbour/include/hbtypes.h index 2030ac7873..3724539332 100644 --- a/harbour/include/hbtypes.h +++ b/harbour/include/hbtypes.h @@ -60,8 +60,12 @@ #include "hbvm.h" #include "hbapiitm.h" -typedef void ( * VM_PROCESS_DLL_SYMBOLS ) ( PHB_SYMB pModuleSymbols, - USHORT uiModuleSymbols ); +typedef PHB_SYMB ( * VM_PROCESS_DLL_SYMBOLS ) ( PHB_SYMB pModuleSymbols, + USHORT uiModuleSymbols ); +typedef PHB_SYMB ( * VM_PROCESS_SYMBOLS_EXT ) + ( PHB_SYMB pModuleSymbols, USHORT uiModuleSymbols, + char * szModuleName, ULONG ulID, + USHORT uiPcodeMin, USHORT uiPcodeMax ); typedef void ( * VM_DLL_EXECUTE ) ( const BYTE * pCode, PHB_SYMB pSymbols ); @@ -126,7 +130,6 @@ typedef BOOL ( * HB_ARRAYINS)( PHB_ITEM pArray, ULONG ulIndex ); typedef BOOL ( * HB_ARRAYDEL)( PHB_ITEM pArray, ULONG ulIndex ); typedef BOOL ( * HB_ARRAYSIZE)( PHB_ITEM pArray, ULONG ulLen ); typedef BOOL ( * HB_ARRAYLAST)( PHB_ITEM pArray, PHB_ITEM pResult ); -typedef BOOL ( * HB_ARRAYRELEASE)( PHB_ITEM pArray ); typedef BOOL ( * HB_ARRAYSET)( PHB_ITEM pArray, ULONG ulIndex, PHB_ITEM pItem ); typedef BOOL ( * HB_ARRAYGET)( PHB_ITEM pArray, ULONG ulIndex, PHB_ITEM pItem ); typedef void ( * HB_XINIT)( void ); /* Initialize fixed memory subsystem */ diff --git a/harbour/include/hbver.h b/harbour/include/hbver.h index 8b28643d08..e520100e8b 100644 --- a/harbour/include/hbver.h +++ b/harbour/include/hbver.h @@ -63,7 +63,7 @@ #define HB_VER_MAJOR 0 /* Major version number */ #define HB_VER_MINOR 46 /* Minor version number */ -#define HB_VER_REVISION 1 /* Revision number */ +#define HB_VER_REVISION 2 /* Revision number */ /* NOTE: The next two fields are automatically updated by the hbverfix program */ diff --git a/harbour/include/hbvm.h b/harbour/include/hbvm.h index d437be46de..93db7ee66e 100644 --- a/harbour/include/hbvm.h +++ b/harbour/include/hbvm.h @@ -69,8 +69,31 @@ extern HB_EXPORT void hb_vmAtExit( HB_INIT_FUNC pFunc, void * cargo ); /* Harbour virtual machine functions */ extern HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ); /* invokes the virtual machine */ -extern HB_EXPORT void hb_vmProcessSymbols( PHB_SYMB pSymbols, USHORT uiSymbols ); /* statics symbols initialization */ - +extern HB_EXPORT PHB_SYMB hb_vmProcessSymbols( PHB_SYMB pSymbols, USHORT uiSymbols ); /* old module symbols initialization */ +extern HB_EXPORT PHB_SYMB hb_vmProcessSymbolsExt( PHB_SYMB pSymbols, USHORT uiSymbols, char * szModuleName, ULONG ulID, USHORT uiPcodeMin, USHORT uiPcodeMax ); /* module symbols initialization with extended information */ + +#ifdef _HB_API_INTERNAL_ + typedef struct _HB_SYMBOLS + { + PHB_SYMB pModuleSymbols; /* pointer to module symbol table */ + USHORT uiModuleSymbols; /* number of symbols on that table */ + struct _HB_SYMBOLS * pNext; /* pointer to the next SYMBOLS structure */ + HB_SYMBOLSCOPE hScope; /* scope collected from all symbols in module used to speed initialization code */ + void * hDynLib; /* handler to dynamic library */ + BOOL fAllocated; /* the symbol table is dynamically allocated and should be freed on HVM exit */ + BOOL fActive; /* the symbol table is currently active */ + BOOL fInitStatics; /* static initialization should be executed */ + char * szModuleName; /* module name */ + ULONG ulID; /* module unique identifier */ + } HB_SYMBOLS, * PHB_SYMBOLS; /* structure to keep track of all modules symbol tables */ + + extern PHB_SYMBOLS hb_vmRegisterSymbols( PHB_SYMB pModuleSymbols, USHORT uiSymbols, char * szModuleName, ULONG ulID, BOOL fDynLib, BOOL fClone ); + extern void hb_vmFreeSymbols( PHB_SYMBOLS pSymbols ); + extern void hb_vmBeginSymbolGroup( void * hDynLib, BOOL fClone ); + extern void hb_vmInitSymbolGroup( void * hNewDynLib, int argc, char * argv[] ); + extern void hb_vmExitSymbolGroup( void * hDynLib ); +#endif + extern HB_EXPORT void hb_vmSymbolInit_RT( void ); /* initialization of runtime support symbols */ /* Harbour virtual machine escaping API */ @@ -90,7 +113,7 @@ extern HB_EXPORT void hb_vmRequestQuit( void ); /* Execution */ extern HB_EXPORT void hb_vmDo( USHORT uiParams ); /* invoke the virtual machine */ -extern HB_EXPORT void hb_vmFunction( USHORT uiParams ); /* executes a function saving its result */ +extern HB_EXPORT void hb_vmFunction( USHORT uiParams ); /* executes a function */ extern HB_EXPORT void hb_vmSend( USHORT uiParams ); /* sends a message to an object */ extern HB_EXPORT PHB_ITEM hb_vmEvalBlock( PHB_ITEM pBlockItem ); /* executes passed codeblock with no arguments */ /* executes passed codeblock with variable number of arguments */ diff --git a/harbour/include/hbvmpub.h b/harbour/include/hbvmpub.h index cdc38a0c13..7965e0c585 100644 --- a/harbour/include/hbvmpub.h +++ b/harbour/include/hbvmpub.h @@ -94,14 +94,22 @@ struct _HB_SYMB; typedef struct _HB_DYNS { struct _HB_SYMB * pSymbol; /* pointer to its relative local symbol */ - PHB_FUNC pFunPtr; /* Pointer to the function address */ HB_HANDLE hArea; /* Workarea number */ HB_HANDLE hMemvar; /* Index number into memvars ( publics & privates ) array */ +#ifndef HB_NO_PROFILER ULONG ulCalls; /* profiler support */ ULONG ulTime; /* profiler support */ ULONG ulRecurse; /* profiler support */ +#endif } HB_DYNS, * PHB_DYNS, * HB_DYNS_PTR; + /* pCode dynamic function - HRB */ + typedef struct _HB_PCODEFUNC + { + BYTE * pCode; /* function body - PCODE */ + struct _HB_SYMB * pSymbols;/* module symbol table */ + } HB_PCODEFUNC, * PHB_PCODEFUNC; + #else # undef HB_API_MACROS @@ -119,6 +127,7 @@ struct _HB_SYMB; typedef void * PHB_ITEM; typedef void * HB_ITEM_PTR; typedef void * HB_CODEBLOCK_PTR; + typedef void * PHB_PCODEFUNC; typedef void HB_STACK; @@ -154,7 +163,8 @@ typedef struct _HB_SYMB } scope; union { - PHB_FUNC pFunPtr; /* function address for function symbol table entries */ + PHB_FUNC pFunPtr; /* machine code function address for function symbol table entries */ + PHB_PCODEFUNC pCodeFunc; /* PCODE function address */ int iStaticsBase; /* base offset to array of statics */ } value; PHB_DYNS pDynSym; /* pointer to its dynamic symbol if defined */ @@ -173,14 +183,18 @@ typedef struct _HB_FUNC_LIST } HB_FUNC_LIST, * PHB_FUNC_LIST; /* Harbour Functions scope ( HB_SYMBOLSCOPE ) */ -#define HB_FS_PUBLIC ( ( HB_SYMBOLSCOPE ) 0x01 ) -#define HB_FS_STATIC ( ( HB_SYMBOLSCOPE ) 0x02 ) -#define HB_FS_FIRST ( ( HB_SYMBOLSCOPE ) 0x04 ) -#define HB_FS_INIT ( ( HB_SYMBOLSCOPE ) 0x08 ) -#define HB_FS_EXIT ( ( HB_SYMBOLSCOPE ) 0x10 ) +#define HB_FS_PUBLIC ( ( HB_SYMBOLSCOPE ) 0x0001 ) +#define HB_FS_STATIC ( ( HB_SYMBOLSCOPE ) 0x0002 ) +#define HB_FS_FIRST ( ( HB_SYMBOLSCOPE ) 0x0004 ) +#define HB_FS_INIT ( ( HB_SYMBOLSCOPE ) 0x0008 ) +#define HB_FS_EXIT ( ( HB_SYMBOLSCOPE ) 0x0010 ) +#define HB_FS_MESSAGE ( ( HB_SYMBOLSCOPE ) 0x0020 ) +#define HB_FS_MEMVAR ( ( HB_SYMBOLSCOPE ) 0x0080 ) +#define HB_FS_PCODEFUNC ( ( HB_SYMBOLSCOPE ) 0x0100 ) +#define HB_FS_LOCAL ( ( HB_SYMBOLSCOPE ) 0x0200 ) +#define HB_FS_DYNCODE ( ( HB_SYMBOLSCOPE ) 0x0400 ) + #define HB_FS_INITEXIT ( HB_FS_INIT | HB_FS_EXIT ) -#define HB_FS_MESSAGE ( ( HB_SYMBOLSCOPE ) 0x20 ) -#define HB_FS_MEMVAR ( ( HB_SYMBOLSCOPE ) 0x80 ) extern HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ); /* invokes the virtual machine */ diff --git a/harbour/include/hbxvm.h b/harbour/include/hbxvm.h index cb971c3dbc..b15d8f0dd8 100644 --- a/harbour/include/hbxvm.h +++ b/harbour/include/hbxvm.h @@ -73,7 +73,7 @@ HB_EXTERN_BEGIN * to check HVM state so they are simply declared as void. */ -extern HB_EXPORT void hb_xvmExitPorc( ULONG ); +extern HB_EXPORT void hb_xvmExitProc( ULONG ulPrivateBase ); extern HB_EXPORT void hb_xvmSeqBegin( void ); extern HB_EXPORT BOOL hb_xvmSeqEnd( LONG * ); extern HB_EXPORT BOOL hb_xvmSeqRecover( LONG * ); @@ -198,6 +198,26 @@ extern HB_EXPORT BOOL hb_xvmArrayItemPop( ULONG ulIndex ); extern HB_EXPORT BOOL hb_xvmMultByInt( LONG lValue ); extern HB_EXPORT BOOL hb_xvmDivideByInt( LONG lValue ); extern HB_EXPORT BOOL hb_xvmAddInt( LONG lValue ); +extern HB_EXPORT void hb_xvmLocalSetInt( int iLocal, LONG lValue ); +/*extern HB_EXPORT void hb_xvmLocalSetStr( int iLocal, const char * pValue, ULONG ulLen );*/ +extern HB_EXPORT void hb_xvmPushFuncSymbol( PHB_SYMB pSym ); + +extern HB_EXPORT BOOL hb_xvmLessThenInt( LONG lValue ); +extern HB_EXPORT BOOL hb_xvmLessThenIntIs( LONG lValue, BOOL *fValue ); +extern HB_EXPORT BOOL hb_xvmLessEqualThenInt( LONG lValue ); +extern HB_EXPORT BOOL hb_xvmLessEqualThenIntIs( LONG lValue, BOOL *fValue ); +extern HB_EXPORT BOOL hb_xvmGreaterThenInt( LONG lValue ); +extern HB_EXPORT BOOL hb_xvmGreaterThenIntIs( LONG lValue, BOOL *fValue ); +extern HB_EXPORT BOOL hb_xvmGreaterEqualThenInt( LONG lValue ); +extern HB_EXPORT BOOL hb_xvmGreaterEqualThenIntIs( LONG lValue, BOOL *fValue ); +extern HB_EXPORT BOOL hb_xvmEqualInt( LONG lValue ); +extern HB_EXPORT BOOL hb_xvmEqualIntIs( LONG lValue, BOOL *fValue ); +extern HB_EXPORT BOOL hb_xvmNotEqualInt( LONG lValue ); +extern HB_EXPORT BOOL hb_xvmNotEqualIntIs( LONG lValue, BOOL *fValue ); + +extern HB_EXPORT BOOL hb_xvmLocalAdd( int iLocal ); +extern HB_EXPORT BOOL hb_xvmStaticAdd( USHORT uiStatic ); +extern HB_EXPORT BOOL hb_xvmMemvarAdd( PHB_SYMB pSymbol ); HB_EXTERN_END diff --git a/harbour/source/codepage/cpbg866.c b/harbour/source/codepage/cpbg866.c index 5d326065e3..c626098e5b 100644 --- a/harbour/source/codepage/cpbg866.c +++ b/harbour/source/codepage/cpbg866.c @@ -89,7 +89,7 @@ static HB_CODEPAGE s_codepage = { "BG866", " ¡¢£¤¥¦§¨©ª«¬­®¯àáâãäåæçèéêëìíîï", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( BG866 ); +HB_CODEPAGE_INIT( BG866 ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_BG866 diff --git a/harbour/source/codepage/cpbgiso.c b/harbour/source/codepage/cpbgiso.c index 67b35457c5..cbbde91644 100644 --- a/harbour/source/codepage/cpbgiso.c +++ b/harbour/source/codepage/cpbgiso.c @@ -89,7 +89,7 @@ static HB_CODEPAGE s_codepage = { "BGISO", "ÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîï", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( BGISO ); +HB_CODEPAGE_INIT( BGISO ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_BGISO diff --git a/harbour/source/codepage/cpbgwin.c b/harbour/source/codepage/cpbgwin.c index def402e99f..a43ccef8df 100644 --- a/harbour/source/codepage/cpbgwin.c +++ b/harbour/source/codepage/cpbgwin.c @@ -89,7 +89,7 @@ static HB_CODEPAGE s_codepage = { "BGWIN", "àáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( BGWIN ); +HB_CODEPAGE_INIT( BGWIN ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_BGWIN diff --git a/harbour/source/codepage/cpeldos.c b/harbour/source/codepage/cpeldos.c index e746af362e..c6276dbde2 100644 --- a/harbour/source/codepage/cpeldos.c +++ b/harbour/source/codepage/cpeldos.c @@ -89,7 +89,7 @@ static HB_CODEPAGE s_codepage = { "EL", "˜~ᙚ›œ~âž~㟠~å¡¢£¤¥¦~槨©ª«¬~ç­®¯à~é", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( EL ); +HB_CODEPAGE_INIT( EL ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_EL diff --git a/harbour/source/codepage/cpelwin.c b/harbour/source/codepage/cpelwin.c index 87b3d97ca6..542ed7ca51 100644 --- a/harbour/source/codepage/cpelwin.c +++ b/harbour/source/codepage/cpelwin.c @@ -90,7 +90,7 @@ static HB_CODEPAGE s_codepage = { "ELWIN", "á~Üâãäå~Ýæç~Þèé~ßêëìíîï~üðñóòôõ~ýö÷øù~þ", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( ELWIN ); +HB_CODEPAGE_INIT( ELWIN ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_ELWIN diff --git a/harbour/source/codepage/cpesdos.c b/harbour/source/codepage/cpesdos.c index 717139a3d8..26229e40b8 100644 --- a/harbour/source/codepage/cpesdos.c +++ b/harbour/source/codepage/cpesdos.c @@ -90,8 +90,7 @@ static HB_CODEPAGE s_codepage = { "ES", "a bcde‚fghi¡jklmn¤o¢pqrstu£vwxyz", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; - -HB_CODEPAGE_INIT( ES ); +HB_CODEPAGE_INIT( ES ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_ES diff --git a/harbour/source/codepage/cpesmwi.c b/harbour/source/codepage/cpesmwi.c index dd219e4f69..0c13063166 100644 --- a/harbour/source/codepage/cpesmwi.c +++ b/harbour/source/codepage/cpesmwi.c @@ -90,7 +90,7 @@ static HB_CODEPAGE s_codepage = { "ESMWIN", "aáàäbcçdeéèëfghiíìïjklmnñoóòöpqrstuúùüvwxyz", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( ESMWIN ); +HB_CODEPAGE_INIT( ESMWIN ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_ESMWIN diff --git a/harbour/source/codepage/cpeswin.c b/harbour/source/codepage/cpeswin.c index e289609004..893e352842 100644 --- a/harbour/source/codepage/cpeswin.c +++ b/harbour/source/codepage/cpeswin.c @@ -90,7 +90,7 @@ static HB_CODEPAGE s_codepage = { "ESWIN", "aábcdeéfghiíjklmnñoópqrstuúüvwxyz", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( ESWIN ); +HB_CODEPAGE_INIT( ESWIN ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_ESWIN diff --git a/harbour/source/codepage/cpgedos.c b/harbour/source/codepage/cpgedos.c index 1d8e748f19..148ced525c 100644 --- a/harbour/source/codepage/cpgedos.c +++ b/harbour/source/codepage/cpgedos.c @@ -90,7 +90,7 @@ static HB_CODEPAGE s_codepage = { "DE", "a„bcdefghijklmno”pqrsátuvwxyz", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( DE ); +HB_CODEPAGE_INIT( DE ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_DE diff --git a/harbour/source/codepage/cpgewin.c b/harbour/source/codepage/cpgewin.c index e79170cf52..5942ce2f0b 100644 --- a/harbour/source/codepage/cpgewin.c +++ b/harbour/source/codepage/cpgewin.c @@ -90,7 +90,7 @@ static HB_CODEPAGE s_codepage = { "DEWIN", "aäbcdefghijklmnoöpqrsßtuüvwxyz", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( DEWIN ); +HB_CODEPAGE_INIT( DEWIN ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_DEWIN diff --git a/harbour/source/codepage/cphu852.c b/harbour/source/codepage/cphu852.c index 63c751cd76..fe0344a083 100644 --- a/harbour/source/codepage/cphu852.c +++ b/harbour/source/codepage/cphu852.c @@ -92,7 +92,7 @@ static HB_CODEPAGE s_codepage = { "HU852", "a „bcde‚fghi¡jklmno¢”‹pqrstu£ûvwxyz", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( HU852 ); +HB_CODEPAGE_INIT( HU852 ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_HU852 diff --git a/harbour/source/codepage/cphuiso.c b/harbour/source/codepage/cphuiso.c index 48011254fb..9bca2e00bb 100644 --- a/harbour/source/codepage/cphuiso.c +++ b/harbour/source/codepage/cphuiso.c @@ -89,7 +89,7 @@ static HB_CODEPAGE s_codepage = { "HUISO", "aábcdeéfghiíjklmnoóöõpqrstuúüûvwxyz", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( HUISO ); +HB_CODEPAGE_INIT( HUISO ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_HUISO diff --git a/harbour/source/codepage/cphuwin.c b/harbour/source/codepage/cphuwin.c index 2b7976e60b..67f4019747 100644 --- a/harbour/source/codepage/cphuwin.c +++ b/harbour/source/codepage/cphuwin.c @@ -89,7 +89,7 @@ static HB_CODEPAGE s_codepage = { "HUWIN", "aábcdeéfghiíjklmnoóöõpqrstuúüûvwxyz", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( HUWIN ); +HB_CODEPAGE_INIT( HUWIN ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_HUWIN diff --git a/harbour/source/codepage/cppl852.c b/harbour/source/codepage/cppl852.c index f2b42ce42f..463fab3636 100644 --- a/harbour/source/codepage/cppl852.c +++ b/harbour/source/codepage/cppl852.c @@ -90,7 +90,7 @@ static HB_CODEPAGE s_codepage = { "PL852", "a¥bc†de©fghijklˆmnäo¢pqrs˜tuvwxyz«¾", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( PL852 ); +HB_CODEPAGE_INIT( PL852 ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_PL852 diff --git a/harbour/source/codepage/cppliso.c b/harbour/source/codepage/cppliso.c index 0a17df8afd..4000258347 100644 --- a/harbour/source/codepage/cppliso.c +++ b/harbour/source/codepage/cppliso.c @@ -90,7 +90,7 @@ static HB_CODEPAGE s_codepage = { "PLISO", "a±bcædeêfghijkl³mnñoópqrs¶tuvwxyz¼¿", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( PLISO ); +HB_CODEPAGE_INIT( PLISO ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_PLISO diff --git a/harbour/source/codepage/cpplmaz.c b/harbour/source/codepage/cpplmaz.c index 3338b65dc9..c6107e688f 100644 --- a/harbour/source/codepage/cpplmaz.c +++ b/harbour/source/codepage/cpplmaz.c @@ -90,7 +90,7 @@ static HB_CODEPAGE s_codepage = { "PLMAZ", "a†bcde‘fghijkl’mn¤o¢pqrsžtuvwxyz¦§", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( PLMAZ ); +HB_CODEPAGE_INIT( PLMAZ ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_PLMAZ diff --git a/harbour/source/codepage/cpplwin.c b/harbour/source/codepage/cpplwin.c index 406157667d..319bbab4f8 100644 --- a/harbour/source/codepage/cpplwin.c +++ b/harbour/source/codepage/cpplwin.c @@ -90,7 +90,7 @@ static HB_CODEPAGE s_codepage = { "PLWIN", "a¹bcædeêfghijkl³mnñoópqrsœtuvwxyzŸ¿", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( PLWIN ); +HB_CODEPAGE_INIT( PLWIN ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_PLWIN diff --git a/harbour/source/codepage/cppt850.c b/harbour/source/codepage/cppt850.c index aa486bf5e1..e98c4ae1e1 100644 --- a/harbour/source/codepage/cppt850.c +++ b/harbour/source/codepage/cppt850.c @@ -91,7 +91,7 @@ static HB_CODEPAGE s_codepage = { "PT850", "a …ƒÆ„bc‡de‚Šˆfghi¡Œ‹jklmn¤o¢•“ä”pqrstu£—–vwxyz", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( PT850 ); +HB_CODEPAGE_INIT( PT850 ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_PT850 diff --git a/harbour/source/codepage/cpptiso.c b/harbour/source/codepage/cpptiso.c index d5b0375c1b..d7129d68bc 100644 --- a/harbour/source/codepage/cpptiso.c +++ b/harbour/source/codepage/cpptiso.c @@ -91,7 +91,7 @@ static HB_CODEPAGE s_codepage = { "PTISO", "aáàâãäbcçdeéèêfghiíìîïjklmnñoóòôõöpqrstuúùûüvwxyz", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( PTISO ); +HB_CODEPAGE_INIT( PTISO ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_PTISO diff --git a/harbour/source/codepage/cpru866.c b/harbour/source/codepage/cpru866.c index 65a77a3610..bf657dfb26 100644 --- a/harbour/source/codepage/cpru866.c +++ b/harbour/source/codepage/cpru866.c @@ -64,7 +64,7 @@ static HB_CODEPAGE s_codepage = { "RU866", " ¡¢£¤¥¦§¨©ª«¬­®¯àáâãäåæçèéêëìíîï", 0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL }; -HB_CODEPAGE_INIT( RU866 ); +HB_CODEPAGE_INIT( RU866 ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_RU866 diff --git a/harbour/source/codepage/cprukoi.c b/harbour/source/codepage/cprukoi.c index 4794ad66d2..0352ed70fd 100644 --- a/harbour/source/codepage/cprukoi.c +++ b/harbour/source/codepage/cprukoi.c @@ -64,7 +64,7 @@ static HB_CODEPAGE s_codepage = { "RUKOI8", "ÁÂ×ÇÄÅÖÚÉÊËÌÍÎÏÐÒÓÔÕÆÈÃÞÛÝßÙØÜÀÑ", 0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL }; -HB_CODEPAGE_INIT( RUKOI8 ); +HB_CODEPAGE_INIT( RUKOI8 ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_RUKOI8 diff --git a/harbour/source/codepage/cpruwin.c b/harbour/source/codepage/cpruwin.c index a7231a27ff..ddda18d6ed 100644 --- a/harbour/source/codepage/cpruwin.c +++ b/harbour/source/codepage/cpruwin.c @@ -64,7 +64,7 @@ static HB_CODEPAGE s_codepage = { "RU1251", "àáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ", 0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL }; -HB_CODEPAGE_INIT( RU1251 ); +HB_CODEPAGE_INIT( RU1251 ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_RU1251 diff --git a/harbour/source/codepage/cpsl437.c b/harbour/source/codepage/cpsl437.c index 88b74aa7c2..7f82cc1767 100644 --- a/harbour/source/codepage/cpsl437.c +++ b/harbour/source/codepage/cpsl437.c @@ -90,7 +90,7 @@ static HB_CODEPAGE s_codepage = { "SL437", "abc~}d|efghijklmnopqrs{tuvwz`xy", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( SL437 ); +HB_CODEPAGE_INIT( SL437 ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_SL437 diff --git a/harbour/source/codepage/cpsl852.c b/harbour/source/codepage/cpsl852.c index 4eed64757d..ab4d6d0ce1 100644 --- a/harbour/source/codepage/cpsl852.c +++ b/harbour/source/codepage/cpsl852.c @@ -90,7 +90,7 @@ static HB_CODEPAGE s_codepage = { "SL852", "abcŸ†dÐefghijklmnopqrsçtuvwz§xy", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( SL852 ); +HB_CODEPAGE_INIT( SL852 ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_SL852 diff --git a/harbour/source/codepage/cpsliso.c b/harbour/source/codepage/cpsliso.c index 4ce030fab0..5e4f611ffb 100644 --- a/harbour/source/codepage/cpsliso.c +++ b/harbour/source/codepage/cpsliso.c @@ -90,7 +90,7 @@ static HB_CODEPAGE s_codepage = { "SLISO", "abcèædðefghijklmnopqrs¹tuvwz¾xy", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( SLISO ); +HB_CODEPAGE_INIT( SLISO ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_SLISO diff --git a/harbour/source/codepage/cpslwin.c b/harbour/source/codepage/cpslwin.c index ea6c41bb6f..456b0a9064 100644 --- a/harbour/source/codepage/cpslwin.c +++ b/harbour/source/codepage/cpslwin.c @@ -90,7 +90,7 @@ static HB_CODEPAGE s_codepage = { "SLWIN", "abcèædðefghijklmnopqrsštuvwzžxy", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( SLWIN ); +HB_CODEPAGE_INIT( SLWIN ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_SLWIN diff --git a/harbour/source/codepage/cpsrwin.c b/harbour/source/codepage/cpsrwin.c index 659a9520a2..693f699e7c 100644 --- a/harbour/source/codepage/cpsrwin.c +++ b/harbour/source/codepage/cpsrwin.c @@ -90,7 +90,7 @@ static HB_CODEPAGE s_codepage = { "SRWIN", "àáâãäåæçè¼êëšìíœîïðñòžóôõö÷Ÿø", IS_LATIN, ACCENTED_EQUAL, ACCENTED_INTERLEAVED, 0, 0, NULL, NULL, NULL, NULL, 0, NULL }; -HB_CODEPAGE_INIT( SRWIN ); +HB_CODEPAGE_INIT( SRWIN ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_codepage_Init_SRWIN diff --git a/harbour/source/common/hbfhnd.c b/harbour/source/common/hbfhnd.c index 2f712f5bb8..3365daf337 100644 --- a/harbour/source/common/hbfhnd.c +++ b/harbour/source/common/hbfhnd.c @@ -90,7 +90,7 @@ void hb_fhnd_ForceLink( void ) { /* Intentionally do nothing */ -}; +} #if defined(__WIN32__) && defined(__BORLANDC__) diff --git a/harbour/source/common/hbstr.c b/harbour/source/common/hbstr.c index 8047b39efc..237c56ddc6 100644 --- a/harbour/source/common/hbstr.c +++ b/harbour/source/common/hbstr.c @@ -358,7 +358,7 @@ HB_EXPORT double hb_numRound( double dNum, int iDec ) * use the similar hack in ==, >=, <=, <, > operations if it's set. */ -//#define HB_NUM_PRECISION 16 +/* #define HB_NUM_PRECISION 16 */ #ifdef HB_NUM_PRECISION /* diff --git a/harbour/source/common/hbver.c b/harbour/source/common/hbver.c index 4952c4f683..d4cdb32854 100644 --- a/harbour/source/common/hbver.c +++ b/harbour/source/common/hbver.c @@ -298,7 +298,7 @@ HB_EXPORT BOOL hb_iswinnt(void) OSVERSIONINFO osvi ; osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx (&osvi); - return(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT); // && osvi.dwMajorVersion >= 4); + return(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT); /* && osvi.dwMajorVersion >= 4); */ #else return FALSE ; #endif diff --git a/harbour/source/compiler/cmdcheck.c b/harbour/source/compiler/cmdcheck.c index ee4cd00c6a..9d3337a7e9 100644 --- a/harbour/source/compiler/cmdcheck.c +++ b/harbour/source/compiler/cmdcheck.c @@ -75,36 +75,36 @@ extern int hb_pp_ParseDefine( char * ); static ULONG PackDateTime( void ) { - BYTE szString[ 4 ]; + BYTE szString[4]; BYTE nValue; time_t t; - struct tm * oTime; + struct tm *oTime; time( &t ); oTime = localtime( &t ); - nValue = ( BYTE ) ( ( ( oTime->tm_year + 1900 ) - 1980 ) & ( 2 ^ 6 ) ) ; /* 6 bits */ - szString[ 0 ] = nValue << 2; - nValue = ( BYTE ) ( oTime->tm_mon + 1 ); /* 4 bits */ - szString[ 0 ] |= nValue >> 2; - szString[ 1 ] = nValue << 6; - nValue = ( BYTE ) ( oTime->tm_mday ); /* 5 bits */ - szString[ 1 ] |= nValue << 1; + nValue = ( BYTE ) ( ( ( oTime->tm_year + 1900 ) - 1980 ) & ( 2 ^ 6 ) ); /* 6 bits */ + szString[0] = nValue << 2; + nValue = ( BYTE ) ( oTime->tm_mon + 1 ); /* 4 bits */ + szString[0] |= nValue >> 2; + szString[1] = nValue << 6; + nValue = ( BYTE ) ( oTime->tm_mday ); /* 5 bits */ + szString[1] |= nValue << 1; - nValue = ( BYTE ) oTime->tm_hour; /* 5 bits */ - szString[ 1 ] = nValue >> 4; - szString[ 2 ] = nValue << 4; - nValue = ( BYTE ) oTime->tm_min; /* 6 bits */ - szString[ 2 ] |= nValue >> 2; - szString[ 3 ] = nValue << 6; - nValue = ( BYTE ) oTime->tm_sec; /* 6 bits */ - szString[ 3 ] |= nValue; + nValue = ( BYTE ) oTime->tm_hour; /* 5 bits */ + szString[1] = nValue >> 4; + szString[2] = nValue << 4; + nValue = ( BYTE ) oTime->tm_min; /* 6 bits */ + szString[2] |= nValue >> 2; + szString[3] = nValue << 6; + nValue = ( BYTE ) oTime->tm_sec; /* 6 bits */ + szString[3] |= nValue; - return HB_MKLONG( szString[ 3 ], szString[ 2 ], szString[ 1 ], szString[ 0 ] ); + return HB_MKLONG( szString[3], szString[2], szString[1], szString[0] ); } -void hb_compChkCompilerSwitch( int iArg, char * Args[] ) +void hb_compChkCompilerSwitch( int iArg, char *Args[] ) { /* If iArg is passed check the command line options */ if( iArg ) @@ -113,29 +113,29 @@ void hb_compChkCompilerSwitch( int iArg, char * Args[] ) /* Check all switches in command line They start with an OS_OPT_DELIMITER char - */ + */ for( i = 0; i < iArg; i++ ) { - if( ! HB_ISOPTSEP( Args[ i ][0] ) ) + if( !HB_ISOPTSEP( Args[i][0] ) ) continue; - if( Args[ i ][0] == '-' ) + if( Args[i][0] == '-' ) { int j = 1; char Switch[7]; Switch[0] = '-'; - while( Args[ i ][j] ) + while( Args[i][j] ) { - Switch[1] = Args[ i ][j]; + Switch[1] = Args[i][j]; - if( Args[ i ][j + 1 ] && Args[ i ][j + 1 ] == '-' ) + if( Args[i][j + 1] == '-' ) { Switch[2] = '-'; Switch[3] = '\0'; - hb_compChkEnvironVar( (char*) Switch ); + hb_compChkEnvironVar( ( char * ) Switch ); j += 2; continue; @@ -144,250 +144,255 @@ void hb_compChkCompilerSwitch( int iArg, char * Args[] ) { switch( Switch[1] ) { - case 'b' : - case 'B' : - if( Args[i][j + 1] && toupper( Args[i][j + 1] ) == 'U' && - Args[i][j + 2] && toupper( Args[i][j + 2] ) == 'I' && - Args[i][j + 3] && toupper( Args[i][j + 3] ) == 'L' && - Args[i][j + 4] && toupper( Args[i][j + 4] ) == 'D' ) - { - Switch[2] = 'U'; - Switch[3] = 'I'; - Switch[4] = 'L'; - Switch[5] = 'D'; - Switch[6] = '\0'; + case 'b': + case 'B': + if( Args[i][j + 1] && toupper( ( BYTE ) Args[i][j + 1] ) == 'U' && + Args[i][j + 2] && toupper( ( BYTE ) Args[i][j + 2] ) == 'I' && + Args[i][j + 3] && toupper( ( BYTE ) Args[i][j + 3] ) == 'L' && + Args[i][j + 4] && toupper( ( BYTE ) Args[i][j + 4] ) == 'D' ) + { + Switch[2] = 'U'; + Switch[3] = 'I'; + Switch[4] = 'L'; + Switch[5] = 'D'; + Switch[6] = '\0'; - hb_compChkEnvironVar( (char*) Switch ); + hb_compChkEnvironVar( ( char * ) Switch ); - j += 5; - continue; - } - else if( !Args[i][j + 1] ) - { - Switch[2] = '\0'; - hb_compChkEnvironVar( (char*) Switch ); - j += 1; - continue; - } - break; + j += 5; + continue; + } + else if( !Args[i][j + 1] ) + { + Switch[2] = '\0'; + hb_compChkEnvironVar( ( char * ) Switch ); + j += 1; + continue; + } + break; - case 'c' : - case 'C' : - if( Args[i][j + 1] && toupper( Args[i][j + 1] ) == 'R' && - Args[i][j + 2] && toupper( Args[i][j + 2] ) == 'E' && - Args[i][j + 3] && toupper( Args[i][j + 3] ) == 'D' ) - { - Switch[2] = 'R'; - Switch[3] = 'E'; - Switch[4] = 'D'; - Switch[5] = '\0'; + case 'c': + case 'C': + if( Args[i][j + 1] && toupper( ( BYTE ) Args[i][j + 1] ) == 'R' && + Args[i][j + 2] && toupper( ( BYTE ) Args[i][j + 2] ) == 'E' && + Args[i][j + 3] && toupper( ( BYTE ) Args[i][j + 3] ) == 'D' ) + { + Switch[2] = 'R'; + Switch[3] = 'E'; + Switch[4] = 'D'; + Switch[5] = '\0'; - j += 4; + j += 4; - if( Args[i][j] && toupper( Args[i][j] ) == 'I' ) - { - j++; - if( Args[i][j] && toupper( Args[i][j] ) == 'T' ) - { - j++; - if( Args[i][j] && toupper( Args[i][j] ) == 'S' ) - { - j++; - } - } - } + if( Args[i][j] && toupper( ( BYTE ) Args[i][j] ) == 'I' ) + { + j++; + if( Args[i][j] && toupper( ( BYTE ) Args[i][j] ) == 'T' ) + { + j++; + if( Args[i][j] && toupper( ( BYTE ) Args[i][j] ) == 'S' ) + { + j++; + } + } + } - hb_compChkEnvironVar( (char*) Switch ); + hb_compChkEnvironVar( ( char * ) Switch ); - continue; - } - else - { - Switch[2] = '\0'; - hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_BADOPTION, (char*) Switch, NULL ); - } + continue; + } + else + { + Switch[2] = '\0'; + hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_BADOPTION, ( char * ) Switch, NULL ); + } - case 'd' : - case 'D' : - Args[i] += ( j - 1 ); - hb_compChkEnvironVar( Args[i] ); + case 'd': + case 'D': + Args[i] += ( j - 1 ); + hb_compChkEnvironVar( Args[i] ); - /* Accept rest as part of #define and continue with next Args[]. */ - j = strlen( Args[i] ); - continue; + /* Accept rest as part of #define and continue with next Args[]. */ + j = strlen( Args[i] ); + continue; - case 'e' : - case 'E' : - if( Args[i][j + 1] && toupper( ( BYTE ) Args[i][j + 1] ) == 'S' && Args[i][j + 2] && isdigit( ( BYTE ) Args[i][j + 2] ) ) - { - Switch[2] = 'S'; - Switch[3] = Args[i][j + 2]; - Switch[4] = '\0'; + case 'e': + case 'E': + if( toupper( ( BYTE ) Args[i][j + 1] ) == 'S' && isdigit( ( BYTE ) Args[i][j + 2] ) ) + { + Switch[2] = 'S'; + Switch[3] = Args[i][j + 2]; + Switch[4] = '\0'; - hb_compChkEnvironVar( (char*) Switch ); + hb_compChkEnvironVar( ( char * ) Switch ); - j += 3; - continue; - } - else - { - Switch[2] = '\0'; - hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_BADOPTION, (char*) Switch, NULL ); - } + j += 3; + continue; + } + else + { + Switch[2] = '\0'; + hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_BADOPTION, ( char * ) Switch, NULL ); + } - break; + break; - case 'g' : - case 'G' : - /* Required argument */ - Switch[2] = Args[i][j + 1]; - if( isdigit( ( BYTE ) Args[i][j + 2] ) ) - { - /* Optional argument */ - Switch[3] = Args[i][j + 2]; - Switch[4] = '\0'; - j += 3; - } - else - { - /* No optional argument */ - Switch[3] = '\0'; - j += 2; - } - hb_compChkEnvironVar( (char*) Switch ); - continue; + case 'g': + case 'G': + /* Required argument */ + Switch[2] = Args[i][j + 1]; + if( Switch[2] ) + { + if( isdigit( ( BYTE ) Args[i][j + 2] ) ) + { + /* Optional argument */ + Switch[3] = Args[i][j + 2]; + Switch[4] = '\0'; + j += 3; + } + else + { + /* No optional argument */ + Switch[3] = '\0'; + j += 2; + } + hb_compChkEnvironVar( ( char * ) Switch ); + continue; + } + else + hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_BADOPTION, ( char * ) Switch, NULL ); - case 'i' : - case 'I' : - Args[i] += (j - 1); - hb_compChkEnvironVar( Args[i] ); + case 'i': + case 'I': + Args[i] += ( j - 1 ); + hb_compChkEnvironVar( Args[i] ); - /* Accept rest as IncludePath and continue with next Args[]. */ - j = strlen( Args[i] ); - continue; + /* Accept rest as IncludePath and continue with next Args[]. */ + j = strlen( Args[i] ); + continue; - case 'k' : - case 'K' : - Args[i] += ( j - 1 ); - hb_compChkEnvironVar( Args[i] ); + case 'k': + case 'K': + Args[i] += ( j - 1 ); + hb_compChkEnvironVar( Args[i] ); - /* Accept rest as part of #define and continue with next Args[]. */ - j = strlen( Args[i] ); - continue; + /* Accept rest as part of #define and continue with next Args[]. */ + j = strlen( Args[i] ); + continue; - case 'n' : - case 'N' : - /* Required argument */ - if ( Args[i][j + 1] ) - { - /* Optional argument */ - Switch[2] = Args[i][j + 1]; - Switch[3] = '\0'; - j += 2; - } - else - { - /* No optional argument */ - Switch[2] = '\0'; - j += 1; - } - hb_compChkEnvironVar( (char*) Switch ); - continue; + case 'n': + case 'N': + /* Required argument */ + if( Args[i][j + 1] ) + { + /* Optional argument */ + Switch[2] = Args[i][j + 1]; + Switch[3] = '\0'; + j += 2; + } + else + { + /* No optional argument */ + Switch[2] = '\0'; + j += 1; + } + hb_compChkEnvironVar( ( char * ) Switch ); + continue; - case 'o' : - case 'O' : - Args[i] += (j - 1); - hb_compChkEnvironVar( Args[i] ); + case 'o': + case 'O': + Args[i] += ( j - 1 ); + hb_compChkEnvironVar( Args[i] ); - /* Accept rest as OutputPath and continue with next Args[]. */ - j = strlen( Args[i] ); - continue; + /* Accept rest as OutputPath and continue with next Args[]. */ + j = strlen( Args[i] ); + continue; - case 'p' : - case 'P' : - if( Args[i][ j+1 ] ) - { - Args[i] += (j - 1); + case 'p': + case 'P': + if( Args[i][j + 1] ) + { + Args[i] += ( j - 1 ); hb_compChkEnvironVar( Args[i] ); /* Accept rest as PPOPath and continue with next Args[]. */ - j += strlen( Args[i] ) -1; - } - else - { + j += strlen( Args[i] ) - 1; + } + else + { Switch[2] = '\0'; - hb_compChkEnvironVar( (char*) Switch ); + hb_compChkEnvironVar( ( char * ) Switch ); j++; - } - continue; - - case 'q' : - case 'Q' : - if( Args[i][j + 1] && isdigit( ( BYTE ) Args[i][j + 1] ) ) - { - Switch[2] = Args[i][j + 1]; - Switch[3] = '\0'; + } + continue; - hb_compChkEnvironVar( (char*) Switch ); + case 'q': + case 'Q': + if( Args[i][j + 1] && isdigit( ( BYTE ) Args[i][j + 1] ) ) + { + Switch[2] = Args[i][j + 1]; + Switch[3] = '\0'; - j += 2; - continue; - } - else - { - Switch[2] = '\0'; - hb_compChkEnvironVar( (char*) Switch ); - } + hb_compChkEnvironVar( ( char * ) Switch ); - break; + j += 2; + continue; + } + else + { + Switch[2] = '\0'; + hb_compChkEnvironVar( ( char * ) Switch ); + } - case 'r' : - case 'R' : - hb_compChkEnvironVar( Args[i] ); - j = strlen( Args[i] ) - 1; - break; + break; - case 'u' : - case 'U' : - Args[i] += (j - 1); - hb_compChkEnvironVar( Args[i] ); + case 'r': + case 'R': + hb_compChkEnvironVar( Args[i] ); + j = strlen( Args[i] ) - 1; + break; - /* Accept rest as part of .CH Path or "undef:" and continue with next Args[]. */ - j = strlen( Args[i] ); - continue; + case 'u': + case 'U': + Args[i] += ( j - 1 ); + hb_compChkEnvironVar( Args[i] ); - case 'w' : - case 'W' : - if( Args[i][j + 1] && isdigit( ( BYTE ) Args[i][j + 1] ) ) - { - Switch[2] = Args[i][j + 1]; - Switch[3] = '\0'; + /* Accept rest as part of .CH Path or "undef:" and continue with next Args[]. */ + j = strlen( Args[i] ); + continue; - hb_compChkEnvironVar( (char*) Switch ); + case 'w': + case 'W': + if( Args[i][j + 1] && isdigit( ( BYTE ) Args[i][j + 1] ) ) + { + Switch[2] = Args[i][j + 1]; + Switch[3] = '\0'; - j += 2; - continue; - } - else - { - Switch[2] = '\0'; - hb_compChkEnvironVar( (char*) Switch ); - } + hb_compChkEnvironVar( ( char * ) Switch ); - break; + j += 2; + continue; + } + else + { + Switch[2] = '\0'; + hb_compChkEnvironVar( ( char * ) Switch ); + } - case 'x' : - case 'X' : - Args[i] += (j - 1); - hb_compChkEnvironVar( Args[i] ); + break; - /* Accept rest as INIT Symbol and continue with next Args[]. */ - j = strlen( Args[i] ); - continue; + case 'x': + case 'X': + Args[i] += ( j - 1 ); + hb_compChkEnvironVar( Args[i] ); - default : - Switch[2] = '\0'; - hb_compChkEnvironVar( (char*) Switch ); + /* Accept rest as INIT Symbol and continue with next Args[]. */ + j = strlen( Args[i] ); + continue; + + default: + Switch[2] = '\0'; + hb_compChkEnvironVar( ( char * ) Switch ); } } @@ -397,39 +402,42 @@ void hb_compChkCompilerSwitch( int iArg, char * Args[] ) continue; } - CheckMultiSlashSwitch : + CheckMultiSlashSwitch: { int j = 1; - while( Args[ i ][j] && ! HB_ISOPTSEP( Args[ i ][j] ) ) j++; - if( Args[ i ][j] && Args[ i ][j] == '/' ) + while( Args[i][j] && !HB_ISOPTSEP( Args[i][j] ) ) + j++; + + if( Args[i][j] && Args[i][j] == '/' ) { - char cSep = Args[ i ][j]; - Args[ i ][j] = 0; + char cSep = Args[i][j]; - hb_compChkEnvironVar( Args[ i ] ); + Args[i][j] = 0; - Args[ i ] += j; + hb_compChkEnvironVar( Args[i] ); + + Args[i] += j; Args[i][0] = cSep; goto CheckMultiSlashSwitch; } else { - hb_compChkEnvironVar( Args[ i ] ); + hb_compChkEnvironVar( Args[i] ); } } } } else - /* Chech the environment variables */ + /* Chech the environment variables */ { /* NOTE: CLIPPERCMD enviroment variable - is overriden if HARBOURCMD exists - */ - char * szStrEnv = hb_getenv( "HARBOURCMD" ); + is overriden if HARBOURCMD exists + */ + char *szStrEnv = hb_getenv( "HARBOURCMD" ); - if( !szStrEnv || szStrEnv[ 0 ] == '\0' ) + if( !szStrEnv || szStrEnv[0] == '\0' ) { if( szStrEnv ) hb_xfree( ( void * ) szStrEnv ); @@ -437,13 +445,13 @@ void hb_compChkCompilerSwitch( int iArg, char * Args[] ) szStrEnv = hb_getenv( "CLIPPERCMD" ); } - if( szStrEnv && szStrEnv[ 0 ] != '\0' ) + if( szStrEnv && szStrEnv[0] != '\0' ) { - char * szSwitch = strtok( szStrEnv, " " ); + char *szSwitch = strtok( szStrEnv, " " ); /* Check the environment var while it isn't empty. - */ + */ while( szSwitch != NULL ) { hb_compChkEnvironVar( szSwitch ); @@ -456,19 +464,19 @@ void hb_compChkCompilerSwitch( int iArg, char * Args[] ) } } -void hb_compChkEnvironVar( char * szSwitch ) +void hb_compChkEnvironVar( char *szSwitch ) { if( szSwitch ) { - char * s = szSwitch; + char *s = szSwitch; /* If szSwitch doesn't start with a HB_OSOPTSEP char show an error - */ + */ /* - printf( "Switch: %s\n", s ); - */ + printf( "Switch: %s\n", s ); + */ if( !HB_ISOPTSEP( *s ) ) hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_BADOPTION, s, NULL ); @@ -487,49 +495,49 @@ void hb_compChkEnvironVar( char * szSwitch ) case 'b': case 'B': - { - unsigned int i = 0; - char * szOption = hb_strupr( hb_strdup( s ) ); - while( i < strlen( szOption ) && !HB_ISOPTSEP( szOption[ i ] ) ) - i++; - szOption[ i ] = '\0'; + { + unsigned int i = 0; + char *szOption = hb_strupr( hb_strdup( s ) ); - if( strcmp( szOption, "BUILD" ) == 0 ) - hb_comp_bBuildInfo = TRUE; + while( i < strlen( szOption ) && !HB_ISOPTSEP( szOption[i] ) ) + i++; + szOption[i] = '\0'; + + if( strcmp( szOption, "BUILD" ) == 0 ) + hb_comp_bBuildInfo = TRUE; + else + { + if( *( s + 1 ) == '-' ) + hb_comp_bDebugInfo = FALSE; else { - if( *( s + 1 ) == '-' ) - hb_comp_bDebugInfo = FALSE; - else - { - hb_comp_bDebugInfo = TRUE; - hb_comp_bLineNumbers = TRUE; - } + hb_comp_bDebugInfo = TRUE; + hb_comp_bLineNumbers = TRUE; } - - hb_xfree( szOption ); } + + hb_xfree( szOption ); + } break; case 'c': case 'C': - { - unsigned int i = 0; - char * szOption = hb_strupr( hb_strdup( s ) ); - while( i < strlen( szOption ) && !HB_ISOPTSEP( szOption[ i ] ) ) - i++; - szOption[ i ] = '\0'; + { + unsigned int i = 0; + char *szOption = hb_strupr( hb_strdup( s ) ); - if( strcmp( szOption, "CREDITS" ) == 0 || - strcmp( szOption, "CREDIT" ) == 0 || - strcmp( szOption, "CREDI" ) == 0 || - strcmp( szOption, "CRED" ) == 0 ) - hb_comp_bCredits = TRUE; - else - hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_BADOPTION, szOption, NULL ); + while( i < strlen( szOption ) && !HB_ISOPTSEP( szOption[i] ) ) + i++; + szOption[i] = '\0'; - hb_xfree( szOption ); - } + if( strcmp( szOption, "CREDITS" ) == 0 || + strcmp( szOption, "CREDIT" ) == 0 || strcmp( szOption, "CREDI" ) == 0 || strcmp( szOption, "CRED" ) == 0 ) + hb_comp_bCredits = TRUE; + else + hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_BADOPTION, szOption, NULL ); + + hb_xfree( szOption ); + } break; case 'd': @@ -624,14 +632,14 @@ void hb_compChkEnvironVar( char * szSwitch ) default: printf( "\nUnsupported output language option\n" ); - hb_compMainExit(); + hb_compMainExit( ); exit( EXIT_FAILURE ); } break; /* NOTE: h or H from HELP or help - */ + */ case 'h': case 'H': case '?': @@ -639,7 +647,7 @@ void hb_compChkEnvironVar( char * szSwitch ) /* NOTE: It already has support for several include files - */ + */ case 'i': case 'I': hb_fsAddSearchPath( s + 1, &hb_comp_pIncludePath ); @@ -647,55 +655,56 @@ void hb_compChkEnvironVar( char * szSwitch ) case 'k': case 'K': + { + int i = 1; + + while( s[i] ) { - int i = 1; - while( s[ i ] ) + switch( s[i++] ) { - switch( s[ i++ ] ) - { - case '?': - hb_compPrintLogo(); - hb_compPrintModes(); - hb_comp_bLogo = FALSE; - hb_comp_bQuiet = TRUE; - break; + case '?': + hb_compPrintLogo( ); + hb_compPrintModes( ); + hb_comp_bLogo = FALSE; + hb_comp_bQuiet = TRUE; + break; - case 'h': - /* default Harbour mode */ - hb_comp_Supported |= HB_COMPFLAG_HARBOUR; - break; + case 'h': + /* default Harbour mode */ + hb_comp_Supported |= HB_COMPFLAG_HARBOUR; + break; - case 'c': - /* clear all flags - minimal set of features */ - hb_comp_Supported = HB_COMPFLAG_OPTJUMP; - break; + case 'c': + /* clear all flags - minimal set of features */ + hb_comp_Supported = HB_COMPFLAG_OPTJUMP; + break; - case 'x': - hb_comp_Supported |= HB_COMPFLAG_XBASE; - break; + case 'x': + hb_comp_Supported |= HB_COMPFLAG_XBASE; + break; - case 'i': - hb_comp_Supported |= HB_COMPFLAG_HB_INLINE; - break; + case 'i': + hb_comp_Supported |= HB_COMPFLAG_HB_INLINE; + break; - case 'J': - hb_comp_Supported &= ~HB_COMPFLAG_OPTJUMP; - break; + case 'J': + hb_comp_Supported &= ~HB_COMPFLAG_OPTJUMP; + break; - case 'r': - hb_comp_Supported |= HB_COMPFLAG_RT_MACRO; - break; + case 'r': + hb_comp_Supported |= HB_COMPFLAG_RT_MACRO; + break; - case 's': - hb_comp_Supported |= HB_COMPFLAG_ARRSTR; - break; + case 's': + hb_comp_Supported |= HB_COMPFLAG_ARRSTR; + break; - default: - hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_BADOPTION, s, NULL ); - break; - } + default: + hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_BADOPTION, s, NULL ); + break; } } + } break; case 'l': @@ -718,7 +727,7 @@ void hb_compChkEnvironVar( char * szSwitch ) case 'N': /* -n1 no start up procedure and no implicit start up procedure - */ + */ if( *( s + 1 ) == '1' ) { hb_comp_bStartProc = FALSE; @@ -726,39 +735,40 @@ void hb_compChkEnvironVar( char * szSwitch ) } /* -n or -n0 no implicit start up procedure - */ - else if ( ( *( s + 1 ) == '0' ) || ( *( s + 1 ) == '\0' ) ) + */ + else if( ( *( s + 1 ) == '0' ) || ( *( s + 1 ) == '\0' ) ) hb_comp_bStartProc = FALSE; /* -n- ceates implicit start up procedure - */ + */ else if( *( s + 1 ) == '-' ) hb_comp_bStartProc = TRUE; /* invalid command - */ + */ else hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_BADOPTION, s, NULL ); break; case 'o': case 'O': - { - char * szPath = hb_strdup( s + 1 ); + { + char *szPath = hb_strdup( s + 1 ); - hb_comp_pOutPath = hb_fsFNameSplit( szPath ); - hb_xfree( szPath ); - } + hb_comp_pOutPath = hb_fsFNameSplit( szPath ); + hb_xfree( szPath ); + } break; - /* Added for preprocessor needs */ + /* Added for preprocessor needs */ case 'p': case 'P': if( *( s + 1 ) == '-' ) hb_comp_bPPO = 0; else { - char * szPath = hb_strdup( s + 1 ); + char *szPath = hb_strdup( s + 1 ); + hb_comp_pPpoPath = hb_fsFNameSplit( szPath ); hb_xfree( szPath ); @@ -778,15 +788,16 @@ void hb_compChkEnvironVar( char * szSwitch ) case 'R': if( *( s + 1 ) == '=' ) { - int iOverflow; - int iCycles = hb_strValInt( s + 2, &iOverflow ); - if( ! iOverflow && iCycles > 0 ) - hb_pp_MaxTranslateCycles = (unsigned int)iCycles; + int iOverflow; + int iCycles = hb_strValInt( s + 2, &iOverflow ); + + if( !iOverflow && iCycles > 0 ) + hb_pp_MaxTranslateCycles = ( unsigned int ) iCycles; } else { - /* TODO: Implement this switch */ - printf( "Not yet supported command line option: %s\n", s ); + /* TODO: Implement this switch */ + printf( "Not yet supported command line option: %s\n", s ); } break; @@ -806,11 +817,8 @@ void hb_compChkEnvironVar( char * szSwitch ) case 'u': case 'U': - if ( s[1] && toupper( s[1] ) == 'N' - && s[2] && toupper( s[2] ) == 'D' - && s[3] && toupper( s[3] ) == 'E' - && s[4] && toupper( s[4] ) == 'F' - && s[5] == ':' ) + if( s[1] && toupper( s[1] ) == 'N' + && s[2] && toupper( s[2] ) == 'D' && s[3] && toupper( s[3] ) == 'E' && s[4] && toupper( s[4] ) == 'F' && s[5] == ':' ) { /* NOTE: Ignore these -undef: switches will be processed separately */ break; @@ -828,33 +836,34 @@ void hb_compChkEnvironVar( char * szSwitch ) case 'w': case 'W': - hb_comp_iWarnings = 1; - if( s[ 1 ] ) - { /*there is -w<0,1,2,3> probably */ - hb_comp_iWarnings = s[ 1 ] - '0'; - if( hb_comp_iWarnings < 0 || hb_comp_iWarnings > 4 ) - hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_BADOPTION, s, NULL ); - } + hb_comp_iWarnings = 1; + if( s[1] ) + { /*there is -w<0,1,2,3> probably */ + hb_comp_iWarnings = s[1] - '0'; + if( hb_comp_iWarnings < 0 || hb_comp_iWarnings > 4 ) + hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_BADOPTION, s, NULL ); + } break; case 'x': case 'X': - { - unsigned int i = 0; - char * szPrefix = hb_strdup( s + 1 ); - while( i < strlen( szPrefix ) && !HB_ISOPTSEP( szPrefix[ i ] ) ) - i++; - szPrefix[ i ] = '\0'; + { + unsigned int i = 0; + char *szPrefix = hb_strdup( s + 1 ); - if( strlen( szPrefix ) == 0 ) - sprintf( szPrefix, "%08lX_", PackDateTime() ); + while( i < strlen( szPrefix ) && !HB_ISOPTSEP( szPrefix[i] ) ) + i++; + szPrefix[i] = '\0'; - strncpy( hb_comp_szPrefix, szPrefix, 16 ); - hb_comp_szPrefix[ 16 ] = '\0'; - strcat( hb_comp_szPrefix, "_" ); + if( strlen( szPrefix ) == 0 ) + sprintf( szPrefix, "%08lX_", PackDateTime( ) ); - hb_xfree( szPrefix ); - } + strncpy( hb_comp_szPrefix, szPrefix, 16 ); + hb_comp_szPrefix[16] = '\0'; + strcat( hb_comp_szPrefix, "_" ); + + hb_xfree( szPrefix ); + } break; #ifdef YYDEBUG @@ -882,29 +891,29 @@ void hb_compChkEnvironVar( char * szSwitch ) void hb_compChkPaths( void ) { - char * szInclude = hb_getenv( "INCLUDE" ); + char *szInclude = hb_getenv( "INCLUDE" ); if( szInclude ) { - if( szInclude[ 0 ] != '\0' ) + if( szInclude[0] != '\0' ) hb_fsAddSearchPath( szInclude, &hb_comp_pIncludePath ); hb_xfree( ( void * ) szInclude ); } } -static void hb_compChkDefineSwitch( char * pszSwitch ) +static void hb_compChkDefineSwitch( char *pszSwitch ) { - if( pszSwitch && HB_ISOPTSEP( pszSwitch[ 0 ] ) ) + if( pszSwitch && HB_ISOPTSEP( pszSwitch[0] ) ) { - if ( pszSwitch[ 1 ] == 'd' || pszSwitch[ 1 ] == 'D' ) + if( pszSwitch[1] == 'd' || pszSwitch[1] == 'D' ) { char *szDefText = hb_strdup( pszSwitch + 2 ), *pAssign, *sDefLine; unsigned int i = 0; - while( i < strlen( szDefText ) && ! HB_ISOPTSEP( szDefText[ i ] ) ) + while( i < strlen( szDefText ) && !HB_ISOPTSEP( szDefText[i] ) ) i++; - szDefText[ i ] = '\0'; + szDefText[i] = '\0'; if( szDefText ) { if( ( pAssign = strchr( szDefText, '=' ) ) == NULL ) @@ -913,10 +922,10 @@ static void hb_compChkDefineSwitch( char * pszSwitch ) } else { - szDefText[ pAssign - szDefText ] = '\0'; + szDefText[pAssign - szDefText] = '\0'; /* hb_pp_AddDefine( szDefText, pAssign + 1 ); */ - sDefLine = ( char* ) hb_xgrab( strlen( szDefText ) + 1 + strlen( pAssign + 1 ) + 1 ); + sDefLine = ( char * ) hb_xgrab( strlen( szDefText ) + 1 + strlen( pAssign + 1 ) + 1 ); sprintf( sDefLine, "%s %s", szDefText, pAssign + 1 ); hb_pp_ParseDefine( sDefLine ); hb_xfree( sDefLine ); @@ -925,27 +934,27 @@ static void hb_compChkDefineSwitch( char * pszSwitch ) hb_xfree( szDefText ); } - else if ( pszSwitch[1] && toupper( pszSwitch[1] ) == 'U' && - pszSwitch[2] && toupper( pszSwitch[2] ) == 'N' && - pszSwitch[3] && toupper( pszSwitch[3] ) == 'D' && - pszSwitch[4] && toupper( pszSwitch[4] ) == 'E' && - pszSwitch[5] && toupper( pszSwitch[5] ) == 'F' && - pszSwitch[6] == ':' ) + else if( pszSwitch[1] && toupper( pszSwitch[1] ) == 'U' && + pszSwitch[2] && toupper( pszSwitch[2] ) == 'N' && + pszSwitch[3] && toupper( pszSwitch[3] ) == 'D' && + pszSwitch[4] && toupper( pszSwitch[4] ) == 'E' && + pszSwitch[5] && toupper( pszSwitch[5] ) == 'F' && + pszSwitch[6] == ':' ) { char *szDefText = hb_strdup( pszSwitch + 7 ); char *szDefLine; unsigned int i = 0; - while ( szDefText[ i ] && ! HB_ISOPTSEP( szDefText[ i ] ) ) + while( szDefText[i] && !HB_ISOPTSEP( szDefText[i] ) ) { - i++; + i++; } - szDefText[ i ] = '\0'; + szDefText[i] = '\0'; - if ( szDefText[ 0 ] ) + if( szDefText[0] ) { - szDefLine = (char *) hb_xgrab( 7 + strlen( szDefText ) + 1 ); + szDefLine = ( char * ) hb_xgrab( 7 + strlen( szDefText ) + 1 ); sprintf( szDefLine, "#undef %s", szDefText ); hb_pp_ParseDirective( szDefLine ); hb_xfree( szDefLine ); @@ -955,15 +964,15 @@ static void hb_compChkDefineSwitch( char * pszSwitch ) } } -void hb_compChkDefines( int iArg, char * Args[] ) +void hb_compChkDefines( int iArg, char *Args[] ) { /* Chech the environment variables */ { /* NOTE: CLIPPERCMD enviroment variable is overriden - if HARBOURCMD exists */ - char * szStrEnv = hb_getenv( "HARBOURCMD" ); + if HARBOURCMD exists */ + char *szStrEnv = hb_getenv( "HARBOURCMD" ); - if( !szStrEnv || szStrEnv[ 0 ] == '\0' ) + if( !szStrEnv || szStrEnv[0] == '\0' ) { if( szStrEnv ) hb_xfree( ( void * ) szStrEnv ); @@ -971,9 +980,9 @@ void hb_compChkDefines( int iArg, char * Args[] ) szStrEnv = hb_getenv( "CLIPPERCMD" ); } - if( szStrEnv && szStrEnv[ 0 ] != '\0' ) + if( szStrEnv && szStrEnv[0] != '\0' ) { - char * szSwitch = strtok( szStrEnv, " " ); + char *szSwitch = strtok( szStrEnv, " " ); /* Check the environment var while it isn't empty. */ while( szSwitch != NULL ) @@ -994,6 +1003,6 @@ void hb_compChkDefines( int iArg, char * Args[] ) /* Check all switches in command line They start with an OS_OPT_DELIMITER char */ for( i = 0; i < iArg; i++ ) - hb_compChkDefineSwitch( Args[ i ] ); + hb_compChkDefineSwitch( Args[i] ); } } diff --git a/harbour/source/compiler/genc.c b/harbour/source/compiler/genc.c index acd3bddfb8..f862a0b956 100644 --- a/harbour/source/compiler/genc.c +++ b/harbour/source/compiler/genc.c @@ -177,7 +177,7 @@ void hb_compGenCCode( PHB_FNAME pFileName ) /* generates the C language ou * we are using these two bits to mark the special function used to * initialize static variables */ - fprintf( yyc, "{ \"(_INITSTATICS)\", {HB_FS_INITEXIT}, {hb_INITSTATICS}, NULL }" ); /* NOTE: hb_ intentionally in lower case */ + fprintf( yyc, "{ \"%s\", {HB_FS_INITEXIT}, {hb_INITSTATICS}, NULL }", pSym->szName ); /* NOTE: hb_ intentionally in lower case */ } else { diff --git a/harbour/source/compiler/gencc.c b/harbour/source/compiler/gencc.c index 31da9b9ed7..b6aaa7fa57 100644 --- a/harbour/source/compiler/gencc.c +++ b/harbour/source/compiler/gencc.c @@ -76,12 +76,77 @@ static void hb_gencc_string_put( FILE * yyc, BYTE * pText, USHORT usLen ) fputc( '"', yyc ); } +static int hb_gencc_checkJumpCondAhead( LONG lValue, PFUNCTION pFunc, ULONG lPCodePos, PHB_LABEL_INFO cargo, + char * szFunc ) +{ + if( HB_GENC_GETLABEL( lPCodePos + 1 ) == 0 ) + { + switch( pFunc->pCode[ lPCodePos + 1 ] ) + { + case HB_P_JUMPFALSENEAR: + fprintf( cargo->yyc, "\tif( hb_xvm%sIntIs( %ld, &fValue ) ) break;\n", + szFunc, lValue ); + fprintf( cargo->yyc, "\tif( !fValue )\n\t\tgoto lab%05ld;\n", + HB_GENC_GETLABEL( lPCodePos + 1 + + ( signed char ) ( pFunc->pCode[ lPCodePos + 2 ] ) ) ); + return 3; + case HB_P_JUMPFALSE: + fprintf( cargo->yyc, "\tif( hb_xvm%sIntIs( %ld, &fValue ) ) break;\n", + szFunc, lValue ); + fprintf( cargo->yyc, "\tif( !fValue )\n\t\tgoto lab%05ld;\n", + HB_GENC_GETLABEL( lPCodePos + 1 + + HB_PCODE_MKSHORT( &pFunc->pCode[ lPCodePos + 2 ] ) ) ); + return 4; + case HB_P_JUMPFALSEFAR: + fprintf( cargo->yyc, "\tif( hb_xvm%sIntIs( %ld, &fValue ) ) break;\n", + szFunc, lValue ); + fprintf( cargo->yyc, "\tif( !fValue )\n\t\tgoto lab%05ld;\n", + HB_GENC_GETLABEL( lPCodePos + 1 + + HB_PCODE_MKINT24( &pFunc->pCode[ lPCodePos + 2 ] ) ) ); + return 5; + } + } + fprintf( cargo->yyc, "\tif( hb_xvm%sInt( %ld ) ) break;\n", + szFunc, lValue ); + return 1; +} + static int hb_gencc_checkNumAhead( LONG lValue, PFUNCTION pFunc, ULONG lPCodePos, PHB_LABEL_INFO cargo ) { if( HB_GENC_GETLABEL( lPCodePos ) == 0 ) { switch( pFunc->pCode[ lPCodePos ] ) { + case HB_P_POPLOCAL: + fprintf( cargo->yyc, "\thb_xvmLocalSetInt( %d, %ld );\n", + HB_PCODE_MKSHORT( &pFunc->pCode[ lPCodePos + 1 ] ), + lValue ); + return 3; + + case HB_P_POPLOCALNEAR: + fprintf( cargo->yyc, "\thb_xvmLocalSetInt( %d, %ld );\n", + ( signed char ) pFunc->pCode[ lPCodePos + 1 ], lValue ); + return 2; + + case HB_P_EQUAL: + case HB_P_EXACTLYEQUAL: + return hb_gencc_checkJumpCondAhead( lValue, pFunc, lPCodePos, cargo, "Equal" ); + + case HB_P_NOTEQUAL: + return hb_gencc_checkJumpCondAhead( lValue, pFunc, lPCodePos, cargo, "NotEqual" ); + + case HB_P_GREATER: + return hb_gencc_checkJumpCondAhead( lValue, pFunc, lPCodePos, cargo, "GreaterThen" ); + + case HB_P_GREATEREQUAL: + return hb_gencc_checkJumpCondAhead( lValue, pFunc, lPCodePos, cargo, "GreaterEqualThen" ); + + case HB_P_LESS: + return hb_gencc_checkJumpCondAhead( lValue, pFunc, lPCodePos, cargo, "LessThen" ); + + case HB_P_LESSEQUAL: + return hb_gencc_checkJumpCondAhead( lValue, pFunc, lPCodePos, cargo, "LessEqualThen" ); + case HB_P_ARRAYPUSH: if( lValue > 0 ) { @@ -118,6 +183,36 @@ static int hb_gencc_checkNumAhead( LONG lValue, PFUNCTION pFunc, ULONG lPCodePos return 0; } +static int hb_gencc_checkPlusAhead( PFUNCTION pFunc, ULONG lPCodePos, PHB_LABEL_INFO cargo ) +{ + if( HB_GENC_GETLABEL( lPCodePos ) == 0 ) + { + switch( pFunc->pCode[ lPCodePos ] ) + { + case HB_P_POPLOCALNEAR: + fprintf( cargo->yyc, "\thb_xvmLocalAdd( %d );\n", + ( signed char ) pFunc->pCode[ lPCodePos + 1 ] ); + return 2; + + case HB_P_POPLOCAL: + fprintf( cargo->yyc, "\thb_xvmLocalAdd( %d );\n", + HB_PCODE_MKSHORT( &pFunc->pCode[ lPCodePos + 1 ] ) ); + return 3; + + case HB_P_POPSTATIC: + fprintf( cargo->yyc, "\thb_xvmStaticAdd( %hu );\n", + HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] ) ); + return 3; + + case HB_P_POPMEMVAR: + fprintf( cargo->yyc, "\thb_xvmMemvarAdd( symbols + %hu );\n", + HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] ) ); + return 3; + } + } + return 0; +} + static HB_GENC_FUNC( hb_p_and ) { HB_GENC_LABEL(); @@ -665,8 +760,15 @@ static HB_GENC_FUNC( hb_p_parameter ) static HB_GENC_FUNC( hb_p_plus ) { + int iSkip; + HB_GENC_LABEL(); + iSkip = hb_gencc_checkPlusAhead( pFunc, lPCodePos + 1, cargo ); + + if( iSkip != 0 ) + return 1 + iSkip; + fprintf( cargo->yyc, "\tif( hb_xvmPlus() ) break;\n" ); return 1; } @@ -736,7 +838,7 @@ static HB_GENC_FUNC( hb_p_poplocalnear ) { HB_GENC_LABEL(); - fprintf( cargo->yyc, "\thb_xvmPopLocal( %hd );\n", + fprintf( cargo->yyc, "\thb_xvmPopLocal( %d );\n", ( signed char ) pFunc->pCode[ lPCodePos + 1 ] ); return 2; } @@ -1070,6 +1172,14 @@ static HB_GENC_FUNC( hb_p_pushsym ) { HB_GENC_LABEL(); + if( HB_GENC_GETLABEL( lPCodePos + 3 ) == 0 && + pFunc->pCode[ lPCodePos + 3 ] == HB_P_PUSHNIL ) + { + fprintf( cargo->yyc, "\thb_xvmPushFuncSymbol( symbols + %hu );\n", + HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] ) ); + return 4; + } + fprintf( cargo->yyc, "\thb_xvmPushSymbol( symbols + %hu );\n", HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] ) ); return 3; @@ -1079,6 +1189,14 @@ static HB_GENC_FUNC( hb_p_pushsymnear ) { HB_GENC_LABEL(); + if( HB_GENC_GETLABEL( lPCodePos + 2 ) == 0 && + pFunc->pCode[ lPCodePos + 2 ] == HB_P_PUSHNIL ) + { + fprintf( cargo->yyc, "\thb_xvmPushFuncSymbol( symbols + %hu );\n", + pFunc->pCode[ lPCodePos + 1 ] ); + return 3; + } + fprintf( cargo->yyc, "\thb_xvmPushSymbol( symbols + %d );\n", pFunc->pCode[ lPCodePos + 1 ] ); return 2; @@ -1621,7 +1739,7 @@ void hb_compGenCRealCode( PFUNCTION pFunc, FILE * yyc ) fprintf( yyc, " } while ( 0 );\n" ); if( label_info.fForEach ) fprintf( yyc, " while( lForEachBase )\n {\n\thb_stackRemove( lForEachBase );\n\thb_xvmEnumEnd( &lForEachBase );\n }\n" ); - fprintf( yyc, " hb_xvmExitPorc( ulPrivateBase );\n" ); + fprintf( yyc, " hb_xvmExitProc( ulPrivateBase );\n" ); fprintf( yyc, "}\n" ); if( label_info.pulLabels ) diff --git a/harbour/source/compiler/gencli.c b/harbour/source/compiler/gencli.c index f3e8317217..130076d7c5 100644 --- a/harbour/source/compiler/gencli.c +++ b/harbour/source/compiler/gencli.c @@ -102,140 +102,6 @@ void hb_compGenILCode( PHB_FNAME pFileName ) /* generates the IL output */ fprintf( yyc, ".assembly " ); fprintf( yyc, hb_strupr( pFileName->szName ) ); fprintf( yyc, "_PRG{}\n" ); - // if( hb_comp_iGenCOutput != HB_COMPGENC_COMPACT ) - // fprintf( yyc, "#include \"hbpcode.h\"\n" ); - // fprintf( yyc, "#include \"hbinit.h\"\n\n\n" ); - - // if( ! hb_comp_bStartProc ) - // pFunc = pFunc->pNext; /* No implicit starting procedure */ - - // /* write functions prototypes for PRG defined functions */ - // while( pFunc ) - // { - // bIsInitFunction = ( pFunc->cScope & HB_FS_INIT ) ; - // bIsExitFunction = ( pFunc->cScope & HB_FS_EXIT ) ; - // bIsStaticVariable = ( pFunc == hb_comp_pInitFunc ) ; - // bIsPublicFunction = ( pFunc->cScope == HB_FS_PUBLIC ) ; - // - // /* Is it a PUBLIC FUNCTION/PROCEDURE */ - // if ( bIsPublicFunction ) - // fprintf( yyc, "HB_FUNC( %s );\n", pFunc->szName ); - // /* Is it a STATIC$ */ - // else if ( bIsStaticVariable ) - // fprintf( yyc, "static HARBOUR hb_INITSTATICS( void );\n" ); /* NOTE: hb_ intentionally in lower case */ - // /* Is it an INIT FUNCTION/PROCEDURE */ - // else if ( bIsInitFunction ) - // fprintf( yyc, "HB_FUNC_INIT( %s );\n", pFunc->szName ); - // /* Is it an EXIT FUNCTION/PROCEDURE */ - // else if ( bIsExitFunction ) - // fprintf( yyc, "HB_FUNC_EXIT( %s );\n", pFunc->szName ); - // /* Then it must be a STATIC FUNCTION/PROCEDURE */ - // else - // fprintf( yyc, "HB_FUNC_STATIC( %s );\n", pFunc->szName ); - // - // pFunc = pFunc->pNext; - // } - - // /* write functions prototypes for inline blocks */ - // while( pInline ) - // { - // if( pInline->szName ) - // fprintf( yyc, "HB_FUNC_STATIC( %s );\n", pInline->szName ); - // pInline = pInline->pNext; - // } - - // /* write functions prototypes for called functions outside this PRG */ - // pFunc = hb_comp_funcalls.pFirst; - // while( pFunc ) - // { - // if( hb_compFunctionFind( pFunc->szName ) == NULL && - // hb_compInlineFind( pFunc->szName ) == NULL ) - // fprintf( yyc, "HB_FUNC_EXTERN( %s );\n", pFunc->szName ); - // - // pFunc = pFunc->pNext; - // } - - // /* writes the symbol table */ - // /* Generate the wrapper that will initialize local symbol table - // */ - // hb_strupr( pFileName->szName ); - // fprintf( yyc, "\n\nHB_INIT_SYMBOLS_BEGIN( hb_vm_SymbolInit_%s%s )\n", hb_comp_szPrefix, pFileName->szName ); - - // while( pSym ) - // { - // if( pSym->szName[ 0 ] == '(' ) - // { - // /* Since the normal function cannot be INIT and EXIT at the same time - // * we are using these two bits to mark the special function used to - // * initialize static variables - // */ - // fprintf( yyc, "{ \"(_INITSTATICS)\", HB_FS_INIT | HB_FS_EXIT, {hb_INITSTATICS}, NULL }" ); /* NOTE: hb_ intentionally in lower case */ - // } - // else - // { - // fprintf( yyc, "{ \"%s\", ", pSym->szName ); - // - // if( pSym->cScope & HB_FS_STATIC ) - // { - // fprintf( yyc, "HB_FS_STATIC" ); - // - // if( pSym->cScope & HB_FS_PUBLIC ) - // fprintf( yyc, " | HB_FS_PUBLIC" ); - // } - // - // else if( pSym->cScope & HB_FS_INIT ) - // fprintf( yyc, "HB_FS_INIT" ); - // - // else if( pSym->cScope & HB_FS_EXIT ) - // fprintf( yyc, "HB_FS_EXIT" ); - // - // else - // fprintf( yyc, "HB_FS_PUBLIC" ); - // - // if( pSym->cScope & VS_MEMVAR ) - // fprintf( yyc, " | HB_FS_MEMVAR" ); - // - // if( pSym->cScope & HB_FS_MESSAGE ) - // fprintf( yyc, " | HB_FS_MESSAGE" ); - // - // if ( ( pSym->cScope & HB_FS_FIRST ) && ( ! hb_comp_bNoStartUp ) ) - // fprintf( yyc, " | HB_FS_FIRST" ); - // - // /* specify the function address if it is a defined function or an - // external called function */ - // if( hb_compFunctionFind( pSym->szName ) ) /* is it a function defined in this module */ - // fprintf( yyc, ", {HB_FUNCNAME( %s )}, NULL }", pSym->szName ); - // else if( hb_compFunCallFind( pSym->szName ) ) /* is it a function called from this module */ - // fprintf( yyc, ", {HB_FUNCNAME( %s )}, NULL }", pSym->szName ); - // else - // fprintf( yyc, ", {NULL}, NULL }" ); /* memvar */ - // } - // - // if( pSym != hb_comp_symbols.pLast ) - // fprintf( yyc, ",\n" ); - // - // pSym = pSym->pNext; - // } - - // fprintf( yyc, "\nHB_INIT_SYMBOLS_END( hb_vm_SymbolInit_%s%s )\n" - // "#if defined(_MSC_VER)\n" - // " #if _MSC_VER >= 1010\n" - // /* [pt] First version of MSC I have that supports this */ - // /* is msvc4.1 (which is msc 10.10) */ - // " #pragma data_seg( \".CRT$XIY\" )\n" - // " #pragma comment( linker, \"/Merge:.CRT=.data\" )\n" - // " #else\n" - // " #pragma data_seg( \"XIY\" )\n" - // " #endif\n" - // " static HB_$INITSYM hb_vm_auto_SymbolInit_%s%s = hb_vm_SymbolInit_%s%s;\n" - // " #pragma data_seg()\n" - // "#elif ! defined(__GNUC__)\n" - // " #pragma startup hb_vm_SymbolInit_%s%s\n" - // "#endif\n\n", - // hb_comp_szPrefix, pFileName->szName, - // hb_comp_szPrefix, pFileName->szName, - // hb_comp_szPrefix, pFileName->szName, - // hb_comp_szPrefix, pFileName->szName ); /* Generate functions data */ @@ -282,7 +148,6 @@ void hb_compGenILCode( PHB_FNAME pFileName ) /* generates the IL output */ fprintf( yyc, " ret\n}\n" ); - // fprintf( yyc, " hb_vmExecute( pcode, symbols );\n}\n\n" ); pFunc = pFunc->pNext; } @@ -316,7 +181,7 @@ void hb_compGenILCode( PHB_FNAME pFileName ) /* generates the IL output */ fprintf( yyc, "/* Empty source file */\n\n" ); } - // Generate .NET support functions + /* Generate .NET support functions */ hb_genNetFunctions( yyc ); fclose( yyc ); @@ -399,7 +264,7 @@ static HB_GENC_FUNC( hb_p_arraypush ) fprintf( cargo->yyc, " IL_%04lX: ", lPCodePos ); fprintf( cargo->yyc, "call object ObjArrayPush( object, object )\n" ); - // fprintf( cargo->yyc, "\tHB_P_ARRAYPUSH,\n" ); + /* fprintf( cargo->yyc, "\tHB_P_ARRAYPUSH,\n" ); */ return 1; } @@ -475,7 +340,7 @@ static HB_GENC_FUNC( hb_p_doshort ) fprintf( cargo->yyc, "call object %s( object )\n", szFunName ); fprintf( cargo->yyc, " pop\n" ); - // fprintf( cargo->yyc, "\tHB_P_DOSHORT, %i,\n", pFunc->pCode[ lPCodePos + 1 ] ); + /* fprintf( cargo->yyc, "\tHB_P_DOSHORT, %i,\n", pFunc->pCode[ lPCodePos + 1 ] ); */ return 2; } @@ -515,7 +380,7 @@ static HB_GENC_FUNC( hb_p_exactlyequal ) fprintf( cargo->yyc, " IL_%04lX: ", lPCodePos ); fprintf( cargo->yyc, "call bool ObjExactlyEqual( object, object )\n" ); - // fprintf( cargo->yyc, "\tHB_P_EXACTLYEQUAL,\n" ); + /* fprintf( cargo->yyc, "\tHB_P_EXACTLYEQUAL,\n" ); */ return 1; } @@ -535,10 +400,6 @@ static HB_GENC_FUNC( hb_p_endproc ) HB_SYMBOL_UNUSED( cargo ); HB_SYMBOL_UNUSED( lPCodePos ); - // if( (lPCodePos+1) == pFunc->lPCodePos ) - // fprintf( cargo->yyc, "\tHB_P_ENDPROC\n" ); - // else - // fprintf( cargo->yyc, "\tHB_P_ENDPROC,\n" ); return 1; } @@ -551,8 +412,6 @@ static HB_GENC_FUNC( hb_p_false ) fprintf( cargo->yyc, "ldc.i4.0\n" ); fprintf( cargo->yyc, " box [mscorlib]System.Boolean\n" ); - // fprintf( cargo->yyc, "\tHB_P_FALSE,\n" ); - return 1; } @@ -564,7 +423,6 @@ static HB_GENC_FUNC( hb_p_fortest ) fprintf( cargo->yyc, " IL_%04lX: ", lPCodePos ); fprintf( cargo->yyc, "call bool ObjForTest( object, object, object )\n" ); - // fprintf( cargo->yyc, "\tHB_P_FORTEST,\n" ); return 1; } @@ -584,12 +442,6 @@ static HB_GENC_FUNC( hb_p_frame ) fprintf( cargo->yyc, " )\n" ); - // fprintf( cargo->yyc, "\tHB_P_FRAME, %i, %i,", - // pFunc->pCode[ lPCodePos + 1 ], - // pFunc->pCode[ lPCodePos + 2 ] ); - // if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* locals, params */" ); - // fprintf( cargo->yyc, "\n" ); - return 3; } @@ -635,8 +487,6 @@ static HB_GENC_FUNC( hb_p_functionshort ) fprintf( cargo->yyc, " IL_%04lX: ", lPCodePos ); fprintf( cargo->yyc, "call object %s( object )\n", szFunName ); - // fprintf( cargo->yyc, "\tHB_P_FUNCTIONHORT, %i,\n", pFunc->pCode[ lPCodePos + 1 ] ); - return 2; } @@ -652,12 +502,6 @@ static HB_GENC_FUNC( hb_p_arraygen ) fprintf( cargo->yyc, ")\n" ); - // fprintf( cargo->yyc, "\tHB_P_ARRAYGEN, %i, %i,", - // pFunc->pCode[ lPCodePos + 1 ], - // pFunc->pCode[ lPCodePos + 2 ] ); - // if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %i */", pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 ); - // fprintf( cargo->yyc, "\n" ); - return 3; } @@ -708,19 +552,6 @@ static HB_GENC_FUNC( hb_p_jumpnear ) fprintf( cargo->yyc, "br.s" ); fprintf( cargo->yyc, " IL_%04lX\n", ( LONG ) ( lPCodePos + lOffset ) ); - // fprintf( cargo->yyc, "\tHB_P_JUMPNEAR, %i,", - // pFunc->pCode[ lPCodePos + 1 ] ); - // if( cargo->bVerbose ) - // { - // LONG lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] ); - // - // if( lOffset > 127 ) - // lOffset -= 256; - // - // fprintf( cargo->yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) ); - // } - // fprintf( cargo->yyc, "\n" ); - return 2; } @@ -736,20 +567,6 @@ static HB_GENC_FUNC( hb_p_jump ) fprintf( cargo->yyc, "br.s" ); fprintf( cargo->yyc, " IL_%04lX\n", ( LONG ) ( lPCodePos + lOffset ) ); - // fprintf( cargo->yyc, "\tHB_P_JUMP, %i, %i,", - // pFunc->pCode[ lPCodePos + 1 ], - // pFunc->pCode[ lPCodePos + 2 ] ); - // if( cargo->bVerbose ) - // { - // LONG lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 ); - // - // if( lOffset > SHRT_MAX ) - // lOffset -= 65536; - // - // fprintf( cargo->yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) ); - // } - // fprintf( cargo->yyc, "\n" ); - return 3; } @@ -782,18 +599,6 @@ static HB_GENC_FUNC( hb_p_jumpfalsenear ) fprintf( cargo->yyc, "brfalse.s" ); fprintf( cargo->yyc, " IL_%04lX\n", ( LONG ) ( lPCodePos + lOffset ) ); - // fprintf( cargo->yyc, "\tHB_P_JUMPFALSENEAR, %i,", - // pFunc->pCode[ lPCodePos + 1 ] ); - // if( cargo->bVerbose ) - // { - // LONG lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] ); - // - // if( lOffset > 127 ) - // lOffset -= 256; - // - // fprintf( cargo->yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) ); - // } - // fprintf( cargo->yyc, "\n" ); return 2; } @@ -901,7 +706,6 @@ static HB_GENC_FUNC( hb_p_lessequal ) fprintf( cargo->yyc, " IL_%04lX: ", lPCodePos ); fprintf( cargo->yyc, "call bool ObjLessEqual( object, object )\n" ); - // fprintf( cargo->yyc, "\tHB_P_LESSEQUAL,\n" ); return 1; } @@ -912,16 +716,6 @@ static HB_GENC_FUNC( hb_p_line ) fprintf( cargo->yyc, " IL_%04lX: ", lPCodePos ); fprintf( cargo->yyc, "nop // HB_P_LINE\n" ); - // if( cargo->bVerbose ) - // fprintf( cargo->yyc, "/* %05li */ ", lPCodePos ); - // else - // fprintf( cargo->yyc, "\t" ); - // fprintf( cargo->yyc, "HB_P_LINE, %i, %i,", - // pFunc->pCode[ lPCodePos + 1 ], - // pFunc->pCode[ lPCodePos + 2 ] ); - // if( cargo->bVerbose ) - // fprintf( cargo->yyc, "\t/* %i */", pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 ); - // fprintf( cargo->yyc, "\n" ); return 3; } @@ -1123,8 +917,6 @@ static HB_GENC_FUNC( hb_p_not ) fprintf( cargo->yyc, " IL_%04lX: ", lPCodePos ); fprintf( cargo->yyc, "call object ObjNot( object )\n" ); - // fprintf( cargo->yyc, "\tHB_P_NOT,\n" ); - return 1; } @@ -1163,7 +955,6 @@ static HB_GENC_FUNC( hb_p_plus ) HB_SYMBOL_UNUSED( lPCodePos ); fprintf( cargo->yyc, " call object ObjAdd( object, object )\n" ); - // fprintf( cargo->yyc, "\tHB_P_PLUS,\n" ); return 1; } @@ -1255,34 +1046,11 @@ static HB_GENC_FUNC( hb_p_poplocal ) static HB_GENC_FUNC( hb_p_poplocalnear ) { - // important: check the below code for codeblock locals management + /* important: check the below code for codeblock locals management */ fprintf( cargo->yyc, " IL_%04lX: ", lPCodePos ); - // warning: IL requires zero based locals index + /* warning: IL requires zero based locals index */ fprintf( cargo->yyc, "stloc.%i\n", pFunc->pCode[ lPCodePos + 1 ] - 1 ); - // fprintf( cargo->yyc, "\tHB_P_POPLOCALNEAR, %i,", - // pFunc->pCode[ lPCodePos + 1 ] ); - // if( cargo->bVerbose ) - // { - // char wVar = ( char ) pFunc->pCode[ lPCodePos + 1 ]; - // /* Variable with negative order are local variables - // * referenced in a codeblock -handle it with care - // */ - // - // if( cargo->iNestedCodeblock ) - // { - // /* we are accesing variables within a codeblock */ - // /* the names of codeblock variable are lost */ - // if( wVar < 0 ) - // fprintf( cargo->yyc, "\t/* localvar%i */", -wVar ); - // else - // fprintf( cargo->yyc, "\t/* codeblockvar%i */", wVar ); - // } - // else - // fprintf( cargo->yyc, "\t/* %s */", hb_compLocalVariableFind( pFunc, wVar )->szName ); - // } - // fprintf( cargo->yyc, "\n" ); - return 2; } @@ -1470,17 +1238,11 @@ static HB_GENC_FUNC( hb_p_pushfield ) static HB_GENC_FUNC( hb_p_pushbyte ) { fprintf( cargo->yyc, " IL_%04lX: ", lPCodePos ); - // load constant numeric onto the stack + /* load constant numeric onto the stack */ fprintf( cargo->yyc, "ldc.i4.s %i\n", pFunc->pCode[ lPCodePos + 1 ] ); - // turn the stack value into an object + /* turn the stack value into an object */ fprintf( cargo->yyc, " box [mscorlib]System.Int32\n" ); - // fprintf( cargo->yyc, "\tHB_P_PUSHBYTE, %i,", - // pFunc->pCode[ lPCodePos + 1 ] ); - // if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %i */", - // pFunc->pCode[ lPCodePos + 1 ] ); - // fprintf( cargo->yyc, "\n" ); - return 2; } @@ -1526,34 +1288,11 @@ static HB_GENC_FUNC( hb_p_pushlocal ) static HB_GENC_FUNC( hb_p_pushlocalnear ) { - // Important: check the below code for codeblocks locals + /* Important: check the below code for codeblocks locals */ fprintf( cargo->yyc, " IL_%04lX: ", lPCodePos ); - // Warning: IL uses zero based locals indexes + /* Warning: IL uses zero based locals indexes */ fprintf( cargo->yyc, "ldloc.%i\n", pFunc->pCode[ lPCodePos + 1 ] - 1 ); - // fprintf( cargo->yyc, "\tHB_P_PUSHLOCALNEAR, %i,", - // pFunc->pCode[ lPCodePos + 1 ] ); - // if( cargo->bVerbose ) - // { - // signed char wVar = ( signed char ) pFunc->pCode[ lPCodePos + 1 ]; - // /* Variable with negative order are local variables - // * referenced in a codeblock -handle it with care - // */ - // - // if( cargo->iNestedCodeblock ) - // { - // /* we are accesing variables within a codeblock */ - // /* the names of codeblock variable are lost */ - // if( wVar < 0 ) - // fprintf( cargo->yyc, "\t/* localvar%i */", -wVar ); - // else - // fprintf( cargo->yyc, "\t/* codeblockvar%i */", wVar ); - // } - // else - // fprintf( cargo->yyc, "\t/* %s */", hb_compLocalVariableFind( pFunc, wVar )->szName ); - // } - // fprintf( cargo->yyc, "\n" ); - return 2; } @@ -1592,14 +1331,6 @@ static HB_GENC_FUNC( hb_p_pushlong ) *( ( long * ) &( pFunc->pCode[ lPCodePos + 1 ] ) ) ); fprintf( cargo->yyc, " box [mscorlib]System.Int32\n" ); - // fprintf( cargo->yyc, "\tHB_P_PUSHLONG, %i, %i, %i, %i,", - // pFunc->pCode[ lPCodePos + 1 ], - // pFunc->pCode[ lPCodePos + 2 ], - // pFunc->pCode[ lPCodePos + 3 ], - // pFunc->pCode[ lPCodePos + 4 ] ); - // if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %li */", *( ( long * ) &( pFunc->pCode[ lPCodePos + 1 ] ) ) ); - // fprintf( cargo->yyc, "\n" ); - return 5; } @@ -1651,18 +1382,20 @@ static HB_GENC_FUNC( hb_p_pushnil ) pTemp->bFirstParam = FALSE; else { - // fprintf( cargo->yyc, " IL_%04lX: ", lPCodePos ); - // fprintf( cargo->yyc, "ldnull\n" ); +/* + fprintf( cargo->yyc, " IL_%04lX: ", lPCodePos ); + fprintf( cargo->yyc, "ldnull\n" ); +*/ } } else { - // fprintf( cargo->yyc, " IL_%04lX: ", lPCodePos ); - // fprintf( cargo->yyc, "ldnull\n" ); +/* + fprintf( cargo->yyc, " IL_%04lX: ", lPCodePos ); + fprintf( cargo->yyc, "ldnull\n" ); +*/ } - // fprintf( cargo->yyc, " // HB_P_PUSHNIL,\n" ); - return 1; } @@ -1759,13 +1492,9 @@ static HB_GENC_FUNC( hb_p_pushstrshort ) ULONG ulStart = lPCodePos; USHORT wLen = pFunc->pCode[ lPCodePos + 1 ]; - // fprintf( cargo->yyc, "\tHB_P_PUSHSTRSHORT, %i,", pFunc->pCode[ lPCodePos + 1 ] ); fprintf( cargo->yyc, " IL_%04lX: ", lPCodePos ); fprintf( cargo->yyc, "ldstr " ); - // if( cargo->bVerbose ) - // fprintf( cargo->yyc, "\t/* %i */", wLen ); - lPCodePos += 2; if( wLen > 0 ) { @@ -1828,17 +1557,9 @@ static HB_GENC_FUNC( hb_p_pushsymnear ) pTemp->bFirstParam = TRUE; pTemp->pNext = NULL; - // fprintf( cargo->yyc, "\tHB_P_PUSHSYMNEAR, %i,", - // pFunc->pCode[ lPCodePos + 1 ] ); - // if( cargo->bVerbose ) - // fprintf( cargo->yyc, "\t/* %s */", hb_compSymbolGetPos( pFunc->pCode[ lPCodePos + 1 ] )->szName ); - fprintf( cargo->yyc, " IL_%04lX: ", lPCodePos ); fprintf( cargo->yyc, "nop\n" ); - // fprintf( cargo->yyc, " call void %s()\n", hb_compSymbolGetPos( pFunc->pCode[ lPCodePos + 1 ] )->szName ); - // fprintf( cargo->yyc, "\n" ); - return 2; } @@ -1981,8 +1702,6 @@ static HB_GENC_FUNC( hb_p_true ) fprintf( cargo->yyc, "ldc.i4.1\n" ); fprintf( cargo->yyc, " box [mscorlib]System.Boolean\n" ); - // fprintf( cargo->yyc, "\tHB_P_TRUE,\n" ); - return 1; } @@ -1993,11 +1712,9 @@ static HB_GENC_FUNC( hb_p_one ) fprintf( cargo->yyc, " IL_%04lX: ", lPCodePos ); fprintf( cargo->yyc, "ldc.i4.1\n" ); - // turn the stack value into an object + /* turn the stack value into an object */ fprintf( cargo->yyc, " box [mscorlib]System.Int32\n" ); - // fprintf( cargo->yyc, "\tHB_P_ONE,\n" ); - return 1; } @@ -2087,18 +1804,6 @@ static HB_GENC_FUNC( hb_p_localnearaddint ) fprintf( cargo->yyc, " box [mscorlib]System.Int32\n" ); fprintf( cargo->yyc, " stloc.%i\n", pFunc->pCode[ lPCodePos + 1 ] - 1 ); - // fprintf( cargo->yyc, "\tHB_P_LOCALNEARADDINT, %i, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], - // pFunc->pCode[ lPCodePos + 2 ], - // pFunc->pCode[ lPCodePos + 3 ] ); - // - // if( cargo->bVerbose ) - // { - // fprintf( cargo->yyc, "\t/* %s %i*/", hb_compLocalVariableFind( pFunc, ( signed char ) pFunc->pCode[ lPCodePos + 1 ] )->szName, - // HB_PCODE_MKSHORT( &( pFunc->pCode[ lPCodePos + 2 ] ) ) ); - // } - // - // fprintf( cargo->yyc, "\n" ); - return 4; } @@ -2257,9 +1962,6 @@ static void hb_compGenCReadable( PFUNCTION pFunc, FILE * yyc ) genc_info.yyc = yyc; hb_compPCodeEval( pFunc, ( HB_PCODE_FUNC_PTR * ) s_verbose_table, ( void * ) &genc_info ); - - // if( genc_info.bVerbose ) - // fprintf( yyc, "/* %05li */\n", pFunc->lPCodePos ); } static void hb_compGenCCompact( PFUNCTION pFunc, FILE * yyc ) @@ -2296,6 +1998,7 @@ static void hb_genNetFunctions( FILE * yyc ) { int i; +/* // generated IL code for C# source code: // public static object ObjAdd( object a, object b ) // { @@ -2309,6 +2012,7 @@ static void hb_genNetFunctions( FILE * yyc ) // } // VERY IMPORTANT: As ObjAdd() is a public method, not specific to a Class, // then arguments have to be decreased, as on a normal method, argument 0 is Self. +*/ char * ObjAdd[] = { "\n.method public static object ObjAdd(object a, object b)", @@ -2359,6 +2063,7 @@ static void hb_genNetFunctions( FILE * yyc ) " IL_0078: ret", "}", 0 }; +/* // public static object ObjArrayGen( __arglist ) // { // ArrayList a = new ArrayList(); @@ -2369,7 +2074,7 @@ static void hb_genNetFunctions( FILE * yyc ) // // return a; // } - +*/ char * ObjArrayGen[] = { "\n.method public static vararg object ObjArrayGen()", "{", @@ -2401,10 +2106,12 @@ static void hb_genNetFunctions( FILE * yyc ) " IL_0034: ret", "}", 0 }; +/* // public static object ObjArrayPush( object array, object index ) // { // return ( ( ArrayList ) array )[ ( ( int ) index ) - 1 ]; // } +*/ char * ObjArrayPush[] = { "\n.method public static object ObjArrayPush(object 'array', object index)", @@ -2425,6 +2132,7 @@ static void hb_genNetFunctions( FILE * yyc ) " IL_0018: ret", "}", 0 }; +/* // public static bool ObjLessEqual( object a, object b ) // { // if( a.GetType() == typeof( int ) && b.GetType() == typeof( int ) ) @@ -2432,6 +2140,7 @@ static void hb_genNetFunctions( FILE * yyc ) // // return false; // } +*/ char * ObjLessEqual[] = { "\n.method public static bool ObjLessEqual( object a, object b )", @@ -2466,6 +2175,7 @@ static void hb_genNetFunctions( FILE * yyc ) " IL_003f: ret", "}", 0 }; +/* // public static bool ObjForTest( object current, object end, object step ) // { // if( ( int ) step >= 0 ) @@ -2473,6 +2183,7 @@ static void hb_genNetFunctions( FILE * yyc ) // else // return ( int ) current >= ( int ) end; // } +*/ char * ObjForTest[] = { "\n.method public static bool ObjForTest(object current,object end,object step)", @@ -2510,6 +2221,7 @@ static void hb_genNetFunctions( FILE * yyc ) " IL_0037: ret", "}", 0 }; +/* // public static bool ObjExactlyEqual( object a, object b ) // { // if( a.GetType() == typeof( int ) && b.GetType() == typeof( int ) ) @@ -2520,6 +2232,7 @@ static void hb_genNetFunctions( FILE * yyc ) // // return false; // } +*/ char * ObjExactlyEqual[] = { "\n.method public static bool ObjExactlyEqual(object a, object b)", @@ -2569,10 +2282,12 @@ static void hb_genNetFunctions( FILE * yyc ) " IL_0074: ret", "}", 0 }; +/* // public static object ObjNot( object o ) // { // return ! ( bool ) o; // } +*/ char * ObjNot[] = { "\n.method public static object ObjNot(object o)", @@ -2591,10 +2306,12 @@ static void hb_genNetFunctions( FILE * yyc ) " IL_0013: ret", "}", 0 }; +/* // public static object LEN( object o ) // { // return ( ( ArrayList ) o ).Count; // } +*/ char * LEN[] = { "\n.method public static object LEN(object o)", @@ -2611,6 +2328,7 @@ static void hb_genNetFunctions( FILE * yyc ) " IL_0014: ret", "}", 0 }; +/* // public static object QOUT( object o ) // { // if( o == null ) @@ -2624,6 +2342,7 @@ static void hb_genNetFunctions( FILE * yyc ) // // return null; // } +*/ char * QOUT[] = { "\n.method public static object QOUT(object o)", diff --git a/harbour/source/compiler/harbour.c b/harbour/source/compiler/harbour.c index cbdf0c58af..a2176f6ab6 100644 --- a/harbour/source/compiler/harbour.c +++ b/harbour/source/compiler/harbour.c @@ -1944,11 +1944,10 @@ void hb_compFunctionAdd( char * szFunName, HB_SYMBOLSCOPE cScope, int iType ) int iLen; iLen = strlen(szFunName); - szNewName =(char *)hb_xgrab( iLen+2 ); - szNewName[0] = '\0'; + szNewName = ( char * ) hb_xgrab( iLen + 2 ); strcpy( szNewName, szFunName ); szNewName[ iLen ] ='$'; - szNewName[ iLen+1 ] = '\0'; + szNewName[ iLen + 1 ] = '\0'; szFunName = hb_compIdentifierNew( szNewName, TRUE ); hb_xfree( szNewName ); } @@ -2207,13 +2206,13 @@ void hb_compExternGen( void ) /* generates the symbols for the EXTERN names */ { if( hb_compSymbolFind( hb_comp_pExterns->szName, NULL, HB_SYM_FUNCNAME ) ) { - if( ! hb_compFunCallFind( hb_comp_pExterns->szName ) ) + if( ! hb_compFunCallFind( hb_comp_pExterns->szName ) ) hb_compFunCallAdd( hb_comp_pExterns->szName ); } else { - hb_compSymbolAdd( hb_comp_pExterns->szName, NULL, HB_SYM_FUNCNAME ); - hb_compFunCallAdd( hb_comp_pExterns->szName ); + hb_compSymbolAdd( hb_comp_pExterns->szName, NULL, HB_SYM_FUNCNAME ); + hb_compFunCallAdd( hb_comp_pExterns->szName ); } pDelete = hb_comp_pExterns; hb_comp_pExterns = hb_comp_pExterns->pNext; @@ -4404,7 +4403,7 @@ void hb_compStaticDefStart( void ) { BYTE pBuffer[ 5 ]; - hb_comp_pInitFunc = hb_compFunctionNew( hb_compIdentifierNew("(_INITSTATICS)", TRUE), HB_FS_INIT ); + hb_comp_pInitFunc = hb_compFunctionNew( hb_compIdentifierNew( "(_INITSTATICS)", TRUE ), HB_FS_INITEXIT ); hb_comp_pInitFunc->pOwner = hb_comp_functions.pLast; hb_comp_pInitFunc->bFlags = FUN_USES_STATICS | FUN_PROCEDURE; hb_comp_pInitFunc->cScope = HB_FS_INITEXIT; @@ -4822,7 +4821,7 @@ int hb_compCompile( char * szPrg, int argc, char * argv[] ) { hb_comp_pFilePpo = hb_fsFNameSplit( szPrg ); hb_compPpoFile(); - //hb_comp_pFileName->szExtension = ".ppo"; + /*hb_comp_pFileName->szExtension = ".ppo";*/ hb_fsFNameMerge( szPpoName, hb_comp_pFilePpo ); hb_comp_yyppo = fopen( szPpoName, "w" ); if( ! hb_comp_yyppo ) @@ -4909,11 +4908,15 @@ int hb_compCompile( char * szPrg, int argc, char * argv[] ) if( hb_comp_pInitFunc ) { PCOMSYMBOL pSym; + char szNewName[ 32 ]; /* Fix the number of static variables */ hb_comp_pInitFunc->pCode[ 3 ] = HB_LOBYTE( hb_comp_iStaticCnt ); hb_comp_pInitFunc->pCode[ 4 ] = HB_HIBYTE( hb_comp_iStaticCnt ); hb_comp_pInitFunc->iStaticsBase = hb_comp_iStaticCnt; + /* Update pseudo function name */ + sprintf( szNewName, "(_INITSTATICS%05d)", hb_comp_iStaticCnt ); + hb_comp_pInitFunc->szName = hb_compIdentifierNew( szNewName, TRUE ); pSym = hb_compSymbolAdd( hb_comp_pInitFunc->szName, NULL, HB_SYM_FUNCNAME ); pSym->cScope |= hb_comp_pInitFunc->cScope; diff --git a/harbour/source/compiler/hbusage.c b/harbour/source/compiler/hbusage.c index 66bdb127c3..6b885e200d 100644 --- a/harbour/source/compiler/hbusage.c +++ b/harbour/source/compiler/hbusage.c @@ -174,6 +174,7 @@ void hb_compPrintCredits( void ) "Paul Tucker \n" "Peter Townsend \n" "Phil Barnett \n" + "Przemyslaw Czerpak \n" "Ron Pinkas \n" "Ryszard Glab \n" "Tim Stone \n" diff --git a/harbour/source/rdd/dbcmd.c b/harbour/source/rdd/dbcmd.c index 00168b8474..e04a330e50 100644 --- a/harbour/source/rdd/dbcmd.c +++ b/harbour/source/rdd/dbcmd.c @@ -1061,7 +1061,7 @@ HB_EXPORT ERRCODE hb_rddSelectWorkAreaAlias( char * szAlias ) } /* - * Function for getting current workarea pointer + * Function for getting current workarea pointer */ HB_EXPORT void * hb_rddGetCurrentWorkAreaPointer( void ) { @@ -4643,262 +4643,3 @@ HB_FUNC( DBSKIPPER ) hb_errRT_DBCMD( EG_NOTABLE, EDBCMD_NOTABLE, NULL, "DBSKIPPER" ); } #endif - - - - - -/* Escaping delimited strings. Need to be cleaned/optimized/improved */ -static char *hb_strescape( char *szInput, int lLen, char *cDelim ) -{ - int lCnt = 0; - char * szChr; - char * szEscape; - char * szReturn; - - szReturn = szEscape = ( char * ) hb_xgrab( lLen * 2 + 4 ); - - while( lLen && HB_ISSPACE( szInput[ lLen - 1 ] ) ) - { - lLen--; - } - - szChr = szInput; - - while ( *szChr && lCnt++ < lLen ) - { - if( *szChr == *cDelim ) - { - *szEscape++ = '\\'; - } - *szEscape++ = *szChr++; - } - *szEscape = '\0'; - - return szReturn; -} - -/* Export field values to text file */ -#ifndef HB_CDP_SUPPORT_OFF -static BOOL hb_ExportVar( int handle, PHB_ITEM pValue, char *cDelim, PHB_CODEPAGE cdp ) -#else -static BOOL hb_ExportVar( int handle, PHB_ITEM pValue, char *cDelim ) -#endif -{ - switch( hb_itemType( pValue ) ) - { - /* a "C" field */ - case HB_IT_STRING: - { - char *szStrEsc; - char *szString; - - szStrEsc = hb_strescape( hb_itemGetCPtr( pValue ), - hb_itemGetCLen( pValue ), cDelim ); -#ifndef HB_CDP_SUPPORT_OFF - if( cdp ) - { - hb_cdpnTranslate( szStrEsc, hb_cdp_page, cdp, hb_itemGetCLen( pValue ) ); - } -#endif - szString = hb_xstrcpy( NULL,cDelim,szStrEsc,cDelim,NULL); - - /* FWrite( handle, szString ) */ - hb_fsWriteLarge( handle, (BYTE*) szString, strlen( szString ) ); - - /* Orphaned, get rif off it */ - hb_xfree( szStrEsc ); - hb_xfree( szString ); - break; - } - /* a "D" field */ - case HB_IT_DATE: - { - char *szDate = (char*) hb_xgrab( 9 ); - - hb_itemGetDS( pValue, szDate ); - hb_fsWriteLarge( handle, (BYTE*) szDate, strlen( szDate ) ); - hb_xfree( szDate ); - break; - } - /* an "L" field */ - case HB_IT_LOGICAL: - { - hb_fsWriteLarge( handle, (BYTE*) ( hb_itemGetL( pValue ) ? "T" : "F" ), 1 ); - break; - } - /* an "N" field */ - case HB_IT_INTEGER: - case HB_IT_LONG: - case HB_IT_DOUBLE: - { - char *szResult = hb_itemStr( pValue, NULL, NULL ); - - if ( szResult ) - { - ULONG ulLen = strlen( szResult ); - char * szTrimmed = hb_strLTrim( szResult, &ulLen ); - - hb_fsWriteLarge( handle, (BYTE*) szTrimmed, strlen( szTrimmed ) ); - hb_xfree( szResult ); - } - break; - } - /* an "M" field or the other, might be a "V" in SixDriver */ - default: - /* We do not want MEMO contents */ - return FALSE; - } - return TRUE; -} - -HB_FUNC( DBF2TEXT ) -{ - HB_THREAD_STUB - - PHB_ITEM pWhile = hb_param( 1, HB_IT_BLOCK ); - PHB_ITEM pFor = hb_param( 2, HB_IT_BLOCK ); - PHB_ITEM pFields = hb_param( 3, HB_IT_ARRAY ); - - char *cDelim = hb_parc( 4 ); - FHANDLE handle = (FHANDLE) hb_parnl(5); - BYTE *cSep = (BYTE *) hb_parc( 6 ); - int nCount = (int) hb_parnl( 7 ); -#ifndef HB_CDP_SUPPORT_OFF - PHB_CODEPAGE cdp = hb_cdpFind( (char *) hb_parc( 8 ) ); -#endif - - AREAP pArea = HB_CURRENT_WA; - - /* Export DBF content to text file */ - - int iSepLen; - USHORT uiFields = 0; - USHORT ui; - PHB_ITEM pTmp; - BOOL bWriteSep = FALSE; - - BOOL bEof = TRUE; - BOOL bBof = TRUE; - - BOOL bNoFieldPassed = ( pFields == NULL || hb_arrayLen( pFields ) == 0 ); - - - if( !pArea ) - { - hb_errRT_DBCMD( EG_NOTABLE, EDBCMD_NOTABLE, NULL, "COPY TO" ); - return; - } - - if( ! handle ) - { - hb_errRT_DBCMD( EG_ARG, EDBCMD_EVAL_BADPARAMETER, NULL, "DBF2TEXT" ); - return; - } - - if( cdp && cdp == hb_cdp_page ) - { - cdp = NULL; - } - - pTmp = hb_itemNew( NULL ); - - if ( !cDelim ) - { - cDelim = "\""; - } - - if ( cSep ) - { - iSepLen = strlen( (char*) cSep ); - } - else - { - cSep = (BYTE*) ','; - iSepLen = 1; - } - - SELF_FIELDCOUNT( pArea, &uiFields ); - - while( ( nCount == -1 || nCount > 0 ) && - ( !pWhile || hb_itemGetL( hb_vmEvalBlock( pWhile ) ) ) ) - { - /* While !BOF() .AND. !EOF() */ - SELF_EOF( pArea, &bEof ); - SELF_BOF( pArea, &bBof ); - - if( bEof || bBof ) - { - break; - } - - /* For condition is met */ - /* if For is NULL, hb__Eval returns TRUE */ - if( !pFor || hb_itemGetL( hb_vmEvalBlock( pFor ) ) ) - { - /* User does not request fields, copy all fields */ - if( bNoFieldPassed ) - { - for ( ui = 1; ui <= uiFields; ui ++ ) - { - if ( bWriteSep ) - { - hb_fsWriteLarge( handle, cSep, iSepLen ); - } - - SELF_GETVALUE( pArea, ui, pTmp ); -#ifndef HB_CDP_SUPPORT_OFF - bWriteSep = hb_ExportVar( handle, pTmp, cDelim, cdp ); -#else - bWriteSep = hb_ExportVar( handle, pTmp, cDelim ); -#endif - hb_itemClear( pTmp ); - } - } - /* Only requested fields are exported here */ - else - { - USHORT uiFieldCopy = ( USHORT ) hb_arrayLen( pFields ); - USHORT uiItter; - - for ( uiItter = 1; uiItter <= uiFieldCopy; uiItter++ ) - { - char * szFieldName = hb_arrayGetCPtr( pFields, uiItter ); - if( szFieldName ) - { - int iPos = hb_rddFieldIndex( pArea, szFieldName ); - - if( iPos ) - { - if ( bWriteSep ) - { - hb_fsWriteLarge( handle, cSep, iSepLen ); - } - SELF_GETVALUE( pArea, iPos, pTmp ); -#ifndef HB_CDP_SUPPORT_OFF - bWriteSep = hb_ExportVar( handle, pTmp, cDelim, cdp ); -#else - bWriteSep = hb_ExportVar( handle, pTmp, cDelim ); -#endif - hb_itemClear( pTmp ); - } - } - } - } - hb_fsWriteLarge( handle, (BYTE*) "\r\n", 2 ); - bWriteSep = FALSE; - } - - if ( nCount != -1 ) - { - nCount-- ; - } - - /* DBSKIP() */ - SELF_SKIP( pArea, 1 ); - } - - /* Writing EOF */ - hb_fsWriteLarge( handle, (BYTE*) "\x1A", 1 ); - hb_itemRelease( pTmp ); -} diff --git a/harbour/source/rdd/dbf1.c b/harbour/source/rdd/dbf1.c index 75295e93b0..450e7bc161 100644 --- a/harbour/source/rdd/dbf1.c +++ b/harbour/source/rdd/dbf1.c @@ -2399,23 +2399,11 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo ) if( pArea->fHasMemo ) { pFileName = hb_fsFNameSplit( ( char * ) szFileName ); - pItem = hb_itemPutC( NULL, "" ); - errCode = SELF_INFO( ( AREAP ) pArea, DBI_MEMOEXT, pItem ); - if( errCode == SUCCESS ) - { - pFileName->szExtension = hb_itemGetCPtr( pItem ); - hb_fsFNameMerge( ( char * ) szFileName, pFileName ); - pArea->szMemoFileName = hb_strdup( ( char * ) szFileName ); - } - hb_itemRelease( pItem ); + pFileName->szExtension = NULL; + hb_fsFNameMerge( ( char * ) szFileName, pFileName ); hb_xfree( pFileName ); - if( errCode == SUCCESS ) - { - BYTE *tmp = pCreateInfo->abName; - pCreateInfo->abName = ( BYTE * ) pArea->szMemoFileName; - errCode = SELF_CREATEMEMFILE( ( AREAP ) pArea, pCreateInfo ); - pCreateInfo->abName = tmp; - } + pCreateInfo->abName = szFileName; + errCode = SELF_CREATEMEMFILE( ( AREAP ) pArea, pCreateInfo ); } /* If successful call SUPER_CREATE to finish system jobs */ if( errCode == SUCCESS ) @@ -3156,24 +3144,11 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo ) if( pArea->fHasMemo ) { pFileName = hb_fsFNameSplit( ( char * ) szFileName ); - pFileExt = hb_itemPutC( NULL, "" ); - errCode = SELF_INFO( ( AREAP ) pArea, DBI_MEMOEXT, pFileExt ); - if( errCode == SUCCESS ) - { - pFileName->szExtension = hb_itemGetCPtr( pFileExt ); - hb_fsFNameMerge( ( char * ) szFileName, pFileName ); - } - hb_itemRelease( pFileExt ); + pFileName->szExtension = NULL; + hb_fsFNameMerge( ( char * ) szFileName, pFileName ); hb_xfree( pFileName ); - if( errCode == SUCCESS ) - { - BYTE * tmp = pOpenInfo->abName; - pArea->szMemoFileName = hb_strdup( ( char * ) szFileName ); - pOpenInfo->abName = ( BYTE * ) pArea->szMemoFileName; - /* Open memo file and exit if error */ - errCode = SELF_OPENMEMFILE( ( AREAP ) pArea, pOpenInfo ); - pOpenInfo->abName = tmp; - } + pOpenInfo->abName = szFileName; + errCode = SELF_OPENMEMFILE( ( AREAP ) pArea, pOpenInfo ); } if( errCode == SUCCESS ) diff --git a/harbour/source/rdd/dbffpt/dbffpt1.c b/harbour/source/rdd/dbffpt/dbffpt1.c index fd25b7271c..17d5844212 100644 --- a/harbour/source/rdd/dbffpt/dbffpt1.c +++ b/harbour/source/rdd/dbffpt/dbffpt1.c @@ -3783,6 +3783,8 @@ static ERRCODE hb_fptCreateMemFile( FPTAREAP pArea, LPDBOPENINFO pCreateInfo ) if( pCreateInfo ) { + BYTE szFileName[ _POSIX_PATH_MAX + 1 ]; + PHB_FNAME pFileName; PHB_ITEM pError = NULL, pItem = NULL; BOOL bRetry; @@ -3808,6 +3810,7 @@ static ERRCODE hb_fptCreateMemFile( FPTAREAP pArea, LPDBOPENINFO pCreateInfo ) { hb_memoErrorRT( pArea, EG_CREATE, EDBF_MEMOTYPE, ( char * ) pCreateInfo->abName, 0, 0 ); + hb_itemRelease( pItem ); return FAILURE; } } @@ -3838,6 +3841,23 @@ static ERRCODE hb_fptCreateMemFile( FPTAREAP pArea, LPDBOPENINFO pCreateInfo ) } pArea->uiMemoBlockSize = hb_itemGetNI( pItem ); } + + /* create file name */ + pFileName = hb_fsFNameSplit( ( char * ) pCreateInfo->abName ); + if( ! pFileName->szExtension ) + { + pItem = hb_itemPutC( pItem, "" ); + SELF_INFO( ( AREAP ) pArea, DBI_MEMOEXT, pItem ); + pFileName->szExtension = hb_itemGetCPtr( pItem ); + hb_fsFNameMerge( ( char * ) szFileName, pFileName ); + } + else + { + hb_strncpy( ( char * ) szFileName, ( char * ) pCreateInfo->abName, _POSIX_PATH_MAX ); + } + hb_xfree( pFileName ); + + if( pItem ) { hb_itemRelease( pItem ); @@ -3846,7 +3866,7 @@ static ERRCODE hb_fptCreateMemFile( FPTAREAP pArea, LPDBOPENINFO pCreateInfo ) /* Try create */ do { - pArea->hMemoFile = hb_fsExtOpen( pCreateInfo->abName, NULL, + pArea->hMemoFile = hb_fsExtOpen( szFileName, NULL, FO_READWRITE | FO_EXCLUSIVE | FXO_TRUNCATE | FXO_DEFAULTS | FXO_SHARELOCK, NULL, pError ); @@ -3859,7 +3879,7 @@ static ERRCODE hb_fptCreateMemFile( FPTAREAP pArea, LPDBOPENINFO pCreateInfo ) hb_errPutSubCode( pError, EDBF_CREATE_MEMO ); hb_errPutDescription( pError, hb_langDGetErrorDesc( EG_CREATE ) ); hb_errPutOsCode( pError, hb_fsError() ); - hb_errPutFileName( pError, ( char * ) pCreateInfo->abName ); + hb_errPutFileName( pError, ( char * ) szFileName ); hb_errPutFlags( pError, EF_CANRETRY ); } bRetry = ( SELF_ERROR( ( AREAP ) pArea, pError ) == E_RETRY ); @@ -3872,6 +3892,8 @@ static ERRCODE hb_fptCreateMemFile( FPTAREAP pArea, LPDBOPENINFO pCreateInfo ) if( pArea->hMemoFile == FS_ERROR ) return FAILURE; + + pArea->szMemoFileName = hb_strdup( ( char * ) szFileName ); } else /* For zap file */ hb_fsSeek( pArea->hMemoFile, 0, FS_SET ); @@ -3984,9 +4006,11 @@ static ERRCODE hb_fptGetValueFile( FPTAREAP pArea, USHORT uiIndex, BYTE * szFile */ static ERRCODE hb_fptOpenMemFile( FPTAREAP pArea, LPDBOPENINFO pOpenInfo ) { + BYTE szFileName[ _POSIX_PATH_MAX + 1 ]; + PHB_FNAME pFileName; + PHB_ITEM pError; USHORT uiFlags; BOOL bRetry; - PHB_ITEM pError; HB_TRACE(HB_TR_DEBUG, ("hb_fptOpenMemFile(%p, %p)", pArea, pOpenInfo)); @@ -4004,6 +4028,22 @@ static ERRCODE hb_fptOpenMemFile( FPTAREAP pArea, LPDBOPENINFO pOpenInfo ) return FAILURE; } + /* create file name */ + pFileName = hb_fsFNameSplit( ( char * ) pOpenInfo->abName ); + if( ! pFileName->szExtension ) + { + PHB_ITEM pItem = hb_itemPutC( NULL, "" ); + SELF_INFO( ( AREAP ) pArea, DBI_MEMOEXT, pItem ); + pFileName->szExtension = hb_itemGetCPtr( pItem ); + hb_fsFNameMerge( ( char * ) szFileName, pFileName ); + hb_itemRelease( pItem ); + } + else + { + hb_strncpy( ( char * ) szFileName, ( char * ) pOpenInfo->abName, _POSIX_PATH_MAX ); + } + hb_xfree( pFileName ); + uiFlags = (pOpenInfo->fReadonly ? FO_READ : FO_READWRITE) | (pOpenInfo->fShared ? FO_DENYNONE : FO_EXCLUSIVE); pError = NULL; @@ -4011,7 +4051,7 @@ static ERRCODE hb_fptOpenMemFile( FPTAREAP pArea, LPDBOPENINFO pOpenInfo ) /* Try open */ do { - pArea->hMemoFile = hb_fsExtOpen( pOpenInfo->abName, NULL, uiFlags | + pArea->hMemoFile = hb_fsExtOpen( szFileName, NULL, uiFlags | FXO_DEFAULTS | FXO_SHARELOCK, NULL, pError ); if( pArea->hMemoFile == FS_ERROR ) @@ -4023,7 +4063,7 @@ static ERRCODE hb_fptOpenMemFile( FPTAREAP pArea, LPDBOPENINFO pOpenInfo ) hb_errPutSubCode( pError, EDBF_OPEN_MEMO ); hb_errPutDescription( pError, hb_langDGetErrorDesc( EG_OPEN ) ); hb_errPutOsCode( pError, hb_fsError() ); - hb_errPutFileName( pError, ( char * ) pOpenInfo->abName ); + hb_errPutFileName( pError, ( char * ) szFileName ); hb_errPutFlags( pError, EF_CANRETRY | EF_CANDEFAULT ); } bRetry = ( SELF_ERROR( ( AREAP ) pArea, pError ) == E_RETRY ); @@ -4038,6 +4078,8 @@ static ERRCODE hb_fptOpenMemFile( FPTAREAP pArea, LPDBOPENINFO pOpenInfo ) if( pArea->hMemoFile == FS_ERROR ) return FAILURE; + pArea->szMemoFileName = hb_strdup( ( char * ) szFileName ); + if( pArea->bMemoType == DB_MEMO_DBT ) { pArea->uiMemoBlockSize = DBT_DEFBLOCKSIZE; @@ -4086,7 +4128,7 @@ static ERRCODE hb_fptOpenMemFile( FPTAREAP pArea, LPDBOPENINFO pOpenInfo ) if( pArea->uiMemoBlockSize == 0 ) { hb_memoErrorRT( pArea, EG_CORRUPTION, EDBF_CORRUPT, - ( char * ) pOpenInfo->abName, 0, 0 ); + ( char * ) pArea->szMemoFileName, 0, 0 ); return FAILURE; } diff --git a/harbour/source/rtl/errorapi.c b/harbour/source/rtl/errorapi.c index 6cbba0aab3..cdb62cc1e4 100644 --- a/harbour/source/rtl/errorapi.c +++ b/harbour/source/rtl/errorapi.c @@ -375,7 +375,7 @@ char * hb_errGetDescription( PHB_ITEM pError ) hb_vmPushSymbol( hb_dynsymGetSymbol( "DESCRIPTION" ) ); hb_vmPush( pError ); - hb_vmDo( 0 ); + hb_vmSend( 0 ); return hb_itemGetCPtr( hb_stackReturnItem() ); } @@ -387,7 +387,7 @@ PHB_ITEM hb_errPutDescription( PHB_ITEM pError, const char * szDescription ) hb_vmPushSymbol( hb_dynsymGetSymbol( "_DESCRIPTION" ) ); hb_vmPush( pError ); hb_vmPushString( ( char * ) szDescription, strlen( szDescription ) ); - hb_vmDo( 1 ); + hb_vmSend( 1 ); return pError; } @@ -398,7 +398,7 @@ char * hb_errGetFileName( PHB_ITEM pError ) hb_vmPushSymbol( hb_dynsymGetSymbol( "FILENAME" ) ); hb_vmPush( pError ); - hb_vmDo( 0 ); + hb_vmSend( 0 ); return hb_itemGetCPtr( hb_stackReturnItem() ); } @@ -410,7 +410,7 @@ PHB_ITEM hb_errPutFileName( PHB_ITEM pError, const char * szFileName ) hb_vmPushSymbol( hb_dynsymGetSymbol( "_FILENAME" ) ); hb_vmPush( pError ); hb_vmPushString( ( char * ) szFileName, strlen( szFileName ) ); - hb_vmDo( 1 ); + hb_vmSend( 1 ); return pError; } @@ -421,7 +421,7 @@ USHORT hb_errGetGenCode( PHB_ITEM pError ) hb_vmPushSymbol( hb_dynsymGetSymbol( "GENCODE" ) ); hb_vmPush( pError ); - hb_vmDo( 0 ); + hb_vmSend( 0 ); return hb_itemGetNI( hb_stackReturnItem() ); } @@ -433,7 +433,7 @@ PHB_ITEM hb_errPutGenCode( PHB_ITEM pError, USHORT uiGenCode ) hb_vmPushSymbol( hb_dynsymGetSymbol( "_GENCODE" ) ); hb_vmPush( pError ); hb_vmPushInteger( uiGenCode ); - hb_vmDo( 1 ); + hb_vmSend( 1 ); return pError; } @@ -444,7 +444,7 @@ char * hb_errGetOperation( PHB_ITEM pError ) hb_vmPushSymbol( hb_dynsymGetSymbol( "OPERATION" ) ); hb_vmPush( pError ); - hb_vmDo( 0 ); + hb_vmSend( 0 ); return hb_itemGetCPtr( hb_stackReturnItem() ); } @@ -456,7 +456,7 @@ PHB_ITEM hb_errPutOperation( PHB_ITEM pError, const char * szOperation ) hb_vmPushSymbol( hb_dynsymGetSymbol( "_OPERATION" ) ); hb_vmPush( pError ); hb_vmPushString( ( char * ) szOperation, strlen( szOperation ) ); - hb_vmDo( 1 ); + hb_vmSend( 1 ); return pError; } @@ -467,7 +467,7 @@ USHORT hb_errGetOsCode( PHB_ITEM pError ) hb_vmPushSymbol( hb_dynsymGetSymbol( "OSCODE" ) ); hb_vmPush( pError ); - hb_vmDo( 0 ); + hb_vmSend( 0 ); return hb_itemGetNI( hb_stackReturnItem() ); } @@ -479,7 +479,7 @@ PHB_ITEM hb_errPutOsCode( PHB_ITEM pError, USHORT uiOsCode ) hb_vmPushSymbol( hb_dynsymGetSymbol( "_OSCODE" ) ); hb_vmPush( pError ); hb_vmPushInteger( uiOsCode ); - hb_vmDo( 1 ); + hb_vmSend( 1 ); return pError; } @@ -490,7 +490,7 @@ USHORT hb_errGetSeverity( PHB_ITEM pError ) hb_vmPushSymbol( hb_dynsymGetSymbol( "SEVERITY" ) ); hb_vmPush( pError ); - hb_vmDo( 0 ); + hb_vmSend( 0 ); return hb_itemGetNI( hb_stackReturnItem() ); } @@ -502,7 +502,7 @@ PHB_ITEM hb_errPutSeverity( PHB_ITEM pError, USHORT uiSeverity ) hb_vmPushSymbol( hb_dynsymGetSymbol( "_SEVERITY" ) ); hb_vmPush( pError ); hb_vmPushInteger( uiSeverity ); - hb_vmDo( 1 ); + hb_vmSend( 1 ); return pError; } @@ -513,7 +513,7 @@ USHORT hb_errGetSubCode( PHB_ITEM pError ) hb_vmPushSymbol( hb_dynsymGetSymbol( "SUBCODE" ) ); hb_vmPush( pError ); - hb_vmDo( 0 ); + hb_vmSend( 0 ); return hb_itemGetNI( hb_stackReturnItem() ); } @@ -525,7 +525,7 @@ PHB_ITEM hb_errPutSubCode( PHB_ITEM pError, USHORT uiSubCode ) hb_vmPushSymbol( hb_dynsymGetSymbol( "_SUBCODE" ) ); hb_vmPush( pError ); hb_vmPushInteger( uiSubCode ); - hb_vmDo( 1 ); + hb_vmSend( 1 ); return pError; } @@ -536,7 +536,7 @@ char * hb_errGetSubSystem( PHB_ITEM pError ) hb_vmPushSymbol( hb_dynsymGetSymbol( "SUBSYSTEM" ) ); hb_vmPush( pError ); - hb_vmDo( 0 ); + hb_vmSend( 0 ); return hb_itemGetCPtr( hb_stackReturnItem() ); } @@ -548,7 +548,7 @@ PHB_ITEM hb_errPutSubSystem( PHB_ITEM pError, const char * szSubSystem ) hb_vmPushSymbol( hb_dynsymGetSymbol( "_SUBSYSTEM" ) ); hb_vmPush( pError ); hb_vmPushString( ( char * ) szSubSystem, strlen( szSubSystem ) ); - hb_vmDo( 1 ); + hb_vmSend( 1 ); return pError; } @@ -559,7 +559,7 @@ USHORT hb_errGetTries( PHB_ITEM pError ) hb_vmPushSymbol( hb_dynsymGetSymbol( "TRIES" ) ); hb_vmPush( pError ); - hb_vmDo( 0 ); + hb_vmSend( 0 ); return hb_itemGetNI( hb_stackReturnItem() ); } @@ -571,7 +571,7 @@ PHB_ITEM hb_errPutTries( PHB_ITEM pError, USHORT uiTries ) hb_vmPushSymbol( hb_dynsymGetSymbol( "_TRIES" ) ); hb_vmPush( pError ); hb_vmPushInteger( uiTries ); - hb_vmDo( 1 ); + hb_vmSend( 1 ); return pError; } @@ -586,7 +586,7 @@ USHORT hb_errGetFlags( PHB_ITEM pError ) hb_vmPushSymbol( hb_dynsymGetSymbol( "CANRETRY" ) ); hb_vmPush( pError ); - hb_vmDo( 0 ); + hb_vmSend( 0 ); if( hb_itemGetL( hb_stackReturnItem() ) ) uiFlags |= EF_CANRETRY; @@ -595,7 +595,7 @@ USHORT hb_errGetFlags( PHB_ITEM pError ) hb_vmPushSymbol( hb_dynsymGetSymbol( "CANSUBSTITUTE" ) ); hb_vmPush( pError ); - hb_vmDo( 0 ); + hb_vmSend( 0 ); if( hb_itemGetL( hb_stackReturnItem() ) ) uiFlags |= EF_CANSUBSTITUTE; @@ -604,7 +604,7 @@ USHORT hb_errGetFlags( PHB_ITEM pError ) hb_vmPushSymbol( hb_dynsymGetSymbol( "CANDEFAULT" ) ); hb_vmPush( pError ); - hb_vmDo( 0 ); + hb_vmSend( 0 ); if( hb_itemGetL( hb_stackReturnItem() ) ) uiFlags |= EF_CANDEFAULT; @@ -621,21 +621,21 @@ PHB_ITEM hb_errPutFlags( PHB_ITEM pError, USHORT uiFlags ) hb_vmPushSymbol( hb_dynsymGetSymbol( "_CANRETRY" ) ); hb_vmPush( pError ); hb_vmPushLogical( ( uiFlags & EF_CANRETRY ) ? TRUE : FALSE ); - hb_vmDo( 1 ); + hb_vmSend( 1 ); /* ; */ hb_vmPushSymbol( hb_dynsymGetSymbol( "_CANSUBSTITUTE" ) ); hb_vmPush( pError ); hb_vmPushLogical( ( uiFlags & EF_CANSUBSTITUTE ) ? TRUE : FALSE ); - hb_vmDo( 1 ); + hb_vmSend( 1 ); /* ; */ hb_vmPushSymbol( hb_dynsymGetSymbol( "_CANDEFAULT" ) ); hb_vmPush( pError ); hb_vmPushLogical( ( uiFlags & EF_CANDEFAULT ) ? TRUE : FALSE ); - hb_vmDo( 1 ); + hb_vmSend( 1 ); /* ; */ @@ -664,7 +664,7 @@ PHB_ITEM hb_errPutArgs( PHB_ITEM pError, ULONG ulArgCount, ... ) hb_vmPushSymbol( hb_dynsymGetSymbol( "_ARGS" ) ); hb_vmPush( pError ); hb_vmPush( pArray ); - hb_vmDo( 1 ); + hb_vmSend( 1 ); hb_itemRelease( pArray ); @@ -824,7 +824,7 @@ USHORT hb_errRT_BASE( ULONG ulGenCode, ULONG ulSubCode, const char * szDescripti hb_vmPushSymbol( hb_dynsymGetSymbol( "_ARGS" ) ); hb_vmPush( pError ); hb_vmPush( pArray ); - hb_vmDo( 1 ); + hb_vmSend( 1 ); /* Release the Array. */ if( bRelease ) @@ -867,7 +867,7 @@ USHORT hb_errRT_BASE_Ext1( ULONG ulGenCode, ULONG ulSubCode, const char * szDesc hb_vmPushSymbol( hb_dynsymGetSymbol( "_ARGS" ) ); hb_vmPush( pError ); hb_vmPush( pArray ); - hb_vmDo( 1 ); + hb_vmSend( 1 ); /* Release the Array. */ hb_itemRelease( pArray ); @@ -906,7 +906,7 @@ PHB_ITEM hb_errRT_BASE_Subst( ULONG ulGenCode, ULONG ulSubCode, const char * szD hb_vmPushSymbol( hb_dynsymGetSymbol( "_ARGS" ) ); hb_vmPush( pError ); hb_vmPush( pArray ); - hb_vmDo( 1 ); + hb_vmSend( 1 ); /* Release the Array. */ hb_itemRelease( pArray ); @@ -969,7 +969,7 @@ void hb_errRT_BASE_SubstR( ULONG ulGenCode, ULONG ulSubCode, const char * szDesc hb_vmPushSymbol( hb_dynsymGetSymbol( "_ARGS" ) ); hb_vmPush( pError ); hb_vmPush( pArray ); - hb_vmDo( 1 ); + hb_vmSend( 1 ); /* Release the Array. */ if( bRelease ) diff --git a/harbour/source/rtl/fstemp.c b/harbour/source/rtl/fstemp.c index 5e6a44f0ed..2bca8a8887 100644 --- a/harbour/source/rtl/fstemp.c +++ b/harbour/source/rtl/fstemp.c @@ -157,7 +157,7 @@ static BOOL fsGetTempDirByCase( BYTE *pszName, const char *pszTempDir ) strcpy( ( char * ) pszName, ( char * ) pszTempDir ); if ( hb_set.HB_SET_DIRCASE == HB_SET_CASE_LOWER || hb_set.HB_SET_DIRCASE == HB_SET_CASE_UPPER ) { - // check to see if temp directory already upper or lower. If not use current directory ( "." ) + /* check to see if temp directory already upper or lower. If not use current directory ( "." ) */ char *psZ = ( char * ) pszName ; int iChar ; BOOL bLower = hb_set.HB_SET_DIRCASE == HB_SET_CASE_LOWER ; diff --git a/harbour/source/rtl/gtalleg/gtalleg.c b/harbour/source/rtl/gtalleg/gtalleg.c index 6abc75fdee..7f0e8b25c2 100644 --- a/harbour/source/rtl/gtalleg/gtalleg.c +++ b/harbour/source/rtl/gtalleg/gtalleg.c @@ -1188,7 +1188,7 @@ static HB_GT_INIT gtInit = { HB_GT_DRVNAME( HB_GT_NAME ), hb_gt_FuncInit, HB_GTSUPER }; -HB_GT_ANNOUNCE( HB_GT_NAME ); +HB_GT_ANNOUNCE( HB_GT_NAME ) HB_CALL_ON_STARTUP_BEGIN( _hb_startup_gt_Init_ ) hb_gtRegister( >Init ); diff --git a/harbour/source/rtl/gtalleg/ssf.h b/harbour/source/rtl/gtalleg/ssf.h index b7998e9e96..40ff7c4e07 100644 --- a/harbour/source/rtl/gtalleg/ssf.h +++ b/harbour/source/rtl/gtalleg/ssf.h @@ -64,7 +64,7 @@ #include -// Hack to use old Allegro branches +/* Hack to use old Allegro branches */ #ifndef AL_GFX_NONE #define AL_GFX_NONE GFX_NONE #define AL_GFX_SAFE GFX_SAFE @@ -239,4 +239,4 @@ extern void ssfSetFontSize(ssfFont *sfont, unsigned short fsize); extern unsigned short ssfDrawChar(AL_BITMAP *dst, ssfFont *sfont, char c, int x, int y, int color); extern int ssfDrawText(AL_BITMAP *dst, ssfFont *sfont, char *s, int x, int y, int color); -#endif // _SSF_H_ +#endif /* _SSF_H_ */ diff --git a/harbour/source/rtl/gtcgi/gtcgi.c b/harbour/source/rtl/gtcgi/gtcgi.c index 76bbdb400a..b6895529b3 100644 --- a/harbour/source/rtl/gtcgi/gtcgi.c +++ b/harbour/source/rtl/gtcgi/gtcgi.c @@ -426,7 +426,7 @@ static HB_GT_INIT gtInit = { HB_GT_DRVNAME( HB_GT_NAME ), hb_gt_FuncInit, HB_GTSUPER }; -HB_GT_ANNOUNCE( HB_GT_NAME ); +HB_GT_ANNOUNCE( HB_GT_NAME ) HB_CALL_ON_STARTUP_BEGIN( _hb_startup_gt_Init_ ) hb_gtRegister( >Init ); diff --git a/harbour/source/rtl/gtcrs/gtcrs.c b/harbour/source/rtl/gtcrs/gtcrs.c index 86f1d55569..0da3de6d93 100644 --- a/harbour/source/rtl/gtcrs/gtcrs.c +++ b/harbour/source/rtl/gtcrs/gtcrs.c @@ -2970,7 +2970,7 @@ static HB_GT_INIT gtInit = { HB_GT_DRVNAME( HB_GT_NAME ), hb_gt_FuncInit, HB_GTSUPER }; -HB_GT_ANNOUNCE( HB_GT_NAME ); +HB_GT_ANNOUNCE( HB_GT_NAME ) HB_CALL_ON_STARTUP_BEGIN( _hb_startup_gt_Init_ ) hb_gtRegister( >Init ); diff --git a/harbour/source/rtl/gtdos/gtdos.c b/harbour/source/rtl/gtdos/gtdos.c index 3aa5d3da4b..421b632096 100644 --- a/harbour/source/rtl/gtdos/gtdos.c +++ b/harbour/source/rtl/gtdos/gtdos.c @@ -1506,7 +1506,7 @@ static HB_GT_INIT gtInit = { HB_GT_DRVNAME( HB_GT_NAME ), hb_gt_FuncInit, HB_GTSUPER }; -HB_GT_ANNOUNCE( HB_GT_NAME ); +HB_GT_ANNOUNCE( HB_GT_NAME ) HB_CALL_ON_STARTUP_BEGIN( _hb_startup_gt_Init_ ) hb_gtRegister( >Init ); diff --git a/harbour/source/rtl/gtos2/gtos2.c b/harbour/source/rtl/gtos2/gtos2.c index 4c3c280f78..46fd796bd0 100644 --- a/harbour/source/rtl/gtos2/gtos2.c +++ b/harbour/source/rtl/gtos2/gtos2.c @@ -956,7 +956,7 @@ static HB_GT_INIT gtInit = { HB_GT_DRVNAME( HB_GT_NAME ), hb_gt_FuncInit, HB_GTSUPER }; -HB_GT_ANNOUNCE( HB_GT_NAME ); +HB_GT_ANNOUNCE( HB_GT_NAME ) HB_CALL_ON_STARTUP_BEGIN( _hb_startup_gt_Init_ ) hb_gtRegister( >Init ); diff --git a/harbour/source/rtl/gtpca/gtpca.c b/harbour/source/rtl/gtpca/gtpca.c index 873c2df914..610784dbb5 100644 --- a/harbour/source/rtl/gtpca/gtpca.c +++ b/harbour/source/rtl/gtpca/gtpca.c @@ -958,7 +958,7 @@ static HB_GT_INIT gtInit = { HB_GT_DRVNAME( HB_GT_NAME ), hb_gt_FuncInit, HB_GTSUPER }; -HB_GT_ANNOUNCE( HB_GT_NAME ); +HB_GT_ANNOUNCE( HB_GT_NAME ) HB_CALL_ON_STARTUP_BEGIN( _hb_startup_gt_Init_ ) hb_gtRegister( >Init ); diff --git a/harbour/source/rtl/gtsln/gtsln.c b/harbour/source/rtl/gtsln/gtsln.c index eb5cfc6c0d..54e6370b72 100644 --- a/harbour/source/rtl/gtsln/gtsln.c +++ b/harbour/source/rtl/gtsln/gtsln.c @@ -1059,7 +1059,7 @@ static HB_GT_INIT gtInit = { HB_GT_DRVNAME( HB_GT_NAME ), hb_gt_FuncInit, HB_GTSUPER }; -HB_GT_ANNOUNCE( HB_GT_NAME ); +HB_GT_ANNOUNCE( HB_GT_NAME ) HB_CALL_ON_STARTUP_BEGIN( _hb_startup_gt_Init_ ) hb_gtRegister( >Init ); diff --git a/harbour/source/rtl/gtstd/gtstd.c b/harbour/source/rtl/gtstd/gtstd.c index b131edb95a..361968f472 100644 --- a/harbour/source/rtl/gtstd/gtstd.c +++ b/harbour/source/rtl/gtstd/gtstd.c @@ -685,7 +685,7 @@ static HB_GT_INIT gtInit = { HB_GT_DRVNAME( HB_GT_NAME ), hb_gt_FuncInit, HB_GTSUPER }; -HB_GT_ANNOUNCE( HB_GT_NAME ); +HB_GT_ANNOUNCE( HB_GT_NAME ) HB_CALL_ON_STARTUP_BEGIN( _hb_startup_gt_Init_ ) hb_gtRegister( >Init ); diff --git a/harbour/source/rtl/gtwin/gtwin.c b/harbour/source/rtl/gtwin/gtwin.c index bddd73729f..9e9190dc48 100644 --- a/harbour/source/rtl/gtwin/gtwin.c +++ b/harbour/source/rtl/gtwin/gtwin.c @@ -1949,7 +1949,7 @@ static HB_GT_INIT gtInit = { HB_GT_DRVNAME( HB_GT_NAME ), hb_gt_FuncInit, HB_GTSUPER }; -HB_GT_ANNOUNCE( HB_GT_NAME ); +HB_GT_ANNOUNCE( HB_GT_NAME ) HB_CALL_ON_STARTUP_BEGIN( _hb_startup_gt_Init_ ) hb_gtRegister( >Init ); diff --git a/harbour/source/rtl/gtwvt/gtwvt.c b/harbour/source/rtl/gtwvt/gtwvt.c index 70854679c4..bf2a68fc2c 100644 --- a/harbour/source/rtl/gtwvt/gtwvt.c +++ b/harbour/source/rtl/gtwvt/gtwvt.c @@ -2079,7 +2079,7 @@ static HB_GT_INIT gtInit = { HB_GT_DRVNAME( HB_GT_NAME ), hb_gt_FuncInit, HB_GTSUPER }; -HB_GT_ANNOUNCE( HB_GT_NAME ); +HB_GT_ANNOUNCE( HB_GT_NAME ) HB_CALL_ON_STARTUP_BEGIN( _hb_startup_gt_Init_ ) hb_gtRegister( >Init ); diff --git a/harbour/source/rtl/gtxwc/gtxwc.c b/harbour/source/rtl/gtxwc/gtxwc.c index b217937ad3..08a5c0a474 100644 --- a/harbour/source/rtl/gtxwc/gtxwc.c +++ b/harbour/source/rtl/gtxwc/gtxwc.c @@ -3951,7 +3951,7 @@ static HB_GT_INIT gtInit = { HB_GT_DRVNAME( HB_GT_NAME ), hb_gt_FuncInit, HB_GTSUPER }; -HB_GT_ANNOUNCE( HB_GT_NAME ); +HB_GT_ANNOUNCE( HB_GT_NAME ) HB_CALL_ON_STARTUP_BEGIN( _hb_startup_gt_Init_ ) hb_gtRegister( >Init ); diff --git a/harbour/source/rtl/hbgtcore.c b/harbour/source/rtl/hbgtcore.c index a3916e43f1..b785ca9e4e 100644 --- a/harbour/source/rtl/hbgtcore.c +++ b/harbour/source/rtl/hbgtcore.c @@ -1955,7 +1955,7 @@ static void hb_gt_def_WhoCares( void * pCargo ) /* ************************************************************************* */ -#ifdef __GNUC__ +#if defined( __GNUC__ ) && 0 static HB_GT_FUNCS gtCoreFunc = { Init : hb_gt_def_Init , @@ -2834,4 +2834,4 @@ HB_EXPORT void hb_gtStartupInit( void ) HB_FUNC_EXEC( HB_GTSYS ); } -HB_GT_ANNOUNCE( HB_GT_NAME ); +HB_GT_ANNOUNCE( HB_GT_NAME ) diff --git a/harbour/source/rtl/langapi.c b/harbour/source/rtl/langapi.c index 29b56adee6..3d390e57ed 100644 --- a/harbour/source/rtl/langapi.c +++ b/harbour/source/rtl/langapi.c @@ -199,7 +199,7 @@ static HB_LANG s_lang_en = } }; -HB_LANG_ANNOUNCE( EN ); +HB_LANG_ANNOUNCE( EN ) /* Always link in the default language */ /* HB_LANG_REQUEST( HB_LANG_DEFAULT ); */ diff --git a/harbour/source/rtl/math.c b/harbour/source/rtl/math.c index 2735777013..293c005f96 100644 --- a/harbour/source/rtl/math.c +++ b/harbour/source/rtl/math.c @@ -350,16 +350,8 @@ int hb_matherr (HB_MATH_EXCEPTION * pexc) PHB_ITEM pMatherrResult; PHB_ITEM pArg1 = hb_itemPutND(NULL, pexc->arg1); PHB_ITEM pArg2 = hb_itemPutND(NULL, pexc->arg2); - PHB_ITEM pArray; PHB_ITEM pError; - /* create an array with the two double arguments */ - /* NOTE: Unfortunately, we cannot decide whether one or two parameters have been used when the - math function has been called, so we always take two */ - pArray = hb_itemArrayNew(2); - hb_itemArrayPut(pArray, 1, pArg1); - hb_itemArrayPut(pArray, 2, pArg2); - /* create an error object */ /* NOTE: In case of HB_MATH_ERRMODE_USER[C]DEFAULT, I am setting both EF_CANSUBSTITUTE and EF_CANDEFAULT to .T. here. This is forbidden according to the original Cl*pper docs, but I think this reflects the situation best here: @@ -370,28 +362,24 @@ int hb_matherr (HB_MATH_EXCEPTION * pexc) (mode == HB_MATH_ERRMODE_USER ? 0: EF_CANDEFAULT)); /* Assign the new array to the object data item. */ - hb_vmPushSymbol (hb_dynsymGetSymbol("_ARGS")); - hb_vmPush (pError); - hb_vmPush (pArray); - hb_vmDo (1); - - /* Release the Array. */ - hb_itemRelease (pArray); + /* NOTE: Unfortunately, we cannot decide whether one or two parameters have been used when the + math function has been called, so we always take two */ + hb_errPutArgs( pError, 2, pArg1, pArg2 ); /* launch error codeblock */ pMatherrResult = hb_errLaunchSubst (pError); hb_errRelease (pError); - if ((pMatherrResult != NULL) && (HB_IS_NUMERIC (pMatherrResult))) + if (pMatherrResult != NULL) { - pexc->retval = hb_itemGetND (pMatherrResult); - hb_itemGetNLen (pMatherrResult, &(pexc->retvalwidth), &(pexc->retvaldec)); - pexc->handled = 1; + if (HB_IS_NUMERIC (pMatherrResult)) + { + pexc->retval = hb_itemGetND (pMatherrResult); + hb_itemGetNLen (pMatherrResult, &(pexc->retvalwidth), &(pexc->retvaldec)); + pexc->handled = 1; + } + hb_itemRelease (pMatherrResult); } - - hb_itemRelease (pMatherrResult); - hb_itemRelease (pArg1); - hb_itemRelease (pArg2); } /* math exception not handled by Harbour error routine above ? */ diff --git a/harbour/source/rtl/philes.c b/harbour/source/rtl/philes.c index 685da8a621..3273154e5b 100644 --- a/harbour/source/rtl/philes.c +++ b/harbour/source/rtl/philes.c @@ -109,7 +109,7 @@ HB_FUNC( FREAD ) /* Unshare the item to avoid GPF on static buffers and changing other items which shares this buffer. [druzus] */ - pBuffer = hb_itemUnShare( pBuffer ); + pBuffer = hb_itemUnShareString( pBuffer ); ulRead = hb_fsReadLarge( hb_parni( 1 ), ( BYTE * ) hb_itemGetCPtr( pBuffer ), diff --git a/harbour/source/rtl/space.c b/harbour/source/rtl/space.c index c8d8639ce1..acb303d2b7 100644 --- a/harbour/source/rtl/space.c +++ b/harbour/source/rtl/space.c @@ -58,9 +58,11 @@ HB_FUNC( SPACE ) { - if( ISNUM( 1 ) ) + PHB_ITEM pItem = hb_param( 1, HB_IT_NUMERIC ); + + if( pItem ) { - long lLen = hb_parnl( 1 ); + long lLen = hb_itemGetNL( pItem ); if( lLen > 0 ) { diff --git a/harbour/source/rtl/strpeek.c b/harbour/source/rtl/strpeek.c index 2ae7b74547..5ed7c21e96 100644 --- a/harbour/source/rtl/strpeek.c +++ b/harbour/source/rtl/strpeek.c @@ -84,7 +84,7 @@ HB_FUNC( STRPOKE ) if( ulPos > 0 && ulPos <= hb_itemGetCLen( pText ) ) { - pText = hb_itemUnShare( pText ); + pText = hb_itemUnShareString( pText ); hb_itemGetCPtr( pText )[ ulPos - 1 ] = (char) ( hb_parni( 3 ) & 0xff ); } hb_itemReturn( pText ); diff --git a/harbour/source/vm/arrays.c b/harbour/source/vm/arrays.c index a61286a1aa..3be93db052 100644 --- a/harbour/source/vm/arrays.c +++ b/harbour/source/vm/arrays.c @@ -76,6 +76,38 @@ #include "hbvm.h" #include "hbstack.h" +/* This releases array when called from the garbage collector */ +static HB_GARBAGE_FUNC( hb_arrayReleaseGarbage ) +{ + PHB_BASEARRAY pBaseArray = ( PHB_BASEARRAY ) Cargo; + + /* clear object tree as needed */ + if( pBaseArray->uiClass && pBaseArray->puiClsTree ) + { + hb_xfree( pBaseArray->puiClsTree ); + pBaseArray->puiClsTree = NULL; + } + + if( pBaseArray->pItems ) + { + HB_ITEM_PTR pItems = pBaseArray->pItems; + ULONG ulLen = pBaseArray->ulLen; + + /* clear the pBaseArray->pItems to avoid infinit loop in cross + * referenced items + */ + pBaseArray->pItems = NULL; + pBaseArray->ulLen = 0; + + while( ulLen-- ) + { + if( HB_IS_COMPLEX( pItems + ulLen ) ) + hb_itemClear( pItems + ulLen ); + } + hb_xfree( pItems ); + } +} + HB_EXPORT BOOL hb_arrayNew( PHB_ITEM pItem, ULONG ulLen ) /* creates a new array */ { PHB_BASEARRAY pBaseArray = ( PHB_BASEARRAY ) hb_gcAlloc( sizeof( HB_BASEARRAY ), hb_arrayReleaseGarbage ); @@ -93,7 +125,6 @@ HB_EXPORT BOOL hb_arrayNew( PHB_ITEM pItem, ULONG ulLen ) /* creates a new array pBaseArray->pItems = NULL; pBaseArray->ulLen = ulLen; - pBaseArray->ulHolders = 1; pBaseArray->uiClass = 0; pBaseArray->uiPrevCls = 0; pBaseArray->puiClsTree = NULL; @@ -576,7 +607,7 @@ ULONG hb_arrayScan( PHB_ITEM pArray, PHB_ITEM pValue, ULONG * pulStart, ULONG * hb_vmPushLong( ulStart + 1 ); hb_vmDo( 2 ); - if( HB_IS_LOGICAL( &hb_stack.Return ) && hb_stack.Return.item.asLogical.value ) + if( HB_IS_LOGICAL( hb_stackReturnItem() ) && hb_stackReturnItem()->item.asLogical.value ) return ulStart + 1; /* arrays start from 1 */ } } @@ -686,41 +717,6 @@ BOOL hb_arrayEval( PHB_ITEM pArray, PHB_ITEM bBlock, ULONG * pulStart, ULONG * p return FALSE; } -BOOL hb_arrayRelease( PHB_ITEM pArray ) -{ - HB_TRACE(HB_TR_DEBUG, ("hb_arrayRelease(%p)", pArray)); - - if( HB_IS_ARRAY( pArray ) ) - { - PHB_BASEARRAY pBaseArray = pArray->item.asArray.value; - ULONG ulLen = pBaseArray->ulLen; - ULONG ulPos; - - /* clear object tree as needed */ - if( pBaseArray->uiClass && pBaseArray->puiClsTree ) - { - hb_xfree(pBaseArray->puiClsTree); - pBaseArray->puiClsTree = NULL; - } - - if( pBaseArray->pItems ) - { - for( ulPos = 0; ulPos < ulLen; ulPos++ ) - hb_itemClear( pBaseArray->pItems + ulPos ); - hb_xfree( pBaseArray->pItems ); - } - - hb_gcFree( ( void * ) pBaseArray ); - - pArray->type = HB_IT_NIL; - pArray->item.asArray.value = NULL; - - return TRUE; - } - else - return FALSE; -} - /* NOTE: CA-Cl*pper 5.3a has a fix for the case when the starting position is greater than the length of the array. [vszakats] */ @@ -945,30 +941,3 @@ HB_EXPORT PHB_ITEM hb_arrayBaseParams( void ) return pArray; } - -/* This releases array when called from the garbage collector */ -HB_GARBAGE_FUNC( hb_arrayReleaseGarbage ) -{ - PHB_BASEARRAY pBaseArray = ( PHB_BASEARRAY ) Cargo; - - if( pBaseArray->pItems ) - { - HB_ITEM_PTR pItem = pBaseArray->pItems; - ULONG ulLen = pBaseArray->ulLen; - - while( ulLen-- ) - { - /* Only strings should be deallocated. - * Arrays, objects and codeblock should be released directly by - * the garbage collector - */ - if( HB_IS_STRING( pItem ) ) - hb_itemClear( pItem ); - - ++pItem; - } - hb_xfree( pBaseArray->pItems ); - pBaseArray->pItems = NULL; - pBaseArray->ulLen = 0; - } -} diff --git a/harbour/source/vm/arrayshb.c b/harbour/source/vm/arrayshb.c index 85c415b3f5..88931fea3c 100644 --- a/harbour/source/vm/arrayshb.c +++ b/harbour/source/vm/arrayshb.c @@ -108,7 +108,7 @@ HB_FUNC( ARRAY ) } if( ! bError ) - hb_arrayNewRagged( &hb_stack.Return, 1 ); + hb_arrayNewRagged( hb_stackReturnItem(), 1 ); } } @@ -166,7 +166,7 @@ HB_FUNC( ATAIL ) PHB_ITEM pArray = hb_param( 1, HB_IT_ARRAY ); if( pArray ) - hb_arrayLast( pArray, &hb_stack.Return ); + hb_arrayLast( pArray, hb_stackReturnItem() ); } HB_FUNC( AINS ) @@ -335,7 +335,7 @@ HB_FUNC( HB_APARAMS ) HB_FUNC( HB_AEXPRESSIONS ) { - PHB_ITEM pArray = &hb_stack.Return; + PHB_ITEM pArray = hb_stackReturnItem(); PHB_ITEM pLine = hb_param( 1, HB_IT_STRING ); size_t i, iOffset = 0; int iParans = 0, iArrays = 0, iIndexs = 0; diff --git a/harbour/source/vm/asort.c b/harbour/source/vm/asort.c index fef43dc307..c466f90977 100644 --- a/harbour/source/vm/asort.c +++ b/harbour/source/vm/asort.c @@ -63,8 +63,6 @@ #include "hbvm.h" #include "hbstack.h" -/* #define HB_ASORT_OPT_ITEMCOPY - use hbsetup.h to enable/disable it*/ - static BOOL hb_itemIsLess( PHB_ITEM pItem1, PHB_ITEM pItem2, PHB_ITEM pBlock ) { if( pBlock ) diff --git a/harbour/source/vm/classes.c b/harbour/source/vm/classes.c index eed44b3930..fde1dbfc22 100644 --- a/harbour/source/vm/classes.c +++ b/harbour/source/vm/classes.c @@ -140,6 +140,7 @@ #include "hbvmopt.h" #include "hbapi.h" +#include "hbapicls.h" #include "hbstack.h" #include "hbapierr.h" #include "hbapiitm.h" @@ -154,17 +155,17 @@ typedef struct { PHB_DYNS pMessage; /* Method Symbolic name */ - PHB_FUNC pFunction; /* Function 'pointer' */ + PHB_SYMB pFuncSym; /* Function symbol */ USHORT uiData; /* Item position for data (Harbour like, begin from 1) */ USHORT uiDataShared; /* Item position for datashared (original pos within Shared Class) */ USHORT uiSprClass; /* Originalclass'handel (super or current class'handel if not herited). */ /*Added by RAC&JF*/ USHORT uiScope; /* Scoping value */ PHB_ITEM pInitValue; /* Init Value for data */ - BYTE bClsDataInitiated; /* There is one value assigned at init time */ + USHORT bClsDataInitiated; /* There is one value assigned at init time */ + USHORT bIsPersistent; /* persistence support */ ULONG ulCalls; /* profiler support */ ULONG ulTime; /* profiler support */ ULONG ulRecurse; /* profiler support */ - BOOL bIsPersistent; /* persistence support */ } METHOD, * PMETHOD; typedef struct @@ -178,25 +179,88 @@ typedef struct USHORT uiDatasShared; /* Total shared Class data within Class data */ PHB_ITEM pClassDatas; /* Harbour Array for ClassDatas and shared */ PHB_ITEM pInlines; /* Array for inline codeblocks */ - PHB_FUNC pFunError; /* error handler for not defined messages */ + PHB_SYMB pFunError; /* error handler for not defined messages */ + ULONG ulOpFlags; /* Flags for overloaded operators */ } CLASS, * PCLASS; #define BASE_METHODS 100 /* starting maximum number of message */ #define BUCKET 5 #define HASH_KEY ( BASE_METHODS / BUCKET ) -extern BOOL hb_bProfiler; /* profiler activity status */ + + +static HARBOUR hb___msgGetData( void ); +static HARBOUR hb___msgSetData( void ); +static HARBOUR hb___msgGetClsData( void ); +static HARBOUR hb___msgSetClsData( void ); +static HARBOUR hb___msgGetShrData( void ); +static HARBOUR hb___msgSetShrData( void ); +static HARBOUR hb___msgEvalInline( void ); +static HARBOUR hb___msgVirtual( void ); +static HARBOUR hb___msgSuper( void ); + +static HARBOUR hb___msgClsH( void ); +static HARBOUR hb___msgClsName( void ); +static HARBOUR hb___msgClsSel( void ); +static HARBOUR hb___msgEval( void ); +/* static HARBOUR hb___msgClass( void ); */ +/* static HARBOUR hb___msgClsParent( void ); */ + +/* + * The positions of items in symbol table below have to correspond + * to HB_OO_OP_* constants in hbapicls.h, [druzus] + */ +static HB_SYMB s_opSymbols[ HB_OO_MAX_OPERATOR + 1 ] = { + { "__OPPLUS", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 01 */ + { "__OPMINUS", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 02 */ + { "__OPMULT", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 03 */ + { "__OPDIVIDE", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 04 */ + { "__OPMOD", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 05 */ + { "__OPPOWER", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 06 */ + { "__OPINC", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 07 */ + { "__OPDEC", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 08 */ + { "__OPEQUAL", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 09 */ + { "__OPEXACTEQUAL", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 10 */ + { "__OPNOTEQUAL", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 11 */ + { "__OPLESS", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 12 */ + { "__OPLESSEQUAL", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 13 */ + { "__OPGREATER", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 14 */ + { "__OPGREATEREQUAL", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 15 */ + { "__OPADDIGN", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 16 */ + { "__OPINSTRING", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 17 */ + { "__OPNOT", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 18 */ + { "__OPAND", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 19 */ + { "__OPOR", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 20 */ + { "__OPARRAYINDEX", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 21 */ + { "__ENUMNEXT", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 22 */ + { "__ENUMPREV", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 23 */ + { "__ENUMINDEX", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 24 */ + { "__ENUMBASE", {HB_FS_MESSAGE}, {NULL}, NULL }, /* 25 */ + { "__ENUMVALUE", {HB_FS_MESSAGE}, {NULL}, NULL } /* 26 */ +}; + +static HB_SYMB s___msgSetData = { "__msgSetData", {HB_FS_MESSAGE}, {hb___msgSetData}, NULL }; +static HB_SYMB s___msgGetData = { "__msgGetData", {HB_FS_MESSAGE}, {hb___msgGetData}, NULL }; +static HB_SYMB s___msgSetClsData = { "__msgSetClsData", {HB_FS_MESSAGE}, {hb___msgSetClsData}, NULL }; +static HB_SYMB s___msgGetClsData = { "__msgGetClsData", {HB_FS_MESSAGE}, {hb___msgGetClsData}, NULL }; +static HB_SYMB s___msgSetShrData = { "__msgSetShrData", {HB_FS_MESSAGE}, {hb___msgSetShrData}, NULL }; +static HB_SYMB s___msgGetShrData = { "__msgGetShrData", {HB_FS_MESSAGE}, {hb___msgGetShrData}, NULL }; +static HB_SYMB s___msgEvalInline = { "__msgEvalInline", {HB_FS_MESSAGE}, {hb___msgEvalInline}, NULL }; +static HB_SYMB s___msgVirtual = { "__msgVirtual", {HB_FS_MESSAGE}, {hb___msgVirtual}, NULL }; +static HB_SYMB s___msgSuper = { "__msgSuper", {HB_FS_MESSAGE}, {hb___msgSuper}, NULL }; + +static HB_SYMB s___msgClassName = { "CLASSNAME", {HB_FS_MESSAGE}, {hb___msgClsName}, NULL }; +static HB_SYMB s___msgClassH = { "CLASSH", {HB_FS_MESSAGE}, {hb___msgClsH}, NULL }; +static HB_SYMB s___msgClassSel = { "CLASSSEL", {HB_FS_MESSAGE}, {hb___msgClsSel}, NULL }; +static HB_SYMB s___msgEval = { "EVAL", {HB_FS_MESSAGE}, {hb___msgEval}, NULL }; +/* +static HB_SYMB s___msgClsParent = { "ISDERIVEDFROM", {HB_FS_MESSAGE}, {hb___msgClsParent}, NULL }; +static HB_SYMB s___msgClass = { "CLASS", {HB_FS_MESSAGE}, {hb___msgClass}, NULL }; +*/ static PCLASS s_pClasses = NULL; static USHORT s_uiClasses = 0; static PMETHOD s_pMethod = NULL; /* TOFIX: The object engine is not thread safe because of this. [vszakats] */ -static PHB_DYNS s_msgClassName = NULL; - -static PHB_DYNS s_msgClassH = NULL; -static PHB_DYNS s_msgEval = NULL; -static PHB_DYNS s_msgClassSel = NULL; -static PHB_DYNS s_msgClsParent = NULL; -/* static PHB_DYNS s_msgClass = NULL; */ /* All functions contained in classes.c */ @@ -209,27 +273,10 @@ static ULONG hb_cls_MsgToNum( PHB_DYNS pMsg ); static void hb_clsDictRealloc( PCLASS pClass ); static void hb_clsRelease( PCLASS ); -static PHB_FUNC hb_objGetMthd( PHB_ITEM pObject, PHB_SYMB pMessage, BOOL lAllowErrFunc ); #ifdef HB_CLS_ENFORCERO static PMETHOD hb_objGetpMethod( PHB_ITEM, PHB_SYMB ); #endif -static HARBOUR hb___msgClsH( void ); -static HARBOUR hb___msgClsName( void ); -static HARBOUR hb___msgClsSel( void ); -/* static HARBOUR hb___msgClass( void ); */ -static HARBOUR hb___msgSuper( void ); -static HARBOUR hb___msgEvalInline( void ); -static HARBOUR hb___msgClsParent( void ); -static HARBOUR hb___msgEval( void ); -static HARBOUR hb___msgVirtual( void ); -static HARBOUR hb___msgGetClsData( void ); -static HARBOUR hb___msgSetClsData( void ); -static HARBOUR hb___msgGetShrData( void ); -static HARBOUR hb___msgSetShrData( void ); -static HARBOUR hb___msgGetData( void ); -static HARBOUR hb___msgSetData( void ); - /* ================================================ */ /* @@ -302,6 +349,29 @@ static void hb_clsDictRealloc( PCLASS pClass ) } } +/* + * initialize Classy/OO system at HVM startup + */ +void hb_clsInit( void ) +{ + PHB_SYMB pOpSym; + USHORT uiOperator; + + for( uiOperator = 0, pOpSym = s_opSymbols; uiOperator <= HB_OO_MAX_OPERATOR; + ++uiOperator, ++pOpSym ) + { + pOpSym->pDynSym = hb_dynsymGetCase( pOpSym->szName ); + } + + s___msgClassName.pDynSym = hb_dynsymGetCase( s___msgClassName.szName ); /* Standard messages */ + s___msgClassH.pDynSym = hb_dynsymGetCase( s___msgClassH.szName ); /* Not present in classdef. */ + s___msgClassSel.pDynSym = hb_dynsymGetCase( s___msgClassSel.szName ); + s___msgEval.pDynSym = hb_dynsymGetCase( s___msgEval.szName ); +/* + s___msgClsParent.pDynSym = hb_dynsymGetCase( s___msgClsParent.szName ); + s___msgClass.pDynSym = hb_dynsymGetCase( s___msgClass.szName ); +*/ +} /* * hb_clsRelease( ) @@ -513,15 +583,13 @@ static void hb_clsScope( PHB_ITEM pObject, PMETHOD pMethod ) } if ( uiScope & HB_OO_CLSTP_READONLY ) - { - if( - ( pMethod->pFunction == hb___msgSetData ) || - ( pMethod->pFunction == hb___msgSetClsData ) || - ( pMethod->pFunction == hb___msgSetShrData ) - ) + { + if( ( pMethod->pFuncSym == s___msgSetData ) || + ( pMethod->pFuncSym == s___msgSetClsData ) || + ( pMethod->pFuncSym == s___msgSetShrData ) ) bRetVal = TRUE; - if (bRetVal) + if (bRetVal) { if( ( *( pBase+1 ) )->type == HB_IT_ARRAY ) /* is the sender an object */ { @@ -799,116 +867,157 @@ char * hb_objGetRealClsName( PHB_ITEM pObject, char * szName ) return szClassName; } - -/* - * = hb_objGetMethod( , ) - * - * Internal function to the function pointer of a message of an object - */ -PHB_FUNC hb_objGetMethod( PHB_ITEM pObject, PHB_SYMB pMessage ) +static void hb_objPushSuperCast( PHB_ITEM pObject ) { - return hb_objGetMthd( (PHB_ITEM) pObject, (PHB_SYMB) pMessage, TRUE ); + PHB_BASEARRAY pObjBase; + PHB_ITEM pRealObj; + USHORT uiClass; + USHORT nPos; + + pObjBase = pObject->item.asArray.value; + uiClass = pObjBase->uiClass; + + pRealObj = hb_itemNew( pObjBase->pItems ); + /* and take back the good pObjBase */ + pObjBase = pRealObj->item.asArray.value; + /* Now I should exchnage it with the current stacked value */ + hb_itemSwap( pObject, pRealObj ); + /* and release the fake one */ + hb_itemRelease( pRealObj ); + + /* Push current SuperClass handle */ + if ( ! pObjBase->puiClsTree ) + { + pObjBase->puiClsTree = ( USHORT * ) hb_xgrab( sizeof( USHORT ) ); + pObjBase->puiClsTree[ 0 ] = 0; + } + nPos = pObjBase->puiClsTree[ 0 ] + 1; + pObjBase->puiClsTree = ( USHORT * ) hb_xrealloc( pObjBase->puiClsTree, sizeof( USHORT ) * ( nPos + 1 ) ); + pObjBase->puiClsTree[ 0 ] = nPos ; + pObjBase->puiClsTree[ nPos ] = uiClass; } -static PHB_FUNC hb_objGetMthd( PHB_ITEM pObject, PHB_SYMB pMessage, BOOL lAllowErrFunc ) +void hb_objPopSuperCast( PHB_ITEM pObject ) { - USHORT uiClass; - PHB_DYNS pMsg = pMessage->pDynSym; - PHB_FUNC pFunction; - PMETHOD pMethod; + if( HB_IS_OBJECT( pObject ) ) + { + PHB_BASEARRAY pObjBase = pObject->item.asArray.value; - HB_TRACE(HB_TR_DEBUG, ("hb_objGetMthd(%p, %p)", pObject, pMessage)); + if( pObjBase->puiClsTree ) + { + USHORT nPos = pObjBase->puiClsTree[ 0 ] - 1; + + /* POP SuperClass handle */ + if( nPos ) + { + pObjBase->puiClsTree = ( USHORT * ) hb_xrealloc( pObjBase->puiClsTree, sizeof( USHORT ) * ( nPos + 1 ) ); + pObjBase->puiClsTree[ 0 ] = nPos; + } + else + { + hb_xfree(pObjBase->puiClsTree); + pObjBase->puiClsTree = NULL ; + } + } + } +} + +static PHB_SYMB hb_objGetMthd( PHB_ITEM pObject, PHB_SYMB pMessage, BOOL * pfPopSuper ) +{ + PCLASS pClass = NULL; + PHB_DYNS pMsg; + + HB_TRACE(HB_TR_DEBUG, ("hb_objGetMthd(%p, %p, %p)", pObject, pMessage, pfPopSuper)); + + s_pMethod = NULL; + if( pfPopSuper ) + *pfPopSuper = FALSE; + + pMsg = pMessage->pDynSym; if( pObject->type == HB_IT_ARRAY ) { - uiClass = pObject->item.asArray.value->uiClass; - } - else - { - uiClass = 0; - } + USHORT uiClass = pObject->item.asArray.value->uiClass; - if( uiClass && uiClass <= s_uiClasses ) - { - PCLASS pClass = s_pClasses + ( uiClass - 1 ); - USHORT uiAt = ( USHORT ) ( ( ( hb_cls_MsgToNum( pMsg ) ) % pClass->uiHashKey ) * BUCKET ); - USHORT uiMask = ( USHORT ) ( pClass->uiHashKey * BUCKET ); - USHORT uiLimit = ( USHORT ) ( uiAt ? ( uiAt - 1 ) : ( uiMask - 1 ) ); - - while( uiAt != uiLimit ) + if( pfPopSuper && pObject->item.asArray.value->uiPrevCls ) { - if( pClass->pMethods[ uiAt ].pMessage == pMsg ) + hb_objPushSuperCast( pObject ); + *pfPopSuper = TRUE; + } + + if( uiClass && uiClass <= s_uiClasses ) + { + USHORT uiAt, uiMask, uiLimit; + + pClass = s_pClasses + ( uiClass - 1 ); + uiAt = ( USHORT ) ( ( ( hb_cls_MsgToNum( pMsg ) ) % pClass->uiHashKey ) * BUCKET ); + uiMask = ( USHORT ) ( pClass->uiHashKey * BUCKET ); + uiLimit = ( USHORT ) ( uiAt ? ( uiAt - 1 ) : ( uiMask - 1 ) ); + + while( uiAt != uiLimit ) { - pMethod = pClass->pMethods + uiAt; - pFunction = pMethod->pFunction; - /*hb_clsScope( pObject, pMethod );*/ /* debug */ - s_pMethod = pMethod ; - - if( hb_bProfiler ) + if( pClass->pMethods[ uiAt ].pMessage == pMsg ) { - pMethod->ulCalls++; /* Profiler */ + PMETHOD pMethod = pClass->pMethods + uiAt; + /*hb_clsScope( pObject, pMethod );*/ /* debug */ + s_pMethod = pMethod ; + return pMethod->pFuncSym; } - - return pFunction; + uiAt++; + if( uiAt == uiMask ) + uiAt = 0; } - uiAt++; - if( uiAt == uiMask ) - uiAt = 0; } } - - s_pMethod = NULL; - - /* Default message here */ - - if( s_msgClassName == NULL ) + else if( pObject->type == HB_IT_BLOCK ) { - s_msgClassName = hb_dynsymGetCase( "CLASSNAME" ); /* Standard messages */ - s_msgClassH = hb_dynsymGetCase( "CLASSH" ); /* Not present in classdef. */ - s_msgClassSel = hb_dynsymGetCase( "CLASSSEL" ); - s_msgEval = hb_dynsymGetCase( "EVAL" ); - /*s_msgClsParent = hb_dynsymGetCase( "ISDERIVEDFROM" );*/ - /*s_msgClass = hb_dynsymGetCase( "CLASS" );*/ + if( pMessage == &hb_symEval ) + return pMessage; + else if( pMsg == s___msgEval.pDynSym ) + return &hb_symEval; } - if( pMsg == s_msgClassName ) - return hb___msgClsName; + /* Default messages here */ + if( pMsg == s___msgClassName.pDynSym ) + return &s___msgClassName; - else if( pMsg == s_msgClassH ) - return hb___msgClsH; + else if( pMsg == s___msgClassH.pDynSym ) + return &s___msgClassH; - else if( pMsg == s_msgClassSel ) - return hb___msgClsSel; + else if( pMsg == s___msgClassSel.pDynSym ) + return &s___msgClassSel; - else if( pMsg == s_msgEval ) - return hb___msgEval; + else if( pMsg == s___msgEval.pDynSym ) + return &s___msgEval; +/* + else if( pMsg == s___msgClsParent.pDynSym ) + return &s___msgClsParent; - else if( pMsg == s_msgClsParent ) - return hb___msgClsParent; - -/* else if( pMsg == s_msgClass ) - return hb___msgClass; */ - - if( uiClass && uiClass <= s_uiClasses ) - { - PCLASS pClass = s_pClasses + ( uiClass - 1 ); - - if( lAllowErrFunc && pClass->pFunError ) - return pClass->pFunError; - } + else if( pMsg == s___msgClass.pDynSym ) + return &s___msgClass; +*/ + else if( pClass && pfPopSuper ) + return pClass->pFunError; return NULL; } -static PHB_FUNC hb_objFuncParam( int iParam ) +/* + * = hb_objGetMethod( , , ) + * + * Internal function to the function pointer of a message of an object + */ +PHB_SYMB hb_objGetMethod( PHB_ITEM pObject, PHB_SYMB pMessage, BOOL * pfPopSuper ) { - PHB_ITEM pItem = hb_param( iParam, HB_IT_ANY ); + return hb_objGetMthd( (PHB_ITEM) pObject, (PHB_SYMB) pMessage, pfPopSuper ); +} - if( HB_IS_SYMBOL( pItem ) ) - return pItem->item.asSymbol.value->value.pFunPtr; +static PHB_SYMB hb_objFuncParam( int iParam ) +{ + PHB_ITEM pItem = hb_param( iParam, HB_IT_SYMBOL ); - else if( HB_IS_POINTER( pItem ) ) - return ( PHB_FUNC ) pItem->item.asPointer.value; + if( pItem ) + return pItem->item.asSymbol.value; return NULL; } @@ -948,6 +1057,56 @@ static PMETHOD hb_objGetpMethod( PHB_ITEM pObject, PHB_SYMB pMessage ) } #endif +/* + * Check if object has a given operator + */ +BOOL hb_objHasOperator( PHB_ITEM pObject, USHORT uiOperator ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_objHasOperator(%p,%hu)", pObject, uiOperator)); + + if( pObject->type == HB_IT_ARRAY && + pObject->item.asArray.value->uiClass != 0 ) + { + PCLASS pClass = s_pClasses + pObject->item.asArray.value->uiClass - 1; + return ( pClass->ulOpFlags & ( 1UL << uiOperator ) ) != 0; + } + + return FALSE; +} + +/* + * Call object operator. If pMsgArg is NULL then operator is unary. + * Function return TRUE when object class overloads given operator + * and FALSE otherwise. [druzus] + */ +BOOL hb_objOperatorCall( USHORT uiOperator, HB_ITEM_PTR pResult, + PHB_ITEM pObject, PHB_ITEM pMsgArg ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_objOperatorCall(%hu,%p,%p,%p)", uiOperator, pResult, pObject, pMsgArg)); + + if( hb_objHasOperator( pObject, uiOperator ) ) + { + hb_vmPushSymbol( s_opSymbols + uiOperator ); + hb_vmPush( pObject ); + if( HB_IS_COMPLEX( hb_stackReturnItem() ) ) + hb_itemClear( hb_stackReturnItem() ); + else + hb_stackReturnItem()->type = HB_IT_NIL; + if( pMsgArg ) + { + hb_vmPush( pMsgArg ); + hb_vmSend( 1 ); + } + else + hb_vmSend( 0 ); + + /* store the return value */ + hb_itemCopy( pResult, hb_stackReturnItem() ); + return TRUE; + } + return FALSE; +} + /* * = hb_objHasMsg( , ) * @@ -963,7 +1122,7 @@ BOOL hb_objHasMsg( PHB_ITEM pObject, char *szString ) if( pDynSym ) { - return hb_objGetMthd( pObject, pDynSym->pSymbol, FALSE ) != NULL; + return hb_objGetMthd( pObject, pDynSym->pSymbol, NULL ) != NULL; } else { @@ -1025,61 +1184,79 @@ HB_FUNC( __CLSADDMSG ) USHORT uiAt; PMETHOD pNewMeth; + USHORT uiOperator; + PHB_SYMB pOpSym; + ULONG ulOpFlags = 0; + + /* translate names of operator overloading messages */ if (strcmp("+", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPPLUS" ); + pMessage = ( s_opSymbols + HB_OO_OP_PLUS )->pDynSym; else if (strcmp("-", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPMINUS" ); + pMessage = ( s_opSymbols + HB_OO_OP_MINUS )->pDynSym; else if (strcmp("*", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPMULT" ); + pMessage = ( s_opSymbols + HB_OO_OP_MULT )->pDynSym; else if (strcmp("/", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPDIVIDE" ); + pMessage = ( s_opSymbols + HB_OO_OP_DIVIDE )->pDynSym; else if (strcmp("%", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPMOD" ); + pMessage = ( s_opSymbols + HB_OO_OP_MOD )->pDynSym; else if (strcmp("^", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPPOWER" ); + pMessage = ( s_opSymbols + HB_OO_OP_POWER )->pDynSym; else if (strcmp("**", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPPOWER" ); + pMessage = ( s_opSymbols + HB_OO_OP_POWER )->pDynSym; else if (strcmp("++", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPINC" ); + pMessage = ( s_opSymbols + HB_OO_OP_INC )->pDynSym; else if (strcmp("--", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPDEC" ); + pMessage = ( s_opSymbols + HB_OO_OP_DEC )->pDynSym; else if (strcmp("==", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPEQUAL" ); + pMessage = ( s_opSymbols + HB_OO_OP_EXACTEQUAL )->pDynSym; else if (strcmp("=", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPEQUAL" ); + pMessage = ( s_opSymbols + HB_OO_OP_EQUAL )->pDynSym; else if (strcmp("!=", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPNOTEQUAL" ); + pMessage = ( s_opSymbols + HB_OO_OP_NOTEQUAL )->pDynSym; else if (strcmp("<>", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPNOTEQUAL" ); + pMessage = ( s_opSymbols + HB_OO_OP_NOTEQUAL )->pDynSym; else if (strcmp("#", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPNOTEQUAL" ); + pMessage = ( s_opSymbols + HB_OO_OP_NOTEQUAL )->pDynSym; else if (strcmp("<", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPLESS" ); + pMessage = ( s_opSymbols + HB_OO_OP_LESS )->pDynSym; else if (strcmp("<=", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPLESSEQUAL" ); + pMessage = ( s_opSymbols + HB_OO_OP_LESSEQUAL )->pDynSym; else if (strcmp(">", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPGREATER" ); + pMessage = ( s_opSymbols + HB_OO_OP_GREATER )->pDynSym; else if (strcmp(">=", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPGREATEREQUAL" ); + pMessage = ( s_opSymbols + HB_OO_OP_GREATEREQUAL )->pDynSym; else if (strcmp(":=", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPASSIGN" ); + pMessage = ( s_opSymbols + HB_OO_OP_ASSIGN )->pDynSym; else if (strcmp("$", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPINSTRING" ); + pMessage = ( s_opSymbols + HB_OO_OP_INSTRING )->pDynSym; else if (strcmp("!", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPNOT" ); + pMessage = ( s_opSymbols + HB_OO_OP_NOT )->pDynSym; else if (hb_stricmp(".NOT.", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPNOT" ); + pMessage = ( s_opSymbols + HB_OO_OP_NOT )->pDynSym; else if (hb_stricmp(".AND.", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPAND" ); + pMessage = ( s_opSymbols + HB_OO_OP_AND )->pDynSym; else if (hb_stricmp(".OR.", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPOR" ); + pMessage = ( s_opSymbols + HB_OO_OP_OR )->pDynSym; else if( strcmp("[]", szMessage) == 0) - pMessage = hb_dynsymGetCase( "__OPARRAYINDEX" ); + pMessage = ( s_opSymbols + HB_OO_OP_ARRAYINDEX )->pDynSym; else pMessage = hb_dynsymGet( szMessage ); + for( uiOperator = 0, pOpSym = s_opSymbols; + uiOperator <= HB_OO_MAX_OPERATOR; ++uiOperator, ++pOpSym ) + { + if( pOpSym->pDynSym == pMessage ) + { + ulOpFlags |= 1UL << uiOperator; + break; + } + } + if( wType == HB_OO_MSG_INLINE && hb_param( 3, HB_IT_BLOCK ) == NULL ) + { hb_errRT_BASE( EG_ARG, 3000, NULL, "__CLSADDMSG", 0 ); + return; + } if( pClass->uiMethods > ( pClass->uiHashKey * BUCKET * 2 / 3 ) ) hb_clsDictRealloc( pClass ); @@ -1117,20 +1294,20 @@ HB_FUNC( __CLSADDMSG ) pNewMeth->ulCalls = 0; pNewMeth->ulTime = 0; pNewMeth->ulRecurse = 0; - pNewMeth->bIsPersistent = bPersistent; + pNewMeth->bIsPersistent = bPersistent ? 1 : 0; /* in case of re-used message */ if ( pNewMeth->pInitValue ) - { - hb_itemRelease(pNewMeth->pInitValue) ; - pNewMeth->pInitValue = 0 ; - } + { + hb_itemRelease(pNewMeth->pInitValue) ; + pNewMeth->pInitValue = 0 ; + } switch( wType ) { case HB_OO_MSG_METHOD: - pNewMeth->pFunction = hb_objFuncParam( 3 ); + pNewMeth->pFuncSym = hb_objFuncParam( 3 ); pNewMeth->uiScope = uiScope; pNewMeth->uiData = 0; break; @@ -1141,12 +1318,12 @@ HB_FUNC( __CLSADDMSG ) pNewMeth->uiScope = uiScope; if( pMessage->pSymbol->szName[ 0 ] == '_' ) - pNewMeth->pFunction = hb___msgSetData; + pNewMeth->pFuncSym = &s___msgSetData; else { PHB_ITEM pInit = hb_param( 5, HB_IT_ANY ); - pNewMeth->pFunction = hb___msgGetData; + pNewMeth->pFuncSym = &s___msgGetData; if( pInit && ! HB_IS_NIL( pInit ) ) /* Initializer found */ { @@ -1178,20 +1355,20 @@ HB_FUNC( __CLSADDMSG ) if( ( pNewMeth->uiScope & HB_OO_CLSTP_SHARED ) != HB_OO_CLSTP_SHARED ) { if( pMessage->pSymbol->szName[ 0 ] == '_' ) - pNewMeth->pFunction = hb___msgSetClsData; + pNewMeth->pFuncSym = &s___msgSetClsData; else - pNewMeth->pFunction = hb___msgGetClsData; + pNewMeth->pFuncSym = &s___msgGetClsData; } else { if( pMessage->pSymbol->szName[ 0 ] == '_' ) { - pNewMeth->pFunction = hb___msgSetShrData; + pNewMeth->pFuncSym = &s___msgSetShrData; pClass->uiDatasShared++; } else - pNewMeth->pFunction = hb___msgGetShrData; + pNewMeth->pFuncSym = &s___msgGetShrData; } break; @@ -1202,12 +1379,12 @@ HB_FUNC( __CLSADDMSG ) pNewMeth->uiScope = uiScope; hb_arraySize( pClass->pInlines, pNewMeth->uiData ); hb_arraySet( pClass->pInlines, pNewMeth->uiData, hb_param( 3, HB_IT_BLOCK ) ); - pNewMeth->pFunction = hb___msgEvalInline; + pNewMeth->pFuncSym = &s___msgEvalInline; break; case HB_OO_MSG_VIRTUAL: - pNewMeth->pFunction = hb___msgVirtual; + pNewMeth->pFuncSym = &s___msgVirtual; break; case HB_OO_MSG_SUPER: @@ -1215,7 +1392,7 @@ HB_FUNC( __CLSADDMSG ) pNewMeth->uiData = ( USHORT ) hb_parnl( 3 ); pNewMeth->uiSprClass = ( USHORT ) hb_parnl( 5 ); /* store the super handel */ pNewMeth->uiScope = uiScope; - pNewMeth->pFunction = hb___msgSuper; + pNewMeth->pFuncSym = &s___msgSuper; break; case HB_OO_MSG_ONERROR: @@ -1226,8 +1403,10 @@ HB_FUNC( __CLSADDMSG ) default: hb_errInternal( HB_EI_CLSINVMETHOD, NULL, "__clsAddMsg", NULL ); - break; + return; } + + pClass->ulOpFlags |= ulOpFlags; } } @@ -1271,6 +1450,7 @@ HB_FUNC( __CLSNEW ) pNewCls->uiDatas = 0; pNewCls->uiMethods = 0; pNewCls->uiDatasShared = 0; + pNewCls->ulOpFlags = 0; if( uiSuper ) { @@ -1295,6 +1475,7 @@ HB_FUNC( __CLSNEW ) pNewCls->uiDataFirst += pSprCls->uiDatas; pNewCls->uiDatas = ( USHORT ) ( pNewCls->uiDataFirst + hb_parni( 2 ) ); + pNewCls->ulOpFlags |= pSprCls->ulOpFlags; if( i == 1 ) /* This is the first superclass */ { @@ -1392,24 +1573,24 @@ HB_FUNC( __CLSNEW ) hb_xmemcpy(pNewCls->pMethods + ( uiAt+uiBucket ), pSprCls->pMethods + ui, sizeof( METHOD ) ); if( - pNewCls->pMethods[ uiAt+uiBucket ].pFunction == hb___msgSetClsData + pNewCls->pMethods[ uiAt+uiBucket ].pFuncSym == &s___msgSetClsData || - pNewCls->pMethods[ uiAt+uiBucket ].pFunction == hb___msgGetClsData + pNewCls->pMethods[ uiAt+uiBucket ].pFuncSym == &s___msgGetClsData ) pNewCls->pMethods[ uiAt+uiBucket ].uiData += nLenClsDatas; if( - pNewCls->pMethods[ uiAt+uiBucket ].pFunction == hb___msgSetData + pNewCls->pMethods[ uiAt+uiBucket ].pFuncSym == &s___msgSetData || - pNewCls->pMethods[ uiAt+uiBucket ].pFunction == hb___msgGetData + pNewCls->pMethods[ uiAt+uiBucket ].pFuncSym == &s___msgGetData || - pNewCls->pMethods[ uiAt+uiBucket ].pFunction == hb___msgSuper + pNewCls->pMethods[ uiAt+uiBucket ].pFuncSym == &s___msgSuper ) { pNewCls->pMethods[ uiAt+uiBucket ].uiData += nLenDatas; } - if( pNewCls->pMethods[ uiAt+uiBucket ].pFunction == hb___msgEvalInline ) + if( pNewCls->pMethods[ uiAt+uiBucket ].pFuncSym == &s___msgEvalInline ) pNewCls->pMethods[ uiAt+uiBucket ].uiData += nLenInlines; if( ( pSprCls->pMethods[ ui ].uiScope & HB_OO_CLSTP_SUPER ) != HB_OO_CLSTP_SUPER ) @@ -1499,9 +1680,9 @@ HB_FUNC( __CLSDELMSG ) } if( uiAt != uiLimit ) { /* Requested method found */ - PHB_FUNC pFunc = pClass->pMethods[ uiAt ].pFunction; + PHB_SYMB pFuncSym = pClass->pMethods[ uiAt ].pFuncSym; - if( pFunc == hb___msgEvalInline ) /* INLINE method deleted */ + if( pFuncSym == &s___msgEvalInline ) /* INLINE method deleted */ { hb_arrayDel( pClass->pInlines, pClass->pMethods[ uiAt ].uiData ); /* Delete INLINE block */ @@ -1577,7 +1758,7 @@ static PHB_ITEM hb_clsInst( USHORT uiClass ) if( pMeth->pInitValue ) { - if( pMeth->pFunction == hb___msgGetClsData && !( pMeth->bClsDataInitiated ) ) + if( pMeth->pFuncSym == &s___msgGetClsData && !( pMeth->bClsDataInitiated ) ) { PHB_ITEM pInit; @@ -1591,14 +1772,14 @@ static PHB_ITEM hb_clsInst( USHORT uiClass ) pMeth->bClsDataInitiated = 1; } } - else if( pMeth->pFunction == hb___msgGetData ) /* is a DATA but not herited */ + else if( pMeth->pFuncSym == &s___msgGetData ) /* is a DATA but not herited */ { PHB_ITEM pInit = hb_itemClone( pMeth->pInitValue ); hb_arraySet( pSelf, pMeth->uiData, pInit ); hb_itemRelease( pInit ); } - else if( pMeth->pFunction == hb___msgGetShrData && !( pMeth->bClsDataInitiated ) ) + else if( pMeth->pFuncSym == &s___msgGetShrData && !( pMeth->bClsDataInitiated ) ) { /* Init Shared Classdata as needed, we only need to init the first */ /* not inherited classdata array where all shared will point to */ @@ -1652,9 +1833,9 @@ HB_FUNC( __CLSMODMSG ) if( uiAt != uiLimit ) { /* Requested method found */ - PHB_FUNC pFunc = pClass->pMethods[ uiAt ].pFunction; + PHB_SYMB pFuncSym = pClass->pMethods[ uiAt ].pFuncSym; - if( pFunc == hb___msgEvalInline ) /* INLINE method changed */ + if( pFuncSym == &s___msgEvalInline ) /* INLINE method changed */ { PHB_ITEM pBlock = hb_param( 3, HB_IT_BLOCK ); @@ -1667,13 +1848,13 @@ HB_FUNC( __CLSMODMSG ) hb_arraySet( pClass->pInlines, pClass->pMethods[ uiAt ].uiData, pBlock ); } } - else if( ( pFunc == hb___msgSetData ) || ( pFunc == hb___msgGetData ) ) + else if( pFuncSym == &s___msgSetData || pFuncSym == &s___msgGetData ) { /* Not allowed for DATA */ hb_errRT_BASE( EG_ARG, 3004, "Cannot modify a DATA item", "__CLSMODMSG", 0 ); } else /* Modify METHOD */ { - pClass->pMethods[ uiAt ].pFunction = hb_objFuncParam( 3 ); + pClass->pMethods[ uiAt ].pFuncSym = hb_objFuncParam( 3 ); } } } @@ -1818,7 +1999,7 @@ HB_FUNC( __OBJSENDMSG ) hb_vmPush( hb_param( uiParam, HB_IT_ANY ) ); } - hb_vmDo( ( USHORT ) ( uiPCount - 2 ) ); /* Execute message */ + hb_vmSend( ( USHORT ) ( uiPCount - 2 ) ); /* Execute message */ } } else @@ -1850,7 +2031,7 @@ HB_FUNC( __CLSINSTSUPER ) hb_vmPushNil(); hb_vmFunction( 0 ); /* Execute super class */ - if( HB_IS_OBJECT( hb_stackItemFromTop( -1 ) ) ) /* &hb_stack.Return */ + if( HB_IS_OBJECT( hb_stackReturnItem() ) ) { for( uiClass = 0; ! bFound && uiClass < s_uiClasses; uiClass++ ) { /* Locate the entry */ @@ -2006,11 +2187,7 @@ HB_FUNC( __CLASSSEL ) /* to be used from Classes ERROR HANDLER method */ HB_FUNC( __GETMESSAGE ) { - PHB_ITEM * pBase = hb_stack.pBase; - - pBase = hb_stack.pItems + ( *pBase )->item.asSymbol.stackbase; - - hb_retc( ( *pBase )->item.asSymbol.value->szName ); + hb_retc( hb_stackItem( hb_stackBaseItem()->item.asSymbol.stackbase )->item.asSymbol.value->szName ); } HB_FUNC( __CLSPARENT ) @@ -2020,14 +2197,14 @@ HB_FUNC( __CLSPARENT ) HB_FUNC( __SENDER ) { - PHB_ITEM * pBase = hb_stack.pBase; - PHB_ITEM oSender = NULL; USHORT iLevel = 3; + PHB_ITEM oSender = NULL; + LONG lOffset = hb_stackBaseOffset(); - while( iLevel > 0 && pBase != hb_stack.pItems ) + while( iLevel > 0 && lOffset > 1 ) { - pBase = hb_stack.pItems + ( *pBase )->item.asSymbol.stackbase; - oSender = *( pBase + 1 ); + lOffset = hb_stackItem( lOffset )->item.asSymbol.stackbase; + oSender = hb_stackItem( lOffset + 1 ); if( ( iLevel-- == 2 && oSender->type != HB_IT_BLOCK ) || oSender->type == HB_IT_NIL ) break; @@ -2095,47 +2272,6 @@ static HARBOUR hb___msgClsH( void ) } -/* Added by JfL&RaC - * <= :IsDerivedFrom( xParam ) - * - * Return true if is derived from xParam. - * xParam can be either an obj or a classname - */ -static HARBOUR hb___msgClsParent( void ) -{ - PHB_ITEM pItemRef; - PHB_ITEM pItemParam; - char * szParentName = 0; - USHORT uiClass, i; - BOOL lClass=FALSE; - - if( HB_IS_BYREF( hb_stackSelfItem() ) ) /* Variables by reference */ - pItemRef = hb_itemUnRef( hb_stackSelfItem() ); - else - pItemRef = hb_stackSelfItem(); - - uiClass = pItemRef->item.asArray.value->uiClass; - - pItemParam = hb_stackItemFromBase( 1 ); - - if( HB_IS_OBJECT( pItemParam ) ) - szParentName = hb_objGetClsName( pItemParam ); - else if( HB_IS_STRING( pItemParam ) ) - { - szParentName = hb_itemGetC( pItemParam ); - lClass=TRUE; - } - - for( i = 0; szParentName[ i ] != '\0'; i++ ) - szParentName[ i ] = ( char ) toupper( szParentName[ i ] ); - - hb_retl( hb_clsIsParent( uiClass , szParentName ) ); - - if (lClass) - hb_itemFreeC( szParentName ); -} - - /* * := :ClassName() * @@ -2201,18 +2337,18 @@ static HARBOUR hb___msgClsSel( void ) if( ( nParam == HB_MSGLISTALL ) || ( nParam == HB_MSGLISTCLASS && ( - ( s_pMethod->pFunction == hb___msgSetClsData ) || - ( s_pMethod->pFunction == hb___msgGetClsData ) || - ( s_pMethod->pFunction == hb___msgSetShrData ) || - ( s_pMethod->pFunction == hb___msgGetShrData ) + ( s_pMethod->pFuncSym == &s___msgSetClsData ) || + ( s_pMethod->pFuncSym == &s___msgGetClsData ) || + ( s_pMethod->pFuncSym == &s___msgSetShrData ) || + ( s_pMethod->pFuncSym == &s___msgGetShrData ) ) ) || ( nParam == HB_MSGLISTPURE && !( - ( s_pMethod->pFunction == hb___msgSetClsData ) || - ( s_pMethod->pFunction == hb___msgGetClsData ) || - ( s_pMethod->pFunction == hb___msgSetShrData ) || - ( s_pMethod->pFunction == hb___msgGetShrData ) + ( s_pMethod->pFuncSym == &s___msgSetClsData ) || + ( s_pMethod->pFuncSym == &s___msgGetClsData ) || + ( s_pMethod->pFuncSym == &s___msgSetShrData ) || + ( s_pMethod->pFuncSym == &s___msgGetShrData ) ) ) ) @@ -2227,6 +2363,60 @@ static HARBOUR hb___msgClsSel( void ) hb_itemRelease( hb_itemReturn( pReturn ) ); } +#if 0 + +/* + * __msgClass() + * + * Internal function to return Self at Self:Class call (classy compatibility) + */ +static HARBOUR hb___msgClass( void ) +{ + hb_itemReturn( hb_stackSelfItem() ); +} + +/* Added by JfL&RaC + * <= :IsDerivedFrom( xParam ) + * + * Return true if is derived from xParam. + * xParam can be either an obj or a classname + */ +static HARBOUR hb___msgClsParent( void ) +{ + PHB_ITEM pItemRef; + PHB_ITEM pItemParam; + char * szParentName = 0; + USHORT uiClass, i; + BOOL lClass=FALSE; + + if( HB_IS_BYREF( hb_stackSelfItem() ) ) /* Variables by reference */ + pItemRef = hb_itemUnRef( hb_stackSelfItem() ); + else + pItemRef = hb_stackSelfItem(); + + uiClass = pItemRef->item.asArray.value->uiClass; + + pItemParam = hb_stackItemFromBase( 1 ); + + if( HB_IS_OBJECT( pItemParam ) ) + szParentName = hb_objGetClsName( pItemParam ); + else if( HB_IS_STRING( pItemParam ) ) + { + szParentName = hb_itemGetC( pItemParam ); + lClass=TRUE; + } + + for( i = 0; szParentName[ i ] != '\0'; i++ ) + szParentName[ i ] = ( char ) toupper( szParentName[ i ] ); + + hb_retl( hb_clsIsParent( uiClass , szParentName ) ); + + if (lClass) + hb_itemFreeC( szParentName ); +} + +#endif + /* * __msgEvalInline() @@ -2313,18 +2503,6 @@ static HARBOUR hb___msgSuper( void ) hb_itemRelease( hb_itemReturn( pCopy ) ); } -/* - * __msgClass() - * - * Internal function to return Self at Self:Class call (classy compatibility) - */ -/* -static HARBOUR hb___msgClass( void ) -{ - hb_itemReturn( hb_stackSelfItem() ); -} -*/ - /* * __msgGetClsData() * @@ -2335,7 +2513,7 @@ static HARBOUR hb___msgGetClsData( void ) USHORT uiClass = ( hb_stackSelfItem() )->item.asArray.value->uiClass; if( uiClass && uiClass <= s_uiClasses ) - hb_arrayGet( s_pClasses[ uiClass - 1 ].pClassDatas, s_pMethod->uiData, &hb_stack.Return ); + hb_arrayGet( s_pClasses[ uiClass - 1 ].pClassDatas, s_pMethod->uiData, hb_stackReturnItem() ); } @@ -2368,7 +2546,7 @@ static HARBOUR hb___msgGetShrData( void ) USHORT uiSprCls = s_pMethod->uiSprClass; if( uiSprCls && uiSprCls <= s_uiClasses ) - hb_arrayGet( s_pClasses[ uiSprCls - 1 ].pClassDatas, s_pMethod->uiDataShared, &hb_stack.Return ); + hb_arrayGet( s_pClasses[ uiSprCls - 1 ].pClassDatas, s_pMethod->uiDataShared, hb_stackReturnItem() ); } /* @@ -2404,7 +2582,7 @@ static HARBOUR hb___msgGetData( void ) if( uiIndex > ( USHORT ) hb_arrayLen( pObject ) ) /* Resize needed */ hb_arraySize( pObject, uiIndex ); /* Make large enough */ - hb_arrayGet( pObject, uiIndex, &hb_stack.Return ); + hb_arrayGet( pObject, uiIndex, hb_stackReturnItem() ); } /* @@ -2488,6 +2666,7 @@ HB_FUNC( __CLS_PAR00 ) hb_itemRelease( hb_itemReturn( array ) ); } +#ifndef HB_NO_PROFILER static ULONG MsgToNum( char * szName ) { USHORT i; @@ -2499,20 +2678,39 @@ static ULONG MsgToNum( char * szName ) return nRetVal; } +/* profiler: It provides to the HVM the just requested method pointer */ +void * hb_mthRequested( void ) +{ + return ( void * ) s_pMethod; +} + +void hb_mthAddTime( void * pMethod, ULONG ulClockTicks ) +{ + if( pMethod != NULL ) + { + ( ( PMETHOD ) pMethod )->ulCalls++; /* Profiler */ + ( ( PMETHOD ) pMethod )->ulTime += ulClockTicks; + } +} +#endif + HB_FUNC( __GETMSGPRF ) /* profiler: returns a method called and consumed times */ /* ( nClass, cMsg ) --> aMethodInfo { nTimes, nTime } */ { +#ifndef HB_NO_PROFILER PCLASS pClass = s_pClasses + ( hb_parnl( 1 ) - 1 ); char * cMsg = hb_parc( 2 ); USHORT uiAt = ( USHORT ) ( ( ( MsgToNum( cMsg ) ) % pClass->uiHashKey ) * BUCKET ); USHORT uiMask = ( USHORT ) ( pClass->uiHashKey * BUCKET ); USHORT uiLimit = ( USHORT ) ( uiAt ? ( uiAt - 1 ) : ( uiMask - 1 ) ); PMETHOD pMethod; +#endif hb_reta( 2 ); hb_stornl( 0, -1, 1 ); hb_stornl( 0, -1, 2 ); +#ifndef HB_NO_PROFILER while( uiAt != uiLimit ) { if( ! strcmp( pClass->pMethods[ uiAt ].pMessage->pSymbol->szName, cMsg ) ) @@ -2526,18 +2724,7 @@ HB_FUNC( __GETMSGPRF ) /* profiler: returns a method called and consumed times * if( uiAt == uiMask ) uiAt = 0; } -} - -/* profiler: It provides to the HVM the just requested method pointer */ -void * hb_mthRequested( void ) -{ - return ( void * ) s_pMethod; -} - -void hb_mthAddTime( void * pMethod, ULONG ulClockTicks ) -{ - if( pMethod != NULL ) - ( ( PMETHOD ) pMethod )->ulTime += ulClockTicks; +#endif } /* __ClsGetProperties( nClassHandle ) --> aPropertiesNames @@ -2563,8 +2750,7 @@ HB_FUNC( __CLSGETPROPERTIES ) { PHB_DYNS pMessage = ( PHB_DYNS ) pClass->pMethods[ uiAt ].pMessage; - if( ( pMessage != NULL ) && - ( pClass->pMethods[ uiAt ].bIsPersistent == ( BOOL ) TRUE ) ) /* Hash Entry used ? */ + if( pMessage && pClass->pMethods[ uiAt ].bIsPersistent ) /* Hash Entry used ? */ { PHB_ITEM pItem = hb_itemPutC( NULL, pMessage->pSymbol->szName ); /* Add to array */ @@ -2597,10 +2783,9 @@ HB_FUNC( HB_SETCLSHANDLE ) /* ( oObject, nClassHandle ) --> nPrevClassHandle */ } /* Harbour equivalent for Clipper internal __mdCreate() */ - USHORT hb_clsCreate( USHORT usSize, char * szClassName ) { - PHB_DYNS pDynSym = hb_dynsymFind( "__CLSNEW" ); + PHB_DYNS pDynSym = hb_dynsymGet( "__CLSNEW" ); hb_vmPushSymbol( pDynSym->pSymbol ); hb_vmPushNil(); @@ -2612,28 +2797,25 @@ USHORT hb_clsCreate( USHORT usSize, char * szClassName ) } /* Harbour equivalent for Clipper internal __mdAdd() */ - -void hb_clsAdd( USHORT usClassH, char * szMethodName, void * pFunction ) +void hb_clsAdd( USHORT usClassH, char * szMethodName, PHB_SYMB pFuncSym ) { - PHB_DYNS pDynSym = hb_dynsymFind( "__CLSADDMSG" ); + PHB_DYNS pDynSym = hb_dynsymGet( "__CLSADDMSG" ); hb_vmPushSymbol( pDynSym->pSymbol ); hb_vmPushNil(); hb_vmPushLong( usClassH ); hb_vmPushString( szMethodName, strlen( szMethodName ) ); - hb_vmPushPointer( pFunction ); + hb_vmPushSymbol( pFuncSym ); hb_vmFunction( 3 ); } /* Harbour equivalent for Clipper internal __mdAssociate() */ - void hb_clsAssociate( USHORT usClassH ) { - PHB_DYNS pDynSym = hb_dynsymFind( "__CLSINST" ); + PHB_DYNS pDynSym = hb_dynsymGet( "__CLSINST" ); hb_vmPushSymbol( pDynSym->pSymbol ); hb_vmPushNil(); hb_vmPushLong( usClassH ); hb_vmFunction( 1 ); } - diff --git a/harbour/source/vm/codebloc.c b/harbour/source/vm/codebloc.c index e95c004700..e58cf0e622 100644 --- a/harbour/source/vm/codebloc.c +++ b/harbour/source/vm/codebloc.c @@ -58,6 +58,44 @@ #include "hbvm.h" #include "hbstack.h" +/* Release all allocated memory when called from the garbage collector + */ +static HB_GARBAGE_FUNC( hb_codeblockDeleteGarbage ) +{ + HB_CODEBLOCK_PTR pCBlock = ( HB_CODEBLOCK_PTR ) Cargo; + + HB_TRACE(HB_TR_DEBUG, ("hb_codeblockDeleteGarbage(%p)", Cargo)); + + /* free space allocated for pcodes - if it was a macro-compiled codeblock + */ + if( pCBlock->pCode && pCBlock->dynBuffer ) + { + hb_xfree( pCBlock->pCode ); + pCBlock->pCode = NULL; + } + + /* free space allocated for local variables + */ + if( pCBlock->pLocals ) + { + PHB_ITEM pLocals = pCBlock->pLocals; + USHORT uiLocals = pCBlock->uiLocals; + + /* clear pCBlock->pLocals to avoid infinit loop in cross + * referenced items + */ + pCBlock->pLocals = NULL; + pCBlock->uiLocals = 0; + + if( hb_xRefDec( pLocals ) ) + { + while( uiLocals ) + hb_memvarValueDecRef( pLocals[ uiLocals-- ].item.asMemvar.value ); + hb_xfree( pLocals ); + } + } +} + /* Creates the codeblock structure * * pBuffer -> the buffer with pcodes (without HB_P_PUSHBLOCK) @@ -71,11 +109,12 @@ HB_CODEBLOCK_PTR hb_codeblockNew( const BYTE * pBuffer, USHORT uiLocals, const BYTE * pLocalPosTable, - PHB_SYMB pSymbols ) + PHB_SYMB pSymbols, + USHORT usLen ) { HB_CODEBLOCK_PTR pCBlock; - HB_TRACE(HB_TR_DEBUG, ("hb_codeblockNew(%p, %hu, %p, %p)", pBuffer, uiLocals, pLocalPosTable, pSymbols)); + HB_TRACE(HB_TR_DEBUG, ("hb_codeblockNew(%p, %hu, %p, %p, %hu)", pBuffer, uiLocals, pLocalPosTable, pSymbols, usLen)); pCBlock = ( HB_CODEBLOCK_PTR ) hb_gcAlloc( sizeof( HB_CODEBLOCK ), hb_codeblockDeleteGarbage ); @@ -133,37 +172,41 @@ HB_CODEBLOCK_PTR hb_codeblockNew( const BYTE * pBuffer, { HB_CODEBLOCK_PTR pOwner = pLocal->item.asBlock.value; - pCBlock->pLocals = pOwner->pLocals; - pCBlock->uiLocals = uiLocals = pOwner->uiLocals; + pCBlock->uiLocals = pOwner->uiLocals; + pCBlock->pLocals = pOwner->pLocals; if( pOwner->pLocals ) - { /* the outer codeblock have the table with local references - reuse it */ - while( uiLocals ) - { - hb_memvarValueIncRef( pCBlock->pLocals[ uiLocals ].item.asMemvar.value ); - --uiLocals; - } - /* increment a reference counter for the table of local references - */ - pCBlock->pLocals[ 0 ].item.asLong.value++; - } + hb_xRefInc( pOwner->pLocals ); } else pCBlock->pLocals = NULL; } - /* - * The codeblock pcode is stored in static segment. - * The only allowed operation on a codeblock is evaluating it then - * there is no need to duplicate its pcode - just store the pointer to it - */ - pCBlock->pCode = ( BYTE * ) pBuffer; - pCBlock->dynBuffer = FALSE; + if( usLen ) + { + /* + * The codeblock pcode is stored in dynamically allocated memory that + * can be deallocated after creation of a codeblock. We have to duplicate + * the passed buffer + */ + pCBlock->pCode = ( BYTE * ) hb_xgrab( usLen ); + memcpy( pCBlock->pCode, pBuffer, usLen ); + pCBlock->dynBuffer = TRUE; + } + else + { + /* + * The codeblock pcode is stored in static segment. + * The only allowed operation on a codeblock is evaluating it then + * there is no need to duplicate its pcode - just store the pointer to it + */ + pCBlock->pCode = ( BYTE * ) pBuffer; + pCBlock->dynBuffer = FALSE; + } pCBlock->pDefSymb = hb_stackBaseItem()->item.asSymbol.value; pCBlock->pSymbols = pSymbols; - pCBlock->ulCounter = 1; - HB_TRACE(HB_TR_INFO, ("codeblock created (%li) %lx", pCBlock->ulCounter, pCBlock)); + HB_TRACE(HB_TR_INFO, ("codeblock created %p", pCBlock)); return pCBlock; } @@ -191,86 +234,12 @@ HB_CODEBLOCK_PTR hb_codeblockMacroNew( BYTE * pBuffer, USHORT usLen ) pCBlock->pDefSymb = hb_stackBaseItem()->item.asSymbol.value; pCBlock->pSymbols = NULL; /* macro-compiled codeblock cannot acces a local symbol table */ - pCBlock->ulCounter = 1; - HB_TRACE(HB_TR_INFO, ("codeblock created (%li) %lx", pCBlock->ulCounter, pCBlock)); + HB_TRACE(HB_TR_INFO, ("codeblock created %p", pCBlock)); return pCBlock; } -/* Delete a codeblock - */ -void hb_codeblockDelete( HB_ITEM_PTR pItem ) -{ - HB_CODEBLOCK_PTR pCBlock = pItem->item.asBlock.value; - - HB_TRACE(HB_TR_DEBUG, ("hb_codeblockDelete(%p)", pItem)); - - if( pCBlock && (--pCBlock->ulCounter == 0) ) - { - if( pCBlock->pLocals ) - { - USHORT ui = pCBlock->uiLocals; - while( ui ) - hb_memvarValueDecRef( pCBlock->pLocals[ ui-- ].item.asMemvar.value ); - /* decrement the table reference counter and release memory if - * it was the last reference - */ - if( --pCBlock->pLocals[ 0 ].item.asLong.value == 0 ) - hb_xfree( pCBlock->pLocals ); - } - - /* free space allocated for pcodes - if it was a macro-compiled codeblock - */ - if( pCBlock->pCode && pCBlock->dynBuffer ) - { - hb_xfree( pCBlock->pCode ); - pCBlock->pCode = NULL; - } - - /* free space allocated for a CODEBLOCK structure - */ - hb_gcFree( pCBlock ); - } -} - -/* Release all allocated memory when called from the garbage collector - */ -HB_GARBAGE_FUNC( hb_codeblockDeleteGarbage ) -{ - HB_CODEBLOCK_PTR pCBlock = ( HB_CODEBLOCK_PTR ) Cargo; - - HB_TRACE(HB_TR_DEBUG, ("hb_codeblockDeleteGarbage(%p)", Cargo)); - - /* free space allocated for local variables - */ - if( pCBlock->pLocals ) - { - USHORT ui = 1; - while( ui <= pCBlock->uiLocals ) - { - hb_memvarValueDecGarbageRef( pCBlock->pLocals[ ui ].item.asMemvar.value ); - ++ui; - } - /* decrement the table reference counter and release memory if - * it was the last reference - */ - if( --pCBlock->pLocals[ 0 ].item.asLong.value == 0 ) - { - hb_xfree( pCBlock->pLocals ); - pCBlock->pLocals = NULL; - } - } - - /* free space allocated for pcodes - if it was a macro-compiled codeblock - */ - if( pCBlock->pCode && pCBlock->dynBuffer ) - { - hb_xfree( pCBlock->pCode ); - pCBlock->pCode = NULL; - } -} - /* Evaluate passed codeblock * Before evaluation we have to switch to a static variable base that * was defined when the codeblock was created. @@ -279,13 +248,10 @@ HB_GARBAGE_FUNC( hb_codeblockDeleteGarbage ) */ void hb_codeblockEvaluate( HB_ITEM_PTR pItem ) { - int iStatics = hb_stack.iStatics; - HB_TRACE(HB_TR_DEBUG, ("hb_codeblockEvaluate(%p)", pItem)); hb_stack.iStatics = pItem->item.asBlock.statics; hb_vmExecute( pItem->item.asBlock.value->pCode, pItem->item.asBlock.value->pSymbols ); - hb_stack.iStatics = iStatics; } /* Get local variable referenced in a codeblock diff --git a/harbour/source/vm/debug.c b/harbour/source/vm/debug.c index affe0b9289..3b0f9202a1 100644 --- a/harbour/source/vm/debug.c +++ b/harbour/source/vm/debug.c @@ -61,22 +61,20 @@ * $End$ */ static void AddToArray( PHB_ITEM pItem, PHB_ITEM pReturn, ULONG ulPos ) { - PHB_ITEM pTemp; - HB_TRACE(HB_TR_DEBUG, ("AddToArray(%p, %p, %lu)", pItem, pReturn, ulPos)); if( pItem->type == HB_IT_SYMBOL ) { /* Symbol is pushed as text */ - pTemp = hb_itemNew( NULL ); /* Create temporary string */ - pTemp->type = HB_IT_STRING; - pTemp->item.asString.length = strlen( pItem->item.asSymbol.value->szName ) + 2; - pTemp->item.asString.value = ( char * ) hb_xgrab( pTemp->item.asString.length + 1 ); - pTemp->item.asString.bStatic = FALSE; + PHB_ITEM pArrayItem = hb_arrayGetItemPtr( pReturn, ulPos ); - sprintf( pTemp->item.asString.value, "[%s]", pItem->item.asSymbol.value->szName ); + if( pArrayItem ) + { + ULONG ulLen = strlen( pItem->item.asSymbol.value->szName ) + 2; + char * szBuff = ( char * ) hb_xgrab( ulLen ); - hb_itemArrayPut( pReturn, ulPos, pTemp ); - hb_itemRelease( pTemp ); /* Get rid of temporary str.*/ + sprintf( szBuff, "[%s]", pItem->item.asSymbol.value->szName ); + hb_itemPutCPtr( pArrayItem, szBuff, ulLen ); + } } else /* Normal types */ hb_itemArrayPut( pReturn, ulPos, pItem ); diff --git a/harbour/source/vm/dynlibhb.c b/harbour/source/vm/dynlibhb.c index 12750947e5..e2f8dd97ae 100644 --- a/harbour/source/vm/dynlibhb.c +++ b/harbour/source/vm/dynlibhb.c @@ -63,29 +63,101 @@ #include "hbstack.h" #include "hbvm.h" +#if defined(HB_OS_LINUX) && !defined(__WATCOMC__) +# include +#endif + HB_FUNC( HB_LIBLOAD ) { + void * hDynLib = NULL; + #if defined(HB_OS_WIN_32) + if( hb_parclen( 1 ) > 0 ) { - hb_retnl( ( long ) LoadLibrary( hb_parc( 1 ) ) ); + int argc = hb_pcount() - 1, i; + char **argv = NULL; + + if( argc > 0 ) + { + argv = ( char** ) hb_xgrab( sizeof( char* ) * argc ); + for( i = 0; i < argc; ++i ) + { + argv[i] = hb_parcx( i + 2 ); + } + } + + /* use stack address as first level marker */ + hb_vmBeginSymbolGroup( ( void * ) &hb_stack, TRUE ); + hDynLib = ( void * ) LoadLibrary( hb_parc( 1 ) ); + /* set real marker */ + hb_vmInitSymbolGroup( hDynLib, argc, argv ); + if( argv ) + { + hb_xfree( argv ); + } } -#else +#elif defined(HB_OS_LINUX) && !defined(__WATCOMC__) + if( hb_parclen( 1 ) > 0 ) { - hb_retnl( 0 ); + int argc = hb_pcount() - 1, i; + char **argv = NULL; + + if( argc > 0 ) + { + argv = ( char** ) hb_xgrab( sizeof( char* ) * argc ); + for( i = 0; i < argc; ++i ) + { + argv[i] = hb_parcx( i + 2 ); + } + } + + /* use stack address as first level marker */ + hb_vmBeginSymbolGroup( ( void * ) &hb_stack, TRUE ); + hDynLib = ( void * ) dlopen( hb_parc( 1 ), RTLD_LAZY | RTLD_GLOBAL ); + /* set real marker */ + hb_vmInitSymbolGroup( hDynLib, argc, argv ); + if( argv ) + { + hb_xfree( argv ); + } } #endif + + hb_retptr( hDynLib ); } HB_FUNC( HB_LIBFREE ) { #if defined(HB_OS_WIN_32) + void * hDynLib = hb_parptr( 1 ); + + if( hDynLib ) { - hb_retl( FreeLibrary( ( HMODULE ) hb_parnl( 1 ) ) ); + hb_vmExitSymbolGroup( hDynLib ); + hb_retl( FreeLibrary( ( HMODULE ) hDynLib ) ); } -#else + else +#elif defined(HB_OS_LINUX) && !defined(__WATCOMC__) + void * hDynLib = hb_parptr( 1 ); + + if( hDynLib ) + { + hb_vmExitSymbolGroup( hDynLib ); + hb_retl( dlclose( hDynLib ) == 0 ); + } + else +#endif { hb_retl( FALSE ); } +} + +HB_FUNC( HB_LIBERROR ) +{ +#if defined(HB_OS_LINUX) && !defined(__WATCOMC__) + hb_retc( dlerror() ); +#else + hb_retc( NULL ); #endif } diff --git a/harbour/source/vm/dynsym.c b/harbour/source/vm/dynsym.c index 8dd9456fc1..885a3a31db 100644 --- a/harbour/source/vm/dynsym.c +++ b/harbour/source/vm/dynsym.c @@ -120,16 +120,14 @@ HB_EXPORT PHB_DYNS hb_dynsymNew( PHB_SYMB pSymbol ) /* creates a new dynamic if( pDynSym ) /* If name exists */ { - if( pSymbol->scope.value & HB_FS_PUBLIC ) /* only for HB_FS_PUBLIC */ + if( !pDynSym->pSymbol->value.pFunPtr && pSymbol->value.pFunPtr ) /* The DynSym existed */ { - if( ( ! pDynSym->pFunPtr ) && pSymbol->value.pFunPtr ) /* The DynSym existed */ - { - pDynSym->pFunPtr = pSymbol->value.pFunPtr; /* but had no function ptr assigned */ - pDynSym->pSymbol = pSymbol; - pDynSym->ulCalls = 0; /* profiler support */ - pDynSym->ulTime = 0; /* profiler support */ - pDynSym->ulRecurse = 0; - } + pDynSym->pSymbol = pSymbol; +#ifndef HB_NO_PROFILER + pDynSym->ulCalls = 0; /* profiler support */ + pDynSym->ulTime = 0; /* profiler support */ + pDynSym->ulRecurse = 0; /* profiler support */ +#endif } pSymbol->pDynSym = pDynSym; /* place a pointer to DynSym */ return pDynSym; /* Return pointer to DynSym */ @@ -158,19 +156,12 @@ HB_EXPORT PHB_DYNS hb_dynsymNew( PHB_SYMB pSymbol ) /* creates a new dynamic pDynSym->pSymbol = pSymbol; pDynSym->hMemvar = 0; pDynSym->hArea = 0; - pDynSym->ulCalls = 0; /* profiler support */ - pDynSym->ulTime = 0; /* profiler support */ - pDynSym->ulRecurse = 0; - - if( pSymbol->scope.value & HB_FS_PUBLIC ) /* only for HB_FS_PUBLIC */ - { - pDynSym->pFunPtr = pSymbol->value.pFunPtr; /* place the pointer function at DynSym */ - } - else - { - pDynSym->pFunPtr = NULL; - } - pSymbol->pDynSym = pDynSym; /* place a pointer to DynSym */ +#ifndef HB_NO_PROFILER + pDynSym->ulCalls = 0; /* profiler support */ + pDynSym->ulTime = 0; /* profiler support */ + pDynSym->ulRecurse = 0; /* profiler support */ +#endif + pSymbol->pDynSym = pDynSym; /* place a pointer to DynSym */ return pDynSym; } @@ -464,7 +455,7 @@ HB_FUNC( __DYNSISFUN ) /* returns .t. if a symbol has a function/procedure point long lIndex = hb_parnl( 1 ); /* NOTE: This will return zero if the parameter is not numeric */ if( lIndex >= 1 && lIndex <= s_uiDynSymbols ) - hb_retl( s_pDynItems[ lIndex - 1 ].pDynSym->pFunPtr != NULL ); + hb_retl( s_pDynItems[ lIndex - 1 ].pDynSym->pSymbol->value.pFunPtr != NULL ); else hb_retl( FALSE ); } @@ -473,20 +464,24 @@ HB_FUNC( __DYNSGETPRF ) /* profiler: It returns an array with a function or proc called and consumed times { nTimes, nTime } , given the dynamic symbol index */ { +#ifndef HB_NO_PROFILER long lIndex = hb_parnl( 1 ); /* NOTE: This will return zero if the parameter is not numeric */ +#endif hb_reta( 2 ); hb_stornl( 0, -1, 1 ); hb_stornl( 0, -1, 2 ); +#ifndef HB_NO_PROFILER if( lIndex >= 1 && lIndex <= s_uiDynSymbols ) { - if( s_pDynItems[ lIndex - 1 ].pDynSym->pFunPtr ) /* it is a function or procedure */ + if( s_pDynItems[ lIndex - 1 ].pDynSym->pSymbol->value.pFunPtr ) /* it is a function or procedure */ { hb_stornl( s_pDynItems[ lIndex - 1 ].pDynSym->ulCalls, -1, 1 ); hb_stornl( s_pDynItems[ lIndex - 1 ].pDynSym->ulTime, -1, 2 ); } } +#endif } #endif diff --git a/harbour/source/vm/estack.c b/harbour/source/vm/estack.c index dc46d61dc5..c4afecd495 100644 --- a/harbour/source/vm/estack.c +++ b/harbour/source/vm/estack.c @@ -56,6 +56,7 @@ #include "hbvmopt.h" #include "hbapi.h" +#include "hbapicls.h" #include "hbdefs.h" #include "hbstack.h" #include "hbapiitm.h" @@ -88,6 +89,20 @@ void hb_stackPop( void ) hb_itemClear( * hb_stack.pPos ); } +#undef hb_stackPopReturn +void hb_stackPopReturn( void ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_stackPopReturn()")); + + if( HB_IS_COMPLEX( &hb_stack.Return ) ) + hb_itemClear( &hb_stack.Return ); + + if( --hb_stack.pPos < hb_stack.pItems ) + hb_errInternal( HB_EI_STACKUFLOW, NULL, NULL, NULL ); + + hb_itemRawMove( &hb_stack.Return, * hb_stack.pPos ); +} + #undef hb_stackDec void hb_stackDec( void ) { @@ -131,6 +146,21 @@ void hb_stackPush( void ) ( * hb_stack.pPos )->type = HB_IT_NIL; } +#undef hb_stackPushReturn +void hb_stackPushReturn( void ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_stackPushReturn()")); + + hb_itemRawMove( * hb_stack.pPos, &hb_stack.Return ); + + /* enough room for another item ? */ + if( ++hb_stack.pPos == hb_stack.pEnd ) + hb_stackIncrease(); + + /* now, push it: */ + ( * hb_stack.pPos )->type = HB_IT_NIL; +} + void hb_stackIncrease( void ) { LONG BaseIndex; /* index of stack base */ diff --git a/harbour/source/vm/eval.c b/harbour/source/vm/eval.c index 029357a78e..37d677e11b 100644 --- a/harbour/source/vm/eval.c +++ b/harbour/source/vm/eval.c @@ -130,7 +130,7 @@ PHB_ITEM hb_evalLaunch( PEVALINFO pEvalInfo ) hb_vmDo( pEvalInfo->paramCount ); pResult = hb_itemNew( NULL ); - hb_itemCopy( pResult, &hb_stack.Return ); + hb_itemCopy( pResult, hb_stackReturnItem() ); } else if( HB_IS_BLOCK( pEvalInfo->pItems[ 0 ] ) ) { @@ -141,7 +141,7 @@ PHB_ITEM hb_evalLaunch( PEVALINFO pEvalInfo ) hb_vmDo( pEvalInfo->paramCount ); pResult = hb_itemNew( NULL ); - hb_itemCopy( pResult, &hb_stack.Return ); + hb_itemCopy( pResult, hb_stackReturnItem() ); } else pResult = NULL; @@ -297,7 +297,7 @@ PHB_ITEM hb_itemDoC( char * szFunc, ULONG ulPCount, ... ) } /* - * Notice that these two functions place the result at hb_stack.Return, + * Notice that these two functions place the result at hb_stackReturnItem(), * that you may access its value using a _par...( -1 ). */ diff --git a/harbour/source/vm/extend.c b/harbour/source/vm/extend.c index d5e750e2ad..95706b27fe 100644 --- a/harbour/source/vm/extend.c +++ b/harbour/source/vm/extend.c @@ -86,7 +86,7 @@ HB_EXPORT PHB_ITEM hb_param( int iParam, long lMask ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); if( pItem->type & HB_IT_BYREF ) { @@ -123,7 +123,7 @@ HB_EXPORT PHB_ITEM hb_paramError( int iParam ) HB_EXPORT BOOL hb_extIsArray( int iParam ) { if( iParam == -1 ) - return HB_IS_ARRAY( &hb_stack.Return ); + return HB_IS_ARRAY( hb_stackReturnItem() ); else if( iParam >= 0 && iParam <= hb_pcount() ) return HB_IS_ARRAY( hb_stackItemFromBase( iParam ) ); @@ -138,7 +138,7 @@ HB_EXPORT BOOL hb_extIsArray( int iParam ) HB_EXPORT BOOL hb_extIsObject( int iParam ) { if( iParam == -1 ) - return HB_IS_OBJECT( &hb_stack.Return ); + return HB_IS_OBJECT( hb_stackReturnItem() ); else if( iParam >= 0 && iParam <= hb_pcount() ) return HB_IS_OBJECT( hb_stackItemFromBase( iParam ) ); @@ -156,7 +156,7 @@ HB_EXPORT char * hb_parc( int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); if( HB_IS_BYREF( pItem ) ) pItem = hb_itemUnRef( pItem ); @@ -185,7 +185,7 @@ HB_EXPORT char * hb_parcx( int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); if( HB_IS_BYREF( pItem ) ) pItem = hb_itemUnRef( pItem ); @@ -214,7 +214,7 @@ HB_EXPORT ULONG hb_parclen( int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); if( HB_IS_BYREF( pItem ) ) pItem = hb_itemUnRef( pItem ); @@ -247,7 +247,7 @@ HB_EXPORT ULONG hb_parcsiz( int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); /* NOTE: hb_parcsiz() will only work for strings passed by reference. CA-Cl*pper works like this. [vszakats] */ @@ -284,7 +284,7 @@ HB_EXPORT char * hb_pards( int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); if( HB_IS_BYREF( pItem ) ) pItem = hb_itemUnRef( pItem ); @@ -315,7 +315,7 @@ HB_EXPORT char * hb_pardsbuff( char * szDate, int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); if( HB_IS_BYREF( pItem ) ) pItem = hb_itemUnRef( pItem ); @@ -346,7 +346,7 @@ HB_EXPORT LONG hb_pardl( int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); if( HB_IS_BYREF( pItem ) ) { @@ -380,7 +380,7 @@ HB_EXPORT int hb_parl( int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); if( HB_IS_BYREF( pItem ) ) pItem = hb_itemUnRef( pItem ); @@ -415,7 +415,7 @@ HB_EXPORT double hb_parnd( int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); if( HB_IS_BYREF( pItem ) ) pItem = hb_itemUnRef( pItem ); @@ -448,7 +448,7 @@ HB_EXPORT int hb_parni( int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); if( HB_IS_BYREF( pItem ) ) pItem = hb_itemUnRef( pItem ); @@ -481,7 +481,7 @@ HB_EXPORT long hb_parnl( int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); if( HB_IS_BYREF( pItem ) ) pItem = hb_itemUnRef( pItem ); @@ -521,7 +521,7 @@ HB_EXPORT LONGLONG hb_parnll( int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); if( HB_IS_BYREF( pItem ) ) pItem = hb_itemUnRef( pItem ); @@ -561,7 +561,7 @@ HB_EXPORT HB_LONG hb_parnint( int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); if( HB_IS_BYREF( pItem ) ) pItem = hb_itemUnRef( pItem ); @@ -600,7 +600,7 @@ HB_EXPORT void * hb_parptr( int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); if( HB_IS_BYREF( pItem ) ) pItem = hb_itemUnRef( pItem ); @@ -652,11 +652,11 @@ HB_EXPORT ULONG hb_parinfo( int iParam ) { if( ( iParam > 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - HB_TYPE uiType = ( iParam == -1 ) ? hb_stack.Return.type : ( hb_stackItemFromBase( iParam ) )->type; + HB_TYPE uiType = ( iParam == -1 ) ? hb_stackReturnItem()->type : ( hb_stackItemFromBase( iParam ) )->type; if( uiType & HB_IT_BYREF ) { - PHB_ITEM pItem = hb_itemUnRef( ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ) ); + PHB_ITEM pItem = hb_itemUnRef( ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ) ); if( pItem ) uiType |= pItem->type; @@ -674,7 +674,7 @@ HB_EXPORT void hb_ret( void ) { HB_TRACE(HB_TR_DEBUG, ("hb_ret()")); - hb_itemClear( &hb_stack.Return ); + hb_itemClear( hb_stackReturnItem() ); } #undef hb_reta @@ -682,7 +682,7 @@ HB_EXPORT void hb_reta( ULONG ulLen ) /* undocumented hb_reta() */ { HB_TRACE(HB_TR_DEBUG, ("hb_reta(%lu)", ulLen)); - hb_arrayNew( &hb_stack.Return, ulLen ); + hb_arrayNew( hb_stackReturnItem(), ulLen ); } #undef hb_retc @@ -690,7 +690,7 @@ HB_EXPORT void hb_retc( const char * szText ) { HB_TRACE(HB_TR_DEBUG, ("hb_retc(%s)", szText)); - hb_itemPutC( &hb_stack.Return, szText ); + hb_itemPutC( hb_stackReturnItem(), szText ); } #undef hb_retc_buffer @@ -698,7 +698,7 @@ HB_EXPORT void hb_retc_buffer( char * szText ) { HB_TRACE(HB_TR_DEBUG, ("hb_retc_buffer(%s)", szText)); - hb_itemPutCPtr( &hb_stack.Return, szText, strlen( szText ) ); + hb_itemPutCPtr( hb_stackReturnItem(), szText, strlen( szText ) ); } #undef hb_retc_const @@ -706,7 +706,7 @@ HB_EXPORT void hb_retc_const( const char * szText ) { HB_TRACE(HB_TR_DEBUG, ("hb_retc_const(%s)", szText)); - hb_itemPutCConst( &hb_stack.Return, szText ); + hb_itemPutCConst( hb_stackReturnItem(), szText ); } #undef hb_retclen @@ -714,7 +714,7 @@ HB_EXPORT void hb_retclen( const char * szText, ULONG ulLen ) { HB_TRACE(HB_TR_DEBUG, ("hb_retclen(%s, %lu)", szText, ulLen)); - hb_itemPutCL( &hb_stack.Return, szText, ulLen ); + hb_itemPutCL( hb_stackReturnItem(), szText, ulLen ); } #undef hb_retclen_buffer @@ -722,7 +722,7 @@ HB_EXPORT void hb_retclen_buffer( char * szText, ULONG ulLen ) { HB_TRACE(HB_TR_DEBUG, ("hb_retclen_buffer(%s, %lu)", szText, ulLen)); - hb_itemPutCPtr( &hb_stack.Return, szText, ulLen ); + hb_itemPutCPtr( hb_stackReturnItem(), szText, ulLen ); } #undef hb_retcAdopt @@ -736,7 +736,7 @@ HB_EXPORT void hb_retcAdopt( char * szText ) */ HB_TRACE_STEALTH( HB_TR_INFO, ("hb_retcAdopt(%s)", szText ) ); - hb_itemPutCPtr( &hb_stack.Return, szText, strlen( szText ) ); + hb_itemPutCPtr( hb_stackReturnItem(), szText, strlen( szText ) ); } /* szDate must have YYYYMMDD format */ @@ -746,7 +746,7 @@ HB_EXPORT void hb_retds( const char * szDate ) { HB_TRACE(HB_TR_DEBUG, ("hb_retds(%s)", szDate)); - hb_itemPutDS( &hb_stack.Return, szDate ); + hb_itemPutDS( hb_stackReturnItem(), szDate ); } #undef hb_retd @@ -754,7 +754,7 @@ HB_EXPORT void hb_retd( int iYear, int iMonth, int iDay ) { HB_TRACE(HB_TR_DEBUG, ("hb_retd(%04i, %02i, %02i)", iYear, iMonth, iDay)); - hb_itemPutD( &hb_stack.Return, iYear, iMonth, iDay ); + hb_itemPutD( hb_stackReturnItem(), iYear, iMonth, iDay ); } #undef hb_retdl @@ -762,7 +762,7 @@ HB_EXPORT void hb_retdl( long lJulian ) { HB_TRACE(HB_TR_DEBUG, ("hb_retdl(%ld)", lJulian)); - hb_itemPutDL( &hb_stack.Return, lJulian ); + hb_itemPutDL( hb_stackReturnItem(), lJulian ); } #undef hb_retl @@ -770,7 +770,7 @@ HB_EXPORT void hb_retl( int iLogical ) { HB_TRACE(HB_TR_DEBUG, ("hb_retl(%d)", iLogical)); - hb_itemPutL( &hb_stack.Return, iLogical ? TRUE : FALSE ); + hb_itemPutL( hb_stackReturnItem(), iLogical ? TRUE : FALSE ); } #undef hb_retnd @@ -778,7 +778,7 @@ HB_EXPORT void hb_retnd( double dNumber ) { HB_TRACE(HB_TR_DEBUG, ("hb_retnd(%lf)", dNumber)); - hb_itemPutND( &hb_stack.Return, dNumber ); + hb_itemPutND( hb_stackReturnItem(), dNumber ); } #undef hb_retni @@ -786,7 +786,7 @@ HB_EXPORT void hb_retni( int iNumber ) { HB_TRACE(HB_TR_DEBUG, ("hb_retni(%d)", iNumber)); - hb_itemPutNI( &hb_stack.Return, iNumber ); + hb_itemPutNI( hb_stackReturnItem(), iNumber ); } #undef hb_retnl @@ -794,7 +794,7 @@ HB_EXPORT void hb_retnl( long lNumber ) { HB_TRACE(HB_TR_DEBUG, ("hb_retnl(%ld)", lNumber)); - hb_itemPutNL( &hb_stack.Return, lNumber ); + hb_itemPutNL( hb_stackReturnItem(), lNumber ); } #ifndef HB_LONG_LONG_OFF @@ -803,7 +803,7 @@ HB_EXPORT void hb_retnll( LONGLONG llNumber ) { HB_TRACE(HB_TR_DEBUG, ("hb_retnll(%" PFLL "d)", llNumber)); - hb_itemPutNLL( &hb_stack.Return, llNumber ); + hb_itemPutNLL( hb_stackReturnItem(), llNumber ); } #endif @@ -812,7 +812,7 @@ HB_EXPORT void hb_retnint( HB_LONG lNumber ) { HB_TRACE(HB_TR_DEBUG, ("hb_retnl(%ld)", lNumber)); - hb_itemPutNInt( &hb_stack.Return, lNumber ); + hb_itemPutNInt( hb_stackReturnItem(), lNumber ); } #undef hb_retnlen @@ -820,7 +820,7 @@ HB_EXPORT void hb_retnlen( double dNumber, int iWidth, int iDec ) { HB_TRACE(HB_TR_DEBUG, ("hb_retnlen(%lf, %d, %d)", dNumber, iWidth, iDec)); - hb_itemPutNLen( &hb_stack.Return, dNumber, iWidth, iDec ); + hb_itemPutNLen( hb_stackReturnItem(), dNumber, iWidth, iDec ); } #undef hb_retndlen @@ -828,7 +828,7 @@ HB_EXPORT void hb_retndlen( double dNumber, int iWidth, int iDec ) { HB_TRACE(HB_TR_DEBUG, ("hb_retndlen(%lf, %d, %d)", dNumber, iWidth, iDec)); - hb_itemPutNDLen( &hb_stack.Return, dNumber, iWidth, iDec ); + hb_itemPutNDLen( hb_stackReturnItem(), dNumber, iWidth, iDec ); } #undef hb_retnilen @@ -836,7 +836,7 @@ HB_EXPORT void hb_retnilen( int iNumber, int iWidth ) { HB_TRACE(HB_TR_DEBUG, ("hb_retnilen(%d, %d)", iNumber, iWidth)); - hb_itemPutNILen( &hb_stack.Return, iNumber, iWidth ); + hb_itemPutNILen( hb_stackReturnItem(), iNumber, iWidth ); } #undef hb_retnllen @@ -844,7 +844,7 @@ HB_EXPORT void hb_retnllen( long lNumber, int iWidth ) { HB_TRACE(HB_TR_DEBUG, ("hb_retnllen(%ld, %d)", lNumber, iWidth)); - hb_itemPutNLLen( &hb_stack.Return, lNumber, iWidth ); + hb_itemPutNLLen( hb_stackReturnItem(), lNumber, iWidth ); } #ifndef HB_LONG_LONG_OFF @@ -853,7 +853,7 @@ HB_EXPORT void hb_retnlllen( LONGLONG llNumber, int iWidth ) { HB_TRACE(HB_TR_DEBUG, ("hb_retnlllen(%" PFLL "d, %d)", llNumber, iWidth)); - hb_itemPutNLLLen( &hb_stack.Return, llNumber, iWidth ); + hb_itemPutNLLLen( hb_stackReturnItem(), llNumber, iWidth ); } #endif @@ -862,7 +862,7 @@ HB_EXPORT void hb_retnintlen( HB_LONG lNumber, int iWidth ) { HB_TRACE(HB_TR_DEBUG, ("hb_retnintlen(%" PFHL "d, %d)", lNumber, iWidth)); - hb_itemPutNIntLen( &hb_stack.Return, lNumber, iWidth ); + hb_itemPutNIntLen( hb_stackReturnItem(), lNumber, iWidth ); } #undef hb_retptr @@ -870,7 +870,15 @@ HB_EXPORT void hb_retptr( void * pointer ) { HB_TRACE(HB_TR_DEBUG, ("hb_retptr(%p)", pointer)); - hb_itemPutPtr( &hb_stack.Return, pointer ); + hb_itemPutPtr( hb_stackReturnItem(), pointer ); +} + +#undef hb_retptrGC +void HB_EXPORT hb_retptrGC( void * pointer ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_retptrGC(%p)", pointer)); + + hb_itemPutPtrGC( hb_stackReturnItem(), pointer ); } @@ -880,7 +888,7 @@ HB_EXPORT int hb_storc( char * szText, int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); BOOL bByRef = HB_IS_BYREF( pItem ); if( bByRef ) @@ -914,7 +922,7 @@ HB_EXPORT int hb_storclen( char * szText, ULONG ulLen, int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); BOOL bByRef = HB_IS_BYREF( pItem ); if( bByRef ) @@ -950,7 +958,7 @@ HB_EXPORT int hb_stords( char * szDate, int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); BOOL bByRef = HB_IS_BYREF( pItem ); if( bByRef ) @@ -984,7 +992,7 @@ HB_EXPORT int hb_storl( int iLogical, int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); BOOL bByRef = HB_IS_BYREF( pItem ); if( bByRef ) @@ -1018,7 +1026,7 @@ HB_EXPORT int hb_storni( int iValue, int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); BOOL bByRef = HB_IS_BYREF( pItem ); if( bByRef ) @@ -1052,7 +1060,7 @@ HB_EXPORT int hb_stornl( long lValue, int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); BOOL bByRef = HB_IS_BYREF( pItem ); if( bByRef ) @@ -1087,7 +1095,7 @@ HB_EXPORT int hb_stornll( LONGLONG llValue, int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); BOOL bByRef = HB_IS_BYREF( pItem ); if( bByRef ) @@ -1122,7 +1130,7 @@ HB_EXPORT int hb_stornint( HB_LONG lValue, int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); BOOL bByRef = HB_IS_BYREF( pItem ); if( bByRef ) @@ -1156,7 +1164,7 @@ HB_EXPORT int hb_stornd( double dNumber, int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); BOOL bByRef = HB_IS_BYREF( pItem ); if( bByRef ) @@ -1190,7 +1198,7 @@ HB_EXPORT int hb_storptr( void * pointer, int iParam, ... ) if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) ) { - PHB_ITEM pItem = ( iParam == -1 ) ? &hb_stack.Return : hb_stackItemFromBase( iParam ); + PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam ); BOOL bByRef = HB_IS_BYREF( pItem ); if( bByRef ) diff --git a/harbour/source/vm/fm.c b/harbour/source/vm/fm.c index ee3f87d6a4..256607c5cc 100644 --- a/harbour/source/vm/fm.c +++ b/harbour/source/vm/fm.c @@ -88,6 +88,7 @@ /* #define HB_PARANOID_MEM_CHECK */ +/*#undef HB_FM_STATISTICS*/ #ifndef HB_FM_STATISTICS # undef HB_PARANOID_MEM_CHECK #endif @@ -96,6 +97,7 @@ #define HB_TR_LEVEL HB_TR_ERROR #endif + #ifdef HB_FM_STATISTICS #ifndef HB_MEMFILER @@ -105,21 +107,34 @@ typedef struct _HB_MEMINFO { - ULONG ulSignature; - ULONG ulSize; - USHORT uiProcLine; - char szProcName[ HB_SYMBOL_NAME_LEN + 1 ]; + UINT32 u32Signature; + ULONG ulSize; + USHORT uiProcLine; + char szProcName[ HB_SYMBOL_NAME_LEN + 1 ]; struct _HB_MEMINFO * pPrevBlock; struct _HB_MEMINFO * pNextBlock; } HB_MEMINFO, * PHB_MEMINFO; #ifdef HB_ALLOC_ALIGNMENT -# define HB_MEMINFO_SIZE ( ( sizeof( HB_MEMINFO ) + HB_ALLOC_ALIGNMENT - 1 ) - \ - ( sizeof( HB_MEMINFO ) + HB_ALLOC_ALIGNMENT - 1 ) % HB_ALLOC_ALIGNMENT ) +# define HB_MEMINFO_SIZE ( ( ( sizeof( HB_MEMINFO ) + HB_ALLOC_ALIGNMENT - 1 ) - \ + ( sizeof( HB_MEMINFO ) + HB_ALLOC_ALIGNMENT - 1 ) % HB_ALLOC_ALIGNMENT ) + \ + HB_COUNTER_OFFSET ) #else -# define HB_MEMINFO_SIZE sizeof( HB_MEMINFO ) +# define HB_MEMINFO_SIZE ( sizeof( HB_MEMINFO ) + HB_COUNTER_OFFSET ) #endif +#define HB_ALLOC_SIZE( n ) ( ( n ) + HB_MEMINFO_SIZE + sizeof( UINT32 ) ) +#define HB_FM_PTR( p ) ( ( PHB_MEMINFO ) ( ( BYTE * ) ( p ) - HB_MEMINFO_SIZE ) ) + +#define HB_FM_GETSIG( p, n ) HB_GET_UINT32( ( BYTE * )( p ) + ( n ) ) +#define HB_FM_SETSIG( p, n ) HB_PUT_UINT32( ( BYTE * )( p ) + ( n ), HB_MEMINFO_SIGNATURE ) +#define HB_FM_CLRSIG( p, n ) HB_PUT_UINT32( ( BYTE * )( p ) + ( n ), 0 ) + +/* NOTE: we cannot use here HB_TRACE because it will overwrite the + * function name/line number of code which called hb_xalloc/hb_xgrab + */ +#define HB_TRACE_FM HB_TRACE_STEALTH + static LONG s_lMemoryBlocks = 0; /* memory blocks used */ static LONG s_lMemoryMaxBlocks = 0; /* maximum number of used memory blocks */ static LONG s_lMemoryMaxConsumed = 0; /* memory size consumed */ @@ -128,44 +143,50 @@ static LONG s_lMemoryConsumed = 0; /* memory max size consumed */ static PHB_MEMINFO s_pFirstBlock = NULL; static PHB_MEMINFO s_pLastBlock = NULL; -#endif +#else /* ! HB_FM_STATISTICS */ + +typedef void * PHB_MEMINFO; +#define HB_MEMINFO_SIZE HB_COUNTER_OFFSET +#define HB_ALLOC_SIZE( n ) ( ( n ) + HB_MEMINFO_SIZE ) +#define HB_FM_PTR( p ) HB_COUNTER_PTR( p ) +#define HB_TRACE_FM HB_TRACE + +#endif /* HB_FM_STATISTICS */ + +#define HB_MEM_PTR( p ) ( ( void * ) ( ( BYTE * ) ( p ) + HB_MEMINFO_SIZE ) ) + HB_EXPORT void * hb_xalloc( ULONG ulSize ) /* allocates fixed memory, returns NULL on failure */ { + PHB_MEMINFO pMem; -#ifdef HB_FM_STATISTICS - - void * pMem; - - /* NOTE: we cannot use here HB_TRACE because it will overwrite the - * function name/line number of code which called hb_xalloc/hb_xgrab - */ - HB_TRACE_STEALTH(HB_TR_DEBUG, ("hb_xalloc(%lu)", ulSize)); + HB_TRACE_FM(HB_TR_DEBUG, ("hb_xalloc(%lu)", ulSize)); if( ulSize == 0 ) hb_errInternal( HB_EI_XALLOCNULLSIZE, NULL, NULL, NULL ); - pMem = malloc( ulSize + HB_MEMINFO_SIZE + sizeof( ULONG ) ); + pMem = ( PHB_MEMINFO ) malloc( HB_ALLOC_SIZE( ulSize ) ); if( ! pMem ) return pMem; +#ifdef HB_FM_STATISTICS if( ! s_pFirstBlock ) { - ( ( PHB_MEMINFO ) pMem )->pPrevBlock = NULL; - s_pFirstBlock = ( PHB_MEMINFO ) pMem; + pMem->pPrevBlock = NULL; + s_pFirstBlock = pMem; } else { - ( ( PHB_MEMINFO ) pMem )->pPrevBlock = s_pLastBlock; - s_pLastBlock->pNextBlock = ( PHB_MEMINFO ) pMem; + pMem->pPrevBlock = s_pLastBlock; + s_pLastBlock->pNextBlock = pMem; } - s_pLastBlock = ( PHB_MEMINFO ) pMem; + s_pLastBlock = pMem; - ( ( PHB_MEMINFO ) pMem )->pNextBlock = NULL; - ( ( PHB_MEMINFO ) pMem )->ulSignature = HB_MEMINFO_SIGNATURE; - HB_PUT_LONG( ( ( BYTE * ) pMem ) + ulSize + HB_MEMINFO_SIZE, HB_MEMINFO_SIGNATURE ); - ( ( PHB_MEMINFO ) pMem )->ulSize = ulSize; /* size of the memory block */ + pMem->pNextBlock = NULL; + pMem->u32Signature = HB_MEMINFO_SIGNATURE; + HB_FM_SETSIG( HB_MEM_PTR( pMem ), ulSize ); + pMem->ulSize = ulSize; /* size of the memory block */ if( hb_tr_level() >= HB_TR_DEBUG ) { @@ -174,25 +195,25 @@ HB_EXPORT void * hb_xalloc( ULONG ulSize ) /* allocates fixed memory, re * function/line info - this is a location of code that called * hb_xalloc/hb_xgrab */ - ( ( PHB_MEMINFO ) pMem )->uiProcLine = hb_tr_line_; /* C line number */ - strcpy( ( ( PHB_MEMINFO ) pMem )->szProcName, hb_tr_file_ ); + pMem->uiProcLine = hb_tr_line_; /* C line number */ + strcpy( pMem->szProcName, hb_tr_file_ ); } else { if( hb_stack.pItems && ( hb_stack.pBase != hb_stack.pItems ) ) { - ( ( PHB_MEMINFO ) pMem )->uiProcLine = ( hb_stackBaseItem() )->item.asSymbol.lineno; /* PRG line number */ - strcpy( ( ( PHB_MEMINFO ) pMem )->szProcName, + pMem->uiProcLine = ( hb_stackBaseItem() )->item.asSymbol.lineno; /* PRG line number */ + strcpy( pMem->szProcName, ( hb_stackBaseItem() )->item.asSymbol.value->szName ); /* PRG ProcName */ } else { - ( ( PHB_MEMINFO ) pMem )->uiProcLine = 0; /* PRG line number */ - ( ( PHB_MEMINFO ) pMem )->szProcName[ 0 ] = '\0'; /* PRG ProcName */ + pMem->uiProcLine = 0; /* PRG line number */ + pMem->szProcName[ 0 ] = '\0'; /* PRG ProcName */ } } - s_lMemoryConsumed += ulSize; + s_lMemoryConsumed += ulSize + sizeof( HB_COUNTER ); if( s_lMemoryMaxConsumed < s_lMemoryConsumed ) s_lMemoryMaxConsumed = s_lMemoryConsumed; s_lMemoryBlocks++; @@ -200,57 +221,47 @@ HB_EXPORT void * hb_xalloc( ULONG ulSize ) /* allocates fixed memory, re s_lMemoryMaxBlocks = s_lMemoryBlocks; #ifdef HB_PARANOID_MEM_CHECK - memset( ( char * ) pMem + HB_MEMINFO_SIZE, HB_MEMFILER, ulSize ); + memset( HB_MEM_PTR( pMem ), HB_MEMFILER, ulSize ); #endif - return ( void * ) ( ( BYTE * ) pMem + HB_MEMINFO_SIZE ); - -#else - - HB_TRACE(HB_TR_DEBUG, ("hb_xalloc(%lu)", ulSize)); - - if( ulSize == 0 ) - hb_errInternal( HB_EI_XALLOCNULLSIZE, NULL, NULL, NULL ); - - return malloc( ulSize ); #endif + + * HB_COUNTER_PTR( HB_MEM_PTR( pMem ) ) = 1; + + return HB_MEM_PTR( pMem ); } HB_EXPORT void * hb_xgrab( ULONG ulSize ) /* allocates fixed memory, exits on failure */ { - void * pMem; + PHB_MEMINFO pMem; - /* NOTE: we cannot use here HB_TRACE because it will overwrite the - * function name/line number of code which called hb_xalloc/hb_xgrab - */ - HB_TRACE_STEALTH(HB_TR_DEBUG, ("hb_xgrab(%lu)", ulSize)); + HB_TRACE_FM(HB_TR_DEBUG, ("hb_xgrab(%lu)", ulSize)); if( ulSize == 0 ) hb_errInternal( HB_EI_XGRABNULLSIZE, NULL, NULL, NULL ); -#ifdef HB_FM_STATISTICS - - pMem = malloc( ulSize + HB_MEMINFO_SIZE + sizeof( ULONG ) ); + pMem = ( PHB_MEMINFO ) malloc( HB_ALLOC_SIZE( ulSize ) ); if( ! pMem ) hb_errInternal( HB_EI_XGRABALLOC, NULL, NULL, NULL ); +#ifdef HB_FM_STATISTICS if( ! s_pFirstBlock ) { - ( ( PHB_MEMINFO ) pMem )->pPrevBlock = NULL; - s_pFirstBlock = ( PHB_MEMINFO ) pMem; + pMem->pPrevBlock = NULL; + s_pFirstBlock = pMem; } else { - ( ( PHB_MEMINFO ) pMem )->pPrevBlock = s_pLastBlock; - s_pLastBlock->pNextBlock = ( PHB_MEMINFO ) pMem; + pMem->pPrevBlock = s_pLastBlock; + s_pLastBlock->pNextBlock = pMem; } - s_pLastBlock = ( PHB_MEMINFO ) pMem; + s_pLastBlock = pMem; - ( ( PHB_MEMINFO ) pMem )->pNextBlock = NULL; - ( ( PHB_MEMINFO ) pMem )->ulSignature = HB_MEMINFO_SIGNATURE; - HB_PUT_LONG( ( ( BYTE * ) pMem ) + ulSize + HB_MEMINFO_SIZE, HB_MEMINFO_SIGNATURE ); - ( ( PHB_MEMINFO ) pMem )->ulSize = ulSize; /* size of the memory block */ + pMem->pNextBlock = NULL; + pMem->u32Signature = HB_MEMINFO_SIGNATURE; + HB_FM_SETSIG( HB_MEM_PTR( pMem ), ulSize ); + pMem->ulSize = ulSize; /* size of the memory block */ if( hb_tr_level() >= HB_TR_DEBUG ) { @@ -259,25 +270,25 @@ HB_EXPORT void * hb_xgrab( ULONG ulSize ) /* allocates fixed memory, exi * function/line info - this is a location of code that called * hb_xalloc/hb_xgrab */ - ( ( PHB_MEMINFO ) pMem )->uiProcLine = hb_tr_line_; /* C line number */ - strcpy( ( ( PHB_MEMINFO ) pMem )->szProcName, hb_tr_file_ ); + pMem->uiProcLine = hb_tr_line_; /* C line number */ + strcpy( pMem->szProcName, hb_tr_file_ ); } else { if( hb_stack.pItems && ( hb_stack.pBase != hb_stack.pItems ) ) { - ( ( PHB_MEMINFO ) pMem )->uiProcLine = ( hb_stackBaseItem() )->item.asSymbol.lineno; /* PRG line number */ - strcpy( ( ( PHB_MEMINFO ) pMem )->szProcName, + pMem->uiProcLine = ( hb_stackBaseItem() )->item.asSymbol.lineno; /* PRG line number */ + strcpy( pMem->szProcName, ( hb_stackBaseItem() )->item.asSymbol.value->szName ); /* PRG ProcName */ } else { - ( ( PHB_MEMINFO ) pMem )->uiProcLine = 0; /* PRG line number */ - ( ( PHB_MEMINFO ) pMem )->szProcName[ 0 ] = '\0'; /* PRG ProcName */ + pMem->uiProcLine = 0; /* PRG line number */ + pMem->szProcName[ 0 ] = '\0'; /* PRG ProcName */ } } - s_lMemoryConsumed += ulSize; + s_lMemoryConsumed += ulSize + sizeof( HB_COUNTER ); if( s_lMemoryMaxConsumed < s_lMemoryConsumed ) s_lMemoryMaxConsumed = s_lMemoryConsumed; s_lMemoryBlocks++; @@ -285,30 +296,19 @@ HB_EXPORT void * hb_xgrab( ULONG ulSize ) /* allocates fixed memory, exi s_lMemoryMaxBlocks = s_lMemoryBlocks; #ifdef HB_PARANOID_MEM_CHECK - memset( ( char * ) pMem + HB_MEMINFO_SIZE, HB_MEMFILER, ulSize ); + memset( HB_MEM_PTR( pMem ), HB_MEMFILER, ulSize ); #endif - return ( void * ) ( ( BYTE * ) pMem + HB_MEMINFO_SIZE ); - -#else - - pMem = malloc( ulSize ); - - if( ! pMem ) - hb_errInternal( HB_EI_XGRABALLOC, NULL, NULL, NULL ); - - return pMem; #endif + + * HB_COUNTER_PTR( HB_MEM_PTR( pMem ) ) = 1; + + return HB_MEM_PTR( pMem ); } HB_EXPORT void * hb_xrealloc( void * pMem, ULONG ulSize ) /* reallocates memory */ { -#ifdef HB_FM_STATISTICS - - PHB_MEMINFO pMemBlock; - ULONG ulMemSize; - - HB_TRACE_STEALTH(HB_TR_DEBUG, ("hb_xrealloc(%p, %lu)", pMem, ulSize)); + HB_TRACE_FM(HB_TR_DEBUG, ("hb_xrealloc(%p, %lu)", pMem, ulSize)); if( ! pMem ) hb_errInternal( HB_EI_XREALLOCNULL, NULL, NULL, NULL ); @@ -316,94 +316,88 @@ HB_EXPORT void * hb_xrealloc( void * pMem, ULONG ulSize ) /* reallocates m if( ulSize == 0 ) hb_errInternal( HB_EI_XREALLOCNULLSIZE, NULL, NULL, NULL ); - pMemBlock = ( PHB_MEMINFO ) ( ( BYTE * ) pMem - HB_MEMINFO_SIZE ); +#ifdef HB_FM_STATISTICS + { + PHB_MEMINFO pMemBlock; + ULONG ulMemSize; - if( pMemBlock->ulSignature != HB_MEMINFO_SIGNATURE ) - hb_errInternal( HB_EI_XREALLOCINV, NULL, NULL, NULL ); + pMemBlock = HB_FM_PTR( pMem ); - ulMemSize = pMemBlock->ulSize; + if( pMemBlock->u32Signature != HB_MEMINFO_SIGNATURE ) + hb_errInternal( HB_EI_XREALLOCINV, NULL, NULL, NULL ); - if ( HB_GET_LONG( ( ( BYTE * ) pMem ) + ulMemSize ) != HB_MEMINFO_SIGNATURE ) - hb_errInternal( HB_EI_XMEMOVERFLOW, NULL, NULL, NULL ); + ulMemSize = pMemBlock->ulSize; - HB_PUT_LONG( ( ( BYTE * ) pMem ) + ulMemSize, 0 ); + if( HB_FM_GETSIG( pMem, ulMemSize ) != HB_MEMINFO_SIGNATURE ) + hb_errInternal( HB_EI_XMEMOVERFLOW, NULL, NULL, NULL ); + + HB_FM_CLRSIG( pMem, ulMemSize ); #ifdef HB_PARANOID_MEM_CHECK - pMem = malloc( ulSize + HB_MEMINFO_SIZE + sizeof( ULONG ) ); - if ( pMem ) - { - if ( ulSize > ulMemSize ) + pMem = malloc( HB_ALLOC_SIZE( ulSize ) ); + if( pMem ) { - memcpy( pMem, pMemBlock, ulMemSize + HB_MEMINFO_SIZE ); - memset( ( char * ) pMem + HB_MEMINFO_SIZE + ulMemSize, HB_MEMFILER, ulSize - ulMemSize ); + if( ulSize > ulMemSize ) + { + memcpy( pMem, pMemBlock, HB_ALLOC_SIZE( ulMemSize ) ); + memset( ( BYTE * ) pMem + HB_ALLOC_SIZE( ulMemSize ), ulSize - ulMemSize ); + } + else + memcpy( pMem, pMemBlock, HB_ALLOC_SIZE( ulSize ) ); } - else - memcpy( pMem, pMemBlock, ulSize + HB_MEMINFO_SIZE ); + memset( pMemBlock, HB_MEMFILER, HB_ALLOC_SIZE( ulMemSize ) ); + free( pMemBlock ); +#else + pMem = realloc( pMemBlock, HB_ALLOC_SIZE( ulSize ) ); +#endif + + s_lMemoryConsumed += ( ulSize - ulMemSize ); + if( s_lMemoryMaxConsumed < s_lMemoryConsumed ) + s_lMemoryMaxConsumed = s_lMemoryConsumed; + + if( ! pMem ) + hb_errInternal( HB_EI_XREALLOC, NULL, NULL, NULL ); + + ( ( PHB_MEMINFO ) pMem )->ulSize = ulSize; /* size of the memory block */ + HB_FM_SETSIG( HB_MEM_PTR( pMem ), ulSize ); + if( ( ( PHB_MEMINFO ) pMem )->pPrevBlock ) + ( ( PHB_MEMINFO ) pMem )->pPrevBlock->pNextBlock = ( PHB_MEMINFO ) pMem; + if( ( ( PHB_MEMINFO ) pMem )->pNextBlock ) + ( ( PHB_MEMINFO ) pMem )->pNextBlock->pPrevBlock = ( PHB_MEMINFO ) pMem; + + if( s_pFirstBlock == pMemBlock ) + s_pFirstBlock = ( PHB_MEMINFO ) pMem; + if( s_pLastBlock == pMemBlock ) + s_pLastBlock = ( PHB_MEMINFO ) pMem; } - memset( pMemBlock, HB_MEMFILER, ulMemSize + HB_MEMINFO_SIZE + sizeof( ULONG ) ); - free( pMemBlock ); -#else - pMem = realloc( pMemBlock, ulSize + HB_MEMINFO_SIZE + sizeof( ULONG ) ); -#endif - - s_lMemoryConsumed += ( ulSize - ulMemSize ); - if( s_lMemoryMaxConsumed < s_lMemoryConsumed ) - s_lMemoryMaxConsumed = s_lMemoryConsumed; - - if( ! pMem ) - hb_errInternal( HB_EI_XREALLOC, NULL, NULL, NULL ); - - ( ( PHB_MEMINFO ) pMem )->ulSize = ulSize; /* size of the memory block */ - HB_PUT_LONG( ( ( BYTE * ) pMem ) + ulSize + HB_MEMINFO_SIZE, HB_MEMINFO_SIGNATURE ); - if( ( ( PHB_MEMINFO ) pMem )->pPrevBlock ) - ( ( PHB_MEMINFO ) pMem )->pPrevBlock->pNextBlock = ( PHB_MEMINFO ) pMem; - if( ( ( PHB_MEMINFO ) pMem )->pNextBlock ) - ( ( PHB_MEMINFO ) pMem )->pNextBlock->pPrevBlock = ( PHB_MEMINFO ) pMem; - - if( s_pFirstBlock == pMemBlock ) - s_pFirstBlock = ( PHB_MEMINFO ) pMem; - if( s_pLastBlock == pMemBlock ) - s_pLastBlock = ( PHB_MEMINFO ) pMem; - - return ( void * ) ( ( BYTE * ) pMem + HB_MEMINFO_SIZE ); - #else - HB_TRACE(HB_TR_DEBUG, ("hb_xrealloc(%p, %lu)", pMem, ulSize)); - - if( ! pMem ) - hb_errInternal( HB_EI_XREALLOCNULL, NULL, NULL, NULL ); - - if( ulSize == 0 ) - hb_errInternal( HB_EI_XREALLOCNULLSIZE, NULL, NULL, NULL ); - - pMem = realloc( pMem, ulSize ); - - if( ! pMem ) + pMem = realloc( HB_FM_PTR( pMem ), HB_ALLOC_SIZE( ulSize ) ); + if( !pMem ) hb_errInternal( HB_EI_XREALLOC, NULL, NULL, NULL ); - return pMem; - #endif + + return HB_MEM_PTR( pMem ); } HB_EXPORT void hb_xfree( void * pMem ) /* frees fixed memory */ { -#ifdef HB_FM_STATISTICS - - HB_TRACE_STEALTH(HB_TR_DEBUG, ("hb_xfree(%p)", pMem)); + HB_TRACE_FM(HB_TR_DEBUG, ("hb_xfree(%p)", pMem)); if( pMem ) { - PHB_MEMINFO pMemBlock = ( PHB_MEMINFO ) ( ( BYTE * ) pMem - HB_MEMINFO_SIZE ); +#ifdef HB_FM_STATISTICS - if( pMemBlock->ulSignature != HB_MEMINFO_SIGNATURE ) + PHB_MEMINFO pMemBlock = HB_FM_PTR( pMem ); + + if( pMemBlock->u32Signature != HB_MEMINFO_SIGNATURE ) hb_errInternal( HB_EI_XFREEINV, NULL, NULL, NULL ); - if ( HB_GET_LONG( ( ( BYTE * ) pMem ) + pMemBlock->ulSize ) != HB_MEMINFO_SIGNATURE ) + if( HB_FM_GETSIG( pMem, pMemBlock->ulSize ) != HB_MEMINFO_SIGNATURE ) hb_errInternal( HB_EI_XMEMOVERFLOW, NULL, NULL, NULL ); - s_lMemoryConsumed -= pMemBlock->ulSize; + s_lMemoryConsumed -= pMemBlock->ulSize + sizeof( HB_COUNTER ); s_lMemoryBlocks--; if( pMemBlock->pPrevBlock ) @@ -416,26 +410,106 @@ HB_EXPORT void hb_xfree( void * pMem ) /* frees fixed memory */ else s_pLastBlock = pMemBlock->pPrevBlock; - pMemBlock->ulSignature = 0; - HB_PUT_LONG( ( ( BYTE * ) pMem ) + pMemBlock->ulSize, 0 ); + pMemBlock->u32Signature = 0; + HB_FM_CLRSIG( pMem, pMemBlock->ulSize ); #ifdef HB_PARANOID_MEM_CHECK - memset( pMemBlock, HB_MEMFILER, pMemBlock->ulSize + HB_MEMINFO_SIZE + sizeof( ULONG ) ); + memset( pMemBlock, HB_MEMFILER, HB_ALLOC_SIZE( pMemBlock->ulSize ) ); #endif + free( ( void * ) pMemBlock ); - } - else - hb_errInternal( HB_EI_XFREENULL, NULL, NULL, NULL ); #else - HB_TRACE(HB_TR_DEBUG, ("hb_xfree(%p)", pMem)); + free( HB_FM_PTR( pMem ) ); - if( pMem ) - free( pMem ); +#endif + } else hb_errInternal( HB_EI_XFREENULL, NULL, NULL, NULL ); +} +/* increment reference counter */ +#undef hb_xRefInc +void hb_xRefInc( void * pMem ) +{ + ++( * HB_COUNTER_PTR( pMem ) ); +} + +/* decrement reference counter, return TRUE when 0 reached */ +#undef hb_xRefDec +BOOL hb_xRefDec( void * pMem ) +{ + return --( * HB_COUNTER_PTR( pMem ) ) == 0; +} + +/* decrement reference counter and free the block when 0 reached */ +#undef hb_xRefFree +void hb_xRefFree( void * pMem ) +{ +#ifdef HB_FM_STATISTICS + + if( HB_FM_PTR( pMem )->u32Signature != HB_MEMINFO_SIGNATURE ) + hb_errInternal( HB_EI_XFREEINV, NULL, NULL, NULL ); + + if( --( * HB_COUNTER_PTR( pMem ) ) == 0 ) + hb_xfree( pMem ); + +#else + + if( --( * HB_COUNTER_PTR( pMem ) ) == 0 ) + free( HB_FM_PTR( pMem ) ); + +#endif +} + +/* return number of references */ +#undef hb_xRefCount +HB_COUNTER hb_xRefCount( void * pMem ) +{ + return * HB_COUNTER_PTR( pMem ); +} + +/* reallocates memory, create copy if reference counter greater then 1 */ +#undef hb_xRefResize +void * hb_xRefResize( void * pMem, ULONG ulSave, ULONG ulSize ) +{ + +#ifdef HB_FM_STATISTICS + if( * HB_COUNTER_PTR( pMem ) > 1 ) + { + void * pMemNew = hb_xgrab( ulSize ); + + --( * HB_COUNTER_PTR( pMem ) ); + memcpy( pMemNew, pMem, HB_MIN( ulSave, ulSize ) ); + return pMemNew; + } + + return hb_xrealloc( pMem, ulSize ); + +#else + + if( * HB_COUNTER_PTR( pMem ) > 1 ) + { + void * pMemNew = malloc( HB_ALLOC_SIZE( ulSize ) ); + + if( pMemNew ) + { + --( * HB_COUNTER_PTR( pMem ) ); + * HB_COUNTER_PTR( HB_MEM_PTR( pMemNew ) ) = 1; + memcpy( HB_MEM_PTR( pMemNew ), pMem, HB_MIN( ulSave, ulSize ) ); + return HB_MEM_PTR( pMemNew ); + } + } + else + { + pMem = realloc( HB_FM_PTR( pMem ), HB_ALLOC_SIZE ( ulSize ) ); + if( pMem ) + return HB_MEM_PTR( pMem ); + } + + hb_errInternal( HB_EI_XREALLOC, NULL, NULL, NULL ); + return NULL; #endif } @@ -447,7 +521,7 @@ HB_EXPORT ULONG hb_xsize( void * pMem ) /* returns the size of an allocated mem HB_TRACE(HB_TR_DEBUG, ("hb_xsize(%p)", pMem)); #ifdef HB_FM_STATISTICS - return ( ( PHB_MEMINFO ) ( ( BYTE * ) pMem - HB_MEMINFO_SIZE ) )->ulSize; + return HB_FM_PTR( pMem )->ulSize; #else HB_SYMBOL_UNUSED( pMem ); @@ -779,7 +853,7 @@ HB_FUNC( MEMORY ) } #ifdef HB_FM_STATISTICS -HB_FUNC( HB_FM_STAT ) {}; +HB_FUNC( HB_FM_STAT ) {} #else -HB_FUNC( HB_FM_NOSTAT ) {}; +HB_FUNC( HB_FM_NOSTAT ) {} #endif diff --git a/harbour/source/vm/garbage.c b/harbour/source/vm/garbage.c index f9cbf374ec..ba15791d22 100644 --- a/harbour/source/vm/garbage.c +++ b/harbour/source/vm/garbage.c @@ -53,6 +53,7 @@ #include "hbvmopt.h" #include "hbapi.h" #include "hbstack.h" +#include "hbapicls.h" #include "hbapiitm.h" #include "hbapierr.h" #include "hbvm.h" @@ -78,6 +79,13 @@ typedef struct HB_GARBAGE_ # define HB_GARBAGE_SIZE sizeof( HB_GARBAGE ) #endif +#define HB_GC_PTR( p ) ( ( HB_GARBAGE_PTR ) ( ( BYTE * ) ( p ) - HB_GARBAGE_SIZE ) ) +#define HB_MEM_PTR( p ) ( ( void * ) ( ( BYTE * ) ( p ) + HB_GARBAGE_SIZE ) ) + +/* we may use a cache later */ +#define HB_GARBAGE_NEW( ulSize ) ( ( HB_GARBAGE_PTR ) hb_xgrab( HB_GARBAGE_SIZE + ( ulSize ) ) ) +#define HB_GARBAGE_FREE( pAlloc ) hb_xfree( ( void * ) ( pAlloc ) ) + /* status of memory block */ #define HB_GC_UNLOCKED 0 #define HB_GC_LOCKED 1 /* do not collect a memory block */ @@ -91,6 +99,9 @@ static HB_GARBAGE_PTR s_pCurrBlock = NULL; /* pointer to locked memory blocks */ static HB_GARBAGE_PTR s_pLockedBlock = NULL; +/* pointer to memory blocks that will be deleted */ +static HB_GARBAGE_PTR s_pDeletedBlock = NULL; + /* marks if block releasing is requested during garbage collecting */ static BOOL s_bCollecting = FALSE; @@ -99,10 +110,6 @@ static BOOL s_bCollecting = FALSE; */ static USHORT s_uUsedFlag = HB_GC_USED_FLAG; -/* we may use a cache later */ -#define HB_GARBAGE_NEW( ulSize ) ( ( HB_GARBAGE_PTR ) hb_xgrab( ulSize ) ) -#define HB_GARBAGE_FREE( pAlloc ) hb_xfree( ( void * ) ( pAlloc ) ) - static void hb_gcLink( HB_GARBAGE_PTR *pList, HB_GARBAGE_PTR pAlloc ) { if( *pList ) @@ -134,14 +141,14 @@ void * hb_gcAlloc( ULONG ulSize, HB_GARBAGE_FUNC_PTR pCleanupFunc ) { HB_GARBAGE_PTR pAlloc; - pAlloc = HB_GARBAGE_NEW( HB_GARBAGE_SIZE + ulSize ); + pAlloc = HB_GARBAGE_NEW( ulSize ); if( pAlloc ) { hb_gcLink( &s_pCurrBlock, pAlloc ); pAlloc->pFunc = pCleanupFunc; pAlloc->locked = 0; pAlloc->used = s_uUsedFlag; - return ( void * ) ( ( BYTE * ) pAlloc + HB_GARBAGE_SIZE ); /* hide the internal data */ + return HB_MEM_PTR( pAlloc ); /* hide the internal data */ } else return NULL; @@ -152,7 +159,7 @@ void hb_gcFree( void *pBlock ) { if( pBlock ) { - HB_GARBAGE_PTR pAlloc = ( HB_GARBAGE_PTR ) ( ( BYTE * ) pBlock - HB_GARBAGE_SIZE ); + HB_GARBAGE_PTR pAlloc = HB_GC_PTR( pBlock ); if( !( pAlloc->used & HB_GC_DELETE ) ) { @@ -170,6 +177,69 @@ void hb_gcFree( void *pBlock ) } } +/* increment reference counter */ +void hb_gcRefInc( void * pBlock ) +{ + hb_xRefInc( HB_GC_PTR( pBlock ) ); +} + +/* decrement reference counter, return TRUE when 0 reached */ +BOOL hb_gcRefDec( void * pBlock ) +{ + return hb_xRefDec( HB_GC_PTR( pBlock ) ); +} + +/* decrement reference counter and free the block when 0 reached */ +void hb_gcRefFree( void * pBlock ) +{ + if( pBlock ) + { + HB_GARBAGE_PTR pAlloc = HB_GC_PTR( pBlock ); + + if( hb_xRefDec( pAlloc ) ) + { + /* Don't release the block that will be deleted during finalization */ + if( !( pAlloc->used & HB_GC_DELETE ) ) + { + /* unlink the block first to avoid possible problems + * if cleanup function activate GC + */ + if( pAlloc->locked ) + hb_gcUnlink( &s_pLockedBlock, pAlloc ); + else + hb_gcUnlink( &s_pCurrBlock, pAlloc ); + + /* execute clean-up function */ + if( pAlloc->pFunc ) + { + /* + * we do not have to set HB_GC_DELETE flag here. If upper level + * code is not broken then the reference counter to this block + * now reach 0 so is nowhere accessible. I set this flag only + * as workaround for some wrong code which may want to execute + * hb_gcFree() for this block from clean-up function. [druzus] + */ + pAlloc->used |= HB_GC_DELETE; + ( pAlloc->pFunc )( pBlock ); + } + + HB_GARBAGE_FREE( pAlloc ); + } + } + } + else + { + hb_errInternal( HB_EI_XFREENULL, NULL, NULL, NULL ); + } +} + +/* return number of references */ +HB_COUNTER hb_gcRefCount( void * pBlock ) +{ + return hb_xRefCount( HB_GC_PTR( pBlock ) ); +} + + static HB_GARBAGE_FUNC( hb_gcGripRelease ) { /* Item was already released in hb_gcGripDrop() - then we have nothing @@ -182,10 +252,10 @@ HB_ITEM_PTR hb_gcGripGet( HB_ITEM_PTR pOrigin ) { HB_GARBAGE_PTR pAlloc; - pAlloc = HB_GARBAGE_NEW( HB_GARBAGE_SIZE + sizeof( HB_ITEM ) ); + pAlloc = HB_GARBAGE_NEW( sizeof( HB_ITEM ) ); if( pAlloc ) { - HB_ITEM_PTR pItem = ( HB_ITEM_PTR ) ( ( BYTE * ) pAlloc + HB_GARBAGE_SIZE ); + HB_ITEM_PTR pItem = ( HB_ITEM_PTR ) HB_MEM_PTR( pAlloc ); hb_gcLink( &s_pLockedBlock, pAlloc ); pAlloc->pFunc = hb_gcGripRelease; @@ -206,7 +276,7 @@ void hb_gcGripDrop( HB_ITEM_PTR pItem ) { if( pItem ) { - HB_GARBAGE_PTR pAlloc = ( HB_GARBAGE_PTR ) ( ( BYTE * ) pItem - HB_GARBAGE_SIZE ); + HB_GARBAGE_PTR pAlloc = HB_GC_PTR( pItem ); if( HB_IS_COMPLEX( pItem ) ) hb_itemClear( pItem ); /* clear value stored in this item */ @@ -223,7 +293,7 @@ void * hb_gcLock( void * pBlock ) { if( pBlock ) { - HB_GARBAGE_PTR pAlloc = ( HB_GARBAGE_PTR ) ( ( BYTE * ) pBlock - HB_GARBAGE_SIZE ); + HB_GARBAGE_PTR pAlloc = HB_GC_PTR( pBlock ); if( ! pAlloc->locked ) { @@ -239,11 +309,11 @@ void * hb_gcLock( void * pBlock ) /* Unlock a memory pointer so it can be released if there is no references inside of harbour variables */ -void *hb_gcUnlock( void *pBlock ) +void *hb_gcUnlock( void * pBlock ) { if( pBlock ) { - HB_GARBAGE_PTR pAlloc = ( HB_GARBAGE_PTR ) ( ( BYTE * ) pBlock - HB_GARBAGE_SIZE ); + HB_GARBAGE_PTR pAlloc = HB_GC_PTR( pBlock ); if( pAlloc->locked ) { @@ -267,7 +337,7 @@ void hb_gcItemRef( HB_ITEM_PTR pItem ) if( HB_IS_ARRAY( pItem ) ) { - HB_GARBAGE_PTR pAlloc = ( HB_GARBAGE_PTR ) ( ( BYTE * ) pItem->item.asArray.value - HB_GARBAGE_SIZE ); + HB_GARBAGE_PTR pAlloc = HB_GC_PTR( pItem->item.asArray.value ); /* Check this array only if it was not checked yet */ if( pAlloc->used == s_uUsedFlag ) @@ -289,7 +359,7 @@ void hb_gcItemRef( HB_ITEM_PTR pItem ) } else if( HB_IS_BLOCK( pItem ) ) { - HB_GARBAGE_PTR pAlloc = ( HB_GARBAGE_PTR ) ( ( BYTE * ) pItem->item.asBlock.value - HB_GARBAGE_SIZE ); + HB_GARBAGE_PTR pAlloc = HB_GC_PTR( pItem->item.asBlock.value ); if( pAlloc->used == s_uUsedFlag ) { @@ -305,6 +375,16 @@ void hb_gcItemRef( HB_ITEM_PTR pItem ) } } } + else if( HB_IS_POINTER( pItem ) ) + { + if( pItem->item.asPointer.collect ) + { + HB_GARBAGE_PTR pAlloc = HB_GC_PTR( pItem->item.asPointer.value ); + + if( pAlloc->used == s_uUsedFlag ) + pAlloc->used ^= HB_GC_USED_FLAG; /* mark this codeblock as used */ + } + } /* all other data types don't need the GC */ } @@ -335,7 +415,7 @@ void hb_gcCollectAll( void ) hb_vmIsLocalRef(); hb_vmIsStaticRef(); hb_memvarsIsMemvarRef(); - hb_gcItemRef( &hb_stack.Return ); + hb_gcItemRef( hb_stackReturnItem() ); hb_clsIsClassRef(); /* check list of locked block for blocks referenced from @@ -348,25 +428,85 @@ void hb_gcCollectAll( void ) { /* it is not very elegant method but it works well */ if( pAlloc->pFunc == hb_gcGripRelease ) { - hb_gcItemRef( ( HB_ITEM_PTR ) ( ( BYTE * ) pAlloc + HB_GARBAGE_SIZE ) ); + hb_gcItemRef( ( HB_ITEM_PTR ) HB_MEM_PTR( pAlloc ) ); } pAlloc = pAlloc->pNext; - } while ( s_pLockedBlock != pAlloc ); + } while( s_pLockedBlock != pAlloc ); } /* Step 3 - finalize */ /* Release all blocks that are still marked as unused */ + + /* + * infinite loop can appear when we are executing clean-up functions + * scanning s_pCurrBlock. It's possible that one of them will free + * the GC block which we are using as stop condition. Only blocks + * for which we set HB_GC_DELETE flag are guarded against releasing. + * To avoid such situation first we are moving blocks which will be + * deleted to separate list. It's additional operation but it can + * even increase the speed when we are deleting only few percent + * of all allocated blocks because in next passes we will scan only + * deleted block list. [druzus] + */ + + pAlloc = NULL; /* for stop condition */ + do + { + if( s_pCurrBlock->used == s_uUsedFlag ) + { + pDelete = s_pCurrBlock; + s_pCurrBlock->used |= HB_GC_DELETE; + hb_gcUnlink( &s_pCurrBlock, s_pCurrBlock ); + hb_gcLink( &s_pDeletedBlock, pDelete ); + } + else + { + /* at least one block will not be deleted, set new stop condition */ + if( ! pAlloc ) + pAlloc = s_pCurrBlock; + s_pCurrBlock = s_pCurrBlock->pNext; + } + + } while( pAlloc != s_pCurrBlock ); + + /* do we have any deleted blocks? */ + if( s_pDeletedBlock ) + { + + /* call a cleanup function */ + pAlloc = s_pDeletedBlock; + do + { + if( s_pDeletedBlock->pFunc ) + ( s_pDeletedBlock->pFunc )( HB_MEM_PTR( s_pDeletedBlock ) ); + + s_pDeletedBlock = s_pDeletedBlock->pNext; + + } while( pAlloc != s_pDeletedBlock ); + + /* release all deleted blocks */ + do + { + pDelete = s_pDeletedBlock; + hb_gcUnlink( &s_pDeletedBlock, s_pDeletedBlock ); + HB_GARBAGE_FREE( pDelete ); + + } while( s_pDeletedBlock ); + } + + +#if 0 pAlloc = s_pCurrBlock; do { if( s_pCurrBlock->used == s_uUsedFlag ) { - /* call a cleanup function */ - s_pCurrBlock->used |= HB_GC_DELETE; - if( s_pCurrBlock->pFunc ) - { - ( s_pCurrBlock->pFunc )( ( void *) ( ( BYTE * ) s_pCurrBlock + HB_GARBAGE_SIZE ) ); - } + /* call a cleanup function */ + s_pCurrBlock->used |= HB_GC_DELETE; + if( s_pCurrBlock->pFunc ) + { + ( s_pCurrBlock->pFunc )( HB_MEM_PTR( s_pCurrBlock ) ); + } } s_pCurrBlock = s_pCurrBlock->pNext; @@ -408,18 +548,18 @@ void hb_gcCollectAll( void ) { s_pCurrBlock = s_pCurrBlock->pNext; } - } while ( s_pCurrBlock && ( pAlloc != s_pCurrBlock ) ); - s_bCollecting = FALSE; - s_pCurrBlock = pAlloc; +#endif /* Step 4 - flip flag */ /* Reverse used/unused flag so we don't have to mark all blocks * during next collecting */ s_uUsedFlag ^= HB_GC_USED_FLAG; + + s_bCollecting = FALSE; } } @@ -438,7 +578,9 @@ void hb_gcReleaseAll( void ) if( s_pCurrBlock->pFunc ) { HB_TRACE( HB_TR_INFO, ( "Cleanup, %p", s_pCurrBlock ) ); - ( s_pCurrBlock->pFunc )( ( void *) ( ( BYTE * ) s_pCurrBlock + HB_GARBAGE_SIZE ) ); + + s_pCurrBlock->used |= HB_GC_DELETE; + ( s_pCurrBlock->pFunc )( HB_MEM_PTR( s_pCurrBlock ) ); } s_pCurrBlock = s_pCurrBlock->pNext; diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index 86fddf8f92..1d2ae0bef2 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -73,6 +73,7 @@ #include "hbapi.h" #include "hbstack.h" #include "hbapierr.h" +#include "hbapicls.h" #include "hbapiitm.h" #include "hbapilng.h" #include "hbapirdd.h" @@ -95,14 +96,6 @@ /* DEBUG only*/ /* #include */ -typedef struct _SYMBOLS -{ - PHB_SYMB pModuleSymbols; /* pointer to a one module own symbol table */ - USHORT uiModuleSymbols; /* number of symbols on that table */ - struct _SYMBOLS * pNext; /* pointer to the next SYMBOLS structure */ - HB_SYMBOLSCOPE hScope; /* scope collected from all symbols in module used to speed initialization code */ -} SYMBOLS, * PSYMBOLS; /* structure to keep track of all modules symbol tables */ - HB_FUNC_EXTERN( SYSINIT ); /* PCode functions */ @@ -146,10 +139,6 @@ static void hb_vmArrayPop( void ); /* pops a value from the stack */ static void hb_vmArrayDim( USHORT uiDimensions ); /* generates an uiDimensions Array and initialize those dimensions from the stack values */ static void hb_vmArrayGen( ULONG ulElements ); /* generates an ulElements Array and fills it from the stack values */ -/* Object */ -static void hb_vmOperatorCall( HB_ITEM_PTR, PHB_ITEM, PHB_ITEM, char * ); /* call an overloaded operator */ -static void hb_vmOperatorCallUnary( PHB_ITEM, char * ); /* call an overloaded unary operator */ - /* Database */ static ERRCODE hb_vmSelectWorkarea( PHB_ITEM ); /* select the workarea using a given item or a substituted value */ static void hb_vmSwapAlias( void ); /* swaps items on the eval stack and pops the workarea number */ @@ -171,8 +160,8 @@ static void hb_vmDebuggerEndProc( void ); /* notifies the debugger for an static void hb_vmPushAlias( void ); /* pushes the current workarea number */ static void hb_vmPushAliasedField( PHB_SYMB ); /* pushes an aliased field on the eval stack */ static void hb_vmPushAliasedVar( PHB_SYMB ); /* pushes an aliased variable on the eval stack */ -static void hb_vmPushBlock( const BYTE * pCode, PHB_SYMB pSymbols ); /* creates a codeblock */ -static void hb_vmPushBlockShort( const BYTE * pCode, PHB_SYMB pSymbols ); /* creates a codeblock */ +static void hb_vmPushBlock( const BYTE * pCode, PHB_SYMB pSymbols, USHORT usLen ); /* creates a codeblock */ +static void hb_vmPushBlockShort( const BYTE * pCode, PHB_SYMB pSymbols, USHORT usLen ); /* creates a codeblock */ static void hb_vmPushDoubleConst( double dNumber, int iWidth, int iDec ); /* Pushes a double constant (pcode) */ static void hb_vmPushMacroBlock( BYTE * pCode, PHB_SYMB pSymbols ); /* creates a macro-compiled codeblock */ static void hb_vmPushLocal( SHORT iLocal ); /* pushes the containts of a local onto the stack */ @@ -214,10 +203,13 @@ static void hb_vmDoInitFunctions( void ); /* executes all defined PRGs I static void hb_vmDoExitFunctions( void ); /* executes all defined PRGs EXIT functions */ static void hb_vmReleaseLocalSymbols( void ); /* releases the memory of the local symbols linked list */ -BOOL hb_bProfiler = FALSE; /* profiler status is off */ +#ifndef HB_NO_PROFILER +static ULONG hb_ulOpcodesCalls[ HB_P_LAST_PCODE ];/* array to profile opcodes calls */ +static ULONG hb_ulOpcodesTime[ HB_P_LAST_PCODE ]; /* array to profile opcodes consumed time */ +BOOL hb_bProfiler = FALSE; /* profiler status is off */ +#endif + BOOL hb_bTracePrgCalls = FALSE; /* prg tracing is off */ -ULONG hb_ulOpcodesCalls[ HB_P_LAST_PCODE ]; /* array to profile opcodes calls */ -ULONG hb_ulOpcodesTime[ HB_P_LAST_PCODE ]; /* array to profile opcodes consumed time */ #ifdef HARBOUR_START_PROCEDURE char *s_pszLinkedMain = NULL; /* name of starup function set by linker */ @@ -225,16 +217,20 @@ ULONG hb_ulOpcodesTime[ HB_P_LAST_PCODE ]; /* array to profile opcodes consumed /* virtual machine state */ -HB_SYMB hb_symEval = { "__EVAL", {HB_FS_PUBLIC}, {hb_vmDoBlock}, NULL }; /* symbol to evaluate codeblocks */ -HB_SYMB hb_symEnumIndex = { "__ENUMINDEX", {HB_FS_PUBLIC}, {NULL}, NULL }; -HB_SYMB hb_symEnumBase = { "__ENUMBASE", {HB_FS_PUBLIC}, {NULL}, NULL }; -HB_SYMB hb_symEnumValue = { "__ENUMVALUE", {HB_FS_PUBLIC}, {NULL}, NULL }; +HB_SYMB hb_symEval = { "__EVAL", {HB_FS_PUBLIC}, {hb_vmDoBlock}, NULL }; /* symbol to evaluate codeblocks */ +HB_SYMB hb_symEnumIndex = { "__ENUMINDEX", {HB_FS_MESSAGE}, {NULL}, NULL }; +HB_SYMB hb_symEnumBase = { "__ENUMBASE", {HB_FS_MESSAGE}, {NULL}, NULL }; +HB_SYMB hb_symEnumValue = { "__ENUMVALUE", {HB_FS_MESSAGE}, {NULL}, NULL }; static HB_ITEM s_aStatics; /* Harbour array to hold all application statics variables */ -static USHORT s_uiStatics; /* Number of statics added after processing hb_vmStatics() */ -static PHB_SYMB s_pSymStart = NULL; /* start symbol of the application. MAIN() is not required */ -static PSYMBOLS s_pSymbols = NULL; /* to hold a linked list of all different modules symbol tables */ + static BYTE s_byErrorLevel; /* application exit errorlevel */ +static PHB_SYMB s_pSymStart = NULL; /* start symbol of the application. MAIN() is not required */ + +static PHB_SYMBOLS s_pSymbols = NULL; /* to hold a linked list of all different modules symbol tables */ +static ULONG s_ulFreeSymbols = 0;/* number of free module symbols */ +static void * s_hDynLibID = NULL; /* unique identifer to mark symbol tables loaded from dynamic libraries */ +static BOOL s_fCloneSym = FALSE;/* clone registered symbol tables */ static BOOL s_bDebugging; static BOOL s_bDebugRequest; /* debugger invoked via the VM */ @@ -421,9 +417,10 @@ HB_EXPORT void hb_vmInit( BOOL bStartMainProc ) hb_dynsymNew( &hb_symEnumValue ); hb_setInitialize(); /* initialize Sets */ - hb_conInit(); /* initialize Console */ + hb_conInit(); /* initialize Console */ hb_memvarsInit(); hb_vmSymbolInit_RT(); /* initialize symbol table with runtime support functions */ + hb_clsInit(); /* initialize Classy/OO system */ /* Set the language to the default */ @@ -436,6 +433,7 @@ HB_EXPORT void hb_vmInit( BOOL bStartMainProc ) s_VMFlags = hb_cmdargProcessVM( &s_VMCancelKey, &s_VMCancelKeyEx ); hb_inkeySetCancelKeys( s_VMCancelKey, s_VMCancelKeyEx ); +#ifndef HB_NO_PROFILER /* Initialize opcodes profiler support arrays */ { ULONG ul; @@ -446,6 +444,7 @@ HB_EXPORT void hb_vmInit( BOOL bStartMainProc ) hb_ulOpcodesTime[ ul ] = 0; } } +#endif /* Call functions that initializes static variables * Static variables have to be initialized before any INIT functions @@ -568,8 +567,8 @@ HB_EXPORT void hb_vmQuit( void ) /* release all remaining items */ hb_stackRemove( 0 ); - hb_itemClear( &hb_stack.Return ); - hb_arrayRelease( &s_aStatics ); + hb_itemClear( hb_stackReturnItem() ); + hb_itemClear( &s_aStatics ); hb_memvarsRelease(); /* clear all PUBLIC variables */ /* release all known garbage */ @@ -593,10 +592,13 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) { LONG w = 0; BOOL bCanRecover = FALSE; + LONG lForEachBase = 0; /* Stores the position on the stack of current FOR EACH envelope */ ULONG ulPrivateBase; + BOOL bDynCode = pSymbols == NULL || ( pSymbols->scope.value & HB_FS_DYNCODE ) != 0; +#ifndef HB_NO_PROFILER ULONG ulLastOpcode = 0; /* opcodes profiler support */ ULONG ulPastClock = 0; /* opcodes profiler support */ - LONG lForEachBase = 0; /* Stores the position on the stack of current FOR EACH envelope */ +#endif #ifndef HB_GUI static unsigned short uiPolls = 1; #endif @@ -611,11 +613,14 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) /* NOTE: Initialization with 0 is needed to avoid GCC -O2 warning */ ulPrivateBase = pSymbols ? hb_memvarGetPrivatesBase() : 0; +#ifndef HB_NO_PROFILER if( hb_bProfiler ) ulPastClock = ( ULONG ) clock(); +#endif while( TRUE ) { +#ifndef HB_NO_PROFILER if( hb_bProfiler ) { ULONG ulActualClock = ( ULONG ) clock(); @@ -625,6 +630,7 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) ulLastOpcode = pCode[ w ]; hb_ulOpcodesCalls[ ulLastOpcode ]++; } +#endif #ifndef HB_GUI if( ! --uiPolls ) @@ -938,35 +944,21 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_FUNCTION: - if( HB_IS_COMPLEX( &hb_stack.Return ) ) - hb_itemClear( &hb_stack.Return ); - else - hb_stack.Return.type = HB_IT_NIL; - + hb_itemSetNil( hb_stackReturnItem() ); hb_vmDo( HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); - hb_itemMove( hb_stackTopItem(), &hb_stack.Return ); - hb_stackPush(); + hb_stackPushReturn(); w += 3; break; case HB_P_FUNCTIONSHORT: - if( HB_IS_COMPLEX( &hb_stack.Return ) ) - hb_itemClear( &hb_stack.Return ); - else - hb_stack.Return.type = HB_IT_NIL; - + hb_itemSetNil( hb_stackReturnItem() ); hb_vmDo( pCode[ w + 1 ] ); - hb_itemMove( hb_stackTopItem(), &hb_stack.Return ); - hb_stackPush(); + hb_stackPushReturn(); w += 2; break; case HB_P_SEND: - if( HB_IS_COMPLEX( &hb_stack.Return ) ) - hb_itemClear( &hb_stack.Return ); - else - hb_stack.Return.type = HB_IT_NIL; - + hb_itemSetNil( hb_stackReturnItem() ); hb_vmSend( HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); w += 3; @@ -974,28 +966,18 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) if( pCode[ w ] == HB_P_POP ) w++; else - { - hb_itemMove( hb_stackTopItem(), &hb_stack.Return ); - hb_stackPush(); - } + hb_stackPushReturn(); break; case HB_P_SENDSHORT: - if( HB_IS_COMPLEX( &hb_stack.Return ) ) - hb_itemClear( &hb_stack.Return ); - else - hb_stack.Return.type = HB_IT_NIL; - + hb_itemSetNil( hb_stackReturnItem() ); hb_vmSend( pCode[ w + 1 ] ); w += 2; if( pCode[ w ] == HB_P_POP ) w++; else - { - hb_itemMove( hb_stackTopItem(), &hb_stack.Return ); - hb_stackPush(); - } + hb_stackPushReturn(); break; case HB_P_LINE: @@ -1342,13 +1324,19 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) case HB_P_PUSHSTR: { USHORT uiSize = HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ); - hb_vmPushStringPcode( ( char * ) pCode + w + 3, ( ULONG ) uiSize - 1 ); + if( bDynCode ) + hb_vmPushString( ( char * ) pCode + w + 3, ( ULONG ) ( uiSize - 1 ) ); + else + hb_vmPushStringPcode( ( char * ) pCode + w + 3, ( ULONG ) uiSize - 1 ); w += ( 3 + uiSize ); break; } case HB_P_PUSHSTRSHORT: - hb_vmPushStringPcode( ( char * ) pCode + w + 2, ( ULONG ) pCode[ w + 1 ] - 1 ); + if( bDynCode ) + hb_vmPushString( ( char * ) pCode + w + 2, ( ULONG ) pCode[ w + 1 ] - 1 ); + else + hb_vmPushStringPcode( ( char * ) pCode + w + 2, ( ULONG ) pCode[ w + 1 ] - 1 ); w += ( 2 + pCode[ w + 1 ] ); break; @@ -1359,23 +1347,28 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_PUSHBLOCK: + { /* +0 -> _pushblock * +1 +2 -> size of codeblock * +3 +4 -> number of expected parameters * +5 +6 -> number of referenced local variables * +7 -> start of table with referenced local variables */ - hb_vmPushBlock( ( const BYTE * ) ( pCode + w + 3 ), pSymbols ); - w += HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ); + USHORT usSize = HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ); + hb_vmPushBlock( ( const BYTE * ) ( pCode + w + 3 ), pSymbols, bDynCode ? usSize - 7 : 0 ); + w += usSize; break; - + } case HB_P_PUSHBLOCKSHORT: + { /* +0 -> _pushblock * +1 -> size of codeblock */ - hb_vmPushBlockShort( ( const BYTE * ) ( pCode + w + 2 ), pSymbols ); - w += pCode[ w + 1 ]; + USHORT usSize = pCode[ w + 1 ]; + hb_vmPushBlockShort( ( const BYTE * ) ( pCode + w + 2 ), pSymbols, bDynCode ? usSize - 2 : 0 ); + w += usSize; break; + } case HB_P_PUSHSELF: hb_vmPush( hb_stackSelfItem() ); @@ -1447,15 +1440,15 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_PUSHMEMVAR: - hb_memvarGetValue( ( hb_stackTopItem() ), pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); hb_stackPush(); + hb_memvarGetValue( hb_stackItemFromTop( -1 ), pSymbols + HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ) ); HB_TRACE(HB_TR_INFO, ("(hb_vmPushMemvar)")); w += 3; break; case HB_P_PUSHMEMVARREF: - hb_memvarGetRefer( ( hb_stackTopItem() ), pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); hb_stackPush(); + hb_memvarGetRefer( hb_stackItemFromTop( -1 ), pSymbols + HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ) ); HB_TRACE(HB_TR_INFO, ("(hb_vmPushMemvarRef)")); w += 3; break; @@ -1530,9 +1523,8 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_POPMEMVAR: - hb_stackDec(); - hb_memvarSetValue( pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ), ( hb_stackTopItem() ) ); - hb_itemClear( ( hb_stackTopItem() ) ); + hb_memvarSetValue( pSymbols + HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ), hb_stackItemFromTop( -1 ) ); + hb_stackPop(); HB_TRACE(HB_TR_INFO, ("(hb_vmPopMemvar)")); w += 3; break; @@ -1545,7 +1537,7 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) /* Pops a value from the eval stack and uses it to set * a new value of a variable of unknown type. */ - uiParams = HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ); + uiParams = HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ); /* First try if passed symbol is a name of field * in a current workarea - if it is not a field (FAILURE) * then try the memvar variable (it will create PRIVATE @@ -1553,18 +1545,19 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) */ /* memvars.c 417 */ - pDyn = ( PHB_DYNS ) (pSymbols + uiParams)->pDynSym; + pDyn = ( PHB_DYNS ) ( pSymbols + uiParams )->pDynSym; if( pDyn && pDyn->hMemvar ) { /* If exist a memory symbol with this name use it */ - hb_memvarSetValue( pSymbols + uiParams, ( hb_stackItemFromTop(-1) ) ); - } else { - /* Try with a field and after create a memvar */ - if( hb_rddFieldPut( ( hb_stackItemFromTop(-1) ), pSymbols + uiParams ) == FAILURE ) - hb_memvarSetValue( pSymbols + uiParams, ( hb_stackItemFromTop(-1) ) ); + hb_memvarSetValue( pSymbols + uiParams, hb_stackItemFromTop( -1 ) ); } - hb_stackDec(); - hb_itemClear( ( hb_stackTopItem() ) ); + else + { + /* Try with a field and after create a memvar */ + if( hb_rddFieldPut( hb_stackItemFromTop( -1 ), pSymbols + uiParams ) == FAILURE ) + hb_memvarSetValue( pSymbols + uiParams, hb_stackItemFromTop( -1 ) ); + } + hb_stackPop(); HB_TRACE(HB_TR_INFO, ("(hb_vmPopVariable)")); w += 3; break; @@ -1783,9 +1776,8 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) case HB_P_MPOPMEMVAR: { HB_DYNS_PTR pDynSym = ( HB_DYNS_PTR ) HB_GET_PTR( pCode + w + 1 ); - hb_stackDec(); - hb_memvarSetValue( pDynSym->pSymbol, hb_stackTopItem() ); - hb_itemClear( hb_stackTopItem() ); + hb_memvarSetValue( pDynSym->pSymbol, hb_stackItemFromTop( -1 ) ); + hb_stackPop(); HB_TRACE(HB_TR_INFO, ("(hb_vmMPopMemvar)")); w += sizeof( HB_DYNS_PTR ) + 1; break; @@ -1838,8 +1830,8 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) case HB_P_MPUSHMEMVAR: { HB_DYNS_PTR pDynSym = ( HB_DYNS_PTR ) HB_GET_PTR( pCode + w + 1 ); - hb_memvarGetValue( ( hb_stackTopItem() ), pDynSym->pSymbol ); hb_stackPush(); + hb_memvarGetValue( hb_stackItemFromTop( -1 ), pDynSym->pSymbol ); HB_TRACE(HB_TR_INFO, ("(hb_vmMPushMemvar)")); w += sizeof( HB_DYNS_PTR ) + 1; break; @@ -1848,8 +1840,8 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) case HB_P_MPUSHMEMVARREF: { HB_DYNS_PTR pDynSym = ( HB_DYNS_PTR ) HB_GET_PTR( pCode + w + 1 ); - hb_memvarGetRefer( ( hb_stackTopItem() ), pDynSym->pSymbol ); hb_stackPush(); + hb_memvarGetRefer( hb_stackItemFromTop( -1 ), pDynSym->pSymbol ); HB_TRACE(HB_TR_INFO, ("(hb_vmMPushMemvarRef)")); w += sizeof( HB_DYNS_PTR ) + 1; break; @@ -2010,17 +2002,17 @@ static void hb_vmAddInt( HB_ITEM_PTR pResult, LONG lAdd ) } else { - PHB_ITEM pSubst, pAdd = hb_stackTopItem(); + PHB_ITEM pSubst; if( lAdd > 0 ) { hb_vmPushLong( lAdd ); - pSubst = hb_errRT_BASE_Subst( EG_ARG, 1081, NULL, "+", 2, pResult, pAdd ); + pSubst = hb_errRT_BASE_Subst( EG_ARG, 1081, NULL, "+", 2, pResult, hb_stackItemFromTop( -1 ) ); } else { hb_vmPushLong( -lAdd ); - pSubst = hb_errRT_BASE_Subst( EG_ARG, 1082, NULL, "-", 2, pResult, pAdd ); + pSubst = hb_errRT_BASE_Subst( EG_ARG, 1082, NULL, "-", 2, pResult, hb_stackItemFromTop( -1 ) ); } if( pSubst ) @@ -2143,16 +2135,39 @@ static void hb_vmPlus( HB_ITEM_PTR pResult, HB_ITEM_PTR pItem1, HB_ITEM_PTR pIte ULONG ulLen1 = pItem1->item.asString.length; ULONG ulLen2 = pItem2->item.asString.length; - if( ulLen1 < ULONG_MAX - ulLen2 ) + if( ulLen2 ) { - char * szNewString = ( char * ) hb_xgrab( ulLen1 + ulLen2 + 1 ); + if( ulLen1 ) + { + if( ulLen1 < ULONG_MAX - ulLen2 ) + { +#if 1 + if( pResult != pItem1 ) + { + hb_itemMove( pResult, pItem1 ); + pItem1 = pResult; + } + hb_itemReSizeString( pItem1, ulLen1 + ulLen2 ); + hb_xmemcpy( pItem1->item.asString.value + ulLen1, + pItem2->item.asString.value, ulLen2 ); +#else + char * szNewString = ( char * ) hb_xgrab( ulLen1 + ulLen2 + 1 ); - hb_xmemcpy( szNewString, pItem1->item.asString.value, ulLen1 ); - hb_xmemcpy( szNewString + ulLen1, pItem2->item.asString.value, ulLen2 ); - hb_itemPutCPtr( pResult, szNewString, ulLen1 + ulLen2 ); + hb_xmemcpy( szNewString, pItem1->item.asString.value, ulLen1 ); + hb_xmemcpy( szNewString + ulLen1, pItem2->item.asString.value, ulLen2 ); + hb_itemPutCPtr( pResult, szNewString, ulLen1 + ulLen2 ); +#endif + } + else + hb_errRT_BASE( EG_STROVERFLOW, 1209, NULL, "+", 2, pItem1, pItem2 ); + } + else if( iPopCnt > 0 ) + hb_itemMove( pResult, pItem2 ); + else + hb_itemCopy( pResult, pItem2 ); } - else - hb_errRT_BASE( EG_STROVERFLOW, 1209, NULL, "+", 2, pItem1, pItem2 ); + else if( pResult != pItem1 ) + hb_itemCopy( pResult, pItem1 ); } else if( HB_IS_DATE( pItem1 ) && HB_IS_DATE( pItem2 ) ) { @@ -2167,12 +2182,7 @@ static void hb_vmPlus( HB_ITEM_PTR pResult, HB_ITEM_PTR pItem1, HB_ITEM_PTR pIte { hb_itemPutDL( pResult, hb_itemGetNL( pItem1 ) + hb_itemGetDL( pItem2 ) ); } - else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpPlus" ) ) - { - hb_vmOperatorCall( pResult, pItem1, pItem2, "__OPPLUS" ); - --iPopCnt; /* hb_vmOperatorCall pops pItem2 */ - } - else + else if( ! hb_objOperatorCall( HB_OO_OP_PLUS, pResult, pItem1, pItem2 ) ) { PHB_ITEM pSubst = hb_errRT_BASE_Subst( EG_ARG, 1081, NULL, "+", 2, pItem1, pItem2 ); @@ -2244,12 +2254,7 @@ static void hb_vmMinus( HB_ITEM_PTR pResult, HB_ITEM_PTR pItem1, HB_ITEM_PTR pIt else hb_errRT_BASE( EG_STROVERFLOW, 1210, NULL, "-", 2, pItem1, pItem2 ); } - else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpMinus" ) ) - { - hb_vmOperatorCall( pResult, pItem1, pItem2, "__OPMINUS" ); - --iPopCnt; /* hb_vmOperatorCall pops pItem2 */ - } - else + else if( ! hb_objOperatorCall( HB_OO_OP_MINUS, pResult, pItem1, pItem2 ) ) { PHB_ITEM pSubst = hb_errRT_BASE_Subst( EG_ARG, 1082, NULL, "-", 2, pItem1, pItem2 ); @@ -2288,12 +2293,7 @@ static void hb_vmMult( HB_ITEM_PTR pResult, HB_ITEM_PTR pItem1, HB_ITEM_PTR pIte hb_itemPutNumType( pResult, dNumber1 * dNumber2, iDec1 + iDec2, iType1, iType2 ); } - else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpMult" ) ) - { - hb_vmOperatorCall( pResult, pItem1, pItem2, "__OPMULT" ); - --iPopCnt; /* hb_vmOperatorCall pops pItem2 */ - } - else + else if( ! hb_objOperatorCall( HB_OO_OP_MULT, pResult, pItem1, pItem2 ) ) { PHB_ITEM pSubst = hb_errRT_BASE_Subst( EG_ARG, 1083, NULL, "*", 2, pItem1, pItem2 ); @@ -2365,12 +2365,7 @@ static void hb_vmDivide( HB_ITEM_PTR pResult, HB_ITEM_PTR pItem1, HB_ITEM_PTR pI hb_itemPutNDDec( pResult, dNumber1 / dDivisor, hb_set.HB_SET_DECIMALS ); } } - else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpDivide" ) ) - { - hb_vmOperatorCall( pResult, pItem1, pItem2, "__OPDIVIDE" ); - --iPopCnt; /* hb_vmOperatorCall pops pItem2 */ - } - else + else if( ! hb_objOperatorCall( HB_OO_OP_DIVIDE, pResult, pItem1, pItem2 ) ) { PHB_ITEM pSubst = hb_errRT_BASE_Subst( EG_ARG, 1084, NULL, "/", 2, pItem1, pItem2 ); @@ -2450,8 +2445,9 @@ static void hb_vmModulus( void ) hb_vmPushDouble( fmod( hb_vmPopNumber(), dDivisor ), hb_set.HB_SET_DECIMALS ); } } - else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpMod" ) ) - hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPMOD" ); + else if( hb_objOperatorCall( HB_OO_OP_MOD, pItem1, pItem1, pItem2 ) ) + hb_stackPop(); + else { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1085, NULL, "%", 2, pItem1, pItem2 ); @@ -2485,8 +2481,9 @@ static void hb_vmPower( void ) with the SET number of decimal places. */ hb_vmPushDouble( pow( d1, d2 ), hb_set.HB_SET_DECIMALS ); } - else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpPower" ) ) - hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPPOWER" ); + else if( hb_objOperatorCall( HB_OO_OP_POWER, pItem1, pItem1, pItem2 ) ) + hb_stackPop(); + else { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1088, NULL, "^", 2, pItem1, pItem2 ); @@ -2535,9 +2532,7 @@ static void hb_vmInc( void ) pItem->item.asDouble.value++; pItem->item.asDouble.length = HB_DBL_LENGTH( pItem->item.asDouble.value ); } - else if( HB_IS_OBJECT( pItem ) && hb_objHasMsg( pItem, "__OpInc" ) ) - hb_vmOperatorCallUnary( hb_stackItemFromTop( -1 ), "__OPINC" ); - else + else if( ! hb_objOperatorCall( HB_OO_OP_INC, pItem, pItem, NULL ) ) { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1086, NULL, "++", 1, pItem ); @@ -2584,9 +2579,7 @@ static void hb_vmDec( void ) pItem->item.asDouble.value--; pItem->item.asDouble.length = HB_DBL_LENGTH( pItem->item.asDouble.value ); } - else if( HB_IS_OBJECT( pItem ) && hb_objHasMsg( pItem, "__OpDec" ) ) - hb_vmOperatorCallUnary( pItem, "__OPDEC" ); - else + else if( ! hb_objOperatorCall( HB_OO_OP_DEC, pItem, pItem, NULL ) ) { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1087, NULL, "--", 1, pItem ); @@ -2661,9 +2654,16 @@ static void hb_vmEqual( BOOL bExact ) hb_vmPushLogical( hb_vmPopDate() == hb_vmPopDate() ); else if( HB_IS_LOGICAL( pItem1 ) && HB_IS_LOGICAL( pItem2 ) ) hb_vmPushLogical( hb_vmPopLogical() == hb_vmPopLogical() ); - else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpEqual" ) ) - hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPEQUAL" ); - else if( bExact && HB_IS_ARRAY( pItem1 ) && HB_IS_ARRAY( pItem2 ) ) + else if( HB_IS_POINTER( pItem1 ) && HB_IS_POINTER( pItem2 ) ) + { + BOOL fValue = pItem1->item.asPointer.value == + pItem2->item.asPointer.value; + hb_stackPop(); + hb_stackPop(); + hb_vmPushLogical( fValue ); + } + else if( bExact && HB_IS_ARRAY( pItem1 ) && HB_IS_ARRAY( pItem2 ) && + ! hb_objHasOperator( pItem1, HB_OO_OP_EXACTEQUAL ) ) { BOOL bResult = ( pItem1->item.asArray.value == pItem2->item.asArray.value ); @@ -2671,9 +2671,10 @@ static void hb_vmEqual( BOOL bExact ) hb_stackPop(); hb_vmPushLogical( bResult ); } - else if( pItem1->type != pItem2->type || - ( HB_IS_BLOCK( pItem1 ) && HB_IS_BLOCK( pItem2 ) ) || - ( ! bExact && HB_IS_ARRAY( pItem1 ) && HB_IS_ARRAY( pItem2 ) ) ) + else if( hb_objOperatorCall( bExact ? HB_OO_OP_EXACTEQUAL : HB_OO_OP_EQUAL, + pItem1, pItem1, pItem2 ) ) + hb_stackPop(); + else { PHB_ITEM pResult; @@ -2690,12 +2691,6 @@ static void hb_vmEqual( BOOL bExact ) hb_itemRelease( pResult ); } } - else - { - hb_stackPop(); - hb_stackPop(); - hb_vmPushLogical( FALSE ); - } } static void hb_vmNotEqual( void ) @@ -2736,11 +2731,17 @@ static void hb_vmNotEqual( void ) hb_vmPushLogical( hb_vmPopDate() != hb_vmPopDate() ); else if( HB_IS_LOGICAL( pItem1 ) && HB_IS_LOGICAL( pItem2 ) ) hb_vmPushLogical( hb_vmPopLogical() != hb_vmPopLogical() ); - else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpNotEqual" ) ) - hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPNOTEQUAL" ); - else if( pItem1->type != pItem2->type || - ( HB_IS_BLOCK( pItem1 ) && HB_IS_BLOCK( pItem2 ) ) || - ( HB_IS_ARRAY( pItem1 ) && HB_IS_ARRAY( pItem2 ) ) ) + else if( HB_IS_POINTER( pItem1 ) && HB_IS_POINTER( pItem2 ) ) + { + BOOL fValue = pItem1->item.asPointer.value != + pItem2->item.asPointer.value; + hb_stackPop(); + hb_stackPop(); + hb_vmPushLogical( fValue ); + } + else if( hb_objOperatorCall( HB_OO_OP_NOTEQUAL, pItem1, pItem1, pItem2 ) ) + hb_stackPop(); + else { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1072, NULL, "<>", 2, pItem1, pItem2 ); @@ -2752,12 +2753,6 @@ static void hb_vmNotEqual( void ) hb_itemRelease( pResult ); } } - else - { - hb_stackPop(); - hb_stackPop(); - hb_vmPushLogical( TRUE ); - } } static void hb_vmLess( void ) @@ -2801,8 +2796,9 @@ static void hb_vmLess( void ) BOOL bLogical1 = hb_vmPopLogical(); hb_vmPushLogical( bLogical1 < bLogical2 ); } - else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpLess" ) ) - hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPLESS" ); + else if( hb_objOperatorCall( HB_OO_OP_LESS, pItem1, pItem1, pItem2 ) ) + hb_stackPop(); + else { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1073, NULL, "<", 2, pItem1, pItem2 ); @@ -2858,8 +2854,9 @@ static void hb_vmLessEqual( void ) BOOL bLogical1 = hb_vmPopLogical(); hb_vmPushLogical( bLogical1 <= bLogical2 ); } - else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpLessEqual" ) ) - hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPLESSEQUAL" ); + else if( hb_objOperatorCall( HB_OO_OP_LESSEQUAL, pItem1, pItem1, pItem2 ) ) + hb_stackPop(); + else { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1074, NULL, "<=", 2, pItem1, pItem2 ); @@ -2915,8 +2912,9 @@ static void hb_vmGreater( void ) BOOL bLogical1 = hb_vmPopLogical(); hb_vmPushLogical( bLogical1 > bLogical2 ); } - else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpGreater" ) ) - hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPGREATER" ); + else if( hb_objOperatorCall( HB_OO_OP_GREATER, pItem1, pItem1, pItem2 ) ) + hb_stackPop(); + else { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1075, NULL, ">", 2, pItem1, pItem2 ); @@ -2972,8 +2970,9 @@ static void hb_vmGreaterEqual( void ) BOOL bLogical1 = hb_vmPopLogical(); hb_vmPushLogical( bLogical1 >= bLogical2 ); } - else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpGreaterEqual" ) ) - hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPGREATEREQUAL" ); + else if( hb_objOperatorCall( HB_OO_OP_GREATEREQUAL, pItem1, pItem1, pItem2 ) ) + hb_stackPop(); + else { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1076, NULL, ">=", 2, pItem1, pItem2 ); @@ -3006,8 +3005,9 @@ static void hb_vmInstring( void ) hb_stackPop(); hb_vmPushLogical( bResult ); } - else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpInstring" ) ) - hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPINSTRING" ); + else if( hb_objOperatorCall( HB_OO_OP_INSTRING, pItem1, pItem1, pItem2 ) ) + hb_stackPop(); + else { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1109, NULL, "$", 2, pItem1, pItem2 ); @@ -3139,17 +3139,15 @@ static void hb_vmForTest( void ) /* Test to check the end point of the FO static LONG hb_vmEnumStart( BYTE nVars, BYTE nDescend, LONG lOldBase ) { HB_ITEM_PTR pItem; - HB_ITEM_PTR pRef; - int i; ULONG ulMax; + int i; - --nVars; - pItem = hb_itemUnRef( hb_stackItemFromTop( -(nVars*2) -2 ) ); + pItem = hb_itemUnRef( hb_stackItemFromTop( -( ( int ) nVars << 1 ) ) ); if( HB_IS_ARRAY( pItem ) ) { ulMax = pItem->item.asArray.value->ulLen; } - else if( HB_IS_STRING(pItem) ) + else if( HB_IS_STRING( pItem ) ) { ulMax = pItem->item.asString.length; } @@ -3159,37 +3157,40 @@ static LONG hb_vmEnumStart( BYTE nVars, BYTE nDescend, LONG lOldBase ) return lOldBase; } - for( i = nVars * 2; i >= 0; i -= 2 ) + for( i = ( int ) nVars << 1; i > 0; i -= 2 ) { - PHB_ITEM pBaseValue; + HB_ITEM_PTR pValueRef, pEnum; + pValueRef = hb_stackItemFromTop( -i ); /* copy value to iterate */ - pBaseValue = hb_itemNew( hb_itemUnRef( hb_stackItemFromTop( -i -2 ) ) ); + pItem = hb_itemNew( hb_itemUnRef( pValueRef ) ); /* the control variable */ - pRef = hb_itemUnRefOnce( hb_stackItemFromTop( -i -1 ) ); - /* store the old value of variable and clear it */ - hb_itemMove( hb_stackItemFromTop( -i -2 ), pRef ); + pEnum = hb_itemUnRefOnce( hb_stackItemFromTop( -i + 1 ) ); + /* store the old value of control variable and clear it */ + hb_itemMove( pValueRef, pEnum ); /* set the iterator value */ - pRef->type = HB_IT_BYREF; - pRef->item.asRefer.ValuePtr.itemPtr = NULL; - pRef->item.asRefer.BasePtr.itemPtr = pBaseValue; - pRef->item.asRefer.offset = -1; /* enumerator variable */ + pEnum->type = HB_IT_BYREF | HB_IT_ENUM; + pEnum->item.asEnum.basePtr = pItem; + pEnum->item.asEnum.valuePtr = NULL; - pItem = pRef->item.asRefer.BasePtr.itemPtr; if( HB_IS_ARRAY( pItem ) ) { - pRef->item.asRefer.value = ( nDescend > 0 ) ? 1 : pItem->item.asArray.value->ulLen; /* the index into an array */ + /* the index into an array */ + pEnum->item.asEnum.offset = ( nDescend > 0 ) ? 1 : + pItem->item.asArray.value->ulLen; if( ulMax > pItem->item.asArray.value->ulLen ) ulMax = pItem->item.asArray.value->ulLen; } else if( HB_IS_STRING( pItem ) ) { /* storage item for single characters */ - pRef->item.asRefer.value = ( nDescend > 0 ) ? 1 : pItem->item.asString.length; - pRef->item.asRefer.ValuePtr.itemPtr = - hb_itemPutCL( NULL, pItem->item.asString.value + - pRef->item.asRefer.value - 1, 1 ); + pEnum->item.asEnum.offset = ( nDescend > 0 ) ? 1 : + pItem->item.asString.length; + if( pItem->item.asString.length ) /* TODO: RT error if not? */ + pEnum->item.asEnum.valuePtr = + hb_itemPutCL( NULL, pItem->item.asString.value + + pEnum->item.asEnum.offset - 1, 1 ); if( ulMax > pItem->item.asString.length ) ulMax = pItem->item.asString.length; } @@ -3199,9 +3200,8 @@ static LONG hb_vmEnumStart( BYTE nVars, BYTE nDescend, LONG lOldBase ) } } - hb_vmPushLong( nVars + 1 ); /* number of iterators */ + hb_vmPushLong( nVars ); /* number of iterators */ hb_vmPushLong( lOldBase ); /* previous FOREACH frame */ - hb_vmPushLong( ulMax ); /* max number of iterations */ /* empty array/string - do not start enumerations loop */ hb_vmPushLogical( ulMax != 0 ); @@ -3212,143 +3212,110 @@ static LONG hb_vmEnumStart( BYTE nVars, BYTE nDescend, LONG lOldBase ) /* Enumeration in ascending order * At this moment the eval stack should store: - * -5 -> - * -4 -> - * -3 -> - * -2 -> - * -1 -> + * -4 -> + * -3 -> + * -2 -> + * -1 -> */ static void hb_vmEnumNext( void ) { - ULONG ulIdx; - HB_ITEM_PTR pIdx; - HB_ITEM_PTR pRef; + HB_ITEM_PTR pEnum; int i; - LONG lVars; - - lVars = ( hb_stackItemFromTop( - 3 ) )->item.asLong.value; - - --lVars; - pIdx = hb_stackItemFromTop( -1 ); - ulIdx = pIdx->item.asLong.value - 1; - if( ulIdx > 0 ) + + for( i = ( int ) hb_stackItemFromTop( -2 )->item.asLong.value; i > 0; --i ) { - for( i=lVars; i >= 0; i-- ) +// pEnum = hb_itemUnRefRefer( hb_stackItemFromTop( -( i << 1 ) - 1 ) ); + pEnum = hb_itemUnRefOnce( hb_stackItemFromTop( -( i << 1 ) - 1 ) ); + if( HB_IS_ARRAY( pEnum->item.asEnum.basePtr ) ) { - pRef = hb_itemUnRefRefer( hb_stackItemFromTop( -(i<<1) - 4 ) ); - if( HB_IS_ARRAY( pRef->item.asRefer.BasePtr.itemPtr ) ) - { - pRef->item.asRefer.value++; - } - else if( HB_IS_STRING( pRef->item.asRefer.BasePtr.itemPtr ) ) - { - HB_ITEM_PTR pItem; - pRef->item.asRefer.value++; - pItem = pRef->item.asRefer.BasePtr.itemPtr; - hb_itemPutCL( pRef->item.asRefer.ValuePtr.itemPtr, - pItem->item.asString.value + pRef->item.asRefer.value - 1, 1 ); - } - else - { - hb_errRT_BASE( EG_ARG, 1068, NULL, hb_langDGetErrorDesc( EG_ARRACCESS ), 1, pRef->item.asRefer.BasePtr.itemPtr ); - } + if( ( ULONG ) ++pEnum->item.asEnum.offset > + pEnum->item.asEnum.basePtr->item.asArray.value->ulLen ) + break; + } + else if( HB_IS_STRING( pEnum->item.asEnum.basePtr ) ) + { + if( ( ULONG ) ++pEnum->item.asEnum.offset > + pEnum->item.asEnum.basePtr->item.asString.length ) + break; + hb_itemPutCL( pEnum->item.asEnum.valuePtr, + pEnum->item.asEnum.basePtr->item.asString.value + + pEnum->item.asEnum.offset - 1, 1 ); + } + else + { + hb_errRT_BASE( EG_ARG, 1068, NULL, hb_langDGetErrorDesc( EG_ARRACCESS ), 1, pEnum->item.asEnum.basePtr ); } - hb_vmPushLogical( TRUE ); } - else - { - hb_vmPushLogical( FALSE ); - } - pIdx->item.asLong.value = ulIdx; + hb_vmPushLogical( i == 0 ); } /* Enumeration in descending order * At this moment the eval stack should store: - * -5 -> - * -4 -> - * -3 -> - * -2 -> - * -1 -> + * -4 -> + * -3 -> + * -2 -> + * -1 -> */ static void hb_vmEnumPrev( void ) { - ULONG ulIdx; - HB_ITEM_PTR pIdx; - HB_ITEM_PTR pRef; + HB_ITEM_PTR pEnum; int i; - LONG lVars; - lVars = ( hb_stackItemFromTop( -3 ) )->item.asLong.value; - - --lVars; - pIdx = hb_stackItemFromTop( -1 ); - ulIdx = pIdx->item.asLong.value - 1; - if( ulIdx > 0 ) + for( i = hb_stackItemFromTop( -2 )->item.asLong.value; i > 0; --i ) { - for( i=lVars; i >= 0; i-- ) +// pEnum = hb_itemUnRefRefer( hb_stackItemFromTop( -( i << 1 ) - 1 ) ); + pEnum = hb_itemUnRefOnce( hb_stackItemFromTop( -( i << 1 ) - 1 ) ); + if( HB_IS_ARRAY( pEnum->item.asEnum.basePtr ) ) { - pRef = hb_itemUnRefRefer( hb_stackItemFromTop( -(i<<1) - 4 ) ); - if( HB_IS_ARRAY( pRef->item.asRefer.BasePtr.itemPtr ) ) - { - pRef->item.asRefer.value--; - } - else if( HB_IS_STRING( pRef->item.asRefer.BasePtr.itemPtr ) ) - { - HB_ITEM_PTR pItem; - pRef->item.asRefer.value--; - pItem = pRef->item.asRefer.BasePtr.itemPtr; - hb_itemPutCL( pRef->item.asRefer.ValuePtr.itemPtr, - pItem->item.asString.value + pRef->item.asRefer.value - 1, 1 ); - } - else - { - hb_errRT_BASE( EG_ARG, 1068, NULL, hb_langDGetErrorDesc( EG_ARRACCESS ), 1, pRef->item.asRefer.BasePtr.itemPtr ); - } + if( --pEnum->item.asEnum.offset == 0 ) + break; + } + else if( HB_IS_STRING( pEnum->item.asEnum.basePtr ) ) + { + if( --pEnum->item.asEnum.offset == 0 ) + break; + hb_itemPutCL( pEnum->item.asEnum.valuePtr, + pEnum->item.asEnum.basePtr->item.asString.value + + pEnum->item.asEnum.offset - 1, 1 ); + } + else + { + hb_errRT_BASE( EG_ARG, 1068, NULL, hb_langDGetErrorDesc( EG_ARRACCESS ), 1, pEnum->item.asEnum.basePtr ); } - hb_vmPushLogical( TRUE ); } - else - { - hb_vmPushLogical( FALSE ); - } - pIdx->item.asLong.value = ulIdx; + hb_vmPushLogical( i == 0 ); } /* Enumeration in descending order * At this moment the eval stack should store: - * -5 -> - * -4 -> - * -3 -> - * -2 -> - * -1 -> + * -4 -> + * -3 -> + * -2 -> + * -1 -> */ static LONG hb_vmEnumEnd( void ) { - int i; LONG lOldBase; LONG lVars; - /* remove loop counter */ - hb_stackDec(); - hb_stackTopItem()->type = HB_IT_NIL; - /* restore stack frame offset of previous FOREACH loop - */ + /* restore stack frame offset of previous FOREACH loop */ hb_stackDec(); lOldBase = hb_stackTopItem()->item.asLong.value; hb_stackTopItem()->type = HB_IT_NIL; + /* remove number of iterators */ hb_stackDec(); lVars = hb_stackTopItem()->item.asLong.value; hb_stackTopItem()->type = HB_IT_NIL; - --lVars; - for( i=lVars; i>=0; i-- ) + while( --lVars >= 0 ) { /* restore the value of variable before the FOREACH loop */ hb_itemMove( hb_itemUnRefOnce( hb_stackItemFromTop( -1 ) ), hb_stackItemFromTop( -2 ) ); hb_stackDec(); hb_stackPop(); } + return lOldBase; } @@ -3440,9 +3407,7 @@ static void hb_vmNot( void ) if( HB_IS_LOGICAL( pItem ) ) pItem->item.asLogical.value = ! pItem->item.asLogical.value; - else if( HB_IS_OBJECT( pItem ) && hb_objHasMsg( pItem, "__OpNot" ) ) - hb_vmOperatorCallUnary( pItem, "__OPNOT" ); - else + else if( ! hb_objOperatorCall( HB_OO_OP_NOT, pItem, pItem, NULL ) ) { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1077, NULL, ".NOT.", 1, pItem ); @@ -3471,8 +3436,9 @@ static void hb_vmAnd( void ) pItem2->type = HB_IT_NIL; hb_stackDec(); } - else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpAnd" ) ) - hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPAND" ); + else if( hb_objOperatorCall( HB_OO_OP_AND, pItem1, pItem1, pItem2 ) ) + hb_stackPop(); + else { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1078, NULL, ".AND.", 2, pItem1, pItem2 ); @@ -3503,8 +3469,9 @@ static void hb_vmOr( void ) pItem2->type = HB_IT_NIL; hb_stackDec(); } - else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpOr" ) ) - hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPOR" ); + else if( hb_objOperatorCall( HB_OO_OP_OR, pItem1, pItem1, pItem2 ) ) + hb_stackPop(); + else { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1079, NULL, ".OR.", 2, pItem1, pItem2 ); @@ -3572,17 +3539,19 @@ static void hb_vmArrayPush( void ) } /* #endif */ - if( HB_IS_OBJECT( pArray ) && hb_objHasMsg( pArray, "__OpArrayIndex" ) ) - { - hb_vmOperatorCall( pArray, pArray, pIndex, "__OPARRAYINDEX" ); - return; - } if( HB_IS_ARRAY( pArray ) ) { + if( HB_IS_OBJECT( pArray ) && + hb_objOperatorCall( HB_OO_OP_ARRAYINDEX, pArray, pArray, pIndex ) ) + { + hb_stackPop(); + return; + } + if( ulIndex > 0 && ulIndex <= pArray->item.asArray.value->ulLen ) { - if( pArray->item.asArray.value->ulHolders > 1 ) + if( hb_gcRefCount( pArray->item.asArray.value ) > 1 ) { /* this is a temporary copy of an array - we can overwrite * it with no problem @@ -3603,6 +3572,9 @@ static void hb_vmArrayPush( void ) else hb_errRT_BASE( EG_BOUND, 1132, NULL, hb_langDGetErrorDesc( EG_ARRACCESS ), 2, pArray, pIndex ); } + else if( hb_objOperatorCall( HB_OO_OP_ARRAYINDEX, pArray, pArray, pIndex ) ) + hb_stackPop(); + else hb_errRT_BASE( EG_ARG, 1068, NULL, hb_langDGetErrorDesc( EG_ARRACCESS ), 2, pArray, pIndex ); } @@ -3657,8 +3629,7 @@ static void hb_vmArrayPop( void ) hb_itemPutCL( pArray, hb_vm_acAscii[ ( BYTE ) hb_itemGetNI( pValue ) ], 1 ); else { - if( pArray->item.asString.bStatic || *( pArray->item.asString.u.pulHolders ) > 1 ) - hb_itemPutCL( pArray, pArray->item.asString.value, pArray->item.asString.length ); + hb_itemUnShareString( pArray ); pArray->item.asString.value[ ulIndex - 1 ] = hb_itemGetNI( pValue ); } @@ -3667,7 +3638,7 @@ static void hb_vmArrayPop( void ) hb_stackPop(); /* remove the value from the stack just like other POP operations */ } else - hb_errRT_BASE( EG_BOUND, 1132, NULL, hb_langDGetErrorDesc( EG_ARRACCESS ), + hb_errRT_BASE( EG_BOUND, 1133, NULL, hb_langDGetErrorDesc( EG_ARRACCESS ), 2, pArray, pIndex ); } /* #endif */ @@ -3768,74 +3739,6 @@ static void hb_vmArrayDim( USHORT uiDimensions ) /* generates an uiDimensions Ar hb_stackPush(); } -/* ------------------------------- */ -/* Object */ -/* ------------------------------- */ - -static void hb_vmOperatorCall( HB_ITEM_PTR pResult, PHB_ITEM pObjItem, PHB_ITEM pMsgItem, char * szSymbol ) -{ - /* NOTE: There is no need to test if specified symbol exists. It is checked - * by the caller (if HB_IS_OBJECT() && HAS_METHOD() ) - */ - PHB_ITEM pTop; - - HB_TRACE(HB_TR_DEBUG, ("hb_vmOperatorCall(%p, %p, %p, %s)", pResult, pObjItem, pMsgItem, szSymbol)); - - pTop = hb_stackTopItem(); - pTop->type = HB_IT_SYMBOL; - pTop->item.asSymbol.value = hb_dynsymFind( szSymbol )->pSymbol; - pTop->item.asSymbol.stackbase = hb_stackTopOffset(); - hb_stackPush(); - hb_vmPush( pObjItem ); /* Push object */ - hb_vmPush( pMsgItem ); /* Push argument */ - - if( HB_IS_COMPLEX( &hb_stack.Return ) ) - hb_itemClear( &hb_stack.Return ); - else - hb_stack.Return.type = HB_IT_NIL; - - hb_vmDo( 1 ); - - /* Push return value on the stack - * NOTE: for performance reason we don't pop the second argument. - * We can replace the second argument with the return value. - */ - hb_itemCopy( pResult, &hb_stack.Return ); - - /* pop passed arguments - only one here */ - hb_stackPop(); /* pMsgItem */ -} - -static void hb_vmOperatorCallUnary( PHB_ITEM pObjItem, char * szSymbol ) -{ - /* NOTE: There is no need to test if specified symbol exists. It is checked - * by the caller (if HB_IS_OBJECT() && HAS_METHOD() ) - */ - PHB_ITEM pTop; - - HB_TRACE(HB_TR_DEBUG, ("hb_vmOperatorCallUnary(%p, %s)", pObjItem, szSymbol)); - - pTop = hb_stackTopItem(); - pTop->type = HB_IT_SYMBOL; - pTop->item.asSymbol.value = hb_dynsymFind( szSymbol )->pSymbol; - pTop->item.asSymbol.stackbase = hb_stackTopOffset(); - hb_stackPush(); - hb_vmPush( pObjItem ); /* Push object */ - - if( HB_IS_COMPLEX( &hb_stack.Return ) ) - hb_itemClear( &hb_stack.Return ); - else - hb_stack.Return.type = HB_IT_NIL; - - hb_vmDo( 0 ); - - /* Pop passed argument. - * NOTE: for performance reason we don't pop it and we don't push the - * return value. We can replace the last element with the new value. - */ - hb_itemCopy( pObjItem, &hb_stack.Return ); -} - /* ------------------------------- */ /* Database */ /* ------------------------------- */ @@ -3954,15 +3857,16 @@ static void hb_vmSwapAlias( void ) HB_EXPORT void hb_vmDo( USHORT uiParams ) { - PHB_ITEM pItem; - PHB_SYMB pSym; HB_STACK_STATE sStackState; + PHB_SYMB pSym; PHB_ITEM pSelf; - PHB_FUNC pFunc; BOOL bDebugPrevState; + +#ifndef HB_NO_PROFILER ULONG ulClock = 0; void * pMethod = NULL; BOOL bProfiler = hb_bProfiler; /* because profiler state may change */ +#endif HB_TRACE(HB_TR_DEBUG, ("hb_vmDo(%hu)", uiParams)); @@ -3971,15 +3875,22 @@ HB_EXPORT void hb_vmDo( USHORT uiParams ) */ s_ulProcLevel++; - if( hb_vm_iExtraParamsIndex && - HB_IS_SYMBOL( pItem = hb_stackItemFromTop( -( uiParams + hb_vm_aiExtraParams[hb_vm_iExtraParamsIndex - 1] + 2 ) ) ) && - pItem->item.asSymbol.value == hb_vm_apExtraParamsSymbol[hb_vm_iExtraParamsIndex - 1] ) + if( hb_vm_iExtraParamsIndex ) { - uiParams += hb_vm_aiExtraParams[--hb_vm_iExtraParamsIndex]; + pSelf = hb_stackItemFromTop( -( uiParams + + hb_vm_aiExtraParams[hb_vm_iExtraParamsIndex - 1] + 2 ) ); + if( HB_IS_SYMBOL( pSelf ) && + pSelf->item.asSymbol.value == + hb_vm_apExtraParamsSymbol[hb_vm_iExtraParamsIndex - 1] ) + { + uiParams += hb_vm_aiExtraParams[--hb_vm_iExtraParamsIndex]; + } } +#ifndef HB_NO_PROFILER if( bProfiler ) ulClock = ( ULONG ) clock(); +#endif /* Poll the console keyboard #ifndef HB_GUI @@ -3987,92 +3898,37 @@ HB_EXPORT void hb_vmDo( USHORT uiParams ) #endif */ - pItem = hb_stackNewFrame( &sStackState, uiParams ); - pSym = pItem->item.asSymbol.value; + pSym = hb_stackNewFrame( &sStackState, uiParams )->item.asSymbol.value; pSelf = hb_stackSelfItem(); /* NIL, OBJECT or BLOCK */ bDebugPrevState = s_bDebugging; s_bDebugging = FALSE; if( ! HB_IS_NIL( pSelf ) ) /* are we sending a message ? */ { - BOOL lPopSuper = FALSE; - PHB_BASEARRAY pSelfBase = NULL; + PHB_SYMB pExecSym; + BOOL lPopSuper; - if( pSym == &hb_symEval && HB_IS_BLOCK( pSelf ) ) - pFunc = pSym->value.pFunPtr; /* __EVAL method = function */ - else - { - pFunc = hb_objGetMethod( pSelf, pSym ); - if( HB_IS_OBJECT( pSelf ) ) /* Object passed */ - { - pSelfBase = pSelf->item.asArray.value; - if( pSelfBase->uiPrevCls ) /* Is is a Super cast ? */ - { - PHB_ITEM pRealSelf; - USHORT nPos; - USHORT uiClass; - - /* - printf( "\n VmDo Method: %s \n", pSym->szName ); - */ - uiClass=pSelfBase->uiClass; - - pRealSelf = hb_itemNew( NULL ) ; - hb_itemCopy(pRealSelf ,pSelf->item.asArray.value->pItems) ; /* hb_arrayGetItemPtr(pSelf,1) ; */ - /* and take back the good pSelfBase */ - pSelfBase = pRealSelf->item.asArray.value; - /* Now I should exchnage it with the current stacked value */ - hb_itemSwap( pSelf, pRealSelf ); - hb_itemRelease(pRealSelf) ; /* and release the fake one */ - - /* Push current SuperClass handle */ - lPopSuper = TRUE ; - - if ( ! pSelf->item.asArray.value->puiClsTree) - { - pSelf->item.asArray.value->puiClsTree = ( USHORT * ) hb_xgrab( sizeof( USHORT ) ); - pSelf->item.asArray.value->puiClsTree[0]=0; - } - - nPos=pSelfBase->puiClsTree[0]+1; - pSelfBase->puiClsTree = ( USHORT * ) hb_xrealloc( pSelfBase->puiClsTree, sizeof( USHORT ) * ( nPos + 1 ) ); - - pSelfBase->puiClsTree[0] = nPos ; - pSelfBase->puiClsTree[ nPos ] = uiClass; - } - } - } - - if( pFunc ) + pExecSym = hb_objGetMethod( pSelf, pSym, &lPopSuper ); + if( pExecSym && pExecSym->value.pFunPtr ) { +#ifndef HB_NO_PROFILER if( bProfiler ) pMethod = hb_mthRequested(); +#endif + if( hb_bTracePrgCalls ) + HB_TRACE(HB_TR_ALWAYS, ("Calling: %s:%s", hb_objGetClsName( pSelf ), pSym->szName)); - if ( hb_bTracePrgCalls ) - HB_TRACE(HB_TR_ALWAYS, ("Calling: %s", pSym->szName)); - - pFunc(); - - if (lPopSuper && pSelfBase->puiClsTree) - { - - USHORT nPos=pSelfBase->puiClsTree[0]-1; - /* POP SuperClass handle */ - - if (nPos) - { - pSelfBase->puiClsTree = ( USHORT * ) hb_xrealloc( pSelfBase->puiClsTree, sizeof( USHORT ) * (nPos + 1) ); - pSelfBase->puiClsTree[0]=nPos; - } - else - { - hb_xfree(pSelfBase->puiClsTree); - pSelfBase->puiClsTree = NULL ; - } - } + if( pExecSym->scope.value & HB_FS_PCODEFUNC ) + /* Running pCode dynamic function from .HRB */ + hb_vmExecute( pExecSym->value.pCodeFunc->pCode, + pExecSym->value.pCodeFunc->pSymbols ); + else + pExecSym->value.pFunPtr(); +#ifndef HB_NO_PROFILER if( bProfiler ) hb_mthAddTime( pMethod, clock() - ulClock ); +#endif } else if( pSym->szName[ 0 ] == '_' ) { @@ -4084,38 +3940,37 @@ HB_EXPORT void hb_vmDo( USHORT uiParams ) hb_vmArrayGen( uiParams ); hb_errRT_BASE_SubstR( EG_NOMETHOD, 1004, NULL, pSym->szName, 1, hb_stackItemFromTop( -1 ) ); } + + if( lPopSuper ) + hb_objPopSuperCast( pSelf ); } else /* it is a function */ { - pFunc = pSym->value.pFunPtr; - - if( pFunc ) + if( pSym->value.pFunPtr ) { - if( bProfiler && pSym->pDynSym ) - { - pSym->pDynSym->ulRecurse++; - } - - if ( hb_bTracePrgCalls ) + if( hb_bTracePrgCalls ) HB_TRACE(HB_TR_ALWAYS, ("Calling: %s", pSym->szName)); - pFunc(); +#ifndef HB_NO_PROFILER + if( bProfiler && pSym->pDynSym ) + pSym->pDynSym->ulRecurse++; +#endif + /* Running pCode dynamic function from .HRB? */ + if( pSym->scope.value & HB_FS_PCODEFUNC ) + hb_vmExecute( pSym->value.pCodeFunc->pCode, + pSym->value.pCodeFunc->pSymbols ); + else + pSym->value.pFunPtr(); +#ifndef HB_NO_PROFILER if( bProfiler && pSym->pDynSym ) { pSym->pDynSym->ulCalls++; /* profiler support */ - /* Time spent has to be added only inside topmost call of a recursive function */ - if( pSym->pDynSym->ulRecurse == 1 ) - { + if( --pSym->pDynSym->ulRecurse == 0 ) pSym->pDynSym->ulTime += clock() - ulClock; /* profiler support */ - } - } - - if( bProfiler && pSym->pDynSym ) - { - pSym->pDynSym->ulRecurse--; } +#endif } else { @@ -4141,12 +3996,13 @@ HB_EXPORT void hb_vmSend( USHORT uiParams ) PHB_SYMB pSym; HB_STACK_STATE sStackState; PHB_ITEM pSelf; - PHB_FUNC pFunc = NULL; BOOL bDebugPrevState; + BOOL bNotHandled = TRUE; +#ifndef HB_NO_PROFILER ULONG ulClock = 0; void * pMethod = NULL; BOOL bProfiler = hb_bProfiler; /* because profiler state may change */ - BOOL bNotHandled = TRUE; +#endif HB_TRACE(HB_TR_DEBUG, ("hb_vmSend(%hu)", uiParams)); @@ -4162,8 +4018,10 @@ HB_EXPORT void hb_vmSend( USHORT uiParams ) uiParams += hb_vm_aiExtraParams[--hb_vm_iExtraParamsIndex]; } +#ifndef HB_NO_PROFILER if( bProfiler ) ulClock = ( ULONG ) clock(); +#endif /* Poll the console keyboard #ifndef HB_GUI @@ -4180,215 +4038,83 @@ HB_EXPORT void hb_vmSend( USHORT uiParams ) if( HB_IS_BYREF( pSelf ) ) { /* method of enumerator variable from FOR EACH statement - */ - HB_ITEM_PTR pRef; - - pRef = hb_itemUnRefRefer( pSelf ); - if( HB_IS_BYREF( pRef ) && pRef->item.asRefer.offset < 0 && pRef->item.asRefer.value >= 0 ) + */ + //HB_ITEM_PTR pEnum = hb_itemUnRefRefer( pSelf ); + HB_ITEM_PTR pEnum = hb_itemUnRefOnce( pSelf ); + + if( HB_IS_ENUM( pEnum ) ) { if( pSym->pDynSym == hb_symEnumIndex.pDynSym ) { - hb_itemPutNL( &hb_stack.Return, pRef->item.asRefer.value ); + hb_itemPutNL( &hb_stack.Return, pEnum->item.asEnum.offset ); bNotHandled = FALSE; } else if( pSym->pDynSym == hb_symEnumBase.pDynSym ) { - hb_itemCopy( &hb_stack.Return, pRef->item.asRefer.BasePtr.itemPtr ); + hb_itemCopy( &hb_stack.Return, pEnum->item.asEnum.basePtr ); bNotHandled = FALSE; } else if( pSym->pDynSym == hb_symEnumValue.pDynSym ) { - hb_itemCopy( &hb_stack.Return, hb_itemUnRefOnce( pRef ) ); + hb_itemCopy( &hb_stack.Return, hb_itemUnRefOnce( pEnum ) ); bNotHandled = FALSE; } } } - else if( HB_IS_NIL( pSelf ) ) /* are we sending a message ? */ - { - pFunc = pSym->value.pFunPtr; - - if( pFunc ) - { - if( bProfiler && pSym->pDynSym ) - { - pSym->pDynSym->ulRecurse++; - } - - if ( hb_bTracePrgCalls ) - HB_TRACE(HB_TR_ALWAYS, ("Calling: %s", pSym->szName)); - - pFunc(); - - if( bProfiler && pSym->pDynSym ) - { - pSym->pDynSym->ulCalls++; /* profiler support */ - - /* Time spent has to be added only inside topmost call of a recursive function */ - if( pSym->pDynSym->ulRecurse == 1 ) - { - pSym->pDynSym->ulTime += clock() - ulClock; /* profiler support */ - } - } - - if( bProfiler && pSym->pDynSym ) - { - pSym->pDynSym->ulRecurse--; - } - } - else - { - /* Attempt to call an undefined function - * - generate unrecoverable runtime error - */ - if( strncmp( pSym->szName, "CLASSNAME", strlen( pSym->szName ) ) == 0 ) - { - hb_itemPutC( &hb_stack.Return, "NIL" ); - } - else if( pSym->szName[ 0 ] == '_' ) - { - hb_vmArrayGen( uiParams ); - hb_errRT_BASE_SubstR( EG_NOVARMETHOD, 1005, "Class: NIL has no exported property", pSym->szName + 1, 1, hb_stackItemFromTop( -1 ) ); - } - else - { - hb_vmArrayGen( uiParams ); - hb_errRT_BASE_SubstR( EG_NOMETHOD, 1004, "Class: NIL has no exported method", pSym->szName, 1, hb_stackItemFromTop( -1 ) ); - } - } - - bNotHandled = FALSE; - } if( bNotHandled ) { - BOOL lPopSuper = FALSE; - PHB_BASEARRAY pSelfBase = NULL; + PHB_SYMB pExecSym; + BOOL lPopSuper; - if( HB_IS_BLOCK( pSelf ) ) - { - if( pSym == &( hb_symEval ) ) - { - pFunc = pSym->value.pFunPtr; /* __EVAL method = function */ - } - else if( strncmp( pSym->szName, "EVAL", 4 ) == 0 ) - { - pSym = &hb_symEval; - pFunc = pSym->value.pFunPtr; /* __EVAL method = function */ - } - } - else if( HB_IS_OBJECT( pSelf ) ) /* Object passed */ - { - pFunc = hb_objGetMethod( pSelf, pSym ); - pSelfBase = pSelf->item.asArray.value; - - if( pSelfBase->uiPrevCls ) /* Is is a Super cast ? */ - { - PHB_ITEM pRealSelf; - USHORT nPos; - USHORT uiClass; - - /* - printf( "\n VmSend Method: %s \n", pSym->szName ); - */ - uiClass = pSelfBase->uiClass; - - pRealSelf = hb_itemNew( NULL ) ; - hb_itemCopy( pRealSelf, pSelf->item.asArray.value->pItems ) ; /* hb_arrayGetItemPtr(pSelf,1) ; */ - /* and take back the good pSelfBase */ - pSelfBase = pRealSelf->item.asArray.value; - /* Now I should exchnage it with the current stacked value */ - hb_itemSwap( pSelf, pRealSelf ); - hb_itemRelease( pRealSelf ) ; /* and release the fake one */ - - /* Push current SuperClass handle */ - lPopSuper = TRUE; - - if ( ! pSelf->item.asArray.value->puiClsTree ) - { - pSelf->item.asArray.value->puiClsTree = ( USHORT * ) hb_xgrab( sizeof( USHORT ) ); - pSelf->item.asArray.value->puiClsTree[0]=0; - } - - nPos=pSelfBase->puiClsTree[0]+1; - pSelfBase->puiClsTree = ( USHORT * ) hb_xrealloc( pSelfBase->puiClsTree, sizeof( USHORT ) * (nPos+1) ) ; - pSelfBase->puiClsTree[0] = nPos ; - pSelfBase->puiClsTree[ nPos ] = uiClass; - } - } - - if( pFunc ) + pExecSym = hb_objGetMethod( pSelf, pSym, &lPopSuper ); + if( pExecSym && pExecSym->value.pFunPtr ) { +#ifndef HB_NO_PROFILER if( bProfiler ) - { pMethod = hb_mthRequested(); - } +#endif + if( hb_bTracePrgCalls ) + HB_TRACE(HB_TR_ALWAYS, ("Calling: %s:%s", hb_objGetClsName( pSelf ), pSym->szName)); - if ( hb_bTracePrgCalls ) - { - HB_TRACE(HB_TR_ALWAYS, ("Calling: %s", pSym->szName)); - } - - pFunc(); - - if ( pSym != &hb_symEval && lPopSuper && pSelfBase->puiClsTree ) - { - USHORT nPos=pSelfBase->puiClsTree[0] - 1; - - /* POP SuperClass handle */ - if (nPos) - { - pSelfBase->puiClsTree = ( USHORT * ) hb_xrealloc( pSelfBase->puiClsTree, sizeof( USHORT ) * (nPos + 1) ); - pSelfBase->puiClsTree[0]=nPos; - } - else - { - hb_xfree(pSelfBase->puiClsTree); - pSelfBase->puiClsTree = NULL ; - } - } + if( pExecSym->scope.value & HB_FS_PCODEFUNC ) + /* Running pCode dynamic function from .HRB */ + hb_vmExecute( pExecSym->value.pCodeFunc->pCode, + pExecSym->value.pCodeFunc->pSymbols ); + else + pExecSym->value.pFunPtr(); +#ifndef HB_NO_PROFILER if( bProfiler ) - { hb_mthAddTime( pMethod, clock() - ulClock ); - } +#endif } else { - char *sClass = hb_objGetClsName( pSelf ); + char sDesc[128]; - if( strncmp( pSym->szName, "CLASSNAME", strlen( pSym->szName ) < 4 ? 4 : strlen( pSym->szName ) ) == 0 ) + if( pSym->szName[ 0 ] == '_' ) { - hb_itemPutC( &hb_stack.Return, sClass ); - } - else if( strncmp( pSym->szName, "CLASSH", 6 ) == 0 ) - { - hb_itemPutNI( &hb_stack.Return, 0 ); + sprintf( (char *) sDesc, "Class: '%s' has no property", hb_objGetClsName( pSelf ) ); + hb_vmArrayGen( uiParams ); + hb_errRT_BASE_SubstR( EG_NOVARMETHOD, 1005, (char *) sDesc, pSym->szName + 1, 1, hb_stackItemFromTop( -1 ) ); } else { - char sDesc[128]; - - if( pSym->szName[ 0 ] == '_' ) - { - sprintf( (char *) sDesc, "Class: '%s' has no property", sClass ); - hb_vmArrayGen( uiParams ); - hb_errRT_BASE_SubstR( EG_NOVARMETHOD, 1005, (char *) sDesc, pSym->szName + 1, 1, hb_stackItemFromTop( -1 ) ); - } - else - { - sprintf( (char *) sDesc, "Class: '%s' has no exported method", sClass ); - hb_vmArrayGen( uiParams ); - hb_errRT_BASE_SubstR( EG_NOMETHOD, 1004, (char *) sDesc, pSym->szName, 1, hb_stackItemFromTop( -1 ) ); - } + sprintf( (char *) sDesc, "Class: '%s' has no exported method", hb_objGetClsName( pSelf ) ); + hb_vmArrayGen( uiParams ); + hb_errRT_BASE_SubstR( EG_NOMETHOD, 1004, (char *) sDesc, pSym->szName, 1, hb_stackItemFromTop( -1 ) ); } } + + if( lPopSuper ) + hb_objPopSuperCast( pSelf ); } if( s_bDebugging ) hb_vmDebuggerEndProc(); hb_stackOldFrame( &sStackState ); - s_bDebugging = bDebugPrevState; s_ulProcLevel--; } @@ -4410,18 +4136,18 @@ static HARBOUR hb_vmDoBlock( void ) iParam = pBlock->item.asBlock.paramcnt - hb_pcount(); /* add missing parameters */ - while( iParam-- > 0 ) + while( --iParam >= 0 ) hb_vmPushNil(); /* set the current line number to a line where the codeblock was defined */ - uiLine = ( hb_stackBaseItem() )->item.asSymbol.lineno; - ( hb_stackBaseItem() )->item.asSymbol.lineno = pBlock->item.asBlock.lineno; + uiLine = hb_stackBaseItem()->item.asSymbol.lineno; + hb_stackBaseItem()->item.asSymbol.lineno = pBlock->item.asBlock.lineno; hb_codeblockEvaluate( pBlock ); /* restore stack pointers */ - ( hb_stackBaseItem() )->item.asSymbol.lineno = uiLine; + hb_stackBaseItem()->item.asSymbol.lineno = uiLine; } /* Evaluates a passed codeblock item with no arguments passed to a codeblock @@ -4484,12 +4210,11 @@ HB_EXPORT PHB_ITEM hb_vmEvalBlockOrMacro( PHB_ITEM pItem ) if( pMacro ) { hb_macroRun( pMacro ); - hb_itemForwardValue( hb_stackReturnItem(), hb_stackItemFromTop( - 1 ) ); - hb_stackPop(); + hb_stackPopReturn(); } else { - hb_itemClear( hb_stackReturnItem() ); + hb_itemSetNil( hb_stackReturnItem() ); } } return hb_stackReturnItem(); @@ -4517,10 +4242,8 @@ void hb_vmFunction( USHORT uiParams ) { HB_TRACE(HB_TR_DEBUG, ("hb_vmFunction(%hu)", uiParams)); - hb_itemClear( &hb_stack.Return ); + hb_itemSetNil( hb_stackReturnItem() ); hb_vmDo( uiParams ); - hb_itemCopy( hb_stackTopItem(), &hb_stack.Return ); - hb_stackPush(); } static void hb_vmLocalName( USHORT uiLocal, char * szLocalName ) /* locals and parameters index and name information for the debugger */ @@ -4628,47 +4351,39 @@ static void hb_vmStatics( PHB_SYMB pSym, USHORT uiStatics ) /* initializes the g else { pSym->value.iStaticsBase = hb_arrayLen( &s_aStatics ); - hb_arraySize( &s_aStatics, hb_arrayLen( &s_aStatics ) + uiStatics ); + hb_arraySize( &s_aStatics, ( ULONG ) pSym->value.iStaticsBase + uiStatics ); } - - s_uiStatics = uiStatics; /* We need s_uiStatics for processing hb_vmStaticName() */ } static void hb_vmEndBlock( void ) { HB_TRACE(HB_TR_DEBUG, ("hb_vmEndBlock()")); - hb_stackDec(); /* make the last item visible */ - hb_itemMove( &hb_stack.Return, hb_stackTopItem() ); /* copy it */ + hb_stackPopReturn(); } static void hb_vmRetValue( void ) { HB_TRACE(HB_TR_DEBUG, ("hb_vmRetValue()")); - hb_stackDec(); /* make the last item visible */ - hb_itemMove( &hb_stack.Return, hb_stackTopItem() ); /* copy it */ + hb_stackPopReturn(); } static void hb_vmDebuggerEndProc( void ) { - PHB_ITEM pReturn; - HB_TRACE(HB_TR_DEBUG, ("hb_vmDebuggerEndProc()")); s_bDebugShowLines = FALSE; s_bDebuggerIsWorking = TRUE; - pReturn = hb_stackTopItem(); - hb_stackPush(); - hb_itemMove( pReturn, &hb_stack.Return ); /* saves the previous returned value */ + hb_stackPushReturn(); /* saves the previous returned value */ hb_vmPushSymbol( s_pDynsDbgEntry->pSymbol ); hb_vmPushNil(); hb_vmPushLongConst( HB_DBG_ENDPROC ); hb_vmDo( 1 ); - hb_itemMove( &hb_stack.Return, pReturn ); /* restores the previous returned value */ + hb_stackPopReturn(); /* restores the previous returned value */ s_bDebuggerIsWorking = FALSE; s_bDebugShowLines = TRUE; @@ -4708,8 +4423,7 @@ HB_EXPORT void hb_vmPushState( void ) /* Save top item which can be processed at this moment */ hb_stackPush(); - hb_itemMove( hb_stackTopItem(), hb_stackReturnItem() ); - hb_stackPush(); + hb_stackPushReturn(); } HB_EXPORT void hb_vmPushNil( void ) @@ -4929,41 +4643,19 @@ HB_EXPORT void hb_vmPushPointer( void * pPointer ) pStackTopItem->type = HB_IT_POINTER; pStackTopItem->item.asPointer.value = pPointer; + pStackTopItem->item.asPointer.collect = FALSE; hb_stackPush(); } HB_EXPORT void hb_vmPushString( char * szText, ULONG length ) { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pStackTopItem; HB_TRACE(HB_TR_DEBUG, ("hb_vmPushString(%s, %lu)", szText, length)); - pStackTopItem->type = HB_IT_STRING; - pStackTopItem->item.asString.length = length; - if( length == 0 ) - { - pStackTopItem->item.asString.length = 0; - pStackTopItem->item.asString.value = hb_vm_sNull; - pStackTopItem->item.asString.bStatic = -1; - } - else if( length == 1 ) - { - pStackTopItem->item.asString.length = 1; - pStackTopItem->item.asString.value = hb_vm_acAscii[ (unsigned char) ( szText[0] ) ]; - pStackTopItem->item.asString.bStatic = -1; - } - else - { - char * szTemp = ( char * ) hb_xgrab( length + 1 ); - hb_xmemcpy( szTemp, szText, length ); - szTemp[ length ] = '\0'; - - pStackTopItem->item.asString.value = szTemp; - pStackTopItem->item.asString.bStatic = 0; - pStackTopItem->item.asString.u.pulHolders = ( HB_COUNTER * ) hb_xgrab( sizeof( HB_COUNTER ) ); - *( pStackTopItem->item.asString.u.pulHolders ) = 1; - } + pStackTopItem = hb_stackTopItem(); hb_stackPush(); + hb_itemPutCL( pStackTopItem, szText, length ); } HB_EXPORT void hb_vmPushStringPcode( char * szText, ULONG length ) @@ -4973,9 +4665,9 @@ HB_EXPORT void hb_vmPushStringPcode( char * szText, ULONG length ) HB_TRACE(HB_TR_DEBUG, ("hb_vmPushStringPcode(%s, %lu)", szText, length)); pStackTopItem->type = HB_IT_STRING; - pStackTopItem->item.asString.length = length; - pStackTopItem->item.asString.value = szText; - pStackTopItem->item.asString.bStatic = 1; + pStackTopItem->item.asString.length = length; + pStackTopItem->item.asString.allocated = 0; + pStackTopItem->item.asString.value = szText; hb_stackPush(); } @@ -4999,21 +4691,26 @@ HB_EXPORT void hb_vmPushSymbol( PHB_SYMB pSym ) * * NOTE: pCode points to static memory */ -static void hb_vmPushBlock( const BYTE * pCode, PHB_SYMB pSymbols ) +static void hb_vmPushBlock( const BYTE * pCode, PHB_SYMB pSymbols, USHORT usLen ) { USHORT uiLocals; PHB_ITEM pStackTopItem = hb_stackTopItem(); - HB_TRACE(HB_TR_DEBUG, ("hb_vmPushBlock(%p, %p)", pCode, pSymbols)); + HB_TRACE(HB_TR_DEBUG, ("hb_vmPushBlock(%p,%p,%hu)", pCode, pSymbols, usLen)); pStackTopItem->type = HB_IT_BLOCK; uiLocals = HB_PCODE_MKUSHORT( &pCode[ 2 ] ); + + if( usLen ) + usLen -= uiLocals << 1; + pStackTopItem->item.asBlock.value = - hb_codeblockNew( pCode + 4 + uiLocals * 2, /* pcode buffer */ - uiLocals, /* number of referenced local variables */ - pCode + 4, /* table with referenced local variables */ - pSymbols ); + hb_codeblockNew( pCode + 4 + ( uiLocals << 1 ),/* pcode buffer */ + uiLocals, /* number of referenced local variables */ + pCode + 4, /* table with referenced local variables */ + pSymbols, + usLen ); /* store the statics base of function where the codeblock was defined */ @@ -5033,11 +4730,11 @@ static void hb_vmPushBlock( const BYTE * pCode, PHB_SYMB pSymbols ) * * NOTE: pCode points to static memory */ -static void hb_vmPushBlockShort( const BYTE * pCode, PHB_SYMB pSymbols ) +static void hb_vmPushBlockShort( const BYTE * pCode, PHB_SYMB pSymbols, USHORT usLen ) { PHB_ITEM pStackTopItem = hb_stackTopItem(); - HB_TRACE(HB_TR_DEBUG, ("hb_vmPushBlockShort(%p, %p)", pCode, pSymbols)); + HB_TRACE(HB_TR_DEBUG, ("hb_vmPushBlockShort(%p,%p,%hu)", pCode, pSymbols, usLen)); pStackTopItem->type = HB_IT_BLOCK; @@ -5045,7 +4742,8 @@ static void hb_vmPushBlockShort( const BYTE * pCode, PHB_SYMB pSymbols ) hb_codeblockNew( pCode, /* pcode buffer */ 0, /* number of referenced local variables */ NULL, /* table with referenced local variables */ - pSymbols ); + pSymbols, + usLen ); /* store the statics base of function where the codeblock was defined */ @@ -5340,8 +5038,7 @@ HB_EXPORT void hb_vmPopState( void ) { HB_TRACE_STEALTH( HB_TR_DEBUG, ( "hb_vmPopState()" ) ); - hb_itemMove( hb_stackReturnItem(), hb_stackItemFromTop( -1 ) ); - hb_stackDec(); + hb_stackPopReturn(); /* Restore top item */ hb_stackDec(); @@ -5355,8 +5052,8 @@ static BOOL hb_vmPopLogical( void ) { hb_stackDec(); - ( hb_stackTopItem() )->type = HB_IT_NIL; - return ( hb_stackTopItem() )->item.asLogical.value; + hb_stackTopItem()->type = HB_IT_NIL; + return hb_stackTopItem()->item.asLogical.value; } else { @@ -5407,8 +5104,7 @@ static double hb_vmPopNumber( void ) default: hb_errInternal( HB_EI_VMPOPINVITEM, NULL, "hb_vmPopNumber()", NULL ); - dNumber = 0; /* To avoid GCC -O2 warning */ - break; + return 0.0; /* To avoid GCC -O2 warning */ } pItem->type = HB_IT_NIL; @@ -5443,9 +5139,8 @@ static HB_LONG hb_vmPopHBLong( void ) break; default: - lNumber = 0; /* To avoid GCC -O2 warning */ hb_errInternal( HB_EI_VMPOPINVITEM, NULL, "hb_vmPopNumber()", NULL ); - break; + return 0; /* To avoid GCC -O2 warning */ } pItem->type = HB_IT_NIL; @@ -5483,10 +5178,9 @@ static double hb_vmPopDouble( int * piDec ) break; default: - dNumber = 0; /* To avoid GCC -O2 warning */ - *piDec = 0; /* To avoid GCC -O3 warning */ hb_errInternal( HB_EI_VMPOPINVITEM, NULL, "hb_vmPopDouble()", NULL ); - break; + *piDec = 0; /* To avoid GCC -O3 warning */ + return 0.0; /* To avoid GCC -O2 warning */ } pItem->type = HB_IT_NIL; @@ -5607,9 +5301,10 @@ static void hb_vmPopLocal( SHORT iLocal ) pLocal = hb_codeblockGetVar( hb_stackSelfItem(), iLocal ); } - if( HB_IS_OBJECT( pLocal ) && hb_objHasMsg( pLocal, "__OpAssign" ) ) + if( HB_IS_OBJECT( pLocal ) && + hb_objOperatorCall( HB_OO_OP_ASSIGN, pLocal, pLocal, pVal ) ) { - hb_vmOperatorCall( pLocal, pLocal, pVal, "__OPASSIGN" ); + hb_stackPop(); return; } @@ -5633,9 +5328,10 @@ static void hb_vmPopStatic( USHORT uiStatic ) if( HB_IS_BYREF( pStatic ) ) pStatic = hb_itemUnRef( pStatic ); - if( HB_IS_OBJECT( pStatic ) && hb_objHasMsg( pStatic, "__OpAssign" ) ) + if( HB_IS_OBJECT( pStatic ) && + hb_objOperatorCall( HB_OO_OP_ASSIGN, pStatic, pStatic, pVal ) ) { - hb_vmOperatorCall( pStatic, pStatic, pVal, "__OPASSIGN" ); + hb_stackPop(); return; } @@ -5679,103 +5375,422 @@ static double hb_vmTopNumber( void ) /* ----------------------------------------------- */ - -HB_EXPORT void hb_vmProcessSymbols( PHB_SYMB pModuleSymbols, USHORT uiModuleSymbols ) /* module symbols initialization */ +/* + * Functions to mange module symbols + */ +static PHB_SYMBOLS hb_vmFindFreeModule( PHB_SYMB pSymbols, USHORT uiSymbols, + char * szModuleName, ULONG ulID ) { - PSYMBOLS pNewSymbols; - USHORT ui; + PHB_SYMBOLS pLastSymbols = s_pSymbols; - HB_TRACE(HB_TR_DEBUG, ("hb_vmProcessSymbols(%p, %hu)", pModuleSymbols, uiModuleSymbols)); + HB_TRACE(HB_TR_DEBUG, ("hb_vmFindFreeModule(%p,%hu,%s,%lu)", pSymbols, uiSymbols, szModuleName, ulID)); - pNewSymbols = ( PSYMBOLS ) hb_xgrab( sizeof( SYMBOLS ) ); - pNewSymbols->pModuleSymbols = pModuleSymbols; - pNewSymbols->uiModuleSymbols = uiModuleSymbols; - pNewSymbols->pNext = NULL; - pNewSymbols->hScope = 0; - - if( s_pSymbols == NULL ) - s_pSymbols = pNewSymbols; - else + if( s_ulFreeSymbols ) { - PSYMBOLS pLastSymbols; + while( pLastSymbols ) + { + if( !pLastSymbols->fActive && + pLastSymbols->ulID == ulID && + pLastSymbols->uiModuleSymbols == uiSymbols && + pLastSymbols->szModuleName != NULL && + strcmp( pLastSymbols->szModuleName, szModuleName ) == 0 ) + { + PHB_SYMB pModuleSymbols = pLastSymbols->pModuleSymbols; + USHORT ui; - pLastSymbols = s_pSymbols; - while( pLastSymbols->pNext ) /* locates the latest processed group of symbols */ + for( ui = 0; ui < uiSymbols; ++ui ) + { + if( ( pSymbols[ ui ].scope.value & ~( HB_FS_PCODEFUNC | HB_FS_DYNCODE ) ) != + pModuleSymbols[ ui ].scope.value || + strcmp( pSymbols[ ui ].szName, pModuleSymbols[ ui ].szName ) != 0 ) + { + break; + } + } + if( ui == uiSymbols ) + { + --s_ulFreeSymbols; + return pLastSymbols; + } + } pLastSymbols = pLastSymbols->pNext; - - pLastSymbols->pNext = pNewSymbols; + } } - for( ui = 0; ui < uiModuleSymbols; ui++ ) /* register each public symbol on the dynamic symbol table */ + return NULL; +} + +void hb_vmFreeSymbols( PHB_SYMBOLS pSymbols ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_vmFreeSymbols(%p)", pSymbols)); + + if( pSymbols->fActive ) { - HB_SYMBOLSCOPE hSymScope; + USHORT ui; - hSymScope = ( pModuleSymbols + ui )->scope.value; - pNewSymbols->hScope |= hSymScope; - if( ( ! s_pSymStart ) && ( hSymScope & HB_FS_FIRST && ! ( hSymScope & HB_FS_INITEXIT ) ) ) - s_pSymStart = pModuleSymbols + ui; /* first public defined symbol to start execution */ + for( ui = 0; ui < pSymbols->uiModuleSymbols; ++ui ) + { + HB_SYMBOLSCOPE scope = pSymbols->pModuleSymbols[ ui ].scope.value & HB_FS_INITEXIT; - if( hSymScope & ( HB_FS_PUBLIC | HB_FS_MESSAGE | HB_FS_MEMVAR | HB_FS_FIRST ) ) - hb_dynsymNew( pModuleSymbols + ui ); + /* do not overwrite already initialized statics' frame */ + if( scope != HB_FS_INITEXIT ) + { + pSymbols->pModuleSymbols[ ui ].value.pFunPtr = NULL; + } + pSymbols->pModuleSymbols[ ui ].scope.value &= ~( HB_FS_PCODEFUNC | HB_FS_DYNCODE ); + } + pSymbols->hDynLib = NULL; + pSymbols->fActive = FALSE; + ++s_ulFreeSymbols; } } -/* hvm support for pcode DLLs */ -HB_EXPORT void hb_vmProcessDllSymbols( PHB_SYMB pModuleSymbols, USHORT uiModuleSymbols ) +void hb_vmBeginSymbolGroup( void * hDynLib, BOOL fClone ) { - PSYMBOLS pNewSymbols; - USHORT ui; + HB_TRACE(HB_TR_DEBUG, ("hb_vmBeginSymbolGroup(%p,%d)", hDynLib, (int)fClone)); - HB_TRACE(HB_TR_DEBUG, ("hb_vmProcessDllSymbols(%p, %hu)", pModuleSymbols, uiModuleSymbols)); + s_hDynLibID = hDynLib; + s_fCloneSym = fClone; +} - pNewSymbols = ( PSYMBOLS ) hb_xgrab( sizeof( SYMBOLS ) ); - pNewSymbols->pModuleSymbols = pModuleSymbols; - pNewSymbols->uiModuleSymbols = uiModuleSymbols; - pNewSymbols->pNext = NULL; - pNewSymbols->hScope = 0; +void hb_vmInitSymbolGroup( void * hNewDynLib, int argc, char * argv[] ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_vmInitSymbolGroup(%p,%d,%p)", hNewDynLib, argc, argv)); - if( s_pSymbols == NULL ) - s_pSymbols = pNewSymbols; - else + s_fCloneSym = FALSE; + + if( s_hDynLibID ) { - PSYMBOLS pLastSymbols; + PHB_SYMBOLS pLastSymbols = s_pSymbols; + void * hDynLib = s_hDynLibID; + BOOL fFound = FALSE; + USHORT ui; - pLastSymbols = s_pSymbols; - while( pLastSymbols->pNext ) /* locates the latest processed group of symbols */ - pLastSymbols = pLastSymbols->pNext; + s_hDynLibID = NULL; - pLastSymbols->pNext = pNewSymbols; - } - - for( ui = 0; ui < uiModuleSymbols; ui++ ) /* register each public symbol on the dynamic symbol table */ - { - HB_SYMBOLSCOPE hSymScope; - - hSymScope = ( pModuleSymbols + ui )->scope.value; - pNewSymbols->hScope |= hSymScope; - - if( ( hSymScope == HB_FS_PUBLIC ) || ( hSymScope & ( HB_FS_MESSAGE | HB_FS_MEMVAR | HB_FS_FIRST ) ) ) + while( pLastSymbols ) { - PHB_DYNS pDynSym = hb_dynsymFind( ( pModuleSymbols + ui )->szName ); + if( pLastSymbols->hDynLib == hDynLib ) + { + fFound = TRUE; - if( pDynSym && pDynSym->pFunPtr && ( pModuleSymbols + ui )->value.pFunPtr ) - ( pModuleSymbols + ui )->value.pFunPtr = pDynSym->pFunPtr; - else - hb_dynsymNew( ( pModuleSymbols + ui ) ); + if( pLastSymbols->fInitStatics && pLastSymbols->fActive ) + { + for( ui = 0; ui < pLastSymbols->uiModuleSymbols; ui++ ) + { + HB_SYMBOLSCOPE scope = ( pLastSymbols->pModuleSymbols + ui )->scope.value & HB_FS_INITEXIT; + + if( scope == HB_FS_INITEXIT ) + { + hb_vmPushSymbol( pLastSymbols->pModuleSymbols + ui ); + hb_vmPushNil(); + hb_vmDo( 0 ); + } + } + pLastSymbols->fInitStatics = FALSE; + } + + pLastSymbols->hDynLib = hNewDynLib; + } + pLastSymbols = pLastSymbols->pNext; + } + + if( fFound ) + { + pLastSymbols = s_pSymbols; + while( pLastSymbols ) + { + if( pLastSymbols->hDynLib == hNewDynLib ) + { + if( pLastSymbols->fActive && ( pLastSymbols->hScope & HB_FS_INIT ) != 0 ) + { + for( ui = 0; ui < pLastSymbols->uiModuleSymbols; ui++ ) + { + HB_SYMBOLSCOPE scope = ( pLastSymbols->pModuleSymbols + ui )->scope.value & HB_FS_INITEXIT; + + if( scope == HB_FS_INIT ) + { + int i; + hb_vmPushSymbol( pLastSymbols->pModuleSymbols + ui ); + hb_vmPushNil(); + for( i = 0; i < argc; ++i ) + { + hb_vmPushString( argv[i], strlen( argv[i] ) ); + } + hb_vmDo( argc ); + } + } + } + } + pLastSymbols = pLastSymbols->pNext; + } } } } +void hb_vmExitSymbolGroup( void * hDynLib ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_vmExitSymbolGroup(%p)", hDynLib)); + + if( hDynLib ) + { + PHB_SYMBOLS pLastSymbols = s_pSymbols; + BOOL fFound = FALSE; + + while( pLastSymbols ) + { + if( pLastSymbols->hDynLib == hDynLib ) + { + fFound = TRUE; + if( pLastSymbols->fActive && ( pLastSymbols->hScope & HB_FS_EXIT ) != 0 ) + { + USHORT ui; + for( ui = 0; ui < pLastSymbols->uiModuleSymbols; ui++ ) + { + HB_SYMBOLSCOPE scope = ( pLastSymbols->pModuleSymbols + ui )->scope.value & HB_FS_INITEXIT; + + if( scope == HB_FS_EXIT ) + { + hb_vmPushSymbol( pLastSymbols->pModuleSymbols + ui ); + hb_vmPushNil(); + hb_vmDo( 0 ); + } + } + } + } + pLastSymbols = pLastSymbols->pNext; + } + + if( fFound ) + { + pLastSymbols = s_pSymbols; + while( pLastSymbols ) + { + if( pLastSymbols->hDynLib == hDynLib ) + { + hb_vmFreeSymbols( pLastSymbols ); + } + pLastSymbols = pLastSymbols->pNext; + } + } + } +} + +PHB_SYMBOLS +hb_vmRegisterSymbols( PHB_SYMB pModuleSymbols, USHORT uiSymbols, char * szModuleName, ULONG ulID, BOOL fDynLib, BOOL fClone ) +{ + PHB_SYMBOLS pNewSymbols; + BOOL fRecycled, fInitStatics = FALSE; + USHORT ui; + + HB_TRACE(HB_TR_DEBUG, ("hb_vmRegisterSymbols(%p,%hu,%s,%lu,%d,%d)", pModuleSymbols, uiSymbols, szModuleName, ulID, (int)fDynLib, (int)fClone)); + + pNewSymbols = s_ulFreeSymbols == 0 ? NULL : + hb_vmFindFreeModule( pModuleSymbols, uiSymbols, szModuleName, ulID ); + + if( pNewSymbols ) + { + pNewSymbols->fActive = fRecycled = TRUE; + pNewSymbols->hDynLib = s_hDynLibID; + pNewSymbols->hScope = 0; + } + else + { + fRecycled = FALSE; + + if( fClone ) + { + PHB_SYMB pSymbols = ( PHB_SYMB ) hb_xgrab( uiSymbols * sizeof( HB_SYMB ) ); + memcpy( pSymbols, pModuleSymbols, uiSymbols * sizeof( HB_SYMB ) ); + for( ui = 0; ui < uiSymbols; ui++ ) + { + pSymbols[ ui ].szName = hb_strdup( pSymbols[ ui ].szName ); + } + pModuleSymbols = pSymbols; + } + + pNewSymbols = ( PHB_SYMBOLS ) hb_xgrab( sizeof( HB_SYMBOLS ) ); + pNewSymbols->pModuleSymbols = pModuleSymbols; + pNewSymbols->uiModuleSymbols = uiSymbols; + pNewSymbols->szModuleName = hb_strdup( szModuleName ); + pNewSymbols->ulID = ulID; + pNewSymbols->fAllocated = fClone; + pNewSymbols->fActive = TRUE; + pNewSymbols->fInitStatics = FALSE; + pNewSymbols->hDynLib = s_hDynLibID; + pNewSymbols->hScope = 0; + pNewSymbols->pNext = NULL; + + if( s_pSymbols == NULL ) + { + s_pSymbols = pNewSymbols; + } + else + { + PHB_SYMBOLS pLastSymbols; + + pLastSymbols = s_pSymbols; + while( pLastSymbols->pNext ) /* locates the latest processed group of symbols */ + { + pLastSymbols = pLastSymbols->pNext; + } + pLastSymbols->pNext = pNewSymbols; + } + } + + for( ui = 0; ui < uiSymbols; ui++ ) /* register each public symbol on the dynamic symbol table */ + { + PHB_SYMB pSymbol = pNewSymbols->pModuleSymbols + ui; + HB_SYMBOLSCOPE hSymScope; + BOOL fPublic, fStatics; + + fStatics = ( pSymbol->scope.value & HB_FS_INITEXIT ) == HB_FS_INITEXIT; + + if( fRecycled && !fStatics ) + { + pSymbol->value.pFunPtr = ( pModuleSymbols + ui )->value.pFunPtr; + pSymbol->scope.value = ( pModuleSymbols + ui )->scope.value; + } + if( fDynLib ) + { + pSymbol->scope.value |= HB_FS_DYNCODE; + } + + hSymScope = pSymbol->scope.value; + pNewSymbols->hScope |= hSymScope; + fPublic = ( hSymScope & ( HB_FS_PUBLIC | HB_FS_MESSAGE | HB_FS_MEMVAR ) ) != 0; + if( fStatics ) + { + fInitStatics = TRUE; + } + + if( ( hSymScope & HB_FS_PCODEFUNC ) != 0 && ( fRecycled || fClone ) ) + { + pSymbol->value.pCodeFunc->pSymbols = pNewSymbols->pModuleSymbols; + } + + if( !s_pSymStart && !fDynLib && + ( hSymScope & HB_FS_FIRST ) != 0 && + ( hSymScope & HB_FS_INITEXIT ) == 0 ) + { + /* first public defined symbol to start execution */ + s_pSymStart = pSymbol; + } + + /* Enable this code to see static functions which are registered in global dynsym table */ +#if 0 + if( fPublic && ( hSymScope & ( HB_FS_INITEXIT | HB_FS_STATIC ) ) != 0 ) + { + printf("Registring: %s:%s scope %04x\r\n", szModuleName, pSymbol->szName, hSymScope ); fflush(stdout); + } +#endif + + if( fPublic ) + { + if( fDynLib && pSymbol->value.pFunPtr ) + { + PHB_DYNS pDynSym; + + pDynSym = hb_dynsymFind( pSymbol->szName ); + + if( pDynSym ) + { + pSymbol->pDynSym = pDynSym; + if( pDynSym->pSymbol->value.pFunPtr ) + { + pSymbol->scope.value = + ( pSymbol->scope.value & ~HB_FS_PCODEFUNC ) | + ( pDynSym->pSymbol->scope.value & HB_FS_PCODEFUNC ); + pSymbol->value.pFunPtr = pDynSym->pSymbol->value.pFunPtr; + } + else + { + pDynSym->pSymbol = pSymbol; + } + continue; + } + } + + hb_dynsymNew( pSymbol ); + } + } + + if( !fRecycled ) + { + pNewSymbols->fInitStatics = fInitStatics; + } + + return pNewSymbols; +} + +/* + * module symbols initialization with extended information + */ +HB_EXPORT PHB_SYMB hb_vmProcessSymbolsExt( PHB_SYMB pSymbols, USHORT uiModuleSymbols, + char * szModuleName, ULONG ulID, + USHORT uiPcodeMin, USHORT uiPcodeMax ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_vmProcessSymbols(%p,%hu,%s,%lu,%hu,%hu)", pSymbols, uiModuleSymbols, szModuleName, ulID, uiPcodeMin, uiPcodeMax)); + + /* TODO: verify suported PCODE versions */ + HB_SYMBOL_UNUSED( uiPcodeMin ); + HB_SYMBOL_UNUSED( uiPcodeMax ); + + return hb_vmRegisterSymbols( pSymbols, uiModuleSymbols, szModuleName, ulID, + s_fCloneSym, s_fCloneSym )->pModuleSymbols; +} + +/* + * old module symbols initialization - do not use it. + */ +HB_EXPORT PHB_SYMB hb_vmProcessSymbols( PHB_SYMB pSymbols, USHORT uiSymbols ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_vmProcessSymbols(%p,%hu)", pSymbols, uiSymbols)); + + return hb_vmRegisterSymbols( pSymbols, uiSymbols, "", 0L, + s_fCloneSym, s_fCloneSym )->pModuleSymbols; +} + +/* + * old function - do not use it. + */ +HB_EXPORT PHB_SYMB hb_vmProcessDllSymbols( PHB_SYMB pSymbols, USHORT uiModuleSymbols ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_vmProcessDllSymbols(%p,%hu)", pSymbols, uiModuleSymbols)); + + return hb_vmRegisterSymbols( pSymbols, uiModuleSymbols, "", 0, + TRUE, s_fCloneSym )->pModuleSymbols; +} + static void hb_vmReleaseLocalSymbols( void ) { HB_TRACE(HB_TR_DEBUG, ("hb_vmReleaseLocalSymbols()")); while( s_pSymbols ) { - PSYMBOLS pDestroy; + PHB_SYMBOLS pDestroy; pDestroy = s_pSymbols; s_pSymbols = s_pSymbols->pNext; + + if( pDestroy->szModuleName ) + { + hb_xfree( pDestroy->szModuleName ); + } + if( pDestroy->fAllocated ) + { + USHORT ui; + for( ui = 0; ui < pDestroy->uiModuleSymbols; ++ui ) + { + PHB_SYMB pSymbol = pDestroy->pModuleSymbols + ui; + if( pSymbol->pDynSym && pSymbol->pDynSym->pSymbol == pSymbol ) + { + pSymbol->pDynSym->pSymbol = NULL; + } + hb_xfree( pSymbol->szName ); + } + hb_xfree( pDestroy->pModuleSymbols ); + } hb_xfree( pDestroy ); } } @@ -5787,13 +5802,13 @@ static void hb_vmReleaseLocalSymbols( void ) */ static void hb_vmDoInitStatics( void ) { - PSYMBOLS pLastSymbols = s_pSymbols; + PHB_SYMBOLS pLastSymbols = s_pSymbols; HB_TRACE(HB_TR_DEBUG, ("hb_vmDoInitStatics()")); - do + while( pLastSymbols ) { - if( ( pLastSymbols->hScope & HB_FS_INITEXIT ) == HB_FS_INITEXIT ) + if( pLastSymbols->fInitStatics ) { USHORT ui; @@ -5808,22 +5823,22 @@ static void hb_vmDoInitStatics( void ) hb_vmDo( 0 ); } } + pLastSymbols->fInitStatics = FALSE; } pLastSymbols = pLastSymbols->pNext; - - } while( pLastSymbols ); + } } static void hb_vmDoExitFunctions( void ) { - PSYMBOLS pLastSymbols = s_pSymbols; + PHB_SYMBOLS pLastSymbols = s_pSymbols; HB_TRACE(HB_TR_DEBUG, ("hb_vmDoExitFunctions()")); - do + while( pLastSymbols ) { /* only if module contains some EXIT functions */ - if( pLastSymbols->hScope & HB_FS_EXIT ) + if( pLastSymbols->fActive && pLastSymbols->hScope & HB_FS_EXIT ) { USHORT ui; @@ -5844,20 +5859,19 @@ static void hb_vmDoExitFunctions( void ) } } pLastSymbols = pLastSymbols->pNext; - - } while( pLastSymbols ); + } } static void hb_vmDoInitFunctions( void ) { - PSYMBOLS pLastSymbols = s_pSymbols; + PHB_SYMBOLS pLastSymbols = s_pSymbols; HB_TRACE(HB_TR_DEBUG, ("hb_vmDoInitFunctions()")); - do + while( pLastSymbols ) { /* only if module contains some INIT functions */ - if( pLastSymbols->hScope & HB_FS_INIT ) + if( pLastSymbols->fActive && pLastSymbols->hScope & HB_FS_INIT ) { USHORT ui; @@ -5892,8 +5906,7 @@ static void hb_vmDoInitFunctions( void ) } } pLastSymbols = pLastSymbols->pNext; - - } while( pLastSymbols ); + } } /* NOTE: We should make sure that these get linked. @@ -5971,7 +5984,7 @@ void hb_vmRequestCancel( void ) hb_conOutErr( buffer, 0 ); hb_conOutErr( hb_conNewLine(), 0 ); - while ( buffer[0] ) + while( buffer[0] ) { i2 = i; hb_procname( i++, buffer, FALSE ); @@ -6022,7 +6035,7 @@ static BOOL hb_xvmActionRequest( void ) return FALSE; } -HB_EXPORT void hb_xvmExitPorc( ULONG ulPrivateBase ) +HB_EXPORT void hb_xvmExitProc( ULONG ulPrivateBase ) { if( s_uiActionRequest & HB_ENDPROC_REQUESTED ) s_uiActionRequest = 0; @@ -6030,6 +6043,7 @@ HB_EXPORT void hb_xvmExitPorc( ULONG ulPrivateBase ) hb_memvarSetPrivatesBase( ulPrivateBase ); } + HB_EXPORT void hb_xvmSeqBegin( void ) { /* @@ -6216,19 +6230,14 @@ HB_EXPORT BOOL hb_xvmDo( USHORT uiParams ) HB_XVM_RETURN } + HB_EXPORT BOOL hb_xvmFunction( USHORT uiParams ) { HB_TRACE(HB_TR_DEBUG, ("hb_xvmFunction(%hu)", uiParams)); - if( HB_IS_COMPLEX( &hb_stack.Return ) ) - hb_itemClear( &hb_stack.Return ); - else - hb_stack.Return.type = HB_IT_NIL; - + hb_itemSetNil( hb_stackReturnItem() ); hb_vmDo( uiParams ); - - hb_itemMove( hb_stackTopItem(), &hb_stack.Return ); - hb_stackPush(); + hb_stackPushReturn(); HB_XVM_RETURN } @@ -6237,15 +6246,9 @@ HB_EXPORT BOOL hb_xvmSend( USHORT uiParams ) { HB_TRACE(HB_TR_DEBUG, ("hb_xvmSend(%hu)", uiParams)); - if( HB_IS_COMPLEX( &hb_stack.Return ) ) - hb_itemClear( &hb_stack.Return ); - else - hb_stack.Return.type = HB_IT_NIL; - + hb_itemSetNil( hb_stackReturnItem() ); hb_vmSend( uiParams ); - - hb_itemMove( hb_stackTopItem(), &hb_stack.Return ); - hb_stackPush(); + hb_stackPushReturn(); HB_XVM_RETURN } @@ -6254,8 +6257,7 @@ HB_EXPORT void hb_xvmRetValue( void ) { HB_TRACE(HB_TR_DEBUG, ("hb_xvmRetValue()")); - hb_stackDec(); /* make the last item visible */ - hb_itemMove( &hb_stack.Return, hb_stackTopItem() ); /* copy it */ + hb_stackPopReturn(); } HB_EXPORT void hb_xvmStatics( PHB_SYMB pSymbol, USHORT uiStatics ) @@ -6340,14 +6342,14 @@ HB_EXPORT void hb_xvmPushBlockShort( const BYTE * pCode, PHB_SYMB pSymbols ) { HB_TRACE(HB_TR_DEBUG, ("hb_xvmPushBlockShort(%p, %p)", pCode, pSymbols)); - hb_vmPushBlockShort( pCode, pSymbols ); + hb_vmPushBlockShort( pCode, pSymbols, FALSE ); } HB_EXPORT void hb_xvmPushBlock( const BYTE * pCode, PHB_SYMB pSymbols ) { HB_TRACE(HB_TR_DEBUG, ("hb_xvmPushBlock(%p, %p)", pCode, pSymbols)); - hb_vmPushBlock( pCode, pSymbols ); + hb_vmPushBlock( pCode, pSymbols, FALSE ); } HB_EXPORT void hb_xvmPushSelf( void ) @@ -6357,6 +6359,21 @@ HB_EXPORT void hb_xvmPushSelf( void ) hb_vmPush( hb_stackSelfItem() ); } +HB_EXPORT void hb_xvmPushFuncSymbol( PHB_SYMB pSym ) +{ + PHB_ITEM pStackTopItem; + + HB_TRACE(HB_TR_DEBUG, ("hb_xvmPushFuncSymbol(%p)", pSym)); + + pStackTopItem = hb_stackTopItem(); + pStackTopItem->type = HB_IT_SYMBOL; + pStackTopItem->item.asSymbol.value = pSym; + pStackTopItem->item.asSymbol.stackbase = hb_stackTopOffset(); + hb_stackPush(); + ( hb_stackTopItem() )->type = HB_IT_NIL; + hb_stackPush(); +} + HB_EXPORT BOOL hb_xvmPopLogical( BOOL * pfValue ) { HB_TRACE(HB_TR_DEBUG, ("hb_xvmPopLogical(%p)", pfValue)); @@ -6478,6 +6495,40 @@ HB_EXPORT BOOL hb_xvmPopAliasedVar( PHB_SYMB pSymbol ) HB_XVM_RETURN } +HB_EXPORT void hb_xvmLocalSetInt( int iLocal, LONG lValue ) +{ + PHB_ITEM pLocal; + + HB_TRACE(HB_TR_DEBUG, ("hb_xvmLocalSetInt(%d, %d)", iLocal, lValue)); + + if( iLocal >= 0 ) + { + /* local variable or local parameter */ + pLocal = hb_stackItemFromBase( iLocal ); + if( HB_IS_BYREF( pLocal ) ) + pLocal = hb_itemUnRef( pLocal ); + } + else + { + /* local variable referenced in a codeblock + * hb_stackSelfItem() points to a codeblock that is currently evaluated + */ + pLocal = hb_codeblockGetVar( hb_stackSelfItem(), iLocal ); + } + + if( HB_IS_OBJECT( pLocal ) && hb_objHasOperator( pLocal, HB_OO_OP_ASSIGN ) ) + { + hb_vmPushInteger( lValue ); + hb_objOperatorCall( HB_OO_OP_ASSIGN, pLocal, pLocal, + hb_stackItemFromTop( -1 ) ); + hb_stackPop(); + } + else + { + hb_itemPutNL( pLocal, lValue ); + } +} + HB_EXPORT BOOL hb_xvmLocalAddInt( int iLocal, LONG lAdd ) { HB_TRACE(HB_TR_DEBUG, ("hb_xvmLocalAddInt(%d,%ld)", iLocal, lAdd)); @@ -6487,11 +6538,57 @@ HB_EXPORT BOOL hb_xvmLocalAddInt( int iLocal, LONG lAdd ) HB_XVM_RETURN } -HB_EXPORT BOOL hb_xvmEqual( BOOL fExact ) +HB_EXPORT BOOL hb_xvmLocalAdd( int iLocal ) { - HB_TRACE(HB_TR_DEBUG, ("hb_xvmEqual(%d)", (int) fExact)); + PHB_ITEM pLocal; - hb_vmEqual( fExact ); + HB_TRACE(HB_TR_DEBUG, ("hb_xvmLocalAdd(%d)", iLocal)); + + pLocal = hb_stackItemFromBase( iLocal ); + if( HB_IS_BYREF( pLocal ) ) + pLocal = hb_itemUnRef( pLocal ); + hb_vmPlus( pLocal, hb_stackItemFromTop( -2 ), hb_stackItemFromTop( -1 ), 2 ); + pLocal->type &= ~HB_IT_MEMOFLAG; + + HB_XVM_RETURN +} + +HB_EXPORT BOOL hb_xvmStaticAdd( USHORT uiStatic ) +{ + PHB_ITEM pStatic; + + HB_TRACE(HB_TR_DEBUG, ("hb_xvmStaticAdd(%hu)", uiStatic)); + + pStatic = s_aStatics.item.asArray.value->pItems + hb_stack.iStatics + uiStatic - 1; + if( HB_IS_BYREF( pStatic ) ) + pStatic = hb_itemUnRef( pStatic ); + hb_vmPlus( pStatic, hb_stackItemFromTop( -2 ), hb_stackItemFromTop( -1 ), 2 ); + pStatic->type &= ~HB_IT_MEMOFLAG; + + HB_XVM_RETURN +} + +HB_EXPORT BOOL hb_xvmMemvarAdd( PHB_SYMB pSymbol ) +{ + PHB_ITEM pMemVar, pVal1, pVal2; + + HB_TRACE(HB_TR_INFO, ("hb_xvmMemvarAdd(%p)", pSymbol)); + + pVal1 = hb_stackItemFromTop( -2 ); + pVal2 = hb_stackItemFromTop( -1 ); + if( HB_IS_STRING( pVal1 ) && HB_IS_STRING( pVal2 ) ) + { + pMemVar = hb_memvarGetItem( pSymbol ); + if( pMemVar ) + { + hb_vmPlus( pMemVar, pVal1, pVal2, 2 ); + HB_XVM_RETURN + } + } + + hb_vmPlus( pVal1, pVal1, pVal2, 1 ); + hb_memvarSetValue( pSymbol, pVal1 ); + hb_stackPop(); HB_XVM_RETURN } @@ -6571,15 +6668,216 @@ HB_EXPORT void hb_xvmFuncPtr( void ) hb_vmFuncPtr(); } +HB_EXPORT BOOL hb_xvmEqual( BOOL fExact ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_xvmEqual(%d)", (int) fExact)); + + hb_vmEqual( fExact ); + + HB_XVM_RETURN +} + +HB_EXPORT BOOL hb_xvmEqualInt( LONG lValue ) +{ + PHB_ITEM pItem; + + HB_TRACE(HB_TR_DEBUG, ("hb_xvmEqualInt(%ld)", lValue)); + + pItem = hb_stackItemFromTop( -1 ); + if( HB_IS_NIL( pItem ) ) + { + pItem->type = HB_IT_LOGICAL; + pItem->item.asLogical.value = FALSE; + } + else if( HB_IS_NUMINT( pItem ) ) + { + HB_LONG lNumber = hb_vmPopHBLong(); + hb_vmPushLogical( lNumber == ( HB_LONG ) lValue ); + } + else if( HB_IS_NUMERIC( pItem ) ) + { + double dNumber = hb_vmPopNumber(); + hb_vmPushLogical( dNumber == ( double ) lValue ); + } + else if( hb_objHasOperator( pItem, HB_OO_OP_EQUAL ) ) + { + hb_vmPushNumInt( lValue ); + hb_objOperatorCall( HB_OO_OP_EQUAL, pItem, pItem, + hb_stackItemFromTop( -1 ) ); + hb_stackPop(); + } + else + { + PHB_ITEM pResult; + + hb_vmPushLong( lValue ); + pResult = hb_errRT_BASE_Subst( EG_ARG, 1071, NULL, "=", 2, pItem, hb_stackItemFromTop( -1 ) ); + + if( pResult ) + { + hb_stackPop(); + hb_stackPop(); + hb_vmPush( pResult ); + hb_itemRelease( pResult ); + } + } + + HB_XVM_RETURN +} + +HB_EXPORT BOOL hb_xvmEqualIntIs( LONG lValue, BOOL * pfValue ) +{ + PHB_ITEM pItem; + + HB_TRACE(HB_TR_DEBUG, ("hb_xvmEqualIntIs(%ld,%p)", lValue, pfValue)); + + pItem = hb_stackItemFromTop( -1 ); + if( HB_IS_NIL( pItem ) ) + { + * pfValue = FALSE; + hb_stackPop(); + } + else if( HB_IS_NUMINT( pItem ) ) + { + * pfValue = hb_vmPopHBLong() == ( HB_LONG ) lValue; + } + else if( HB_IS_NUMERIC( pItem ) ) + { + * pfValue = hb_vmPopNumber() == ( double ) lValue; + } + else if( hb_objHasOperator( pItem, HB_OO_OP_EQUAL ) ) + { + hb_vmPushLong( lValue ); + hb_objOperatorCall( HB_OO_OP_EQUAL, pItem, pItem, + hb_stackItemFromTop( -1 ) ); + hb_stackPop(); + return hb_xvmPopLogical( pfValue ); + } + else + { + PHB_ITEM pResult; + + hb_vmPushLong( lValue ); + pResult = hb_errRT_BASE_Subst( EG_ARG, 1071, NULL, "=", 2, pItem, hb_stackItemFromTop( -1 ) ); + + if( pResult ) + { + hb_stackPop(); + hb_stackPop(); + hb_vmPush( pResult ); + hb_itemRelease( pResult ); + return hb_xvmPopLogical( pfValue ); + } + } + + HB_XVM_RETURN +} + HB_EXPORT BOOL hb_xvmNotEqual( void ) { - HB_TRACE(HB_TR_DEBUG, ("hb_xvmEqual()")); + HB_TRACE(HB_TR_DEBUG, ("hb_xvmNotEqual()")); hb_vmNotEqual(); HB_XVM_RETURN } +HB_EXPORT BOOL hb_xvmNotEqualInt( LONG lValue ) +{ + PHB_ITEM pItem; + + HB_TRACE(HB_TR_DEBUG, ("hb_xvmNotEqualInt(%ld)", lValue)); + + pItem = hb_stackItemFromTop( -1 ); + if( HB_IS_NIL( pItem ) ) + { + pItem->type = HB_IT_LOGICAL; + pItem->item.asLogical.value = TRUE; + } + else if( HB_IS_NUMINT( pItem ) ) + { + HB_LONG lNumber = hb_vmPopHBLong(); + hb_vmPushLogical( lNumber != ( HB_LONG ) lValue ); + } + else if( HB_IS_NUMERIC( pItem ) ) + { + double dNumber = hb_vmPopNumber(); + hb_vmPushLogical( dNumber != ( double ) lValue ); + } + else if( hb_objHasOperator( pItem, HB_OO_OP_NOTEQUAL ) ) + { + hb_vmPushLong( lValue ); + hb_objOperatorCall( HB_OO_OP_NOTEQUAL, pItem, pItem, + hb_stackItemFromTop( -1 ) ); + hb_stackPop(); + } + else + { + PHB_ITEM pResult; + + hb_vmPushLong( lValue ); + pResult = hb_errRT_BASE_Subst( EG_ARG, 1072, NULL, "<>", 2, pItem, hb_stackItemFromTop( -1 ) ); + + if( pResult ) + { + hb_stackPop(); + hb_stackPop(); + hb_vmPush( pResult ); + hb_itemRelease( pResult ); + } + } + + HB_XVM_RETURN +} + +HB_EXPORT BOOL hb_xvmNotEqualIntIs( LONG lValue, BOOL * pfValue ) +{ + PHB_ITEM pItem; + + HB_TRACE(HB_TR_DEBUG, ("hb_xvmNotEqualIntIs(%ld,%p)", lValue, pfValue)); + + pItem = hb_stackItemFromTop( -1 ); + if( HB_IS_NIL( pItem ) ) + { + * pfValue = TRUE; + hb_stackPop(); + } + else if( HB_IS_NUMINT( pItem ) ) + { + * pfValue = hb_vmPopHBLong() != ( HB_LONG ) lValue; + } + else if( HB_IS_NUMERIC( pItem ) ) + { + * pfValue = hb_vmPopNumber() != ( double ) lValue; + } + else if( hb_objHasOperator( pItem, HB_OO_OP_NOTEQUAL ) ) + { + hb_vmPushLong( lValue ); + hb_objOperatorCall( HB_OO_OP_NOTEQUAL, pItem, pItem, + hb_stackItemFromTop( -1 ) ); + hb_stackPop(); + return hb_xvmPopLogical( pfValue ); + } + else + { + PHB_ITEM pResult; + + hb_vmPushLong( lValue ); + pResult = hb_errRT_BASE_Subst( EG_ARG, 1072, NULL, "<>", 2, pItem, hb_stackItemFromTop( -1 ) ); + + if( pResult ) + { + hb_stackPop(); + hb_stackPop(); + hb_vmPush( pResult ); + hb_itemRelease( pResult ); + return hb_xvmPopLogical( pfValue ); + } + } + + HB_XVM_RETURN +} + HB_EXPORT BOOL hb_xvmLess( void ) { HB_TRACE(HB_TR_DEBUG, ("hb_xvmLess()")); @@ -6589,6 +6887,92 @@ HB_EXPORT BOOL hb_xvmLess( void ) HB_XVM_RETURN } +HB_EXPORT BOOL hb_xvmLessThenInt( LONG lValue ) +{ + PHB_ITEM pItem; + + HB_TRACE(HB_TR_DEBUG, ("hb_xvmLessThenInt(%ld)", lValue)); + + pItem = hb_stackItemFromTop( -1 ); + if( HB_IS_NUMINT( pItem ) ) + { + HB_LONG lNumber = hb_vmPopHBLong(); + hb_vmPushLogical( lNumber < ( HB_LONG ) lValue ); + } + else if( HB_IS_NUMERIC( pItem ) ) + { + double dNumber = hb_vmPopNumber(); + hb_vmPushLogical( dNumber < ( double ) lValue ); + } + else if( hb_objHasOperator( pItem, HB_OO_OP_LESS ) ) + { + hb_vmPushLong( lValue ); + hb_objOperatorCall( HB_OO_OP_LESS, pItem, pItem, + hb_stackItemFromTop( -1 ) ); + hb_stackPop(); + } + else + { + PHB_ITEM pResult; + + hb_vmPushLong( lValue ); + pResult = hb_errRT_BASE_Subst( EG_ARG, 1073, NULL, "<", 2, pItem, hb_stackItemFromTop( -1 ) ); + + if( pResult ) + { + hb_stackPop(); + hb_stackPop(); + hb_vmPush( pResult ); + hb_itemRelease( pResult ); + } + } + + HB_XVM_RETURN +} + +HB_EXPORT BOOL hb_xvmLessThenIntIs( LONG lValue, BOOL * pfValue ) +{ + PHB_ITEM pItem; + + HB_TRACE(HB_TR_DEBUG, ("hb_xvmLessThenIntIs(%ld,%p)", lValue, pfValue)); + + pItem = hb_stackItemFromTop( -1 ); + if( HB_IS_NUMINT( pItem ) ) + { + * pfValue = hb_vmPopHBLong() < ( HB_LONG ) lValue; + } + else if( HB_IS_NUMERIC( pItem ) ) + { + * pfValue = hb_vmPopNumber() < ( double ) lValue; + } + else if( hb_objHasOperator( pItem, HB_OO_OP_LESS ) ) + { + hb_vmPushLong( lValue ); + hb_objOperatorCall( HB_OO_OP_LESS, pItem, pItem, + hb_stackItemFromTop( -1 ) ); + hb_stackPop(); + return hb_xvmPopLogical( pfValue ); + } + else + { + PHB_ITEM pResult; + + hb_vmPushLong( lValue ); + pResult = hb_errRT_BASE_Subst( EG_ARG, 1073, NULL, "<", 2, pItem, hb_stackItemFromTop( -1 ) ); + + if( pResult ) + { + hb_stackPop(); + hb_stackPop(); + hb_vmPush( pResult ); + hb_itemRelease( pResult ); + return hb_xvmPopLogical( pfValue ); + } + } + + HB_XVM_RETURN +} + HB_EXPORT BOOL hb_xvmLessEqual( void ) { HB_TRACE(HB_TR_DEBUG, ("hb_xvmLessEqual()")); @@ -6598,6 +6982,92 @@ HB_EXPORT BOOL hb_xvmLessEqual( void ) HB_XVM_RETURN } +HB_EXPORT BOOL hb_xvmLessEqualThenInt( LONG lValue ) +{ + PHB_ITEM pItem; + + HB_TRACE(HB_TR_DEBUG, ("hb_xvmLessEqualThenInt(%ld)", lValue)); + + pItem = hb_stackItemFromTop( -1 ); + if( HB_IS_NUMINT( pItem ) ) + { + HB_LONG lNumber = hb_vmPopHBLong(); + hb_vmPushLogical( lNumber <= ( HB_LONG ) lValue ); + } + else if( HB_IS_NUMERIC( pItem ) ) + { + double dNumber = hb_vmPopNumber(); + hb_vmPushLogical( dNumber <= ( double ) lValue ); + } + else if( hb_objHasOperator( pItem, HB_OO_OP_LESSEQUAL ) ) + { + hb_vmPushLong( lValue ); + hb_objOperatorCall( HB_OO_OP_LESSEQUAL, pItem, pItem, + hb_stackItemFromTop( -1 ) ); + hb_stackPop(); + } + else + { + PHB_ITEM pResult; + + hb_vmPushLong( lValue ); + pResult = hb_errRT_BASE_Subst( EG_ARG, 1074, NULL, "<=", 2, pItem, hb_stackItemFromTop( -1 ) ); + + if( pResult ) + { + hb_stackPop(); + hb_stackPop(); + hb_vmPush( pResult ); + hb_itemRelease( pResult ); + } + } + + HB_XVM_RETURN +} + +HB_EXPORT BOOL hb_xvmLessEqualThenIntIs( LONG lValue, BOOL * pfValue ) +{ + PHB_ITEM pItem; + + HB_TRACE(HB_TR_DEBUG, ("hb_xvmLessEqualThenIntIs(%ld,%p)", lValue, pfValue)); + + pItem = hb_stackItemFromTop( -1 ); + if( HB_IS_NUMINT( pItem ) ) + { + * pfValue = hb_vmPopHBLong() <= ( HB_LONG ) lValue; + } + else if( HB_IS_NUMERIC( pItem ) ) + { + * pfValue = hb_vmPopNumber() <= ( double ) lValue; + } + else if( hb_objHasOperator( pItem, HB_OO_OP_LESSEQUAL ) ) + { + hb_vmPushLong( lValue ); + hb_objOperatorCall( HB_OO_OP_LESSEQUAL, pItem, pItem, + hb_stackItemFromTop( -1 ) ); + hb_stackPop(); + return hb_xvmPopLogical( pfValue ); + } + else + { + PHB_ITEM pResult; + + hb_vmPushLong( lValue ); + pResult = hb_errRT_BASE_Subst( EG_ARG, 1074, NULL, "<=", 2, pItem, hb_stackItemFromTop( -1 ) ); + + if( pResult ) + { + hb_stackPop(); + hb_stackPop(); + hb_vmPush( pResult ); + hb_itemRelease( pResult ); + return hb_xvmPopLogical( pfValue ); + } + } + + HB_XVM_RETURN +} + HB_EXPORT BOOL hb_xvmGreater( void ) { HB_TRACE(HB_TR_DEBUG, ("hb_xvmGreater()")); @@ -6607,6 +7077,92 @@ HB_EXPORT BOOL hb_xvmGreater( void ) HB_XVM_RETURN } +HB_EXPORT BOOL hb_xvmGreaterThenInt( LONG lValue ) +{ + PHB_ITEM pItem; + + HB_TRACE(HB_TR_DEBUG, ("hb_xvmGreaterThenInt(%ld)", lValue)); + + pItem = hb_stackItemFromTop( -1 ); + if( HB_IS_NUMINT( pItem ) ) + { + HB_LONG lNumber = hb_vmPopHBLong(); + hb_vmPushLogical( lNumber > ( HB_LONG ) lValue ); + } + else if( HB_IS_NUMERIC( pItem ) ) + { + double dNumber = hb_vmPopNumber(); + hb_vmPushLogical( dNumber > ( double ) lValue ); + } + else if( hb_objHasOperator( pItem, HB_OO_OP_GREATER ) ) + { + hb_vmPushLong( lValue ); + hb_objOperatorCall( HB_OO_OP_GREATER, pItem, pItem, + hb_stackItemFromTop( -1 ) ); + hb_stackPop(); + } + else + { + PHB_ITEM pResult; + + hb_vmPushLong( lValue ); + pResult = hb_errRT_BASE_Subst( EG_ARG, 1075, NULL, ">", 2, pItem, hb_stackItemFromTop( -1 ) ); + + if( pResult ) + { + hb_stackPop(); + hb_stackPop(); + hb_vmPush( pResult ); + hb_itemRelease( pResult ); + } + } + + HB_XVM_RETURN +} + +HB_EXPORT BOOL hb_xvmGreaterThenIntIs( LONG lValue, BOOL * pfValue ) +{ + PHB_ITEM pItem; + + HB_TRACE(HB_TR_DEBUG, ("hb_xvmGreaterThenIntIs(%ld,%p)", lValue, pfValue)); + + pItem = hb_stackItemFromTop( -1 ); + if( HB_IS_NUMINT( pItem ) ) + { + * pfValue = hb_vmPopHBLong() > ( HB_LONG ) lValue; + } + else if( HB_IS_NUMERIC( pItem ) ) + { + * pfValue = hb_vmPopNumber() > ( double ) lValue; + } + else if( hb_objHasOperator( pItem, HB_OO_OP_GREATER ) ) + { + hb_vmPushLong( lValue ); + hb_objOperatorCall( HB_OO_OP_GREATER, pItem, pItem, + hb_stackItemFromTop( -1 ) ); + hb_stackPop(); + return hb_xvmPopLogical( pfValue ); + } + else + { + PHB_ITEM pResult; + + hb_vmPushLong( lValue ); + pResult = hb_errRT_BASE_Subst( EG_ARG, 1075, NULL, ">", 2, pItem, hb_stackItemFromTop( -1 ) ); + + if( pResult ) + { + hb_stackPop(); + hb_stackPop(); + hb_vmPush( pResult ); + hb_itemRelease( pResult ); + return hb_xvmPopLogical( pfValue ); + } + } + + HB_XVM_RETURN +} + HB_EXPORT BOOL hb_xvmGreaterEqual( void ) { HB_TRACE(HB_TR_DEBUG, ("hb_xvmGreaterEqual()")); @@ -6616,6 +7172,92 @@ HB_EXPORT BOOL hb_xvmGreaterEqual( void ) HB_XVM_RETURN } +HB_EXPORT BOOL hb_xvmGreaterEqualThenInt( LONG lValue ) +{ + PHB_ITEM pItem; + + HB_TRACE(HB_TR_DEBUG, ("hb_xvmGreaterEqualThenInt(%ld)", lValue)); + + pItem = hb_stackItemFromTop( -1 ); + if( HB_IS_NUMINT( pItem ) ) + { + HB_LONG lNumber = hb_vmPopHBLong(); + hb_vmPushLogical( lNumber >= ( HB_LONG ) lValue ); + } + else if( HB_IS_NUMERIC( pItem ) ) + { + double dNumber = hb_vmPopNumber(); + hb_vmPushLogical( dNumber >= ( double ) lValue ); + } + else if( hb_objHasOperator( pItem, HB_OO_OP_GREATEREQUAL ) ) + { + hb_vmPushLong( lValue ); + hb_objOperatorCall( HB_OO_OP_GREATEREQUAL, pItem, pItem, + hb_stackItemFromTop( -1 ) ); + hb_stackPop(); + } + else + { + PHB_ITEM pResult; + + hb_vmPushLong( lValue ); + pResult = hb_errRT_BASE_Subst( EG_ARG, 1076, NULL, ">=", 2, pItem, hb_stackItemFromTop( -1 ) ); + + if( pResult ) + { + hb_stackPop(); + hb_stackPop(); + hb_vmPush( pResult ); + hb_itemRelease( pResult ); + } + } + + HB_XVM_RETURN +} + +HB_EXPORT BOOL hb_xvmGreaterEqualThenIntIs( LONG lValue, BOOL * pfValue ) +{ + PHB_ITEM pItem; + + HB_TRACE(HB_TR_DEBUG, ("hb_xvmGreaterEqualThenIntIs(%ld,%p)", lValue, pfValue)); + + pItem = hb_stackItemFromTop( -1 ); + if( HB_IS_NUMINT( pItem ) ) + { + * pfValue = hb_vmPopHBLong() <= ( HB_LONG ) lValue; + } + else if( HB_IS_NUMERIC( pItem ) ) + { + * pfValue = hb_vmPopNumber() <= ( double ) lValue; + } + else if( hb_objHasOperator( pItem, HB_OO_OP_GREATEREQUAL ) ) + { + hb_vmPushLong( lValue ); + hb_objOperatorCall( HB_OO_OP_GREATEREQUAL, pItem, pItem, + hb_stackItemFromTop( -1 ) ); + hb_stackPop(); + return hb_xvmPopLogical( pfValue ); + } + else + { + PHB_ITEM pResult; + + hb_vmPushLong( lValue ); + pResult = hb_errRT_BASE_Subst( EG_ARG, 1074, NULL, "<=", 2, pItem, hb_stackItemFromTop( -1 ) ); + + if( pResult ) + { + hb_stackPop(); + hb_stackPop(); + hb_vmPush( pResult ); + hb_itemRelease( pResult ); + return hb_xvmPopLogical( pfValue ); + } + } + + HB_XVM_RETURN +} + HB_EXPORT BOOL hb_xvmInstring( void ) { HB_TRACE(HB_TR_DEBUG, ("hb_xvmInstring()")); @@ -6627,7 +7269,7 @@ HB_EXPORT BOOL hb_xvmInstring( void ) HB_EXPORT BOOL hb_xvmAddInt( LONG lAdd ) { - HB_TRACE(HB_TR_DEBUG, ("hb_xvmLocalAddInt(%ld)", lAdd)); + HB_TRACE(HB_TR_DEBUG, ("hb_xvmAddInt(%ld)", lAdd)); hb_vmAddInt( hb_stackItemFromTop( -1 ), lAdd ); @@ -6721,10 +7363,12 @@ HB_EXPORT BOOL hb_xvmMultByInt( LONG lValue ) hb_itemPutNumType( pValue, dValue * lValue, iDec, iType, HB_IT_INTEGER ); } - else if( HB_IS_OBJECT( pValue ) && hb_objHasMsg( pValue, "__OpMult" ) ) + else if( hb_objHasOperator( pValue, HB_OO_OP_MULT ) ) { hb_vmPushLong( lValue ); - hb_vmOperatorCall( pValue, pValue, hb_stackItemFromTop( -1 ), "__OPMULT" ); + hb_objOperatorCall( HB_OO_OP_MULT, pValue, pValue, + hb_stackItemFromTop( -1 ) ); + hb_stackPop(); } else { @@ -6808,10 +7452,12 @@ HB_EXPORT BOOL hb_xvmDivideByInt( LONG lDivisor ) hb_itemPutNDDec( pValue, hb_itemGetND( pValue ) / lDivisor, hb_set.HB_SET_DECIMALS ); } } - else if( HB_IS_OBJECT( pValue ) && hb_objHasMsg( pValue, "__OpDivide" ) ) + else if( hb_objHasOperator( pValue, HB_OO_OP_DIVIDE ) ) { hb_vmPushLong( lDivisor ); - hb_vmOperatorCall( pValue, pValue, hb_stackItemFromTop( -1 ), "__OPDIVIDE" ); + hb_objOperatorCall( HB_OO_OP_DIVIDE, pValue, pValue, + hb_stackItemFromTop( -1 ) ); + hb_stackPop(); } else { @@ -6936,18 +7582,20 @@ static void hb_vmArrayItemPush( ULONG ulIndex ) } /* #endif */ - if( HB_IS_OBJECT( pArray ) && hb_objHasMsg( pArray, "__OpArrayIndex" ) ) - { - hb_vmPushNumInt( ulIndex ); - hb_vmOperatorCall( pArray, pArray, hb_stackItemFromTop( -1 ), "__OPARRAYINDEX" ); - return; - } - if( HB_IS_ARRAY( pArray ) ) { + if( HB_IS_OBJECT( pArray ) && hb_objHasOperator( pArray, HB_OO_OP_ARRAYINDEX ) ) + { + hb_vmPushNumInt( ulIndex ); + hb_objOperatorCall( HB_OO_OP_ARRAYINDEX, pArray, pArray, + hb_stackItemFromTop( -1 ) ); + hb_stackPop(); + return; + } + if( ulIndex > 0 && ulIndex <= pArray->item.asArray.value->ulLen ) { - if( pArray->item.asArray.value->ulHolders > 1 ) + if( hb_gcRefCount( pArray->item.asArray.value ) > 1 ) { /* this is a temporary copy of an array - we can overwrite * it with no problem @@ -6973,6 +7621,13 @@ static void hb_vmArrayItemPush( ULONG ulIndex ) hb_errRT_BASE( EG_BOUND, 1132, NULL, hb_langDGetErrorDesc( EG_ARRACCESS ), 2, pArray, hb_stackItemFromTop( -1 ) ); } } + else if( hb_objHasOperator( pArray, HB_OO_OP_ARRAYINDEX ) ) + { + hb_vmPushNumInt( ulIndex ); + hb_objOperatorCall( HB_OO_OP_ARRAYINDEX, pArray, pArray, + hb_stackItemFromTop( -1 ) ); + hb_stackPop(); + } else { hb_vmPushNumInt( ulIndex ); @@ -7017,8 +7672,7 @@ static void hb_vmArrayItemPop( ULONG ulIndex ) hb_itemPutCL( pArray, hb_vm_acAscii[ ( BYTE ) hb_itemGetNI( pValue ) ], 1 ); else { - if( pArray->item.asString.bStatic || *( pArray->item.asString.u.pulHolders ) > 1 ) - hb_itemPutCL( pArray, pArray->item.asString.value, pArray->item.asString.length ); + hb_itemUnShareString( pArray ); pArray->item.asString.value[ ulIndex - 1 ] = hb_itemGetNI( pValue ); } hb_stackPop(); @@ -7027,7 +7681,7 @@ static void hb_vmArrayItemPop( ULONG ulIndex ) else { hb_vmPushNumInt( ulIndex ); - hb_errRT_BASE( EG_BOUND, 1132, NULL, hb_langDGetErrorDesc( EG_ARRACCESS ), + hb_errRT_BASE( EG_BOUND, 1133, NULL, hb_langDGetErrorDesc( EG_ARRACCESS ), 2, pArray, hb_stackItemFromTop( -1 ) ); } } @@ -7300,10 +7954,9 @@ HB_FUNC( HB_DBG_INVOKEDEBUG ) * $End$ */ HB_FUNC( HB_DBG_VMVARSLIST ) { - PHB_ITEM pStatics = hb_arrayClone( &s_aStatics ); + PHB_ITEM pStatics = hb_itemClone( &s_aStatics ); - hb_itemCopy( &hb_stack.Return, pStatics ); - hb_itemRelease( pStatics ); + hb_itemRelease( hb_itemReturn( pStatics ) ); } /* $Doc$ @@ -7321,7 +7974,7 @@ HB_FUNC( HB_DBG_VMVARSLEN ) * $End$ */ HB_FUNC( HB_DBG_VMVARSGET ) { - hb_itemReturn( s_aStatics.item.asArray.value->pItems + hb_parni(1) + hb_parni(2) - 1 ); + hb_arrayGet( &s_aStatics, hb_parni(1) + hb_parni(2), hb_stackReturnItem() ); } /* $Doc$ @@ -7330,8 +7983,7 @@ HB_FUNC( HB_DBG_VMVARSGET ) * $End$ */ HB_FUNC( HB_DBG_VMVARSSET ) { - hb_itemCopy( s_aStatics.item.asArray.value->pItems + hb_parni(1) + hb_parni(2) - 1, - hb_itemParamPtr( 3, HB_IT_ANY ) ); + hb_arraySet( &s_aStatics, hb_parni(1) + hb_parni(2), hb_itemParamPtr( 3, HB_IT_ANY ) ); } HB_FUNC( HB_DBG_PROCLEVEL ) @@ -7360,11 +8012,15 @@ void hb_vmIsStaticRef( void ) * $End$ */ HB_FUNC( __SETPROFILER ) { +#ifndef HB_NO_PROFILER BOOL bOldValue = hb_bProfiler; hb_bProfiler = hb_parl( 1 ); hb_retl( bOldValue ); +#else + hb_retl( FALSE ); +#endif } /* $Doc$ @@ -7389,6 +8045,7 @@ HB_FUNC( __OPGETPRF ) /* profiler: It returns an array with an opcode called and consumed times { nTimes, nTime }, given the opcode index */ { +#ifndef HB_NO_PROFILER ULONG ulOpcode = hb_parnl( 1 ); hb_reta( 2 ); @@ -7398,6 +8055,9 @@ HB_FUNC( __OPGETPRF ) /* profiler: It returns an array with an opcode called and hb_stornl( hb_ulOpcodesTime[ ulOpcode ], -1, 2 ); } else +#else + hb_reta( 2 ); +#endif { hb_stornl( 0, -1, 1 ); hb_stornl( 0, -1, 2 ); diff --git a/harbour/source/vm/itemapi.c b/harbour/source/vm/itemapi.c index 24c0d43d4b..a58e8e253e 100644 --- a/harbour/source/vm/itemapi.c +++ b/harbour/source/vm/itemapi.c @@ -97,6 +97,7 @@ #include "hbapi.h" #include "hbstack.h" #include "hbapiitm.h" +#include "hbapilng.h" #include "hbapierr.h" #include "hbdate.h" #include "hbset.h" @@ -214,25 +215,23 @@ HB_EXPORT PHB_ITEM hb_itemPutC( PHB_ITEM pItem, const char * szText ) if( ulLen == 0 ) { - pItem->item.asString.length = 0; - pItem->item.asString.value = hb_vm_sNull; - pItem->item.asString.bStatic = TRUE; + pItem->item.asString.length = 0; + pItem->item.asString.allocated = 0; + pItem->item.asString.value = hb_vm_sNull; } else if( ulLen == 1 ) { - pItem->item.asString.length = 1; - pItem->item.asString.value = hb_vm_acAscii[ (unsigned char) ( szText[0] ) ]; - pItem->item.asString.bStatic = TRUE; + pItem->item.asString.length = 1; + pItem->item.asString.allocated = 0; + pItem->item.asString.value = hb_vm_acAscii[ (unsigned char) ( szText[0] ) ]; } else { - pItem->item.asString.length = ulLen; - pItem->item.asString.value = ( char * ) hb_xgrab( ulLen + 1 ); - pItem->item.asString.bStatic = 0; - pItem->item.asString.u.pulHolders = ( HB_COUNTER * ) hb_xgrab( sizeof( HB_COUNTER ) ); - * ( pItem->item.asString.u.pulHolders ) = 1; - hb_xmemcpy( pItem->item.asString.value, szText, ulLen ); - pItem->item.asString.value[ ulLen ] = '\0'; + pItem->item.asString.length = ulLen; + pItem->item.asString.allocated = ulLen + 1; + pItem->item.asString.value = ( char * ) hb_xgrab( ulLen + 1 ); + /* we used strlen() above so we no it's 0-ended string */ + hb_xmemcpy( pItem->item.asString.value, szText, ulLen + 1 ); } return pItem; @@ -251,7 +250,7 @@ HB_EXPORT PHB_ITEM hb_itemPutCConst( PHB_ITEM pItem, const char * szText ) pItem = hb_itemNew( NULL ); pItem->type = HB_IT_STRING; - pItem->item.asString.bStatic = 1; + pItem->item.asString.allocated = 0; if( szText == NULL ) { @@ -287,23 +286,21 @@ HB_EXPORT PHB_ITEM hb_itemPutCL( PHB_ITEM pItem, const char * szText, ULONG ulLe if( szText == NULL || ulLen == 0 ) { - pItem->item.asString.length = 0; - pItem->item.asString.value = hb_vm_sNull; - pItem->item.asString.bStatic = TRUE; + pItem->item.asString.length = 0; + pItem->item.asString.allocated = 0; + pItem->item.asString.value = hb_vm_sNull; } else if( ulLen == 1 ) { - pItem->item.asString.length = 1; - pItem->item.asString.value = hb_vm_acAscii[ (unsigned char) ( szText[0] ) ]; - pItem->item.asString.bStatic = TRUE; + pItem->item.asString.length = 1; + pItem->item.asString.allocated = 0; + pItem->item.asString.value = hb_vm_acAscii[ (unsigned char) ( szText[0] ) ]; } else { - pItem->item.asString.length = ulLen; - pItem->item.asString.value = ( char * ) hb_xgrab( ulLen + 1 ); - pItem->item.asString.bStatic = 0; - pItem->item.asString.u.pulHolders = ( HB_COUNTER * ) hb_xgrab( sizeof( HB_COUNTER ) ); - * ( pItem->item.asString.u.pulHolders ) = 1; + pItem->item.asString.length = ulLen; + pItem->item.asString.allocated = ulLen + 1; + pItem->item.asString.value = ( char * ) hb_xgrab( ulLen + 1 ); hb_xmemcpy( pItem->item.asString.value, szText, ulLen ); pItem->item.asString.value[ ulLen ] = '\0'; } @@ -327,23 +324,21 @@ HB_EXPORT PHB_ITEM hb_itemPutCPtr( PHB_ITEM pItem, char * szText, ULONG ulLen ) pItem->item.asString.length = ulLen; if( ulLen == 0 ) { - pItem->item.asString.value = hb_vm_sNull; - pItem->item.asString.bStatic = TRUE; + pItem->item.asString.allocated = 0; + pItem->item.asString.value = hb_vm_sNull; hb_xfree( szText ); } else if( ulLen == 1 ) { - pItem->item.asString.value = hb_vm_acAscii[ (unsigned char) ( szText[0] ) ]; - pItem->item.asString.bStatic = TRUE; + pItem->item.asString.allocated = 0; + pItem->item.asString.value = hb_vm_acAscii[ (unsigned char) ( szText[0] ) ]; hb_xfree( szText ); } else { - pItem->item.asString.value = szText; - pItem->item.asString.value[ ulLen ] = '\0'; - pItem->item.asString.bStatic = FALSE; - pItem->item.asString.u.pulHolders = ( HB_COUNTER * ) hb_xgrab( sizeof( HB_COUNTER ) ); - * ( pItem->item.asString.u.pulHolders ) = 1; + szText[ ulLen ] = '\0'; + pItem->item.asString.allocated = ulLen + 1; + pItem->item.asString.value = szText; } return pItem; @@ -634,7 +629,7 @@ HB_EXPORT PHB_ITEM hb_itemReturn( PHB_ITEM pItem ) HB_TRACE(HB_TR_DEBUG, ("hb_itemReturn(%p)", pItem)); if( pItem ) - hb_itemCopy( &hb_stack.Return, pItem ); + hb_itemCopy( hb_stackReturnItem(), pItem ); return pItem; } @@ -644,9 +639,7 @@ HB_EXPORT PHB_ITEM hb_itemReturnForward( PHB_ITEM pItem ) HB_TRACE_STEALTH( HB_TR_DEBUG, ("hb_itemReturnForward(%p)", pItem ) ); if( pItem ) - { - hb_itemForwardValue( &hb_stack.Return, pItem ); - } + hb_itemMove( hb_stackReturnItem(), pItem ); return pItem; } @@ -918,14 +911,10 @@ HB_EXPORT PHB_ITEM hb_itemPutNDDec( PHB_ITEM pItem, double dNumber, int iDec ) if( pItem ) { if( HB_IS_COMPLEX( pItem ) ) - { hb_itemClear( pItem ); - } } else - { pItem = hb_itemNew( NULL ); - } pItem->type = HB_IT_DOUBLE; pItem->item.asDouble.length = HB_DBL_LENGTH( dNumber ); @@ -1107,6 +1096,26 @@ HB_EXPORT PHB_ITEM hb_itemPutPtr( PHB_ITEM pItem, void * pValue ) pItem->type = HB_IT_POINTER; pItem->item.asPointer.value = pValue; + pItem->item.asPointer.collect = FALSE; + + return pItem; +} + +HB_EXPORT PHB_ITEM hb_itemPutPtrGC( PHB_ITEM pItem, void * pValue ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_itemPutPtrGC(%p, %p)", pItem, pValue)); + + if( pItem ) + { + if( HB_IS_COMPLEX( pItem ) ) + hb_itemClear( pItem ); + } + else + pItem = hb_itemNew( NULL ); + + pItem->type = HB_IT_POINTER; + pItem->item.asPointer.value = pValue; + pItem->item.asPointer.collect = TRUE; return pItem; } @@ -1225,41 +1234,30 @@ HB_EXPORT void hb_itemClear( PHB_ITEM pItem ) if( HB_IS_STRING( pItem ) ) { - if( !pItem->item.asString.bStatic ) - { - if( --*( pItem->item.asString.u.pulHolders ) == 0 ) - { - hb_xfree( pItem->item.asString.value ); - pItem->item.asString.value = NULL; - hb_xfree( pItem->item.asString.u.pulHolders ); - } - } + if( pItem->item.asString.allocated ) + hb_xRefFree( pItem->item.asString.value ); } else if( HB_IS_ARRAY( pItem ) ) - { - if( pItem->item.asArray.value ) - { - if( --( pItem->item.asArray.value )->ulHolders == 0 ) - hb_arrayRelease( pItem ); - } - } + hb_gcRefFree( pItem->item.asArray.value ); + else if( HB_IS_BLOCK( pItem ) ) - hb_codeblockDelete( pItem ); + hb_gcRefFree( pItem->item.asBlock.value ); else if( HB_IS_MEMVAR( pItem ) ) hb_memvarValueDecRef( pItem->item.asMemvar.value ); - else if( HB_IS_BYREF( pItem ) ) + else if( HB_IS_POINTER( pItem ) ) { - if( pItem->item.asRefer.offset < 0 && pItem->item.asRefer.value >= 0 ) - { - /* FOR EACH control variable */ - hb_itemRelease( pItem->item.asRefer.BasePtr.itemPtr ); - if( pItem->item.asRefer.ValuePtr.itemPtr ) - hb_itemRelease( pItem->item.asRefer.ValuePtr.itemPtr ); - } + if( pItem->item.asPointer.collect ) + hb_gcRefFree( pItem->item.asPointer.value ); } - + else if( HB_IS_ENUM( pItem ) ) /* FOR EACH control variable */ + { + hb_itemRelease( pItem->item.asEnum.basePtr ); + if( pItem->item.asEnum.valuePtr ) + hb_itemRelease( pItem->item.asEnum.valuePtr ); + } + #if defined( HB_FM_STATISTICS ) && defined( HB_PARANOID_MEM_CHECK ) else if( HB_IS_BADITEM( pItem ) ) hb_errInternal( HB_EI_VMPOPINVITEM, NULL, "hb_itemClear()", NULL ); @@ -1286,47 +1284,30 @@ HB_EXPORT void hb_itemCopy( PHB_ITEM pDest, PHB_ITEM pSource ) { if( HB_IS_STRING( pSource ) ) { - if( !pSource->item.asString.bStatic ) - ++*( pSource->item.asString.u.pulHolders ); + if( pSource->item.asString.allocated ) + hb_xRefInc( pSource->item.asString.value ); } else if( HB_IS_ARRAY( pSource ) ) - { - ( pSource->item.asArray.value )->ulHolders++; - } + hb_gcRefInc( pSource->item.asArray.value ); + else if( HB_IS_BLOCK( pSource ) ) - { - ( pSource->item.asBlock.value )->ulCounter++; - } + hb_gcRefInc( pSource->item.asBlock.value ); + else if( HB_IS_MEMVAR( pSource ) ) hb_memvarValueIncRef( pSource->item.asMemvar.value ); + + else if( HB_IS_POINTER( pSource ) ) + { + if( pSource->item.asPointer.collect ) + hb_gcRefInc( pSource->item.asPointer.value ); + } } } -/* copy (transfer) the value of item without increasing - * a reference counters (the pSource item cannot be cleared) -*/ -HB_EXPORT void hb_itemForwardValue( PHB_ITEM pDest, PHB_ITEM pSource ) -{ - HB_TRACE_STEALTH( HB_TR_DEBUG, ("hb_itemForwardValue(%p, %p) %i", pDest, pSource, pDest->type ) ); - - if( pDest == pSource ) - { - hb_errInternal( HB_EI_ITEMBADCOPY, NULL, "hb_itemForwardValue()", NULL ); - } - - if( HB_IS_COMPLEX( pDest ) ) - { - hb_itemClear( pDest ); - } - - /* Forward. */ - memcpy( pDest, pSource, sizeof( HB_ITEM ) ); - - /* Now fake clear the transferer. */ - //pSource->item.asString.bStatic = FALSE; - pSource->type = HB_IT_NIL; -} - +/* + * copy (transfer) the value of item without increasing + * a reference counters, the pSource item is cleared + */ HB_EXPORT void hb_itemMove( PHB_ITEM pDest, PHB_ITEM pSource ) { HB_TRACE(HB_TR_DEBUG, ("hb_itemCopy(%p, %p)", pDest, pSource)); @@ -1339,7 +1320,6 @@ HB_EXPORT void hb_itemMove( PHB_ITEM pDest, PHB_ITEM pSource ) memcpy( pDest, pSource, sizeof( HB_ITEM ) ); pSource->type = HB_IT_NIL; - } HB_EXPORT void hb_itemSwap( PHB_ITEM pItem1, PHB_ITEM pItem2 ) @@ -1377,7 +1357,7 @@ PHB_ITEM hb_itemUnRef( PHB_ITEM pItem ) /* Unreference passed variable * Do not unreference the last reference stored -*/ + */ PHB_ITEM hb_itemUnRefRefer( PHB_ITEM pItem ) { PHB_ITEM pRef = pItem; @@ -1412,6 +1392,34 @@ PHB_ITEM hb_itemUnRefOnce( PHB_ITEM pItem ) pItem->item.asMemvar.value; pItem = pValue->pVarItem; } + else if( HB_IS_ENUM( pItem ) ) /* FOR EACH control variable */ + { + /* enumerator variable */ + if( HB_IS_ARRAY( pItem->item.asEnum.basePtr ) ) + { + PHB_ITEM pResult = hb_arrayGetItemPtr( pItem->item.asEnum.basePtr, + pItem->item.asEnum.offset ); + if( pResult ) + return pResult; + } + else if( pItem->item.asEnum.valuePtr ) + return pItem->item.asEnum.valuePtr; + + /* to avoid recursive RT error generation */ + if( pItem->item.asEnum.offset >= 0 ) + { + hb_stackPush(); + hb_itemPutNInt( hb_stackItemFromTop( -1 ), pItem->item.asEnum.offset ); + pItem->item.asEnum.offset = -1; + if( !pItem->item.asEnum.valuePtr ) + pItem->item.asEnum.valuePtr = hb_itemNew( NULL ); + + hb_errRT_BASE( EG_BOUND, 1132, NULL, hb_langDGetErrorDesc( EG_ARRACCESS ), + 2, pItem->item.asEnum.basePtr, hb_stackItemFromTop( -1 ) ); + /* break() was executed by error block */ + } + return pItem->item.asEnum.valuePtr; + } else { if( pItem->item.asRefer.value >= 0 ) @@ -1422,30 +1430,19 @@ PHB_ITEM hb_itemUnRefOnce( PHB_ITEM pItem ) pItem = *( pItem->item.asRefer.BasePtr.itemsbase ) + pItem->item.asRefer.value; } - else if( pItem->item.asRefer.offset < 0 ) - { - /* enumerator variable */ - if( HB_IS_ARRAY( pItem->item.asRefer.BasePtr.itemPtr ) ) - { - pItem = hb_arrayGetItemPtr( pItem->item.asRefer.BasePtr.itemPtr, pItem->item.asRefer.value ); - } - else if( pItem->item.asRefer.ValuePtr.itemPtr ) - { - pItem = pItem->item.asRefer.ValuePtr.itemPtr; - } - } else { /* a reference to a local variable */ HB_ITEM_PTR *pLocal; - pLocal = *( pItem->item.asRefer.BasePtr.itemsbasePtr ) + pItem->item.asRefer.offset + pItem->item.asRefer.value; + + pLocal = *( pItem->item.asRefer.BasePtr.itemsbasePtr ) + + pItem->item.asRefer.offset + pItem->item.asRefer.value; pItem = *pLocal; } } else { - /* local variable referenced in a codeblock - */ + /* local variable referenced in a codeblock */ pItem = hb_codeblockGetRef( pItem->item.asRefer.BasePtr.block, pItem ); } } @@ -1455,36 +1452,79 @@ PHB_ITEM hb_itemUnRefOnce( PHB_ITEM pItem ) } /* Internal API, not standard Clipper */ -/* UnShare string buffer of given item */ +/* Resize string buffer of given string item */ + +PHB_ITEM hb_itemReSizeString( PHB_ITEM pItem, ULONG ulSize ) +{ + HB_TRACE_STEALTH(HB_TR_DEBUG, ("hb_itemReSizeString(%p,%lu)", pItem, ulSize)); + + if( pItem->item.asString.allocated == 0 ) + { + char *szText = ( char* ) hb_xgrab( ulSize + 1 ); + hb_xmemcpy( szText, pItem->item.asString.value, + pItem->item.asString.length ); + szText[ ulSize ] = '\0'; + pItem->item.asString.value = szText; + pItem->item.asString.length = ulSize; + pItem->item.asString.allocated = ulSize + 1; + } +#if 0 + else if( pItem->item.asString.allocated > ulSize ) + { + pItem->item.asString.length = ulSize; + pItem->item.asString.value[ ulSize ] = '\0'; + } +#endif + else + { + ULONG ulAlloc = ulSize + 1 + + ( pItem->item.asString.allocated < ulSize ? ulSize : 0 ); + pItem->item.asString.value = ( char* ) + hb_xRefResize( pItem->item.asString.value, + pItem->item.asString.length, + ulAlloc ); + pItem->item.asString.length = ulSize; + pItem->item.asString.allocated = ulAlloc; + pItem->item.asString.value[ ulSize ] = '\0'; + } + + return pItem; +} + +/* Internal API, not standard Clipper */ +/* UnShare string buffer of given string item */ + +PHB_ITEM hb_itemUnShareString( PHB_ITEM pItem ) +{ + HB_TRACE_STEALTH(HB_TR_DEBUG, ("hb_itemUnShareString(%p)", pItem)); + + if( pItem->item.asString.allocated == 0 || + hb_xRefCount( pItem->item.asString.value ) > 1 ) + { + ULONG ulLen = pItem->item.asString.length + 1; + char *szText = ( char* ) hb_xgrab( ulLen ); + + hb_xmemcpy( szText, pItem->item.asString.value, ulLen ); + pItem->item.asString.value = szText; + if( ! pItem->item.asString.allocated ) + hb_xRefDec( pItem->item.asString.value ); + pItem->item.asString.allocated = ulLen; + } + + return pItem; +} PHB_ITEM hb_itemUnShare( PHB_ITEM pItem ) { HB_TRACE_STEALTH(HB_TR_DEBUG, ("hb_itemUnShare(%p)", pItem)); if( HB_IS_BYREF( pItem ) ) - { pItem = hb_itemUnRef( pItem ); - } if( HB_IS_STRING( pItem ) ) - { - if( pItem->item.asString.bStatic || *( pItem->item.asString.u.pulHolders ) > 1 ) - { - ULONG ulLen = pItem->item.asString.length; - char *szText = ( char* ) hb_xgrab( ulLen + 1 ); - - hb_xmemcpy( szText, pItem->item.asString.value, ulLen + 1 ); - pItem->item.asString.value = szText; - if( ! pItem->item.asString.bStatic ) - { - --*( pItem->item.asString.u.pulHolders ); - } - pItem->item.asString.u.pulHolders = ( HB_COUNTER * ) hb_xgrab( sizeof( HB_COUNTER ) ); - *( pItem->item.asString.u.pulHolders ) = 1; - } - } - - return pItem; + return hb_itemUnShareString( pItem ); + else + return pItem; } /* Internal API, not standard Clipper */ @@ -1645,7 +1685,7 @@ HB_EXPORT BOOL hb_itemStrBuf( char *szResult, PHB_ITEM pNumber, int iSize, int i double dInt, dFract, dDig, doBase = 10.0; int iPrec, iFirst = -1; - //dNumber = hb_numRound( dNumber, iDec ); + /* dNumber = hb_numRound( dNumber, iDec ); */ #ifdef HB_NUM_PRECISION iPrec = HB_NUM_PRECISION; @@ -1979,34 +2019,33 @@ HB_EXPORT char * hb_itemString( PHB_ITEM pItem, ULONG * ulLen, BOOL * bFreeReq ) break; case HB_IT_POINTER: + { + int size = ( sizeof( void * ) << 1 ) + 3; /* n bytes for address + 0x + \0 */ + int n; + BOOL bFail = TRUE; + + buffer = ( char * ) hb_xgrab( size ); + do { - int size = ( sizeof( void * ) << 1 ) + 3; /* n bytes for address + 0x + \0 */ - int n; - BOOL bFail = TRUE; - - buffer = ( char * ) hb_xgrab( size ); - do + n = snprintf( buffer, size, "%p", hb_itemGetPtr( pItem ) ); + if( (n > -1) && (n < size) ) { - n = snprintf( buffer, size, "%p", hb_itemGetPtr( pItem ) ); - if( (n > -1) && (n < size) ) - { - bFail = FALSE; - } - else - { - if( n > -1 ) - size = n + 1; - else - size *= 2; - buffer = ( char * ) hb_xrealloc( buffer, size ); - } + bFail = FALSE; + } + else + { + if( n > -1 ) + size = n + 1; + else + size *= 2; + buffer = ( char * ) hb_xrealloc( buffer, size ); } - while( bFail ); - * ulLen = strlen( buffer ); - * bFreeReq = TRUE; } + while( bFail ); + * ulLen = strlen( buffer ); + * bFreeReq = TRUE; break; - + } default: buffer = ""; * ulLen = 0; diff --git a/harbour/source/vm/macro.c b/harbour/source/vm/macro.c index 14385e90cf..6c3b465ea2 100644 --- a/harbour/source/vm/macro.c +++ b/harbour/source/vm/macro.c @@ -1228,7 +1228,7 @@ void hb_compGenPushSymbol( char * szSymbolName, BOOL bFunction, BOOL bAlias, HB_ } else if( bFunction ) { - if( pSym->pFunPtr==NULL ) + if( pSym->pSymbol->value.pFunPtr == NULL ) { /* static functions are not allowed in macro */ HB_MACRO_DATA->status |= HB_MACRO_UNKN_SYM; diff --git a/harbour/source/vm/maindllp.c b/harbour/source/vm/maindllp.c index 8eb4aa3cd2..9d5154451c 100644 --- a/harbour/source/vm/maindllp.c +++ b/harbour/source/vm/maindllp.c @@ -85,7 +85,7 @@ HB_EXPORT BOOL WINAPI DllEntryPoint( HINSTANCE hInstance, DWORD fdwReason, PVOID } /* module symbols initialization */ -void hb_vmProcessSymbols( PHB_SYMB pModuleSymbols, USHORT uiModuleSymbols ) +PHB_SYMB hb_vmProcessSymbols( PHB_SYMB pSymbols, USHORT uiSymbols ) { /* notice hb_vmProcessDllSymbols() must be used, and not * hb_vmProcessSymbols(), as some special symbols pointers @@ -94,10 +94,27 @@ void hb_vmProcessSymbols( PHB_SYMB pModuleSymbols, USHORT uiModuleSymbols ) FARPROC pProcessSymbols = GetProcAddress( GetModuleHandle( NULL ), "_hb_vmProcessDllSymbols" ); if( pProcessSymbols ) - ( ( VM_PROCESS_DLL_SYMBOLS ) pProcessSymbols ) ( pModuleSymbols, - uiModuleSymbols ); + return ( ( VM_PROCESS_DLL_SYMBOLS ) pProcessSymbols ) ( pSymbols, + uiSymbols ); /* else * may we issue an error ? */ + + return pSymbols; +} + +/* module symbols initialization */ +PHB_SYMB hb_vmProcessSymbolsExt( PHB_SYMB pSymbols, USHORT uiSymbols, char * szModuleName, ULONG ulID, USHORT uiPcodeMin, USHORT uiPcodeMax ) /* module symbols initialization with extended information */ +{ + FARPROC pProcessSymbols = GetProcAddress( GetModuleHandle( NULL ), + "_hb_vmProcessSymbolsExt" ); + if( pProcessSymbols ) + return ( ( VM_PROCESS_SYMBOLS_EXT ) pProcessSymbols ) + ( pSymbols, uiSymbols, szModuleName, + ulID, uiPcodeMin, uiPcodeMax ); + /* else + * may we issue an error ? */ + + return pSymbols; } void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) @@ -768,15 +785,6 @@ BOOL hb_arrayLast( PHB_ITEM pArray, PHB_ITEM pResult ) /* retrieve last ite return FALSE; } -BOOL hb_arrayRelease( PHB_ITEM pArray ) /* releases an array - don't call it - use ItemRelease() !!! */ -{ - HB_ARRAYRELEASE pArrayRelease = (HB_ARRAYRELEASE)GetProcAddress( GetModuleHandle( NULL ), "_hb_arrayRelease" ); - if (pArrayRelease) - return pArrayRelease( pArray ); - else - return FALSE; -} - BOOL hb_arraySet( PHB_ITEM pArray, ULONG ulIndex, PHB_ITEM pItem ) /* sets an array element */ { HB_ARRAYSET pArraySet = (HB_ARRAYSET)GetProcAddress( GetModuleHandle( NULL ), "_hb_arraySet" ); diff --git a/harbour/source/vm/memvars.c b/harbour/source/vm/memvars.c index a28e290c9a..16ffa76297 100644 --- a/harbour/source/vm/memvars.c +++ b/harbour/source/vm/memvars.c @@ -205,7 +205,7 @@ HB_HANDLE hb_memvarValueNew( HB_ITEM_PTR pSource, BOOL bTrueMemvar ) s_globalTable = ( HB_VALUE_PTR ) hb_xrealloc( s_globalTable, sizeof( HB_VALUE ) * s_globalTableSize ); } } - + pValue = s_globalTable + hValue; pValue->pVarItem = ( HB_ITEM_PTR ) hb_xgrab( sizeof( HB_ITEM ) ); pValue->counter = 1; @@ -219,9 +219,9 @@ HB_HANDLE hb_memvarValueNew( HB_ITEM_PTR pSource, BOOL bTrueMemvar ) } if( bTrueMemvar ) - pValue->hPrevMemvar = 0; + pValue->hPrevMemvar = 0; else - pValue->hPrevMemvar = ( HB_HANDLE )-1; /* detached variable */ + pValue->hPrevMemvar = ( HB_HANDLE ) -1; /* detached variable */ HB_TRACE(HB_TR_INFO, ("hb_memvarValueNew: memvar item created with handle %i", hValue)); @@ -233,7 +233,7 @@ HB_HANDLE hb_memvarValueNew( HB_ITEM_PTR pSource, BOOL bTrueMemvar ) HB_ITEM_PTR hb_memvarDetachLocal( HB_ITEM_PTR pLocal ) { HB_TRACE(HB_TR_DEBUG, ("hb_memvarDetachLocal(%p, %d)", pLocal, pLocal->type )); - + if( HB_IS_BYREF( pLocal ) && ! HB_IS_MEMVAR( pLocal ) ) { HB_ITEM_PTR pItem = pLocal; @@ -311,8 +311,7 @@ void hb_memvarSetPrivatesBase( ULONG ulBase ) while( s_privateStackCnt > s_privateStackBase ) { - --s_privateStackCnt; - hVar = s_privateStack[ s_privateStackCnt ]->hMemvar; + hVar = s_privateStack[ --s_privateStackCnt ]->hMemvar; if( hVar ) { hOldValue = s_globalTable[ hVar ].hPrevMemvar; @@ -373,7 +372,7 @@ void hb_memvarValueDecRef( HB_HANDLE hValue ) if( pValue->counter > 0 ) { - /* Notice that Counter can be equal to 0. + /* Notice that Counter can be equal to 0. * This can happen if for example PUBLIC variable holds a codeblock * with detached variable. When hb_memvarsRelease() is called then * detached variable can be released before the codeblock. So if @@ -382,7 +381,8 @@ void hb_memvarValueDecRef( HB_HANDLE hValue ) */ if( --pValue->counter == 0 ) { - hb_itemClear( pValue->pVarItem ); + if( HB_IS_COMPLEX( pValue->pVarItem ) ) + hb_itemClear( pValue->pVarItem ); hb_xfree( pValue->pVarItem ); hb_memvarRecycle( hValue ); @@ -391,6 +391,7 @@ void hb_memvarValueDecRef( HB_HANDLE hValue ) } } +#if 0 /* This function is called from releasing of detached local variables * referenced in a codeblock that is wiped out by the Garbage Collector. * Decrement the reference counter and clear a value stored in the memvar. @@ -409,7 +410,7 @@ void hb_memvarValueDecGarbageRef( HB_HANDLE hValue ) if( pValue->counter > 0 ) { - /* Notice that Counter can be equal to 0. + /* Notice that Counter can be equal to 0. * This can happen if for example PUBLIC variable holds a codeblock * with detached variable. When hb_memvarsRelease() is called then * detached variable can be released before the codeblock. So if @@ -427,6 +428,7 @@ void hb_memvarValueDecGarbageRef( HB_HANDLE hValue ) } } } +#endif /* * This functions copies passed item value into the memvar pointed @@ -513,7 +515,7 @@ void hb_memvarGetValue( HB_ITEM_PTR pItem, PHB_SYMB pMemvarSymb ) HB_ITEM_PTR pError; pError = hb_errRT_New( ES_ERROR, NULL, EG_NOVAR, 1003, - NULL, pMemvarSymb->szName, 0, EF_CANRETRY ); + NULL, pMemvarSymb->szName, 0, EF_CANRETRY ); while( uiAction == E_RETRY ) { @@ -556,7 +558,7 @@ void hb_memvarGetRefer( HB_ITEM_PTR pItem, PHB_SYMB pMemvarSymb ) HB_ITEM_PTR pError; pError = hb_errRT_New( ES_ERROR, NULL, EG_NOVAR, 1003, - NULL, pMemvarSymb->szName, 0, EF_CANRETRY ); + NULL, pMemvarSymb->szName, 0, EF_CANRETRY ); while( uiAction == E_RETRY ) { @@ -581,6 +583,24 @@ void hb_memvarGetRefer( HB_ITEM_PTR pItem, PHB_SYMB pMemvarSymb ) hb_errInternal( HB_EI_MVBADSYMBOL, NULL, pMemvarSymb->szName, NULL ); } +PHB_ITEM hb_memvarGetItem( PHB_SYMB pMemvarSymb ) +{ + PHB_DYNS pDyn; + + HB_TRACE(HB_TR_DEBUG, ("hb_memvarGetItem(%p)", pMemvarSymb)); + + pDyn = ( PHB_DYNS ) pMemvarSymb->pDynSym; + if( pDyn && pDyn->hMemvar ) + { + HB_ITEM_PTR pItem = s_globalTable[ pDyn->hMemvar ].pVarItem; + if( HB_IS_BYREF( pItem ) ) + return hb_itemUnRef( pItem ); + else + return pItem; + } + return NULL; +} + /* */ void hb_memvarNewParameter( PHB_SYMB pSymbol, PHB_ITEM pValue ) @@ -643,7 +663,8 @@ void hb_memvarCreateFromItem( PHB_ITEM pMemvar, BYTE bScope, PHB_ITEM pValue ) /* find dynamic symbol or creeate one */ if( HB_IS_SYMBOL( pMemvar ) ) - pDynVar = hb_dynsymGet( pMemvar->item.asSymbol.value->szName ); + /* pDynVar = hb_dynsymGet( pMemvar->item.asSymbol.value->szName ); */ + pDynVar = pMemvar->item.asSymbol.value->pDynSym; else if( HB_IS_STRING( pMemvar ) ) pDynVar = hb_dynsymGet( pMemvar->item.asString.value ); else @@ -1201,8 +1222,8 @@ HB_FUNC( __MVGET ) { PHB_ITEM pValue; - pValue = hb_stackTopItem(); hb_stackPush(); + pValue = hb_stackItemFromTop( -1 ); hb_memvarGetValue( pValue, pDynVar->pSymbol ); hb_itemReturnForward( pValue ); hb_stackDec(); @@ -1229,8 +1250,8 @@ HB_FUNC( __MVGET ) { PHB_ITEM pValue; - pValue = hb_stackTopItem(); hb_stackPush(); + pValue = hb_stackItemFromTop( -1 ); hb_memvarGetValue( pValue, pDynVar->pSymbol ); hb_itemReturnForward( pValue ); hb_stackDec(); diff --git a/harbour/source/vm/proc.c b/harbour/source/vm/proc.c index 11bdb48449..76da1d4869 100644 --- a/harbour/source/vm/proc.c +++ b/harbour/source/vm/proc.c @@ -69,6 +69,7 @@ #include "hbvmopt.h" #include "hbapi.h" +#include "hbapicls.h" #include "hbapiitm.h" #include "hbstack.h" diff --git a/harbour/source/vm/pvalue.c b/harbour/source/vm/pvalue.c index ad5b483e4c..f21289c195 100644 --- a/harbour/source/vm/pvalue.c +++ b/harbour/source/vm/pvalue.c @@ -58,10 +58,11 @@ HB_FUNC( HB_PVALUE ) { USHORT uiParam = hb_parni( 1 ); - PHB_ITEM *pBase = hb_stack.pItems + ( hb_stackBaseItem() )->item.asSymbol.stackbase; /* Skip function + self */ + LONG lOffset = hb_stackBaseItem()->item.asSymbol.stackbase; /* Skip function + self */ + PHB_ITEM pBase = hb_stackItem( lOffset ); - if( uiParam && uiParam <= ( *pBase )->item.asSymbol.paramcnt ) /* Valid number */ - hb_itemReturn( *( pBase + 1 + uiParam ) ); + if( uiParam && uiParam <= pBase->item.asSymbol.paramcnt ) /* Valid number */ + hb_itemReturn( hb_stackItem( lOffset + 1 + uiParam ) ); else hb_ret(); /* return NIL */ } diff --git a/harbour/source/vm/runner.c b/harbour/source/vm/runner.c index 12c78cd7f6..3a894ecf79 100644 --- a/harbour/source/vm/runner.c +++ b/harbour/source/vm/runner.c @@ -68,79 +68,44 @@ #include "hbapifs.h" #include "hbvm.h" #include "hbpcode.h" +#include "hb_io.h" /* TODO: Fill the error codes with valid ones (instead of 9999) */ -/* TOFIX: Change this assembler hack to something standard and portable */ -/* TODO: Change the fopen()/fread()/fclose() calls to hb_fs*() */ /* TOFIX: Fix the memory leak on error. */ -/* NOTE: This is the assembler output from : hb_vmExecute( pcode, symbols ). */ - -/* #if INTEL32 */ - -static BYTE prgFunction[] = -{ - 0x68, 0x00, 0x00, 0x00, 0x00, /* push offset pcode */ - 0x68, 0x00, 0x00, 0x00, 0x00, /* push offset symbols */ - 0xE8, 0x00, 0x00, 0x00, 0x00, /* call near relative hb_vmExecute */ - 0x83, 0xC4, 0x08, /* add esp, 8 */ - 0xC3 /* ret near */ -}; - -/* #elseif INTEL16 */ -/* #elseif MOTOROLA */ -/* #elseif ... */ -/* #endif */ - -typedef union -{ - BYTE * pAsmData; /* The assembler bytes */ - PHB_FUNC pFunPtr; /* The (dynamic) harbour - function */ -} ASM_CALL, * PASM_CALL; - typedef struct { - char * szName; /* Name of the function */ - PASM_CALL pAsmCall; /* Assembler call */ - BYTE * pCode; /* P-code */ + char * szName; /* Name of the function */ + PHB_PCODEFUNC pCodeFunc; /* Dynamic function info */ + BYTE * pCode; /* P-code */ } HB_DYNF, * PHB_DYNF; typedef struct { - ULONG ulSymbols; /* Number of symbols */ - ULONG ulFuncs; /* Number of functions */ - LONG ulSymStart; /* Startup Symbol */ - PHB_SYMB pSymRead; /* Symbols read */ - PHB_DYNF pDynFunc; /* Functions read */ + ULONG ulSymbols; /* Number of symbols */ + ULONG ulFuncs; /* Number of functions */ + BOOL fInit; /* should be INIT functions executed */ + BOOL fExit; /* should be EXIT functions executed */ + LONG ulSymStart; /* Startup Symbol */ + PHB_SYMB pSymRead; /* Symbols read */ + PHB_DYNF pDynFunc; /* Functions read */ + PHB_SYMBOLS pModuleSymbols; } HRB_BODY, * PHRB_BODY; -#define SYM_NOLINK 0 /* Symbol does not have to - be linked */ +#define SYM_NOLINK 0 /* Symbol does not have to be linked */ #define SYM_FUNC 1 /* Defined function */ #define SYM_EXTERN 2 /* Prev. defined function */ +#define SYM_NOT_FOUND 0xFFFFFFFF /* Symbol not found. */ -#define SYM_NOT_FOUND 0xFFFFFFFF /* Symbol not found. - FindSymbol */ +HB_EXTERN_BEGIN +HB_EXPORT PHRB_BODY hb_hrbLoad( char* szHrbBody, ULONG ulBodySize ); +HB_EXPORT PHRB_BODY hb_hrbLoadFromFile( char* szHrb ); +HB_EXPORT void hb_hrbDo( PHRB_BODY pHrbBody, int argc, char * argv[] ); +HB_EXPORT void hb_hrbUnLoad( PHRB_BODY pHrbBody ); +HB_EXTERN_END -PHRB_BODY hb_hrbLoad( char* szHrb ); -void hb_hrbDo( PHRB_BODY pHrbBody, int argc, char * argv[] ); -void hb_hrbUnLoad( PHRB_BODY pHrbBody ); -static ULONG hb_hrbFindSymbol( char * szName, PHB_DYNF pDynFunc, ULONG ulLoaded ); -static PASM_CALL hb_hrbAsmCreateFun( PHB_SYMB pSymbols, BYTE * pCode ); /* Create a dynamic function*/ -static void hb_hrbAsmPatch( BYTE * pCode, ULONG ulOffset, void * Address ); -static void hb_hrbAsmPatchRelative( BYTE * pCode, ULONG ulOffset, void * Address, ULONG ulNext ); - -static FILE * hb_hrbFileOpen( char * szFileName ); -static void hb_hrbFileRead( FILE * file, char * szFileName, char * cBuffer, int iSize, int iCount ); -static BYTE hb_hrbFileReadByte( FILE * file, char * szFileName ); -static int hb_hrbFileReadHead( FILE * file, char * szFileName ); -static char * hb_hrbFileReadId( FILE * file, char * szFileName ); -static long hb_hrbFileReadLong( FILE * file, char * szFileName ); -static void hb_hrbFileClose( FILE * file ); - -static ULONG s_ulSymEntry = 0; /* Link enhancement */ +static void hb_hrbInit( PHRB_BODY pHrbBody, int argc, char * argv[] ); /* __HRBRUN( [, xParam1 [, xParamN ] ] ) -> return value. @@ -158,38 +123,92 @@ HB_FUNC( __HRBRUN ) if( argc >= 1 ) { - PHRB_BODY pHrbBody = hb_hrbLoad( hb_parc( 1 ) ); + PHRB_BODY pHrbBody = hb_hrbLoadFromFile( hb_parcx( 1 ) ); if( pHrbBody ) { - int i; char **argv = NULL; + int i; if( argc > 1 ) { argv = (char**) hb_xgrab( sizeof(char*) * (argc-1) ); + for( i=0; i= 1 ) - hb_retptr( (void *) hb_hrbLoad( hb_parc( 1 ) ) ); + int argc = hb_pcount(); + + if( argc >= 1 ) + { + BYTE szHead[] = { (BYTE)192,'H','R','B' }; + char * fileOrBody = hb_parc( 1 ); + PHRB_BODY pHrbBody; + + /* If parameter string */ + if ( fileOrBody && hb_parclen( 1 ) > 4 && strncmp( ( char * ) szHead, ( char * ) fileOrBody, 4 ) == 0 ) + { + pHrbBody = hb_hrbLoad( fileOrBody, hb_parclen( 1 ) ); + } + else + { + pHrbBody = hb_hrbLoadFromFile( fileOrBody ); + } + if ( pHrbBody ) + { + char **argv = NULL; + int i; + + if( argc > 1 ) + { + argv = (char**) hb_xgrab( sizeof(char*) * (argc-1) ); + + for( i=0; i 1 ) { - argv = (char**) hb_xgrab( sizeof(char*) * (argc-1) ); - for( i=0; i= 1 ) + { hb_hrbUnLoad( (PHRB_BODY) hb_parptr( 1 ) ); + } else + { hb_errRT_BASE( EG_ARG, 9999, NULL, "__HRBUNLOAD", 0 ); + } } HB_FUNC( __HRBGETFU ) @@ -238,30 +272,44 @@ HB_FUNC( __HRBGETFU ) if( pHrbBody ) { - char * szName = hb_strupr( hb_strdup( hb_parc( 2 ) ) ); + char * szName = hb_strupr( hb_strdup( hb_parcx( 2 ) ) ); while( ulPos < pHrbBody->ulSymbols ) { if( !strcmp( szName, pHrbBody->pSymRead[ ulPos ].szName ) ) + { break; + } + ulPos++; } + if( ulPos < pHrbBody->ulSymbols ) + { hb_retptr( ( void *) ( pHrbBody->pSymRead + ulPos ) ); + } else + { hb_retptr( NULL ); + } + hb_xfree( szName ); } else + { hb_errRT_BASE( EG_ARG, 9999, NULL, "__HRBGETFU", 0 ); + } } else + { hb_errRT_BASE( EG_ARG, 9999, NULL, "__HRBGETFU", 0 ); + } } HB_FUNC( __HRBDOFU ) { int argc = hb_pcount(); + if( argc >=1 ) { int i; @@ -271,48 +319,230 @@ HB_FUNC( __HRBDOFU ) { hb_vmPushSymbol( pSym ); hb_vmPushNil(); + for( i = 0; i < argc-1; i++ ) /* Push other params */ + { hb_vmPush( hb_param( i + 2, HB_IT_ANY ) ); + } hb_vmDo( argc-1 ); /* Run function */ } else + { hb_errRT_BASE( EG_ARG, 9999, NULL, "__HRBDOFU", 0 ); + } } else + { hb_errRT_BASE( EG_ARG, 9999, NULL, "__HRBDOFU", 0 ); + } } -PHRB_BODY hb_hrbLoad( char* szHrb ) + +static ULONG hb_hrbFindSymbol( char * szName, PHB_DYNF pDynFunc, ULONG ulLoaded ) { - char szFileName[ _POSIX_PATH_MAX + 1 ]; - PHB_FNAME pFileName; - FILE * file; - BOOL bError = FALSE; - PHRB_BODY pHrbBody = NULL; + ULONG ulRet = 0; - /* Create full filename */ + HB_TRACE(HB_TR_DEBUG, ("hb_hrbFindSymbol(%s, %p, %lu)", szName, pDynFunc, ulLoaded)); - pFileName = hb_fsFNameSplit( szHrb ); - - if( ! pFileName->szExtension ) - pFileName->szExtension = ".hrb"; - - hb_fsFNameMerge( szFileName, pFileName ); - - hb_xfree( pFileName ); - - /* Open as binary */ - - while ( ( file = hb_hrbFileOpen( szFileName ) ) == NULL ) + while( ulRet < ulLoaded ) { - USHORT uiAction = hb_errRT_BASE_Ext1( EG_OPEN, 9999, NULL, szFileName, 0, EF_CANDEFAULT | EF_CANRETRY, 1, hb_paramError( 1 ) ); + if( ! strcmp( szName, pDynFunc[ ulRet ].szName ) ) + { + return ulRet; + } + ulRet++; + } + return SYM_NOT_FOUND; +} - if( uiAction == E_DEFAULT || uiAction == E_BREAK ) - break; +static int hb_hrbReadHead( char * szBody, ULONG ulBodySize, ULONG * ulBodyOffset ) +{ + BYTE szHead[] = { (BYTE)192,'H','R','B' }; + char cInt[ 2 ]; + + HB_TRACE(HB_TR_DEBUG, ("hb_hrbReadHead(%p,%i,%i)", szBody, ulBodySize, * ulBodyOffset )); + + if( ulBodySize < 6 || strncmp( ( char * ) szHead, ( char * ) szBody, 4 ) ) + { + hb_errRT_BASE( EG_CORRUPTION, 9999, NULL, "__HRBLOAD", 0 ); + return 0; } - if( file ) + cInt[0] = szBody[(*ulBodyOffset)+4]; + cInt[1] = szBody[(*ulBodyOffset)+5]; + + * ulBodyOffset += 6; // header + version offset + + return HB_PCODE_MKSHORT( cInt ); +} + +/* ReadId + Read the next (zero terminated) identifier */ +static char * hb_hrbReadId( char * szBody, ULONG ulBodySize, ULONG * ulBodyOffset ) +{ + char * szIdx; + + HB_TRACE(HB_TR_DEBUG, ("hb_hrbReadId(%p,%lu,%p)", szBody, ulBodySize, ulBodyOffset)); + + szIdx = &szBody[ *ulBodyOffset ]; + + do + { + if ( *ulBodyOffset > ulBodySize ) + { + hb_errRT_BASE( EG_CORRUPTION, 9999, NULL, "__HRBLOAD", 0 ); + szIdx = ""; + break; + } + } + while( szBody[ ( *ulBodyOffset )++ ] ); + + return hb_strdup( szIdx ); +} + + +static LONG hb_hrbReadLong( char * szBody, ULONG ulBodySize, ULONG * ulBodyOffset ) +{ + char cLong[ 4 ]; /* Temporary long */ + + HB_TRACE(HB_TR_DEBUG, ("hb_hrbReadLong(%p,%i,%i)", szBody, ulBodySize, * ulBodyOffset)); + + if ( (* ulBodyOffset + 4) > ulBodySize ) + { + hb_errRT_BASE( EG_CORRUPTION, 9999, NULL, "__HRBLOAD", 0 ); + return 0; + } + + memcpy( cLong, (char *) (szBody+(*ulBodyOffset)), 4 ); + + * ulBodyOffset += 4; + + if( cLong[ 3 ] ) /* Convert to long if ok */ + { + hb_errRT_BASE( EG_CORRUPTION, 9999, NULL, "__HRBLOAD", 0 ); + return 0; + } + else + { + return HB_PCODE_MKLONG( cLong ); + } +} + +static void hb_hrbInitStatic( PHRB_BODY pHrbBody ) +{ + if( ! pHrbBody->fInit && ! pHrbBody->fExit ) + { + ULONG ul; + + pHrbBody->fInit = TRUE; + /* Initialize static variables first */ + for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) /* Check _INITSTATICS functions */ + { + if( ( pHrbBody->pSymRead[ ul ].scope.value & HB_FS_INITEXIT ) == HB_FS_INITEXIT ) + { + /* call (_INITSTATICS) function. This function assigns + * literal values to static variables only. There is no need + * to pass any parameters to this function because they + * cannot be used to initialize static variable. + */ + + /* changed to call VM execution instead of direct function address call + * pHrbBody->pSymRead[ ul ].value.pFunPtr(); + * [MLombardo] + */ + + hb_vmPushSymbol( &(pHrbBody->pSymRead[ ul ]) ); + hb_vmPushNil(); + hb_vmDo( 0 ); + + } + } + } +} + +static void hb_hrbInit( PHRB_BODY pHrbBody, int argc, char * argv[] ) +{ + if ( pHrbBody->fInit ) + { + ULONG ul; + int i; + + pHrbBody->fInit = FALSE; + pHrbBody->fExit = TRUE; + + for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) /* Check INIT functions */ + { + if( ( pHrbBody->pSymRead[ ul ].scope.value & HB_FS_INITEXIT ) == HB_FS_INIT ) + { + hb_vmPushSymbol( pHrbBody->pSymRead + ul ); + hb_vmPushNil(); + for( i = 0; i < argc; i++ ) /* Push other cmdline params*/ + hb_vmPushString( argv[i], strlen( argv[i] ) ); + + hb_vmDo( argc ); /* Run init function */ + } + } + } +} + +static void hb_hrbExit( PHRB_BODY pHrbBody ) +{ + if ( pHrbBody->fExit ) + { + ULONG ul; + + pHrbBody->fExit = FALSE; + pHrbBody->fInit = TRUE; + + for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) + { + if( ( pHrbBody->pSymRead[ ul ].scope.value & HB_FS_INITEXIT ) == HB_FS_EXIT ) + { + hb_vmPushSymbol( pHrbBody->pSymRead + ul ); + hb_vmPushNil(); + hb_vmDo( 0 ); + } + } + } +} + +void hb_hrbUnLoad( PHRB_BODY pHrbBody ) +{ + ULONG ul; + + hb_hrbExit( pHrbBody ); + + if( pHrbBody->pModuleSymbols ) + { + hb_vmFreeSymbols( pHrbBody->pModuleSymbols ); + } + + for( ul = 0; ul < pHrbBody->ulFuncs; ul++ ) + { + PHB_DYNS pDyn; + + pDyn = hb_dynsymFind( pHrbBody->pDynFunc[ ul ].szName ); + if( pDyn && pDyn->pSymbol->value.pCodeFunc == pHrbBody->pDynFunc[ ul ].pCodeFunc ) + { + pDyn->pSymbol->value.pCodeFunc = NULL; + } + + hb_xfree( pHrbBody->pDynFunc[ ul ].pCodeFunc ); + hb_xfree( pHrbBody->pDynFunc[ ul ].pCode ); + hb_xfree( pHrbBody->pDynFunc[ ul ].szName ); + } + + hb_xfree( pHrbBody->pDynFunc ); + hb_xfree( pHrbBody ); +} + +PHRB_BODY hb_hrbLoad( char* szHrbBody, ULONG ulBodySize ) +{ + PHRB_BODY pHrbBody = NULL; + ULONG ulBodyOffset = 0; + + if( szHrbBody ) { ULONG ulSize; /* Size of function */ ULONG ul, ulPos; @@ -320,397 +550,225 @@ PHRB_BODY hb_hrbLoad( char* szHrb ) PHB_SYMB pSymRead; /* Symbols read */ PHB_DYNF pDynFunc; /* Functions read */ PHB_DYNS pDynSym; - int nVersion = hb_hrbFileReadHead( file, szFileName ); + + int nVersion = hb_hrbReadHead( (char *) szHrbBody, (ULONG) ulBodySize, &ulBodyOffset ); if( !nVersion ) { - hb_hrbFileClose( file ); return NULL; } + pHrbBody = ( PHRB_BODY ) hb_xgrab( sizeof( HRB_BODY ) ); + + pHrbBody->fInit = FALSE; + pHrbBody->fExit = FALSE; pHrbBody->ulSymStart = -1; - pHrbBody->ulSymbols = hb_hrbFileReadLong( file, szFileName ); + pHrbBody->ulFuncs = 0; + pHrbBody->pSymRead = NULL; + pHrbBody->pDynFunc = NULL; + pHrbBody->ulSymbols = hb_hrbReadLong( (char *) szHrbBody, ulBodySize, &ulBodyOffset ); + pHrbBody->pModuleSymbols = NULL; + pSymRead = ( PHB_SYMB ) hb_xgrab( pHrbBody->ulSymbols * sizeof( HB_SYMB ) ); - for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) /* Read symbols in .HRB */ + for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) /* Read symbols in .HRB */ { - pSymRead[ ul ].szName = hb_hrbFileReadId( file, szFileName ); - pSymRead[ ul ].scope.value = hb_hrbFileReadByte( file, szFileName ); - pSymRead[ ul ].value.pFunPtr = ( PHB_FUNC ) ( ULONG ) hb_hrbFileReadByte( file, szFileName ); + pSymRead[ ul ].szName = hb_hrbReadId( (char *) szHrbBody, ulBodySize, &ulBodyOffset ); + pSymRead[ ul ].scope.value = szHrbBody[ulBodyOffset++]; + pSymRead[ ul ].value.pCodeFunc = ( PHB_PCODEFUNC ) ( HB_PTRDIFF ) szHrbBody[ulBodyOffset++]; pSymRead[ ul ].pDynSym = NULL; - if ( pHrbBody->ulSymStart == -1 && - pSymRead[ ul ].scope.value & HB_FS_FIRST && - ! ( pSymRead[ ul ].scope.value & HB_FS_INITEXIT ) ) + if( pHrbBody->ulSymStart == -1 && + ( pSymRead[ ul ].scope.value & HB_FS_FIRST ) != 0 && + ( pSymRead[ ul ].scope.value & HB_FS_INITEXIT ) == 0 ) + { pHrbBody->ulSymStart = ul; + } } - pHrbBody->ulFuncs = hb_hrbFileReadLong( file, szFileName ); /* Read number of functions */ + pHrbBody->ulFuncs = hb_hrbReadLong( (char *) szHrbBody, ulBodySize, &ulBodyOffset ); /* Read number of functions */ + pDynFunc = ( PHB_DYNF ) hb_xgrab( pHrbBody->ulFuncs * sizeof( HB_DYNF ) ); memset( pDynFunc, 0, pHrbBody->ulFuncs * sizeof( HB_DYNF ) ); - for( ul = 0; ul < pHrbBody->ulFuncs; ul++ ) /* Read symbols in .HRB */ - { - pDynFunc[ ul ].szName = hb_hrbFileReadId( file, szFileName ); - ulSize = hb_hrbFileReadLong( file, szFileName ); /* Read size of function */ + for( ul = 0; ul < pHrbBody->ulFuncs; ul++ ) + { + pDynFunc[ ul ].szName = hb_hrbReadId( (char *) szHrbBody, ulBodySize, &ulBodyOffset ); + ulSize = hb_hrbReadLong( (char *) szHrbBody, ulBodySize, &ulBodyOffset ); /* Read size of function */ pDynFunc[ ul ].pCode = ( BYTE * ) hb_xgrab( ulSize ); - hb_hrbFileRead( file, szFileName, ( char * ) pDynFunc[ ul ].pCode, 1, ulSize ); - /* Read the block */ - pDynFunc[ ul ].pAsmCall = hb_hrbAsmCreateFun( pSymRead, - pDynFunc[ ul ].pCode ); - /* Create matching dynamic */ - /* function */ + + /* Read the block */ + memcpy( ( char * ) pDynFunc[ ul ].pCode, (char *) (szHrbBody + ulBodyOffset), ulSize ); + ulBodyOffset += ulSize; + pDynFunc[ ul ].pCodeFunc = (PHB_PCODEFUNC) hb_xgrab( sizeof( HB_PCODEFUNC ) ); + pDynFunc[ ul ].pCodeFunc->pCode = pDynFunc[ ul ].pCode; + pDynFunc[ ul ].pCodeFunc->pSymbols = pSymRead; } pHrbBody->pSymRead = pSymRead; pHrbBody->pDynFunc = pDynFunc; - s_ulSymEntry = 0; - for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) /* Linker */ + + for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) /* Linker */ { - if( ( ( ULONG ) pSymRead[ ul ].value.pFunPtr ) == SYM_FUNC ) + if( pSymRead[ ul ].value.pCodeFunc == ( PHB_PCODEFUNC ) SYM_FUNC ) { ulPos = hb_hrbFindSymbol( pSymRead[ ul ].szName, pDynFunc, pHrbBody->ulFuncs ); - if( ulPos != SYM_NOT_FOUND ) + + if( ulPos == SYM_NOT_FOUND ) { - /* Exists and NOT static ? */ -/* if( hb_dynsymFind( pSymRead[ ul ].szName ) && - !( pSymRead[ ul ].scope.value & HB_FS_STATIC ) ) - { - hb_errRT_BASE( EG_ARG, 9999, "Duplicate symbol", pSymRead[ ul ].szName ); - bError = TRUE; - break; - } -*/ - pSymRead[ ul ].value.pFunPtr = pDynFunc[ ulPos ].pAsmCall->pFunPtr; + pSymRead[ ul ].value.pCodeFunc = ( PHB_PCODEFUNC ) SYM_EXTERN; } else - pSymRead[ ul ].value.pFunPtr = ( PHB_FUNC ) SYM_EXTERN; + { + pSymRead[ ul ].value.pCodeFunc = ( PHB_PCODEFUNC ) pDynFunc[ ulPos ].pCodeFunc; + pSymRead[ ul ].scope.value |= HB_FS_PCODEFUNC; /* | HB_FS_LOCAL; */ + } } - if( ( ( ULONG ) pSymRead[ ul ].value.pFunPtr ) == SYM_EXTERN ) - { /* External function */ + + /* External function */ + if( pSymRead[ ul ].value.pCodeFunc == ( PHB_PCODEFUNC ) SYM_EXTERN ) + { pDynSym = hb_dynsymFind( pSymRead[ ul ].szName ); - if( !pDynSym ) + + if( pDynSym ) + { + pSymRead[ ul ].value.pFunPtr = pDynSym->pSymbol->value.pFunPtr; + if( pDynSym->pSymbol->scope.value & HB_FS_PCODEFUNC ) + { + pSymRead[ ul ].scope.value |= HB_FS_PCODEFUNC; + } + } + else { char szName[21]; - strncpy( szName,pSymRead[ ul ].szName,20 ); + + strncpy( szName, pSymRead[ ul ].szName, 20 ); + hb_hrbUnLoad( pHrbBody ); hb_errRT_BASE( EG_ARG, 9999, "Unknown or unregistered symbol", szName, 0 ); - bError = TRUE; - break; + return NULL; } - pSymRead[ ul ].value.pFunPtr = pDynSym->pFunPtr; } } - if( bError ) - { - hb_hrbUnLoad( pHrbBody ); - pHrbBody = NULL; - } - hb_hrbFileClose( file ); + if( pHrbBody ) + { + pHrbBody->pModuleSymbols = hb_vmRegisterSymbols( pHrbBody->pSymRead, + ( USHORT ) pHrbBody->ulSymbols, "pcode.hrb", 0, TRUE, FALSE ); + + if( pHrbBody->pModuleSymbols->pModuleSymbols != pSymRead ) + { + /* + * Old unused symbol table has been recycled - free the one + * we allocated and disactivate static initialization [druzus] + */ + pHrbBody->pSymRead = pHrbBody->pModuleSymbols->pModuleSymbols; + + for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) + { + if( pSymRead[ ul ].szName ) + hb_xfree( pSymRead[ ul ].szName ); + } + hb_xfree( pSymRead ); + + pHrbBody->fInit = TRUE; + } + else + { + /* mark symbol table as dynamically allocated so HVM will free it on exit */ + pHrbBody->pModuleSymbols->fAllocated = TRUE; + + /* initialize static variables */ + hb_hrbInitStatic( pHrbBody ); + } + } } - hb_vmProcessSymbols( pHrbBody->pSymRead, ( USHORT ) pHrbBody->ulSymbols ); + return pHrbBody; } +PHRB_BODY hb_hrbLoadFromFile( char* szHrb ) +{ + char szFileName[ _POSIX_PATH_MAX + 1 ]; + PHRB_BODY pHrbBody = NULL; + PHB_FNAME pFileName; + FHANDLE file; + + /* Create full filename */ + + pFileName = hb_fsFNameSplit( szHrb ); + + if( ! pFileName->szExtension ) + { + pFileName->szExtension = ".hrb"; + } + + hb_fsFNameMerge( szFileName, pFileName ); + + hb_xfree( pFileName ); + + /* Open as binary */ + + while ( ( file = hb_fsOpen( ( BYTE *)szFileName, FO_READ )) == 0 ) + { + USHORT uiAction = hb_errRT_BASE_Ext1( EG_OPEN, 9999, NULL, szFileName, hb_fsError(), EF_CANDEFAULT | EF_CANRETRY, 1, hb_paramError( 1 ) ); + + if( uiAction == E_DEFAULT || uiAction == E_BREAK ) + { + break; + } + } + + if( file ) + { + ULONG ulBodySize = hb_fsSeek( file, 0, FS_END ); + + if( ulBodySize ) + { + BYTE * pbyBuffer; + + pbyBuffer = ( BYTE * ) hb_xgrab( ulBodySize + sizeof( char ) + 1 ); + hb_fsSeek( file, 0, FS_SET ); + hb_fsReadLarge( file, pbyBuffer, ulBodySize ); + pbyBuffer[ ulBodySize ] = '\0'; + + pHrbBody = hb_hrbLoad( (char*) pbyBuffer, (ULONG) ulBodySize ); + + hb_xfree( pbyBuffer ); + } + hb_fsClose( file ); + } + return( pHrbBody ); +} + void hb_hrbDo( PHRB_BODY pHrbBody, int argc, char * argv[] ) { PHB_ITEM pRetVal = NULL; - ULONG ul; int i; - /* Initialize static variables first - */ - for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) /* Check INIT functions */ - { - if( ( pHrbBody->pSymRead[ ul ].scope.value & HB_FS_INITEXIT ) == HB_FS_INITEXIT ) - { - /* call (_INITSTATICS) function. This function assigns - * literal values to static variables only. There is no need - * to pass any parameters to this function because they - * cannot be used to initialize static variable. - */ - pHrbBody->pSymRead[ ul ].value.pFunPtr(); - } - } - for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) /* Check INIT functions */ - { - if( ( pHrbBody->pSymRead[ ul ].scope.value & HB_FS_INITEXIT ) == HB_FS_INIT ) - { - hb_vmPushSymbol( pHrbBody->pSymRead + ul ); - hb_vmPushNil(); - for( i = 0; i < argc; i++ ) /* Push other cmdline params*/ - hb_vmPushString( argv[i],strlen(argv[i]) ); - - hb_vmDo( argc ); /* Run init function */ - } - } + hb_hrbInit( pHrbBody, argc, argv ); /* May not have a startup symbol, if first symbol was an INIT Symbol (was executed already).*/ if ( pHrbBody->ulSymStart >= 0 ) { hb_vmPushSymbol( &( pHrbBody->pSymRead[ pHrbBody->ulSymStart ] ) ); hb_vmPushNil(); + for( i = 0; i < ( hb_pcount() - 1 ); i++ ) + { hb_vmPush( hb_param( i + 2, HB_IT_ANY ) ); /* Push other cmdline params*/ + } + hb_vmDo( hb_pcount() - 1 ); /* Run the thing !!! */ pRetVal = hb_itemNew( NULL ); - hb_itemCopy( pRetVal, &hb_stack.Return ); + hb_itemMove( pRetVal, hb_stackReturnItem() ); } - for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) /* Check EXIT functions */ - { - if( ( pHrbBody->pSymRead[ ul ].scope.value & HB_FS_INITEXIT ) == HB_FS_EXIT ) - { - hb_vmPushSymbol( pHrbBody->pSymRead + ul ); - hb_vmPushNil(); - hb_vmDo( 0 ); /* Run exit function */ - pHrbBody->pSymRead[ ul ].scope.value = pHrbBody->pSymRead[ ul ].scope.value & ( ~HB_FS_EXIT ); - /* Exit function cannot be - handled by main in hvm.c */ - } - } + hb_hrbExit( pHrbBody ); if( pRetVal ) - hb_itemRelease( hb_itemReturn( pRetVal ) ); -} - -void hb_hrbUnLoad( PHRB_BODY pHrbBody ) -{ - ULONG ul; - - for( ul = 0; ul < pHrbBody->ulFuncs; ul++ ) { - hb_xfree( pHrbBody->pDynFunc[ ul ].pAsmCall->pAsmData ); - hb_xfree( pHrbBody->pDynFunc[ ul ].pAsmCall ); - hb_xfree( pHrbBody->pDynFunc[ ul ].pCode ); - hb_xfree( pHrbBody->pDynFunc[ ul ].szName ); + hb_itemRelease( hb_itemReturnForward( pRetVal ) ); } - - for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) - hb_xfree( pHrbBody->pSymRead[ ul ].szName ); - - hb_xfree( pHrbBody->pDynFunc ); - hb_xfree( pHrbBody->pSymRead ); - hb_xfree( pHrbBody ); -} - -static ULONG hb_hrbFindSymbol( char * szName, PHB_DYNF pDynFunc, ULONG ulLoaded ) -{ - ULONG ulRet; - - HB_TRACE(HB_TR_DEBUG, ("hb_hrbFindSymbol(%s, %p, %lu)", szName, pDynFunc, ulLoaded)); - - if( ( s_ulSymEntry < ulLoaded ) && /* Is it a normal list ? */ - !strcmp( szName, pDynFunc[ s_ulSymEntry ].szName ) ) - ulRet = s_ulSymEntry++; - else - { - BOOL bFound = FALSE; - - ulRet = 0; - while( !bFound && ulRet < ulLoaded ) - { - if( !strcmp( szName, pDynFunc[ ulRet ].szName ) ) - bFound = TRUE; - else - ulRet++; - } - if( !bFound ) - ulRet = SYM_NOT_FOUND; - } - return ulRet; -} - -static int hb_hrbFileReadHead( FILE * file, char * szFileName ) -{ - unsigned char szHead[] = { (unsigned char)192,'H','R','B' }, szBuf[4]; - char cInt[ 2 ]; - - HB_TRACE(HB_TR_DEBUG, ("hb_hrbFileReadHead(%p)", file )); - - hb_hrbFileRead( file, szFileName, ( char * ) szBuf, 1, 4 ); - if( strncmp( ( char * ) szHead, ( char * ) szBuf, 4 ) ) - { - hb_errRT_BASE_Ext1( EG_CORRUPTION, 9999, NULL, szFileName, 0, EF_CANDEFAULT, 1, hb_paramError( 1 ) ); - return 0; - } - hb_hrbFileRead( file, szFileName, cInt, 2, 1 ); - - return HB_PCODE_MKSHORT( cInt ); -} - -/* ReadId - Read the next (zero terminated) identifier */ -static char * hb_hrbFileReadId( FILE * file, char * szFileName ) -{ - char * szTemp; /* Temporary buffer */ - char * szIdx; - char * szRet; - BOOL bCont = TRUE; - - HB_TRACE(HB_TR_DEBUG, ("hb_hrbFileReadId(%p, %s)", file, szFileName)); - - szTemp = ( char * ) hb_xgrab( 256 ); - szIdx = szTemp; - do - { - hb_hrbFileRead( file, szFileName, szIdx, 1, 1 ); - if( *szIdx ) - szIdx++; - else - bCont = FALSE; - } while( bCont ); - - szRet = ( char * ) hb_xgrab( szIdx - szTemp + 1 ); - strcpy( szRet, szTemp ); - hb_xfree( szTemp ); - - return szRet; -} - - -static BYTE hb_hrbFileReadByte( FILE * file, char * szFileName ) -{ - BYTE bRet; - - HB_TRACE(HB_TR_DEBUG, ("hb_hrbFileReadByte(%p, %s)", file, szFileName)); - - hb_hrbFileRead( file, szFileName, ( char * ) &bRet, 1, 1 ); - - return bRet; -} - - -static long hb_hrbFileReadLong( FILE * file, char * szFileName ) -{ - char cLong[ 4 ]; /* Temporary long */ - - HB_TRACE(HB_TR_DEBUG, ("hb_hrbFileReadLong(%p, %s)", file, szFileName)); - - hb_hrbFileRead( file, szFileName, cLong, 4, 1 ); - - if( cLong[ 3 ] ) /* Convert to long if ok */ - { - hb_errRT_BASE_Ext1( EG_READ, 9999, NULL, szFileName, 0, EF_NONE, 0 ); - return 0; - } - else - return HB_PCODE_MKLONG( cLong ); -} - - -/* hb_hrbFileRead - Controlled read from file. If errornous -> Break */ -static void hb_hrbFileRead( FILE * file, char * szFileName, char * cBuffer, int iSize, int iCount ) -{ - HB_TRACE(HB_TR_DEBUG, ("hb_hrbFileRead(%p, %s, %p, %d, %d)", file, szFileName, cBuffer, iSize, iCount)); - - if( iCount != ( int ) fread( cBuffer, iSize, iCount, file ) ) - hb_errRT_BASE_Ext1( EG_READ, 9999, NULL, szFileName, 0, EF_NONE, 0 ); -} - - -/* hb_hrbFileOpen - Open an .HRB file */ -static FILE * hb_hrbFileOpen( char * szFileName ) -{ - HB_TRACE(HB_TR_DEBUG, ("hb_hrbFileOpen(%s)", szFileName)); - - return fopen( szFileName, "rb" ); -} - - -/* hb_hrbFileClose - Close an .HRB file */ -static void hb_hrbFileClose( FILE * file ) -{ - HB_TRACE(HB_TR_DEBUG, ("hb_hrbFileClose(%p)", file)); - - fclose( file ); -} - - -/* - Create dynamic function. - - This function is needed, since it will allow the existing strategy of - function pointers to work properly. - - For each Harbour function a little program calling the virtual machine - should be present (see : *.c) - - Since these programs no longer exists when using this system, they should - be create dynamically at run-time. - - If a .PRG contains 10 functions, 10 dynamic functions are created which - are all the same :-) except for 2 pointers. -*/ -static PASM_CALL hb_hrbAsmCreateFun( PHB_SYMB pSymbols, BYTE * pCode ) -{ - PASM_CALL asmRet; - - HB_TRACE(HB_TR_DEBUG, ("hb_hrbAsmCreateFun(%p, %p)", pSymbols, pCode)); - - asmRet = ( PASM_CALL ) hb_xgrab( sizeof( ASM_CALL ) ); - asmRet->pAsmData = ( BYTE * ) hb_xgrab( sizeof( prgFunction ) ); - memcpy( asmRet->pAsmData, prgFunction, sizeof( prgFunction ) ); - /* Copy new assembler code in */ -/* #if INTEL32 */ - - hb_hrbAsmPatch( asmRet->pAsmData, 1, pSymbols ); /* Insert pointer to testsym */ - hb_hrbAsmPatch( asmRet->pAsmData, 6, pCode ); /* Insert pointer to testcode */ - hb_hrbAsmPatchRelative( asmRet->pAsmData, 11, ( void * ) hb_vmExecute, 15 ); - /* Insert pointer to hb_vmExecute() */ - -/* #elseif INTEL16 */ -/* #elseif MOTOROLA */ -/* #elseif ... */ -/* #endif */ - return asmRet; -} - -/* Patch an address of the dynamic function */ -static void hb_hrbAsmPatch( BYTE * pCode, ULONG ulOffset, void * Address ) -{ - HB_TRACE(HB_TR_DEBUG, ("hb_hrbAsmPatch(%p, %lu, %p)", pCode, ulOffset, Address)); - -/* #if 32 bits and low byte first */ - - pCode[ ulOffset ] = ( BYTE ) ( ( ( ULONG ) Address ) & 0xFF ); - pCode[ ulOffset + 1 ] = ( BYTE ) ( ( ( ULONG ) Address >> 8 ) & 0xFF ); - pCode[ ulOffset + 2 ] = ( BYTE ) ( ( ( ULONG ) Address >> 16 ) & 0xFF ); - pCode[ ulOffset + 3 ] = ( BYTE ) ( ( ( ULONG ) Address >> 24 ) & 0xFF ); - -/* #elseif 16 bits and low byte first */ -/* #elseif 32 bits and high byte first */ -/* #elseif ... */ -/* #endif */ -} - - -/* Intel specific ?? Patch an address relative to the next instruction */ -static void hb_hrbAsmPatchRelative( BYTE * pCode, ULONG ulOffset, - void * Address, ULONG ulNext ) -{ - ULONG ulBase; - ULONG ulRelative; - - HB_TRACE(HB_TR_DEBUG, ("hb_hrbAsmPatchRelative(%p, %lu, %p, %lu)", pCode, ulOffset, Address, ulNext)); - -/* #if 32 bits and low byte first */ - ulBase = ( ULONG ) pCode + ulNext; - /* Relative to next instruction */ - ulRelative = ( ULONG ) Address - ulBase; - - pCode[ ulOffset ] = ( BYTE ) ( ( ulRelative ) & 0xFF ); - pCode[ ulOffset + 1 ] = ( BYTE ) ( ( ulRelative >> 8 ) & 0xFF ); - pCode[ ulOffset + 2 ] = ( BYTE ) ( ( ulRelative >> 16 ) & 0xFF ); - pCode[ ulOffset + 3 ] = ( BYTE ) ( ( ulRelative >> 24 ) & 0xFF ); - -/* #elseif 16 bits and low byte first */ -/* #elseif 32 bits and high byte first */ -/* #elseif ... */ -/* #endif */ } diff --git a/harbour/utils/hbtest/rt_misc.prg b/harbour/utils/hbtest/rt_misc.prg index a26dea62b9..97ad2fcce7 100644 --- a/harbour/utils/hbtest/rt_misc.prg +++ b/harbour/utils/hbtest/rt_misc.prg @@ -763,6 +763,7 @@ STATIC FUNCTION HB_TString() oClass:AddData( "cValue" ) + oClass:AddInline( "=" , {| self, cTest | ::cValue = cTest } ) oClass:AddInline( "==" , {| self, cTest | ::cValue == cTest } ) oClass:AddInline( "!=" , {| self, cTest | ::cValue != cTest } ) oClass:AddInline( "<" , {| self, cTest | ::cValue < cTest } )