f6f02d1995-10-16Fredrik Hübinette (Hubbe) /*\
3e9a462002-01-16Martin Nilsson ||| This file is part of Pike. For copyright information see COPYRIGHT.
06983f1996-09-22Fredrik Hübinette (Hubbe) ||| Pike is distributed as GPL (General Public License)
f6f02d1995-10-16Fredrik Hübinette (Hubbe) ||| See the files COPYING and DISCLAIMER for more information. \*/
acbf0a1999-02-20Henrik Grubbström (Grubba) /**/
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "global.h"
3e9a462002-01-16Martin Nilsson RCSID("$Id: program.c,v 1.400 2002/01/16 02:54:18 nilsson Exp $");
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "program.h" #include "object.h" #include "dynamic_buffer.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "pike_types.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "stralloc.h" #include "las.h" #include "language.h" #include "lex.h"
bb55f81997-03-16Fredrik Hübinette (Hubbe) #include "pike_macros.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "fsort.h"
b2d3e42000-12-01Fredrik Hübinette (Hubbe) #include "pike_error.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "docode.h" #include "interpret.h" #include "hashtable.h"
2acdd31995-10-29Fredrik Hübinette (Hubbe) #include "main.h"
624d091996-02-24Fredrik Hübinette (Hubbe) #include "gc.h"
07513e1996-10-04Fredrik Hübinette (Hubbe) #include "threads.h"
0683be1997-01-26Fredrik Hübinette (Hubbe) #include "constants.h"
9c6f7d1997-04-15Fredrik Hübinette (Hubbe) #include "operators.h"
3eb19a1998-01-30Henrik Grubbström (Grubba) #include "builtin_functions.h"
1994981998-04-07Fredrik Hübinette (Hubbe) #include "stuff.h"
05590d1998-04-23Fredrik Hübinette (Hubbe) #include "mapping.h" #include "cyclic.h"
7e97c31999-01-21Fredrik Hübinette (Hubbe) #include "security.h"
51059b1999-12-26Henrik Grubbström (Grubba) #include "pike_types.h"
f76b4c2000-05-11Henrik Grubbström (Grubba) #include "opcodes.h"
ac87152000-09-25Fredrik Hübinette (Hubbe) #include "version.h"
1c1c5e2001-04-08Fredrik Hübinette (Hubbe) #include "block_alloc.h"
0e0cd72001-07-20Henrik Grubbström (Grubba) #include "pikecode.h"
8aeeb21996-11-19Fredrik Hübinette (Hubbe)  #include <errno.h>
5267b71995-08-09Fredrik Hübinette (Hubbe) #include <fcntl.h>
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  #undef ATTRIBUTE #define ATTRIBUTE(X)
1c1c5e2001-04-08Fredrik Hübinette (Hubbe) static void exit_program_struct(struct program *);
f3c7152001-04-14Fredrik Hübinette (Hubbe) static size_t add_xstorage(size_t size, size_t alignment, ptrdiff_t modulo_orig);
1c1c5e2001-04-08Fredrik Hübinette (Hubbe)  #undef EXIT_BLOCK #define EXIT_BLOCK(P) exit_program_struct( (P) ) #undef COUNT_OTHER #define COUNT_OTHER() do{ \ struct program *p; \ for(p=first_program;p;p=p->next) \ { \ size+=p->total_size; \ } \ }while(0) BLOCK_ALLOC(program, 104);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
1549c61999-07-02Henrik Grubbström (Grubba) /* #define COMPILER_DEBUG */
a786431999-11-18Martin Stjernholm /* #define PROGRAM_BUILD_DEBUG */
b6f8c31999-07-01Henrik Grubbström (Grubba)  #ifdef COMPILER_DEBUG #define CDFPRINTF(X) fprintf X #else /* !COMPILER_DEBUG */ #define CDFPRINTF(X) #endif /* COMPILER_DEBUG */
189fd01997-01-28Fredrik Hübinette (Hubbe) /*
5985c12000-10-25Fredrik Hübinette (Hubbe)  * These two values should probably be fine-tuned, but doing so * more or less requires running a predictable 'typical' application * and testing different hashsizes and tresholds. I tried to do it * mathematically by measuring the extremes (no cache hits, 100% * cache hits etc.) but it seems that the processor cache becomes * exhausted in some of my measurements, which renders my mathematical * model useless. * * Further measurements seems to indicate that this cache can slow * things down a bit if the hit/miss rate is not fairly high. * For normal applications, the hitrate is most likely well over 90%, * but that should be verified.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  * - Holistiska Centralbyrån (Hubbe)
189fd01997-01-28Fredrik Hübinette (Hubbe)  */
5985c12000-10-25Fredrik Hübinette (Hubbe)  /* Define the size of the cache that is used for method lookup. */ /* A value of zero disables this cache */ #define FIND_FUNCTION_HASHSIZE 15013 /* Programs with less methods will not use the cache for method lookups.. */ #define FIND_FUNCTION_HASH_TRESHOLD 9
189fd01997-01-28Fredrik Hübinette (Hubbe) 
5c8e891995-10-29Fredrik Hübinette (Hubbe) #define DECLARE #include "compilation.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9e26861999-12-31Martin Stjernholm struct pike_string *this_program_string=0;
5580691996-06-21Fredrik Hübinette (Hubbe) char *lfun_names[] = { "__INIT", "create", "destroy", "`+", "`-", "`&", "`|", "`^", "`<<", "`>>", "`*", "`/", "`%", "`~", "`==", "`<", "`>", "__hash", "cast", "`!",
774b061996-08-03Fredrik Hübinette (Hubbe)  "`[]", "`[]=",
dffa011997-01-15Fredrik Hübinette (Hubbe)  "`->", "`->=",
0683be1997-01-26Fredrik Hübinette (Hubbe)  "_sizeof", "_indices", "_values", "`()",
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  "``+", "``-", "``&", "``|", "``^", "``<<", "``>>", "``*", "``/", "``%",
ee37801999-02-09Fredrik Hübinette (Hubbe)  "`+=",
aa73fc1999-10-21Fredrik Hübinette (Hubbe)  "_is_type", "_sprintf",
2ba9191999-10-23Fredrik Hübinette (Hubbe)  "_equal",
5b74242001-02-05Henrik Grubbström (Grubba)  "_m_delete",
226d642001-02-24Henrik Grubbström (Grubba)  "_get_iterator",
5580691996-06-21Fredrik Hübinette (Hubbe) };
286afb2001-02-05Henrik Grubbström (Grubba) struct pike_string *lfun_strings[NELEM(lfun_names)]; static struct mapping *lfun_ids;
51059b1999-12-26Henrik Grubbström (Grubba) /* mapping(string:type) */ static struct mapping *lfun_types; static char *raw_lfun_types[] = { tFuncV(tNone,tVoid,tVoid), /* "__INIT", */ tFuncV(tNone,tZero,tVoid), /* "create", */ tFuncV(tNone,tVoid,tVoid), /* "destroy", */ tFuncV(tNone,tZero,tMix), /* "`+", */ tFuncV(tNone,tZero,tMix), /* "`-", */ tFuncV(tNone,tZero,tMix), /* "`&", */ tFuncV(tNone,tZero,tMix), /* "`|", */ tFuncV(tNone,tZero,tMix), /* "`^", */ tFuncV(tZero,tVoid,tMix), /* "`<<", */ tFuncV(tZero,tVoid,tMix), /* "`>>", */ tFuncV(tNone,tZero,tMix), /* "`*", */ tFuncV(tNone,tZero,tMix), /* "`/", */ tFuncV(tNone,tZero,tMix), /* "`%", */ tFuncV(tNone,tVoid,tMix), /* "`~", */ tFuncV(tMix,tVoid,tInt), /* "`==", */ tFuncV(tMix,tVoid,tInt), /* "`<", */ tFuncV(tMix,tVoid,tInt), /* "`>", */ tFuncV(tNone,tVoid,tInt), /* "__hash", */ tFuncV(tString,tVoid,tMix), /* "cast", */ tFuncV(tNone,tVoid,tInt), /* "`!", */ tFuncV(tZero,tVoid,tMix), /* "`[]", */ tFuncV(tZero tSetvar(0,tZero),tVoid,tVar(0)), /* "`[]=", */ tFuncV(tStr,tVoid,tMix), /* "`->", */ tFuncV(tStr tSetvar(0,tZero),tVoid,tVar(0)), /* "`->=", */ tFuncV(tNone,tVoid,tInt), /* "_sizeof", */ tFuncV(tNone,tVoid,tArray), /* "_indices", */ tFuncV(tNone,tVoid,tArray), /* "_values", */ tFuncV(tNone,tZero,tMix), /* "`()", */ tFuncV(tNone,tZero,tMix), /* "``+", */ tFuncV(tNone,tZero,tMix), /* "``-", */ tFuncV(tNone,tZero,tMix), /* "``&", */ tFuncV(tNone,tZero,tMix), /* "``|", */ tFuncV(tNone,tZero,tMix), /* "``^", */ tFuncV(tZero,tVoid,tMix), /* "``<<", */ tFuncV(tZero,tVoid,tMix), /* "``>>", */ tFuncV(tNone,tZero,tMix), /* "``*", */ tFuncV(tNone,tZero,tMix), /* "``/", */ tFuncV(tNone,tZero,tMix), /* "``%", */ tFuncV(tZero,tVoid,tMix), /* "`+=", */ tFuncV(tStr,tVoid,tInt), /* "_is_type", */
d8bfc01999-12-27Henrik Grubbström (Grubba)  tFuncV(tInt tOr(tMap(tStr,tInt),tVoid),tVoid,tStr), /* "_sprintf", */
51059b1999-12-26Henrik Grubbström (Grubba)  tFuncV(tMix,tVoid,tInt), /* "_equal", */
3cd7482001-04-28Martin Stjernholm  tFuncV(tZero,tVoid,tMix), /* "_m_delete", */
ef34d52001-02-24Henrik Grubbström (Grubba)  tFuncV(tNone,tVoid,tObj), /* "_get_iterator", */
51059b1999-12-26Henrik Grubbström (Grubba) };
397e7d2001-10-28Martin Nilsson /*! @module lfun:: *! *! @endmodule */
1a5b2f2001-02-09Henrik Grubbström (Grubba) /*! @decl void lfun::__INIT() *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Global variable initialization. *! *! This function is called just before @[lfun::create()] when *! an object is instanciated.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @note *! This function is generated automatically by the compiler, *! and can not be overloaded. *! *! @seealso *! @[lfun::create()] */ /*! @decl void lfun::create(zero ... args) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Object creation callback. *! *! This function is called right after @[lfun::__INIT()]. *! *! @[args] will be the arguments passed when the program was called.
269dd92001-05-23Henrik Grubbström (Grubba)  *! *! @note
83c2612001-05-05Henrik Grubbström (Grubba)  *! In Pike 7.2 and later this function can be created implicitly *! by the compiler using the new syntax: *! @code{ *! class Foo(int foo) { *! int bar; *! } *! @} *! In the above case an implicit @[lfun::create()] will be created, *! and it will be equvivalent to: *! @code{ *! class Foo { *! int foo; *! int bar; *! static void create(int foo) *! { *! local::foo = foo; *! } *! } *! @}
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::__INIT()], @[lfun::destroy()] */ /*! @decl void lfun::destroy() *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Object destruction callback. *! *! This function is called by @[destruct()] right before *! it will zero all the object variables, and destroy the object.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *!
f60f892001-12-20Henrik Grubbström (Grubba)  *! @note *! Note that it will also be called on implicit destruct, eg *! when there are no more references to the object, or when *! the garbage-collector decides to destruct the object. *!
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! @seealso *! @[lfun::create()], @[destruct()] */ /*! @decl mixed lfun::`+(zero ... args) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Left associative addition operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::``+()], @[`+()] */ /*! @decl mixed lfun::`-(zero ... args) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Left associative subtraction operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::``-()], @[`-()] */ /*! @decl mixed lfun::`&(zero ... args) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Left associative and operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::``&()], @[`&()] */ /*! @decl mixed lfun::`|(zero ... args) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Left associative or operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::``|()], @[`|()] */ /*! @decl mixed lfun::`^(zero ... args) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Left associative exclusive or operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::``^()], @[`^()] */ /*! @decl mixed lfun::`<<(zero arg) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Left associative left shift operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::``<<()], @[`<<()] */ /*! @decl mixed lfun::`>>(zero arg) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Left associative right shift operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::``>>()], @[`>>()] */ /*! @decl mixed lfun::`*(zero ... args) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Left associative multiplication operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::``*()], @[`*()] */ /*! @decl mixed lfun::`/(zero ... args) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Left associative division operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::``/()], @[`/()] */ /*! @decl mixed lfun::`%(zero ... args) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Left associative modulo operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::``%()], @[`%()] */ /*! @decl mixed lfun::`~() *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Inversion operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[`~()] */ /*! @decl int(0..1) lfun::`==(mixed arg) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Equality operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[`==()] */ /*! @decl int(0..1) lfun::`<(mixed arg) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Less than operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[`<()] */ /*! @decl int(0..1) lfun::`>(mixed arg) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Greater than operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[`>()] */ /*! @decl int lfun::__hash() *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Hashing callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *!
f60f892001-12-20Henrik Grubbström (Grubba)  *! This function gets called by various mapping operations when the *! object is used as index in a mapping.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  */ /*! @decl mixed lfun::cast(string requested_type) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Cast operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *!
f60f892001-12-20Henrik Grubbström (Grubba)  *! @param requested_type *! Type to cast to. *! *! @returns *! Expected to return the object value-casted (converted) to *! the type described by @[requested_type]. *!
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! @note
3173842001-12-20Martin Nilsson  *! The argument is currently a string with the name
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! of the type, but might in the future be a value of the type type.
f60f892001-12-20Henrik Grubbström (Grubba)  *! *! @note
3173842001-12-20Martin Nilsson  *! Currently casting between object types is a noop.
f60f892001-12-20Henrik Grubbström (Grubba)  *! *! @note *! If the returned value is not deemed to be of the requested type *! a runtime error may be thrown.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  */ /*! @decl int lfun::`!() *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Not operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *!
f60f892001-12-20Henrik Grubbström (Grubba)  *! @returns *! Returns non-zero if the object should be evaluated as false, *! and @tt{0@} (zero) otherwise. *!
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! @seealso *! @[`!()] */ /*! @decl mixed lfun::`[](zero arg1, zero|void arg2) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Index/range operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[`[]()] */ /*! @decl mixed lfun::`[]=(zero arg1, zero arg2) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Index assignment operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso
f60f892001-12-20Henrik Grubbström (Grubba)  *! @[`[]=()], @[lfun::`->=()]
1a5b2f2001-02-09Henrik Grubbström (Grubba)  */ /*! @decl mixed lfun::`->(string arg) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Arrow index operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[`->()] */ /*! @decl mixed lfun::`->=(string arg1, zero arg2) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Arrow index assign operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso
f60f892001-12-20Henrik Grubbström (Grubba)  *! @[`->=()], @[lfun::`[]=()]
1a5b2f2001-02-09Henrik Grubbström (Grubba)  */
5d086e2001-05-05Henrik Grubbström (Grubba) /*! @decl int lfun::_sizeof()
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Sizeof operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *!
f60f892001-12-20Henrik Grubbström (Grubba)  *! Called by @[sizeof()] to determine the number of elements *! in an object. If this function is not present, the number *! of public symbols in the object will be returned. *! *! @returns *! Expected to return the number of valid indices in the object. *!
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! @seealso *! @[sizeof()] */
5d086e2001-05-05Henrik Grubbström (Grubba) /*! @decl array lfun::_indices()
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Indices operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *!
f60f892001-12-20Henrik Grubbström (Grubba)  *! @returns *! Expected to return an array with the valid indices in the object. *!
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! @seealso
f60f892001-12-20Henrik Grubbström (Grubba)  *! @[indices()], @[lfun::_values()]
1a5b2f2001-02-09Henrik Grubbström (Grubba)  */
5d086e2001-05-05Henrik Grubbström (Grubba) /*! @decl array lfun::_values()
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Values operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *!
f60f892001-12-20Henrik Grubbström (Grubba)  *! @returns *! Expected to return an array with the values corresponding to *! the indices returned by @[lfun::_indices()]. *!
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! @seealso
f60f892001-12-20Henrik Grubbström (Grubba)  *! @[values()], @[lfun::_indices()]
1a5b2f2001-02-09Henrik Grubbström (Grubba)  */
5d086e2001-05-05Henrik Grubbström (Grubba) /*! @decl mixed lfun::`()(zero ... args)
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Function call operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[`()] */ /*! @decl mixed lfun::``+(zero ... args) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Right associative addition operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::`+()], @[`+()] */ /*! @decl mixed lfun::``-(zero ... args) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Right associative subtraction operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::`-()], @[`-()] */ /*! @decl mixed lfun::``&(zero ... args) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Right associative and operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::`&()], @[`&()] */ /*! @decl mixed lfun::``|(zero ... args) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Right associative or operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::`|()], @[`|()] */ /*! @decl mixed lfun::``^(zero ... args) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Right associative exclusive or operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::`^()], @[`^()] */ /*! @decl mixed lfun::``<<(zero arg) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Right associative left shift operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::`<<()], @[`<<()] */ /*! @decl mixed lfun::``>>(zero arg) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Right associative right shift operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::`>>()], @[`>>()] */ /*! @decl mixed lfun::``*(zero ... args) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Right associative multiplication operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::`*()], @[`*()] */ /*! @decl mixed lfun::``/(zero ... args) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Right associative division operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::`/()], @[`/()] */ /*! @decl mixed lfun::``%(zero ... args) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Right associative modulo operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[lfun::`%()], @[`%()] */ /*! @decl mixed lfun::`+=(zero arg) *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Self increment operator callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[`+()], @[lfun::`+()] */
f60f892001-12-20Henrik Grubbström (Grubba) /*! @decl int(0..1) lfun::_is_type(string basic_type)
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Type comparison callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *!
f60f892001-12-20Henrik Grubbström (Grubba)  *! Called by the cast operator to determine if an object *! simulates a basic type. *! *! @param basic_type *! One of: *! @string *! @value "array" *! @value "float" *! @value "function" *! @value "int" *! @value "mapping" *! @value "multiset" *! @value "object" *! @value "program" *! @value "string" *! @value "type" *! @value "void" *! @value "zero" *! @endstring *! *! The following five shouldn't occurr, but are here for completeness: *! @string *! @value "lvalue" *! @value "mapping_data" *! @value "object storage" *! @value "pike_frame" *! @value "unknown" *! @endstring *! *! @returns *! Expected to return @tt{1@} if the object is to be regarded as a
3173842001-12-20Martin Nilsson  *! simulation of the type specified by @[basic_type].
f60f892001-12-20Henrik Grubbström (Grubba)  *!
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! @note
3173842001-12-20Martin Nilsson  *! The argument is currently a string with the name
f60f892001-12-20Henrik Grubbström (Grubba)  *! of the type, but might in the future be a value of the type type.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  */
8203d42001-02-09Henrik Grubbström (Grubba) /*! @decl string lfun::_sprintf(int conversion_type, @ *! mapping(string:int)|void params)
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Sprintf callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *!
b772752001-12-20Henrik Grubbström (Grubba)  *! This method is called by @[sprintf()] to print objects. If it is
302b712001-12-20Henrik Grubbström (Grubba)  *! not present, printing of the object will not be supported for any
b772752001-12-20Henrik Grubbström (Grubba)  *! conversion-type except for the @tt{%O@}-conversion-type, which *! will output @tt{"object"@}. *! *! @param conversion_type *! One of: *! @int *! @value 'b' *! Signed binary integer. *! @value 'd' *! Signed decimal integer. *! @value 'u' *! Unsigned decimal integer. *! @value 'o' *! Signed octal integer. *! @value 'x' *! Lowercase signed hexadecimal integer. *! @value 'X' *! Uppercase signed hexadecimal integer. *! @value 'c' *! Character. If a fieldsize has been specified this will output *! the low-order bytes of the integer in network byte order. *! @value 'f' *! Float. *! @value 'g' *! Heuristically chosen representation of float. *! @value 'G' *! Like @tt{%g@}, but uses uppercase @tt{E@} for exponent. *! @value 'e' *! Exponential notation float. *! @value 'E' *! Like @tt{%e@}, but uses uppercase @tt{E@} for exponent. *! @value 's' *! String. *! @value 'O' *! Any value (debug style). *! @value 't' *! Type of the argument. *! @endint *! *! @param params *! Conversion parameters. The following parameters may be supplied: *! @mapping *! @member int "precision" *! Precision. *! @member int "width" *! Field width. *! @member int(1..1) "flag_left" *! Indicates that the output should be left-aligned. *! @member int "indent" *! Indentation level in @tt{%O@}-mode. *! @endmapping *! *! @returns *! Is expected to return a string describing the object formatted *! according to @[conversion_type]. *! *! @note
3173842001-12-20Martin Nilsson  *! @[_sprintf()] is currently not called for the following
b772752001-12-20Henrik Grubbström (Grubba)  *! conversion-types: *! @int *! @value 'F' *! Binary IEEE representation of float (@tt{%4F@} gives *! single precision, @tt{%8F@} gives double precision.) *! @endint *!
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! @seealso *! @[sprintf()] */
8203d42001-02-09Henrik Grubbström (Grubba) /*! @decl int lfun::_equal(mixed arg)
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Equal callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[equal()], @[lfun::`==()] */
8203d42001-02-09Henrik Grubbström (Grubba) /*! @decl mixed lfun::_m_delete(mixed arg)
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Mapping delete callback.
1a5b2f2001-02-09Henrik Grubbström (Grubba)  *! *! @seealso *! @[m_delete()] */
226d642001-02-24Henrik Grubbström (Grubba) /*! @decl object lfun::_get_iterator() *!
83c2612001-05-05Henrik Grubbström (Grubba)  *! Iterator creation callback. *! *! @returns *! Should return an object that implements the iterator API: *! @dl *! @item
f60f892001-12-20Henrik Grubbström (Grubba)  *! @[lfun::`!()] should return @tt{0@} (zero) when not at end of stream, *! and @tt{1@} at end of stream.
83c2612001-05-05Henrik Grubbström (Grubba)  *! @item *! @[lfun::`+=()] should advance the specified number of steps. *! @item *! @[index()] should return the current index. *! @item *! @[value()] should return the current value. *! @enddl
226d642001-02-24Henrik Grubbström (Grubba)  *! *! @seealso *! @[Iterator], @[foreach()] */
5267b71995-08-09Fredrik Hübinette (Hubbe) struct program *first_program = 0;
f8d8f42001-07-01Henrik Grubbström (Grubba) static int current_program_id = PROG_DYNAMIC_ID_START;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
aa68b12001-03-19Fredrik Hübinette (Hubbe) struct program *null_program=0;
10e16f1999-11-04Henrik Grubbström (Grubba) struct object *error_handler=0;
ac87152000-09-25Fredrik Hübinette (Hubbe) struct object *compat_handler=0;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
e2d9e62000-06-10Martin Stjernholm struct program *gc_internal_program = 0; static struct program *gc_mark_program_pos = 0;
51717a2001-04-09Fredrik Hübinette (Hubbe) int compilation_depth=-1;
591c0c1997-01-19Fredrik Hübinette (Hubbe) dynamic_buffer used_modules;
05590d1998-04-23Fredrik Hübinette (Hubbe) static struct mapping *resolve_cache=0;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
1016021999-10-28Fredrik Hübinette (Hubbe) int get_small_number(char **q);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) /* So what if we don't have templates? / Hubbe */
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #define CHECK_FOO(NUMTYPE,TYPE,NAME) \
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->malloc_size_program-> PIKE_CONCAT(num_,NAME) < Pike_compiler->new_program-> PIKE_CONCAT(num_,NAME)) \ fatal("Pike_compiler->new_program->num_" #NAME " is out of order\n"); \ if(Pike_compiler->new_program->flags & PROGRAM_OPTIMIZED) \
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  fatal("Tried to reallocate fixed program.\n") #else #define CHECK_FOO(NUMTYPE,TYPE,NAME) #endif
0e0cd72001-07-20Henrik Grubbström (Grubba) #ifndef RELOCATE_program #define RELOCATE_program(ORIG, NEW) #endif /* !RELOCATE_program */
302ede2001-07-19Henrik Grubbström (Grubba) #define RELOCATE_linenumbers(ORIG,NEW) #define RELOCATE_identifier_index(ORIG,NEW) #define RELOCATE_variable_index(ORIG,NEW) #define RELOCATE_identifier_references(ORIG,NEW) #define RELOCATE_strings(ORIG,NEW) #define RELOCATE_inherits(ORIG,NEW) #define RELOCATE_identifiers(ORIG,NEW) #define RELOCATE_constants(ORIG,NEW) #define RELOCATE_relocations(ORIG,NEW)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #define FOO(NUMTYPE,TYPE,NAME) \
bad5162000-06-23Fredrik Hübinette (Hubbe) void PIKE_CONCAT(low_add_to_,NAME) (struct program_state *state, \ TYPE ARG) { \ if(state->malloc_size_program->PIKE_CONCAT(num_,NAME) == \ state->new_program->PIKE_CONCAT(num_,NAME)) { \
302ede2001-07-19Henrik Grubbström (Grubba)  TYPE *tmp; \
bad5162000-06-23Fredrik Hübinette (Hubbe)  state->malloc_size_program->PIKE_CONCAT(num_,NAME) *= 2; \ state->malloc_size_program->PIKE_CONCAT(num_,NAME)++; \
302ede2001-07-19Henrik Grubbström (Grubba)  tmp = realloc((void *)state->new_program->NAME, \ sizeof(TYPE) * \ state->malloc_size_program-> \ PIKE_CONCAT(num_,NAME)); \
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(!tmp) fatal("Out of memory.\n"); \
302ede2001-07-19Henrik Grubbström (Grubba)  PIKE_CONCAT(RELOCATE_,NAME)(state->new_program, tmp); \
bad5162000-06-23Fredrik Hübinette (Hubbe)  state->new_program->NAME=tmp; \
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  } \
bad5162000-06-23Fredrik Hübinette (Hubbe)  state->new_program-> \ NAME[state->new_program->PIKE_CONCAT(num_,NAME)++]=(ARG); \ } \ void PIKE_CONCAT(add_to_,NAME) (TYPE ARG) { \ CHECK_FOO(NUMTYPE,TYPE,NAME); \ PIKE_CONCAT(low_add_to_,NAME) ( Pike_compiler, ARG ); \
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) }
d429a71998-02-24Fredrik Hübinette (Hubbe)  #include "program_areas.h"
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) void ins_int(INT32 i, void (*func)(char tmp)) { int e;
573ba42001-04-11Henrik Grubbström (Grubba)  unsigned char *p = (unsigned char *)&i; for(e=0;e<(long)sizeof(i);e++) { func(p[e]); }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) } void ins_short(INT16 i, void (*func)(char tmp)) { int e;
4dba522001-07-11Henrik Grubbström (Grubba)  unsigned char *p = (unsigned char *)&i; for(e=0;e<(long)sizeof(i);e++) { func(p[e]); }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) }
5f8eb71997-02-18Fredrik Hübinette (Hubbe) 
591c0c1997-01-19Fredrik Hübinette (Hubbe) void use_module(struct svalue *s)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
a1e8821998-11-05Fredrik Hübinette (Hubbe)  if( (1<<s->type) & (BIT_MAPPING | BIT_OBJECT | BIT_PROGRAM))
5c0a101997-02-06Fredrik Hübinette (Hubbe)  {
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->num_used_modules++;
5c0a101997-02-06Fredrik Hübinette (Hubbe)  assign_svalue_no_free((struct svalue *) low_make_buf_space(sizeof(struct svalue), &used_modules), s);
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->module_index_cache)
05590d1998-04-23Fredrik Hübinette (Hubbe)  {
bad5162000-06-23Fredrik Hübinette (Hubbe)  free_mapping(Pike_compiler->module_index_cache); Pike_compiler->module_index_cache=0;
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
5c0a101997-02-06Fredrik Hübinette (Hubbe)  }else{ yyerror("Module is neither mapping nor object"); }
591c0c1997-01-19Fredrik Hübinette (Hubbe) }
05590d1998-04-23Fredrik Hübinette (Hubbe) void unuse_modules(INT32 howmany) { if(!howmany) return;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(howmany *sizeof(struct svalue) > used_modules.s.len) fatal("Unusing too many modules.\n"); #endif
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->num_used_modules-=howmany;
05590d1998-04-23Fredrik Hübinette (Hubbe)  low_make_buf_space(-sizeof(struct svalue)*howmany, &used_modules); free_svalues((struct svalue *)low_make_buf_space(0, &used_modules), howmany,
a1e8821998-11-05Fredrik Hübinette (Hubbe)  BIT_MAPPING | BIT_OBJECT | BIT_PROGRAM);
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->module_index_cache)
05590d1998-04-23Fredrik Hübinette (Hubbe)  {
bad5162000-06-23Fredrik Hübinette (Hubbe)  free_mapping(Pike_compiler->module_index_cache); Pike_compiler->module_index_cache=0;
05590d1998-04-23Fredrik Hübinette (Hubbe)  } }
b8cda21997-01-21Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) int low_find_shared_string_identifier(struct pike_string *name, struct program *prog);
4d7b181999-12-07Fredrik Hübinette (Hubbe) static struct node_s *index_modules(struct pike_string *ident, struct mapping **module_index_cache, int num_used_modules, struct svalue *modules)
591c0c1997-01-19Fredrik Hübinette (Hubbe) {
4d7b181999-12-07Fredrik Hübinette (Hubbe)  if(*module_index_cache)
05590d1998-04-23Fredrik Hübinette (Hubbe)  {
4d7b181999-12-07Fredrik Hübinette (Hubbe)  struct svalue *tmp=low_mapping_string_lookup(*module_index_cache,ident);
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(tmp) {
9f516a2001-12-16Martin Stjernholm  if(!(SAFE_IS_ZERO(tmp) && tmp->subtype==1))
05590d1998-04-23Fredrik Hübinette (Hubbe)  return mksvaluenode(tmp); return 0; } }
8aae6d1999-08-19Fredrik Hübinette (Hubbe) /* fprintf(stderr,"index_module: %s\n",ident->str); */
591c0c1997-01-19Fredrik Hübinette (Hubbe)  {
8fa3102000-09-05Henrik Grubbström (Grubba)  JMP_BUF tmp; if(SETJMP(tmp))
591c0c1997-01-19Fredrik Hübinette (Hubbe)  {
9036e82001-08-16Martin Stjernholm  struct svalue thrown = throw_value; throw_value.type = T_INT;
b34c9f2001-08-15Martin Stjernholm  if (!ident->size_shift) { my_yyerror("Couldn't index module '%s'.", ident->str); } else { yyerror("Couldn't index module."); }
9036e82001-08-16Martin Stjernholm  push_svalue(&thrown); low_safe_apply_handler("compile_exception", error_handler, compat_handler, 1);
9f516a2001-12-16Martin Stjernholm  if (SAFE_IS_ZERO(sp-1)) yy_describe_exception(&thrown);
b34c9f2001-08-15Martin Stjernholm  pop_stack();
9036e82001-08-16Martin Stjernholm  free_svalue(&thrown);
8fa3102000-09-05Henrik Grubbström (Grubba)  } else { int e = num_used_modules; struct svalue *m = modules - num_used_modules;
27ae842000-02-07Per Hedbor 
8fa3102000-09-05Henrik Grubbström (Grubba)  while(--e>=0)
591c0c1997-01-19Fredrik Hübinette (Hubbe)  {
8fa3102000-09-05Henrik Grubbström (Grubba)  push_svalue(m+e); ref_push_string(ident); f_index(2); if(!IS_UNDEFINED(Pike_sp-1)) { struct node_s *ret; UNSETJMP(tmp); if(!*module_index_cache) *module_index_cache = allocate_mapping(10); mapping_string_insert(*module_index_cache, ident, Pike_sp-1); ret = mksvaluenode(Pike_sp-1); pop_stack(); return ret; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  pop_stack();
591c0c1997-01-19Fredrik Hübinette (Hubbe)  } }
8fa3102000-09-05Henrik Grubbström (Grubba)  UNSETJMP(tmp);
591c0c1997-01-19Fredrik Hübinette (Hubbe)  }
b8cda21997-01-21Fredrik Hübinette (Hubbe) 
8aae6d1999-08-19Fredrik Hübinette (Hubbe) /* fprintf(stderr,"***Undefined.\n"); */
05590d1998-04-23Fredrik Hübinette (Hubbe)  return 0; }
2816052000-03-30Fredrik Hübinette (Hubbe) struct node_s *find_module_identifier(struct pike_string *ident, int see_inherit)
05590d1998-04-23Fredrik Hübinette (Hubbe) { struct node_s *ret;
4d7b181999-12-07Fredrik Hübinette (Hubbe)  struct svalue *modules=(struct svalue *) (used_modules.s.str + used_modules.s.len);
05590d1998-04-23Fredrik Hübinette (Hubbe) 
4d7b181999-12-07Fredrik Hübinette (Hubbe)  if((ret=index_modules(ident,
bad5162000-06-23Fredrik Hübinette (Hubbe)  &Pike_compiler->module_index_cache, Pike_compiler->num_used_modules,
4d7b181999-12-07Fredrik Hübinette (Hubbe)  modules))) return ret;
bad5162000-06-23Fredrik Hübinette (Hubbe)  modules-=Pike_compiler->num_used_modules;
27ae842000-02-07Per Hedbor 
b8cda21997-01-21Fredrik Hübinette (Hubbe)  {
bad5162000-06-23Fredrik Hübinette (Hubbe)  struct program_state *p=Pike_compiler->previous;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  int n; for(n=0;n<compilation_depth;n++,p=p->previous)
b8cda21997-01-21Fredrik Hübinette (Hubbe)  {
2816052000-03-30Fredrik Hübinette (Hubbe)  int i; if(see_inherit)
b8cda21997-01-21Fredrik Hübinette (Hubbe)  {
2816052000-03-30Fredrik Hübinette (Hubbe)  i=really_low_find_shared_string_identifier(ident, p->new_program, SEE_STATIC); if(i!=-1) {
ff88db2000-07-12Henrik Grubbström (Grubba)  return mkexternalnode(p->new_program, i);
2816052000-03-30Fredrik Hübinette (Hubbe)  }
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
bad5162000-06-23Fredrik Hübinette (Hubbe) 
4d7b181999-12-07Fredrik Hübinette (Hubbe)  if((ret=index_modules(ident, &p->module_index_cache, p->num_used_modules, modules))) return ret; modules-=p->num_used_modules; #ifdef PIKE_DEBUG if( ((char *)modules ) < used_modules.s.str) fatal("Modules out of whack!\n"); #endif
05590d1998-04-23Fredrik Hübinette (Hubbe)  } }
1b67072000-03-09Henrik Grubbström (Grubba)  /* Handle this_program */ if (ident == this_program_string) { struct svalue s; s.type=T_PROGRAM;
bad5162000-06-23Fredrik Hübinette (Hubbe)  s.u.program=Pike_compiler->new_program;
1b67072000-03-09Henrik Grubbström (Grubba)  return mkconstantsvaluenode(&s); }
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(resolve_cache) { struct svalue *tmp=low_mapping_string_lookup(resolve_cache,ident); if(tmp) {
9f516a2001-12-16Martin Stjernholm  if(!(SAFE_IS_ZERO(tmp) && tmp->subtype==1))
05590d1998-04-23Fredrik Hübinette (Hubbe)  return mkconstantsvaluenode(tmp); return 0; } }
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(!Pike_compiler->num_parse_error && get_master())
27ae842000-02-07Per Hedbor  {
05590d1998-04-23Fredrik Hübinette (Hubbe)  DECLARE_CYCLIC(); node *ret=0; if(BEGIN_CYCLIC(ident, lex.current_file)) { my_yyerror("Recursive module dependency in %s.", ident->str); }else{
d555692000-03-10Fredrik Hübinette (Hubbe)  int i;
05590d1998-04-23Fredrik Hübinette (Hubbe)  SET_CYCLIC_RET(1); ref_push_string(ident); ref_push_string(lex.current_file);
e5e44e2001-05-24Henrik Grubbström (Grubba)  if (error_handler) { ref_push_object(error_handler); } else { push_int(0); }
d555692000-03-10Fredrik Hübinette (Hubbe) 
9036e82001-08-16Martin Stjernholm  if (safe_apply_handler("resolv", error_handler, compat_handler, 3, 0)) {
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(!resolve_cache)
aed42d1999-12-29Martin Stjernholm  resolve_cache=dmalloc_touch(struct mapping *, allocate_mapping(10));
cd86322000-07-06Fredrik Hübinette (Hubbe)  mapping_string_insert(resolve_cache,ident,Pike_sp-1);
27ae842000-02-07Per Hedbor 
9f516a2001-12-16Martin Stjernholm  if(!(SAFE_IS_ZERO(Pike_sp-1) && Pike_sp[-1].subtype==1))
b8cda21997-01-21Fredrik Hübinette (Hubbe)  {
cd86322000-07-06Fredrik Hübinette (Hubbe)  ret=mkconstantsvaluenode(Pike_sp-1);
b8cda21997-01-21Fredrik Hübinette (Hubbe)  }
9036e82001-08-16Martin Stjernholm  pop_stack();
b8cda21997-01-21Fredrik Hübinette (Hubbe)  }
9036e82001-08-16Martin Stjernholm  else if(Pike_compiler->compiler_pass==2) { if (throw_value.type == T_STRING && !throw_value.u.string->size_shift) { yyerror(throw_value.u.string->str); free_svalue(&throw_value); throw_value.type = T_INT; } else { struct svalue thrown = throw_value; throw_value.type = T_INT; if (!ident->size_shift) my_yyerror("Error resolving '%s'.", ident->str); else yyerror("Error resolving identifier."); push_svalue(&thrown); low_safe_apply_handler("compile_exception", error_handler, compat_handler, 1);
9f516a2001-12-16Martin Stjernholm  if (SAFE_IS_ZERO(sp-1)) yy_describe_exception(&thrown);
9036e82001-08-16Martin Stjernholm  pop_stack(); free_svalue(&thrown); } }
b8cda21997-01-21Fredrik Hübinette (Hubbe)  }
14bb592000-05-06Fredrik Hübinette (Hubbe)  END_CYCLIC();
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(ret) return ret;
b8cda21997-01-21Fredrik Hübinette (Hubbe)  }
27ae842000-02-07Per Hedbor 
b8cda21997-01-21Fredrik Hübinette (Hubbe)  return 0; }
bad5162000-06-23Fredrik Hübinette (Hubbe) /* Fixme: allow level=0 to return the current level */
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) struct program *parent_compilation(int level) { int n;
bad5162000-06-23Fredrik Hübinette (Hubbe)  struct program_state *p=Pike_compiler->previous;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  for(n=0;n<level;n++) { if(n>=compilation_depth) return 0; p=p->previous; if(!p) return 0; } return p->new_program; } #define ID_TO_PROGRAM_CACHE_SIZE 512 struct program *id_to_program_cache[ID_TO_PROGRAM_CACHE_SIZE];
b8cda21997-01-21Fredrik Hübinette (Hubbe) struct program *id_to_program(INT32 id) { struct program *p;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  INT32 h; if(!id) return 0; h=id & (ID_TO_PROGRAM_CACHE_SIZE-1); if((p=id_to_program_cache[h]))
61e9a01998-01-25Fredrik Hübinette (Hubbe)  if(p->id==id) return p;
27ae842000-02-07Per Hedbor 
a382372001-07-02Henrik Grubbström (Grubba)  for(p=first_program;p;p=p->next) { if(id==p->id)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  {
a382372001-07-02Henrik Grubbström (Grubba)  id_to_program_cache[h]=p; return p; } } if ((id > 0) && (id < PROG_DYNAMIC_ID_START)) { /* Reserved id. Attempt to load the proper dynamic module * to resolv the id. */ char *module = NULL; switch(id) { case PROG_PARSER_HTML_ID: module = "Parser._parser"; break; case PROG_GMP_MPZ_ID: module = "Gmp"; break; case PROG_MODULE_MIME_ID: module = "___MIME"; break; default: if ((id >= 100) && (id <= 300)) { module = "Image"; } else if ((id >= 1000) && (id <= 2000)) { module = "GTK"; } break; } if (module) { push_text(module); SAFE_APPLY_MASTER("resolv", 1); pop_stack(); /* Try again... */
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  for(p=first_program;p;p=p->next)
a382372001-07-02Henrik Grubbström (Grubba)  { if(id==p->id)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  {
a382372001-07-02Henrik Grubbström (Grubba)  id_to_program_cache[h]=p; return p;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
a382372001-07-02Henrik Grubbström (Grubba)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
a382372001-07-02Henrik Grubbström (Grubba)  }
591c0c1997-01-19Fredrik Hübinette (Hubbe)  return 0; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) /* Here starts routines which are used to build new programs */
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) /* Re-allocate all the memory in the program in one chunk. because: * 1) The individual blocks are munch bigger than they need to be * 2) cuts down on malloc overhead (maybe) * 3) localizes memory access (decreases paging)
5267b71995-08-09Fredrik Hübinette (Hubbe)  */
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) void optimize_program(struct program *p) {
080b1a2000-08-10Henrik Grubbström (Grubba)  size_t size=0;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  char *data; /* Already done (shouldn't happen, but who knows?) */ if(p->flags & PROGRAM_OPTIMIZED) return; #define FOO(NUMTYPE,TYPE,NAME) \
1994981998-04-07Fredrik Hübinette (Hubbe)  size=DO_ALIGN(size, ALIGNOF(TYPE)); \ size+=p->PIKE_CONCAT(num_,NAME)*sizeof(p->NAME[0]);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #include "program_areas.h" data=malloc(size);
f822262001-07-16Fredrik Hübinette (Hubbe)  if(!data) { make_program_executable(p); return; /* We are out of memory, but we don't care! */ }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  size=0; #define FOO(NUMTYPE,TYPE,NAME) \
1994981998-04-07Fredrik Hübinette (Hubbe)  size=DO_ALIGN(size, ALIGNOF(TYPE)); \
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  MEMCPY(data+size,p->NAME,p->PIKE_CONCAT(num_,NAME)*sizeof(p->NAME[0])); \
302ede2001-07-19Henrik Grubbström (Grubba)  PIKE_CONCAT(RELOCATE_,NAME)(p, (TYPE *)(data+size)); \
424d9c1999-05-02Fredrik Hübinette (Hubbe)  dmfree((char *)p->NAME); \
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  p->NAME=(TYPE *)(data+size); \
1994981998-04-07Fredrik Hübinette (Hubbe)  size+=p->PIKE_CONCAT(num_,NAME)*sizeof(p->NAME[0]);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #include "program_areas.h" p->total_size=size + sizeof(struct program); p->flags |= PROGRAM_OPTIMIZED;
f822262001-07-16Fredrik Hübinette (Hubbe)  make_program_executable(p);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) /* internal function to make the index-table */
05590d1998-04-23Fredrik Hübinette (Hubbe) int program_function_index_compare(const void *a,const void *b)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) { return
b819352000-08-14Henrik Grubbström (Grubba)  DO_NOT_WARN((int)my_order_strcmp(ID_FROM_INT(Pike_compiler->new_program, *(unsigned short *)a)->name, ID_FROM_INT(Pike_compiler->new_program, *(unsigned short *)b)->name));
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) }
a4033e2000-04-14Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
50edc82001-07-13Henrik Grubbström (Grubba) struct pike_string *find_program_name(struct program *p, INT32 *line)
a4033e2000-04-14Fredrik Hübinette (Hubbe) {
393a592000-08-16Henrik Grubbström (Grubba)  ptrdiff_t pos;
cd86322000-07-06Fredrik Hübinette (Hubbe)  INT32 l; if(!line) line=&l;
a4033e2000-04-14Fredrik Hübinette (Hubbe)  #ifdef DEBUG_MALLOC
50edc82001-07-13Henrik Grubbström (Grubba)  { char *tmp=dmalloc_find_name(p); *line=0; if(tmp) return make_shared_string(tmp); }
a4033e2000-04-14Fredrik Hübinette (Hubbe) #endif
4f985f2001-06-30Martin Stjernholm  return get_program_line(p, line);
a4033e2000-04-14Fredrik Hübinette (Hubbe) } #endif
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) void fixate_program(void) { INT32 i,e,t;
3b7d182001-09-26Fredrik Hübinette (Hubbe)  struct program *p=Pike_compiler->new_program; if(p->flags & PROGRAM_FIXED) return;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
3b7d182001-09-26Fredrik Hübinette (Hubbe)  if(p->flags & PROGRAM_OPTIMIZED)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  fatal("Cannot fixate optimized program\n"); #endif /* Ok, sort for binsearch */
3b7d182001-09-26Fredrik Hübinette (Hubbe)  for(e=i=0;i<(int)p->num_identifier_references;i++)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  { struct reference *funp; struct identifier *fun;
3b7d182001-09-26Fredrik Hübinette (Hubbe)  funp=p->identifier_references+i;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(funp->id_flags & (ID_HIDDEN|ID_STATIC)) continue; if(funp->id_flags & ID_INHERITED) {
3b7d182001-09-26Fredrik Hübinette (Hubbe)  int found_better=-1; int funa_is_prototype;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(funp->id_flags & ID_PRIVATE) continue;
3b7d182001-09-26Fredrik Hübinette (Hubbe)  fun=ID_FROM_PTR(p, funp); funa_is_prototype = fun->func.offset == -1; /* if(fun->func.offset == -1) continue; * prototype */
27ae842000-02-07Per Hedbor 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  /* check for multiple definitions */
3b7d182001-09-26Fredrik Hübinette (Hubbe)  for(t=i+1;t<(int)p->num_identifier_references;t++)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  { struct reference *funpb; struct identifier *funb;
27ae842000-02-07Per Hedbor 
3b7d182001-09-26Fredrik Hübinette (Hubbe)  funpb=p->identifier_references+t;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(funpb->id_flags & (ID_HIDDEN|ID_STATIC)) continue;
3b7d182001-09-26Fredrik Hübinette (Hubbe)  funb=ID_FROM_PTR(p,funpb);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  /* if(funb->func.offset == -1) continue; * prototype */
3b7d182001-09-26Fredrik Hübinette (Hubbe)  if(fun->name==funb->name) { found_better=t; if(funa_is_prototype && funb->func.offset != -1) { funp->inherit_offset = funpb->inherit_offset; funp->identifier_offset = funpb->identifier_offset; } if(!funa_is_prototype && funb->func.offset == -1) { funpb->inherit_offset = funp->inherit_offset; funpb->identifier_offset = funp->identifier_offset; } }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
3b7d182001-09-26Fredrik Hübinette (Hubbe)  if(found_better!=-1) continue;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  } add_to_identifier_index(i); }
3b7d182001-09-26Fredrik Hübinette (Hubbe)  fsort((void *)p->identifier_index, p->num_identifier_index,
05590d1998-04-23Fredrik Hübinette (Hubbe)  sizeof(unsigned short),(fsortfun)program_function_index_compare);
27ae842000-02-07Per Hedbor 
a5787d1999-03-03Fredrik Hübinette (Hubbe)  /* Yes, it is supposed to start at 1 /Hubbe */
87d5c52000-02-16Henrik Grubbström (Grubba)  for(i=1;i<NUM_LFUNS;i++) {
3b7d182001-09-26Fredrik Hübinette (Hubbe)  p->lfuns[i] = low_find_lfun(p, i);
2c17091999-06-22Fredrik Hübinette (Hubbe)  }
3b7d182001-09-26Fredrik Hübinette (Hubbe)  p->flags |= PROGRAM_FIXED; if(Pike_compiler->check_final) { for(i=0;i<(int)p->num_identifier_references;i++) { struct identifier *id; if(p->identifier_references[i].id_flags & ID_NOMASK) { struct pike_string *name=ID_FROM_INT(p, i)->name; e=find_shared_string_identifier(name,p);
5a071a2001-10-02Fredrik Hübinette (Hubbe)  if(e == -1) e=really_low_find_shared_string_identifier(name,p,SEE_STATIC);
3b7d182001-09-26Fredrik Hübinette (Hubbe)  if(e != i) { if(name->len < 1024 && !name->size_shift)
5a071a2001-10-02Fredrik Hübinette (Hubbe)  my_yyerror("Illegal to redefine final identifier %s",name->str);
3b7d182001-09-26Fredrik Hübinette (Hubbe)  else
5a071a2001-10-02Fredrik Hübinette (Hubbe)  my_yyerror("Illegal to redefine final identifier (unable to output name of identifier).");
3b7d182001-09-26Fredrik Hübinette (Hubbe)  } } } }
98bc6f2001-09-27Henrik Grubbström (Grubba) 
1e4e5f2000-04-07Fredrik Hübinette (Hubbe) #ifdef DEBUG_MALLOC { #define DBSTR(X) ((X)?(X)->str:"") int e,v;
a4033e2000-04-14Fredrik Hübinette (Hubbe)  INT32 line;
50edc82001-07-13Henrik Grubbström (Grubba)  struct pike_string *tmp;
a4033e2000-04-14Fredrik Hübinette (Hubbe)  struct memory_map *m=0;; if(lex.current_file && lex.current_file->str && lex.current_file->len && !strcmp(lex.current_file->str,"-")) { m=dmalloc_alloc_mmap( DBSTR(lex.current_file), lex.current_line); }
bad5162000-06-23Fredrik Hübinette (Hubbe)  else if( (tmp=find_program_name(Pike_compiler->new_program, &line)) )
a4033e2000-04-14Fredrik Hübinette (Hubbe)  {
50edc82001-07-13Henrik Grubbström (Grubba)  m=dmalloc_alloc_mmap( tmp->str, line); free_string(tmp);
a4033e2000-04-14Fredrik Hübinette (Hubbe)  }else{
bad5162000-06-23Fredrik Hübinette (Hubbe)  m=dmalloc_alloc_mmap( "program id", Pike_compiler->new_program->id);
a4033e2000-04-14Fredrik Hübinette (Hubbe)  }
bad5162000-06-23Fredrik Hübinette (Hubbe)  for(e=0;e<Pike_compiler->new_program->num_inherits;e++)
1e4e5f2000-04-07Fredrik Hübinette (Hubbe)  {
bad5162000-06-23Fredrik Hübinette (Hubbe)  struct inherit *i=Pike_compiler->new_program->inherits+e;
1e4e5f2000-04-07Fredrik Hübinette (Hubbe)  char *tmp;
50edc82001-07-13Henrik Grubbström (Grubba)  struct pike_string *tmp2 = NULL;
1e4e5f2000-04-07Fredrik Hübinette (Hubbe)  char buffer[50]; for(v=0;v<i->prog->num_variable_index;v++) { int d=i->prog->variable_index[v]; struct identifier *id=i->prog->identifiers+d; dmalloc_add_mmap_entry(m, id->name->str,
648a1a2000-06-22Fredrik Hübinette (Hubbe)  /* OFFSETOF(object,storage) + */ i->storage_offset + id->func.offset,
1e4e5f2000-04-07Fredrik Hübinette (Hubbe)  sizeof_variable(id->run_time_type), 1, /* count */ 0,0); } if(i->name) { tmp=i->name->str;
a4033e2000-04-14Fredrik Hübinette (Hubbe)  }
50edc82001-07-13Henrik Grubbström (Grubba)  else if(!(tmp2 = find_program_name(i->prog, &line)))
a4033e2000-04-14Fredrik Hübinette (Hubbe)  { sprintf(buffer,"inherit[%d]",e); tmp=buffer;
50edc82001-07-13Henrik Grubbström (Grubba)  } else { tmp = tmp2->str;
1e4e5f2000-04-07Fredrik Hübinette (Hubbe)  } dmalloc_add_mmap_entry(m, tmp,
648a1a2000-06-22Fredrik Hübinette (Hubbe)  /* OFFSETOF(object, storage) + */ i->storage_offset,
1e4e5f2000-04-07Fredrik Hübinette (Hubbe)  i->prog->storage_needed - i->prog->inherits[0].storage_offset, 1, /* count */ 0,0);
50edc82001-07-13Henrik Grubbström (Grubba)  if (tmp2) { free_string(tmp2); }
1e4e5f2000-04-07Fredrik Hübinette (Hubbe)  }
bad5162000-06-23Fredrik Hübinette (Hubbe)  dmalloc_set_mmap_template(Pike_compiler->new_program, m);
1e4e5f2000-04-07Fredrik Hübinette (Hubbe)  } #endif
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
05590d1998-04-23Fredrik Hübinette (Hubbe) struct program *low_allocate_program(void) {
1c1c5e2001-04-08Fredrik Hübinette (Hubbe)  struct program *p=alloc_program();
05590d1998-04-23Fredrik Hübinette (Hubbe)  MEMSET(p, 0, sizeof(struct program));
aa68b12001-03-19Fredrik Hübinette (Hubbe)  p->flags|=PROGRAM_VIRGIN;
90e9781999-01-31Fredrik Hübinette (Hubbe)  p->alignment_needed=1;
27ae842000-02-07Per Hedbor 
7bf6232000-04-23Martin Stjernholm  GC_ALLOC(p);
05590d1998-04-23Fredrik Hübinette (Hubbe)  p->id=++current_program_id;
45637c2001-04-07Fredrik Hübinette (Hubbe)  INIT_PIKE_MEMOBJ(p);
27ae842000-02-07Per Hedbor 
e2d9e62000-06-10Martin Stjernholm  DOUBLELINK(first_program, p);
05590d1998-04-23Fredrik Hübinette (Hubbe)  GETTIMEOFDAY(& p->timestamp); return p; }
5267b71995-08-09Fredrik Hübinette (Hubbe) /* * Start building a new program */
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) void low_start_new_program(struct program *p,
993ba72000-02-15Fredrik Hübinette (Hubbe)  struct pike_string *name, int flags, int *idp)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
6d22541998-01-28Fredrik Hübinette (Hubbe)  int e,id=0;
993ba72000-02-15Fredrik Hübinette (Hubbe)  struct svalue tmp;
5c8e891995-10-29Fredrik Hübinette (Hubbe) 
27ae842000-02-07Per Hedbor #if 0
f807f01999-11-11Henrik Grubbström (Grubba) #ifdef SHARED_NODES if (!node_hash.table) {
d3a3132000-12-01Henrik Grubbström (Grubba)  node_hash.table = malloc(sizeof(node *)*32831);
f807f01999-11-11Henrik Grubbström (Grubba)  if (!node_hash.table) { fatal("Out of memory!\n"); }
d3a3132000-12-01Henrik Grubbström (Grubba)  MEMSET(node_hash.table, 0, sizeof(node *)*32831); node_hash.size = 32831;
f807f01999-11-11Henrik Grubbström (Grubba)  } #endif /* SHARED_NODES */ #endif /* 0 */
58544f1998-07-17Henrik Grubbström (Grubba)  /* We don't want to change thread, but we don't want to * wait for the other threads to complete. */ low_init_threads_disable();
a91ca01998-07-10Henrik Grubbström (Grubba) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  compilation_depth++;
993ba72000-02-15Fredrik Hübinette (Hubbe)  tmp.type=T_PROGRAM;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(!p) {
05590d1998-04-23Fredrik Hübinette (Hubbe)  p=low_allocate_program();
993ba72000-02-15Fredrik Hübinette (Hubbe)  if(name) { tmp.u.program=p; id=add_constant(name, &tmp, flags & ~ID_EXTERN);
001aa52001-06-08Fredrik Hübinette (Hubbe)  if(TEST_COMPAT(7,2) || (lex.pragmas && ID_SAVE_PARENT)) { p->flags |= PROGRAM_USES_PARENT; }else{ struct pike_string *tmp=findstring("__pragma_save_parent__"); if(tmp) { struct node_s *n=find_module_identifier(tmp, 0); if(n) { free_node(n); p->flags |= PROGRAM_USES_PARENT; } } }
51717a2001-04-09Fredrik Hübinette (Hubbe) #if 0 fprintf(stderr,"Compiling class %s, depth=%d\n",name->str,compilation_depth); }else{ fprintf(stderr,"Compiling file %s, depth=%d\n", lex.current_file ? lex.current_file->str : "-", compilation_depth); #endif
993ba72000-02-15Fredrik Hübinette (Hubbe)  }
51717a2001-04-09Fredrik Hübinette (Hubbe)  if(compilation_depth >= 1) add_ref(p->parent = Pike_compiler->new_program);
e37a3e1999-10-09Fredrik Hübinette (Hubbe)  e=1;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }else{
993ba72000-02-15Fredrik Hübinette (Hubbe)  tmp.u.program=p;
8c83371998-04-16Fredrik Hübinette (Hubbe)  add_ref(p);
993ba72000-02-15Fredrik Hübinette (Hubbe)  if(name) { struct identifier *i; id=isidentifier(name); if (id < 0) fatal("Program constant disappeared in second pass.\n");
bad5162000-06-23Fredrik Hübinette (Hubbe)  i=ID_FROM_INT(Pike_compiler->new_program, id);
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(i->type);
993ba72000-02-15Fredrik Hübinette (Hubbe)  i->type=get_type_of_svalue(&tmp); }
e37a3e1999-10-09Fredrik Hübinette (Hubbe)  e=2;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
aa68b12001-03-19Fredrik Hübinette (Hubbe)  p->flags &=~ PROGRAM_VIRGIN;
342fef2000-08-23Fredrik Hübinette (Hubbe)  Pike_compiler->parent_identifier=id;
993ba72000-02-15Fredrik Hübinette (Hubbe)  if(idp) *idp=id;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
a359742001-12-16Martin Stjernholm  CDFPRINTF((stderr, "th(%ld) %p low_start_new_program() %s "
cb67042001-12-12Martin Stjernholm  "pass=%d: threads_disabled:%d, compilation_depth:%d\n",
a359742001-12-16Martin Stjernholm  (long)th_self(), p, name ? name->str : "-", Pike_compiler->compiler_pass, threads_disabled, compilation_depth));
cb67042001-12-12Martin Stjernholm 
fb2f661998-11-05Fredrik Hübinette (Hubbe)  init_type_stack();
5c8e891995-10-29Fredrik Hübinette (Hubbe) #define PUSH #include "compilation.h"
b8cda21997-01-21Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->compiler_pass=e;
e37a3e1999-10-09Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->num_used_modules=0;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(p && (p->flags & PROGRAM_FINISHED))
0683be1997-01-26Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  yyerror("Pass2: Program already done"); p=0; }
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->malloc_size_program = ALLOC_STRUCT(program);
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->fake_object=alloc_object(); Pike_compiler->fake_object->storage=(char *)xalloc(256 * sizeof(struct svalue));
6d22541998-01-28Fredrik Hübinette (Hubbe)  /* Stipple to find illegal accesses */
bad5162000-06-23Fredrik Hübinette (Hubbe)  MEMSET(Pike_compiler->fake_object->storage,0x55,256*sizeof(struct svalue));
6d22541998-01-28Fredrik Hübinette (Hubbe) #else
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->fake_object=ALLOC_STRUCT(object);
f3c7152001-04-14Fredrik Hübinette (Hubbe)  Pike_compiler->fake_object->storage=(char *)malloc(sizeof(struct parent_info));
6d22541998-01-28Fredrik Hübinette (Hubbe) #endif
ddac672000-07-02Martin Stjernholm  /* Can't use GC_ALLOC on fake objects, but still it's good to know * that they never take over a stale gc marker. */ if (Pike_in_gc) remove_marker(Pike_compiler->fake_object);
6d22541998-01-28Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->fake_object->next=Pike_compiler->fake_object; Pike_compiler->fake_object->prev=Pike_compiler->fake_object; Pike_compiler->fake_object->refs=1; Pike_compiler->fake_object->prog=p;
3aa0db1999-10-22Henrik Grubbström (Grubba)  add_ref(p);
1e4e5f2000-04-07Fredrik Hübinette (Hubbe)  #ifdef PIKE_DEBUG
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->fake_object->program_id=p->id;
1e4e5f2000-04-07Fredrik Hübinette (Hubbe) #endif
7e97c31999-01-21Fredrik Hübinette (Hubbe) #ifdef PIKE_SECURITY
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->fake_object->prot=0;
7e97c31999-01-21Fredrik Hübinette (Hubbe) #endif
6d22541998-01-28Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  debug_malloc_touch(Pike_compiler->fake_object); debug_malloc_touch(Pike_compiler->fake_object->storage);
648a1a2000-06-22Fredrik Hübinette (Hubbe) 
6d22541998-01-28Fredrik Hübinette (Hubbe)  if(name) {
f3c7152001-04-14Fredrik Hübinette (Hubbe)  /* Fake objects have parents regardless of PROGRAM_USE_PARENT */ if((((struct parent_info *)Pike_compiler->fake_object->storage)->parent=Pike_compiler->previous->fake_object)) add_ref(Pike_compiler->previous->fake_object); ((struct parent_info *)Pike_compiler->fake_object->storage)->parent_identifier=id; }else{ ((struct parent_info *)Pike_compiler->fake_object->storage)->parent=0; ((struct parent_info *)Pike_compiler->fake_object->storage)->parent_identifier=0;
6d22541998-01-28Fredrik Hübinette (Hubbe)  }
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->new_program=p;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
a786431999-11-18Martin Stjernholm #ifdef PROGRAM_BUILD_DEBUG if (name) { fprintf (stderr, "%.*sstarting program %d (pass=%d): ",
bad5162000-06-23Fredrik Hübinette (Hubbe)  compilation_depth, " ", Pike_compiler->new_program->id, Pike_compiler->compiler_pass);
a786431999-11-18Martin Stjernholm  push_string (name);
cd86322000-07-06Fredrik Hübinette (Hubbe)  print_svalue (stderr, --Pike_sp);
a786431999-11-18Martin Stjernholm  putc ('\n', stderr); } else fprintf (stderr, "%.*sstarting program %d (pass=%d)\n",
bad5162000-06-23Fredrik Hübinette (Hubbe)  compilation_depth, " ", Pike_compiler->new_program->id, Pike_compiler->compiler_pass);
a786431999-11-18Martin Stjernholm #endif
bad5162000-06-23Fredrik Hübinette (Hubbe)  debug_malloc_touch(Pike_compiler->fake_object); debug_malloc_touch(Pike_compiler->fake_object->storage);
648a1a2000-06-22Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->new_program->program)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  { #define FOO(NUMTYPE,TYPE,NAME) \
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->malloc_size_program->PIKE_CONCAT(num_,NAME)=Pike_compiler->new_program->PIKE_CONCAT(num_,NAME);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #include "program_areas.h"
1016021999-10-28Fredrik Hübinette (Hubbe)  { INT32 line=0, off=0;
50edc82001-07-13Henrik Grubbström (Grubba)  size_t len = 0; INT32 shift = 0;
1016021999-10-28Fredrik Hübinette (Hubbe)  char *file=0;
bad5162000-06-23Fredrik Hübinette (Hubbe)  char *cnt=Pike_compiler->new_program->linenumbers;
27ae842000-02-07Per Hedbor 
50edc82001-07-13Henrik Grubbström (Grubba)  while(cnt < Pike_compiler->new_program->linenumbers + Pike_compiler->new_program->num_linenumbers)
1016021999-10-28Fredrik Hübinette (Hubbe)  { if(*cnt == 127) {
50edc82001-07-13Henrik Grubbström (Grubba)  cnt++; len = get_small_number(&cnt); shift = *cnt; file = ++cnt; cnt += len<<shift;
1016021999-10-28Fredrik Hübinette (Hubbe)  } off+=get_small_number(&cnt); line+=get_small_number(&cnt); }
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->last_line=line; Pike_compiler->last_pc=off;
1016021999-10-28Fredrik Hübinette (Hubbe)  if(file) {
50edc82001-07-13Henrik Grubbström (Grubba)  struct pike_string *str = begin_wide_shared_string(len, shift);
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->last_file) free_string(Pike_compiler->last_file);
50edc82001-07-13Henrik Grubbström (Grubba)  memcpy(str->str, file, len<<shift); Pike_compiler->last_file = end_shared_string(str);
1016021999-10-28Fredrik Hübinette (Hubbe)  } }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }else{ static struct pike_string *s; struct inherit i; #define START_SIZE 64 #define FOO(NUMTYPE,TYPE,NAME) \
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->malloc_size_program->PIKE_CONCAT(num_,NAME)=START_SIZE; \ Pike_compiler->new_program->NAME=(TYPE *)xalloc(sizeof(TYPE) * START_SIZE);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #include "program_areas.h"
bad5162000-06-23Fredrik Hübinette (Hubbe)  i.prog=Pike_compiler->new_program;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  i.identifier_level=0; i.storage_offset=0; i.inherit_level=0; i.parent=0;
342fef2000-08-23Fredrik Hübinette (Hubbe)  i.parent_identifier=-1; i.parent_offset=-18;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  i.name=0;
342fef2000-08-23Fredrik Hübinette (Hubbe)  Pike_compiler->new_program->parent_program_id=compilation_depth>0 && Pike_compiler->previous->new_program ? Pike_compiler->previous->new_program->id : -1;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  add_to_inherits(i);
0683be1997-01-26Fredrik Hübinette (Hubbe)  }
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->init_node=0; Pike_compiler->num_parse_error=0;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
4218011999-01-31Fredrik Hübinette (Hubbe)  push_compiler_frame(0);
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(Pike_compiler->compiler_frame->current_return_type, void_type_string);
648a1a2000-06-22Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  debug_malloc_touch(Pike_compiler->fake_object); debug_malloc_touch(Pike_compiler->fake_object->storage);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void debug_start_new_program(PROGRAM_LINE_ARGS)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) {
b6f8c31999-07-01Henrik Grubbström (Grubba)  CDFPRINTF((stderr,
e0837a1999-07-01Fredrik Hübinette (Hubbe)  "th(%ld) start_new_program(): threads_disabled:%d, compilation_depth:%d\n", (long)th_self(),threads_disabled, compilation_depth));
b6f8c31999-07-01Henrik Grubbström (Grubba) 
993ba72000-02-15Fredrik Hübinette (Hubbe)  low_start_new_program(0,0,0,0);
bcd5741999-03-17Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG { struct pike_string *s=make_shared_string(file); store_linenumber(line,s); free_string(s);
bad5162000-06-23Fredrik Hübinette (Hubbe)  debug_malloc_name(Pike_compiler->new_program, file, line);
bcd5741999-03-17Fredrik Hübinette (Hubbe)  } #endif
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) }
1c1c5e2001-04-08Fredrik Hübinette (Hubbe) static void exit_program_struct(struct program *p)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
5c8e891995-10-29Fredrik Hübinette (Hubbe)  unsigned INT16 e;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
1c1c5e2001-04-08Fredrik Hübinette (Hubbe)  if(p->parent) {
c82a992001-04-13Henrik Grubbström (Grubba)  /* Make sure to break the circularity... */ struct program *parent = p->parent; p->parent = NULL; free_program(parent);
1c1c5e2001-04-08Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(id_to_program_cache[p->id & (ID_TO_PROGRAM_CACHE_SIZE-1)]==p) id_to_program_cache[p->id & (ID_TO_PROGRAM_CACHE_SIZE-1)]=0;
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(p->strings) for(e=0; e<p->num_strings; e++) if(p->strings[e]) free_string(p->strings[e]);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(p->identifiers)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
05590d1998-04-23Fredrik Hübinette (Hubbe)  for(e=0; e<p->num_identifiers; e++) { if(p->identifiers[e].name) free_string(p->identifiers[e].name); if(p->identifiers[e].type)
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(p->identifiers[e].type);
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(p->constants)
43fc171999-09-19Fredrik Hübinette (Hubbe)  {
454d541999-09-18Fredrik Hübinette (Hubbe)  for(e=0;e<p->num_constants;e++)
43fc171999-09-19Fredrik Hübinette (Hubbe)  {
454d541999-09-18Fredrik Hübinette (Hubbe)  free_svalue(& p->constants[e].sval);
43fc171999-09-19Fredrik Hübinette (Hubbe)  if(p->constants[e].name) free_string(p->constants[e].name); } }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(p->inherits) for(e=0; e<p->num_inherits; e++)
3c0c281998-01-26Fredrik Hübinette (Hubbe)  {
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(p->inherits[e].name) free_string(p->inherits[e].name); if(e) { if(p->inherits[e].prog) free_program(p->inherits[e].prog); } if(p->inherits[e].parent) free_object(p->inherits[e].parent);
3c0c281998-01-26Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
e2d9e62000-06-10Martin Stjernholm  DOUBLEUNLINK(first_program, p);
27ae842000-02-07Per Hedbor 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(p->flags & PROGRAM_OPTIMIZED)
05590d1998-04-23Fredrik Hübinette (Hubbe)  { if(p->program)
424d9c1999-05-02Fredrik Hübinette (Hubbe)  dmfree(p->program);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #define FOO(NUMTYPE,TYPE,NAME) p->NAME=0; #include "program_areas.h"
05590d1998-04-23Fredrik Hübinette (Hubbe)  }else{
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #define FOO(NUMTYPE,TYPE,NAME) \
424d9c1999-05-02Fredrik Hübinette (Hubbe)  if(p->NAME) { dmfree((char *)p->NAME); p->NAME=0; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #include "program_areas.h"
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
27ae842000-02-07Per Hedbor 
45637c2001-04-07Fredrik Hübinette (Hubbe)  EXIT_PIKE_MEMOBJ(p);
27ae842000-02-07Per Hedbor 
553d232000-09-14Martin Stjernholm  GC_FREE(p);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
2acdd31995-10-29Fredrik Hübinette (Hubbe) void dump_program_desc(struct program *p) { int e,d,q; /* fprintf(stderr,"Program '%s':\n",p->name->str); */ fprintf(stderr,"All inherits:\n"); for(e=0;e<p->num_inherits;e++) { for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," ");
5f05c11999-12-27Fredrik Hübinette (Hubbe)  fprintf(stderr,"%3d:\n",e);
b8896b2000-02-10Fredrik Hübinette (Hubbe)  for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," "); fprintf(stderr,"inherited program: %d\n",p->inherits[e].prog->id);
5f05c11999-12-27Fredrik Hübinette (Hubbe)  if(p->inherits[e].name) { for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," "); fprintf(stderr,"name : %s\n",p->inherits[e].name->str); } for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," "); fprintf(stderr,"inherit_level: %d\n",p->inherits[e].inherit_level); for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," "); fprintf(stderr,"identifier_level: %d\n",p->inherits[e].identifier_level); for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," "); fprintf(stderr,"parent_identifier: %d\n",p->inherits[e].parent_identifier); for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," "); fprintf(stderr,"parent_offset: %d\n",p->inherits[e].parent_offset); for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," ");
63540d2000-08-15Henrik Grubbström (Grubba)  fprintf(stderr,"storage_offset: %ld\n", DO_NOT_WARN((long)p->inherits[e].storage_offset));
5f05c11999-12-27Fredrik Hübinette (Hubbe)  for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," "); fprintf(stderr,"parent: %p\n",p->inherits[e].parent); if(p->inherits[e].parent && p->inherits[e].parent->prog && p->inherits[e].parent->prog->num_linenumbers>1) { for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," "); fprintf(stderr,"parent: %s\n",p->inherits[e].parent->prog->linenumbers+1); }
2acdd31995-10-29Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  fprintf(stderr,"All identifiers:\n");
2acdd31995-10-29Fredrik Hübinette (Hubbe)  for(e=0;e<(int)p->num_identifier_references;e++) { fprintf(stderr,"%3d:",e); for(d=0;d<INHERIT_FROM_INT(p,e)->inherit_level;d++) fprintf(stderr," ");
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  fprintf(stderr,"%s;\n",ID_FROM_INT(p,e)->name->str);
2acdd31995-10-29Fredrik Hübinette (Hubbe)  } fprintf(stderr,"All sorted identifiers:\n");
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  for(q=0;q<(int)p->num_identifier_index;q++)
2acdd31995-10-29Fredrik Hübinette (Hubbe)  { e=p->identifier_index[q]; fprintf(stderr,"%3d (%3d):",e,q); for(d=0;d<INHERIT_FROM_INT(p,e)->inherit_level;d++) fprintf(stderr," ");
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  fprintf(stderr,"%s;\n", ID_FROM_INT(p,e)->name->str);
2acdd31995-10-29Fredrik Hübinette (Hubbe)  } } #endif
be478c1997-08-30Henrik Grubbström (Grubba) static void toss_compilation_resources(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->fake_object)
a3c6ad1998-01-29Fredrik Hübinette (Hubbe)  {
f3c7152001-04-14Fredrik Hübinette (Hubbe)  if( ((struct parent_info *)Pike_compiler->fake_object->storage)->parent ) { free_object(((struct parent_info *)Pike_compiler->fake_object->storage)->parent); ((struct parent_info *)Pike_compiler->fake_object->storage)->parent=0; }
bad5162000-06-23Fredrik Hübinette (Hubbe)  free_program(Pike_compiler->fake_object->prog); Pike_compiler->fake_object->prog=0; free_object(Pike_compiler->fake_object); Pike_compiler->fake_object=0;
a3c6ad1998-01-29Fredrik Hübinette (Hubbe)  }
bad5162000-06-23Fredrik Hübinette (Hubbe)  free_program(Pike_compiler->new_program); Pike_compiler->new_program=0;
591c0c1997-01-19Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->malloc_size_program)
591c0c1997-01-19Fredrik Hübinette (Hubbe)  {
bad5162000-06-23Fredrik Hübinette (Hubbe)  dmfree((char *)Pike_compiler->malloc_size_program); Pike_compiler->malloc_size_program=0;
591c0c1997-01-19Fredrik Hübinette (Hubbe)  }
05590d1998-04-23Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->module_index_cache)
05590d1998-04-23Fredrik Hübinette (Hubbe)  {
bad5162000-06-23Fredrik Hübinette (Hubbe)  free_mapping(Pike_compiler->module_index_cache); Pike_compiler->module_index_cache=0;
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
27ae842000-02-07Per Hedbor 
bad5162000-06-23Fredrik Hübinette (Hubbe)  while(Pike_compiler->compiler_frame)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  pop_compiler_frame();
591c0c1997-01-19Fredrik Hübinette (Hubbe) 
de1d7d2000-07-10Henrik Grubbström (Grubba)  if(Pike_compiler->last_identifier) { free_string(Pike_compiler->last_identifier); Pike_compiler->last_identifier=0; }
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->last_file)
591c0c1997-01-19Fredrik Hübinette (Hubbe)  {
bad5162000-06-23Fredrik Hübinette (Hubbe)  free_string(Pike_compiler->last_file); Pike_compiler->last_file=0;
591c0c1997-01-19Fredrik Hübinette (Hubbe)  }
bad5162000-06-23Fredrik Hübinette (Hubbe)  unuse_modules(Pike_compiler->num_used_modules);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
e964ae1998-04-08Fredrik Hübinette (Hubbe) int sizeof_variable(int run_time_type)
1994981998-04-07Fredrik Hübinette (Hubbe) { switch(run_time_type) { case T_FUNCTION: case T_MIXED: return sizeof(struct svalue); case T_FLOAT: return sizeof(FLOAT_TYPE);
2ba9191999-10-23Fredrik Hübinette (Hubbe)  case T_INT: return sizeof(INT_TYPE);
1994981998-04-07Fredrik Hübinette (Hubbe)  default: return sizeof(char *); } }
d3b06f2000-08-10Henrik Grubbström (Grubba) static ptrdiff_t alignof_variable(int run_time_type)
1994981998-04-07Fredrik Hübinette (Hubbe) { switch(run_time_type) { case T_FUNCTION:
90e9781999-01-31Fredrik Hübinette (Hubbe)  case T_MIXED: return ALIGNOF(struct svalue);
1994981998-04-07Fredrik Hübinette (Hubbe)  case T_FLOAT: return ALIGNOF(FLOAT_TYPE);
2ba9191999-10-23Fredrik Hübinette (Hubbe)  case T_INT: return ALIGNOF(INT_TYPE);
1994981998-04-07Fredrik Hübinette (Hubbe)  default: return ALIGNOF(char *); } }
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
e51d101999-09-15Fredrik Hübinette (Hubbe) 
624d091996-02-24Fredrik Hübinette (Hubbe) void check_program(struct program *p)
0d202a1995-10-20Fredrik Hübinette (Hubbe) {
3c58e51999-09-22Henrik Grubbström (Grubba)  INT32 size; unsigned INT32 checksum, e;
68b6951999-09-15Fredrik Hübinette (Hubbe)  int variable_positions[1024];
8ba59a2000-03-26Fredrik Hübinette (Hubbe)  if(p->flags & PROGRAM_AVOID_CHECK) return;
68b6951999-09-15Fredrik Hübinette (Hubbe)  for(e=0;e<NELEM(variable_positions);e++) variable_positions[e]=-1;
0d202a1995-10-20Fredrik Hübinette (Hubbe) 
636e471998-04-15Fredrik Hübinette (Hubbe)  if(p->id > current_program_id) fatal("Program id is out of sync! (p->id=%d, current_program_id=%d)\n",p->id,current_program_id);
0d202a1995-10-20Fredrik Hübinette (Hubbe)  if(p->refs <=0) fatal("Program has zero refs.\n"); if(p->next && p->next->prev != p) fatal("Program ->next->prev != program.\n"); if(p->prev) { if(p->prev->next != p) fatal("Program ->prev->next != program.\n"); }else{ if(first_program != p) fatal("Program ->prev == 0 but first_program != program.\n"); }
d2c6081996-11-07Fredrik Hübinette (Hubbe)  if(p->id > current_program_id || p->id <= 0)
0d202a1995-10-20Fredrik Hübinette (Hubbe)  fatal("Program id is wrong.\n"); if(p->storage_needed < 0) fatal("Program->storage_needed < 0.\n");
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(p->num_identifier_index > p->num_identifier_references) fatal("Too many identifier index entries in program!\n");
3c58e51999-09-22Henrik Grubbström (Grubba)  for(e=0;e<p->num_constants;e++)
454d541999-09-18Fredrik Hübinette (Hubbe)  { check_svalue(& p->constants[e].sval); if(p->constants[e].name) check_string(p->constants[e].name); }
0d202a1995-10-20Fredrik Hübinette (Hubbe) 
3c58e51999-09-22Henrik Grubbström (Grubba)  for(e=0;e<p->num_strings;e++)
0d202a1995-10-20Fredrik Hübinette (Hubbe)  check_string(p->strings[e]);
3c58e51999-09-22Henrik Grubbström (Grubba)  for(e=0;e<p->num_inherits;e++)
e51d101999-09-15Fredrik Hübinette (Hubbe)  {
ce277e2000-03-25Fredrik Hübinette (Hubbe)  if(!p->inherits[e].prog) {
e05acb2000-03-25Fredrik Hübinette (Hubbe)  /* This inherit is not yet initialized, ignore rest of tests.. */ return;
ce277e2000-03-25Fredrik Hübinette (Hubbe)  }
e51d101999-09-15Fredrik Hübinette (Hubbe)  if(p->inherits[e].storage_offset < 0) fatal("Inherit->storage_offset is wrong.\n");
1f5bfe1999-09-28Fredrik Hübinette (Hubbe)  if(p->inherits[e].prog && p->inherits[e].storage_offset + STORAGE_NEEDED(p->inherits[e].prog) > p->storage_needed) fatal("Not enough room allocated by inherit!\n");
e51d101999-09-15Fredrik Hübinette (Hubbe)  if(e) {
27ae842000-02-07Per Hedbor  if(p->inherits[e-1].storage_offset >
e51d101999-09-15Fredrik Hübinette (Hubbe)  p->inherits[e].storage_offset) fatal("Overlapping inherits! (1)\n");
27ae842000-02-07Per Hedbor 
e51d101999-09-15Fredrik Hübinette (Hubbe)  if(p->inherits[e-1].prog &&
27ae842000-02-07Per Hedbor  p->inherits[e-1].inherit_level >= p->inherits[e].inherit_level &&
1f5bfe1999-09-28Fredrik Hübinette (Hubbe)  ( p->inherits[e-1].storage_offset + STORAGE_NEEDED(p->inherits[e-1].prog)) > p->inherits[e].storage_offset) fatal("Overlapping inherits! (3)\n");
e51d101999-09-15Fredrik Hübinette (Hubbe)  } }
29338d1999-09-29Henrik Grubbström (Grubba) 
7066e11999-09-14Fredrik Hübinette (Hubbe)  if(p->flags & PROGRAM_FINISHED)
3c58e51999-09-22Henrik Grubbström (Grubba)  for(e=0;e<p->num_identifiers;e++)
0d202a1995-10-20Fredrik Hübinette (Hubbe)  { check_string(p->identifiers[e].name);
4b9d802001-02-21Henrik Grubbström (Grubba)  check_type_string(p->identifiers[e].type);
0d202a1995-10-20Fredrik Hübinette (Hubbe) 
97f6282000-03-07Fredrik Hübinette (Hubbe)  if(p->identifiers[e].identifier_flags & ~IDENTIFIER_MASK)
0d202a1995-10-20Fredrik Hübinette (Hubbe)  fatal("Unknown flags in identifier flag field.\n"); if(p->identifiers[e].run_time_type!=T_MIXED) check_type(p->identifiers[e].run_time_type);
2f1b9e1998-04-06Fredrik Hübinette (Hubbe)  if(IDENTIFIER_IS_VARIABLE(p->identifiers[e].identifier_flags)) {
648a1a2000-06-22Fredrik Hübinette (Hubbe)  if( (p->identifiers[e].func.offset /* + OFFSETOF(object,storage)*/ ) &
1994981998-04-07Fredrik Hübinette (Hubbe)  (alignof_variable(p->identifiers[e].run_time_type)-1))
2f1b9e1998-04-06Fredrik Hübinette (Hubbe)  {
6f95902000-08-17Henrik Grubbström (Grubba)  fatal("Variable %s offset is not properly aligned (%ld).\n", p->identifiers[e].name->str, PTRDIFF_T_TO_LONG(p->identifiers[e].func.offset));
2f1b9e1998-04-06Fredrik Hübinette (Hubbe)  } }
0d202a1995-10-20Fredrik Hübinette (Hubbe)  }
3c58e51999-09-22Henrik Grubbström (Grubba)  for(e=0;e<p->num_identifier_references;e++)
0d202a1995-10-20Fredrik Hübinette (Hubbe)  {
68b6951999-09-15Fredrik Hübinette (Hubbe)  struct identifier *i;
0d202a1995-10-20Fredrik Hübinette (Hubbe)  if(p->identifier_references[e].inherit_offset > p->num_inherits) fatal("Inherit offset is wrong!\n");
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
513ece1999-09-09Fredrik Hübinette (Hubbe)  if(!p->inherits[p->identifier_references[e].inherit_offset].prog) { if(!(p->flags & PROGRAM_FINISHED)) continue; fatal("p->inherit[%d].prog = NULL!\n",p->identifier_references[e].inherit_offset); }
0d202a1995-10-20Fredrik Hübinette (Hubbe)  if(p->identifier_references[e].identifier_offset > p->inherits[p->identifier_references[e].inherit_offset].prog->num_identifiers)
19be9f2001-07-02Fredrik Hübinette (Hubbe)  fatal("Identifier offset %d is wrong! %d > %d\n", e, p->identifier_references[e].identifier_offset, p->inherits[p->identifier_references[e].inherit_offset].prog->num_identifiers);
68b6951999-09-15Fredrik Hübinette (Hubbe)  i=ID_FROM_INT(p, e); if( !(i->identifier_flags & (IDENTIFIER_FUNCTION | IDENTIFIER_CONSTANT))) {
63540d2000-08-15Henrik Grubbström (Grubba)  size_t q, size;
68b6951999-09-15Fredrik Hübinette (Hubbe)  /* Variable */
63540d2000-08-15Henrik Grubbström (Grubba)  ptrdiff_t offset = INHERIT_FROM_INT(p, e)->storage_offset+i->func.offset;
e51d101999-09-15Fredrik Hübinette (Hubbe)  size=sizeof_variable(i->run_time_type);
63540d2000-08-15Henrik Grubbström (Grubba)  if((offset+size > (size_t)p->storage_needed) || offset<0)
e51d101999-09-15Fredrik Hübinette (Hubbe)  fatal("Variable outside storage! (%s)\n",i->name->str); for(q=0;q<size;q++)
68b6951999-09-15Fredrik Hübinette (Hubbe)  { if(offset+q >= NELEM(variable_positions)) break; if(variable_positions[offset+q] != -1) { if(ID_FROM_INT(p,variable_positions[offset+q])->run_time_type != i->run_time_type) {
2509e92001-07-02Henrik Grubbström (Grubba)  fprintf(stderr, "Storage offset: 0x%08x vs 0x%08x\n" "Func offset: 0x%08x vs 0x%08x\n" "Type: %s vs %s\n", INHERIT_FROM_INT(p, variable_positions[offset+q])-> storage_offset, INHERIT_FROM_INT(p, e)->storage_offset, ID_FROM_INT(p, variable_positions[offset+q])->func.offset, i->func.offset, get_name_of_type(ID_FROM_INT(p,variable_positions[offset+q] )->run_time_type), get_name_of_type(i->run_time_type));
66e2cf2001-06-10Henrik Grubbström (Grubba)  if (i->name) {
0626282001-07-02Henrik Grubbström (Grubba)  fatal("Variable '%s' and '%s' overlap\n" "Offset 0x%08x - 0x%08x overlaps with 0x%08x - 0x%08x\n",
66e2cf2001-06-10Henrik Grubbström (Grubba)  ID_FROM_INT(p, variable_positions[offset+q])->name->str,
0626282001-07-02Henrik Grubbström (Grubba)  i->name->str, INHERIT_FROM_INT(p, variable_positions[offset+q])-> storage_offset + ID_FROM_INT(p, variable_positions[offset+q])->func.offset, INHERIT_FROM_INT(p, variable_positions[offset+q])-> storage_offset + ID_FROM_INT(p, variable_positions[offset+q])->func.offset + sizeof_variable(ID_FROM_INT(p, variable_positions[offset+q]
2653e82001-07-02Henrik Grubbström (Grubba)  )->run_time_type)-1,
0626282001-07-02Henrik Grubbström (Grubba)  offset, offset+size-1);
66e2cf2001-06-10Henrik Grubbström (Grubba)  } else {
0626282001-07-02Henrik Grubbström (Grubba)  fatal("Variable '%s' and anonymous variable (%d) overlap\n" "Offset 0x%08x - 0x%08x overlaps with 0x%08x - 0x%08x\n",
66e2cf2001-06-10Henrik Grubbström (Grubba)  ID_FROM_INT(p, variable_positions[offset+q])->name->str,
0626282001-07-02Henrik Grubbström (Grubba)  e, INHERIT_FROM_INT(p, variable_positions[offset+q])-> storage_offset + ID_FROM_INT(p, variable_positions[offset+q])->func.offset, INHERIT_FROM_INT(p, variable_positions[offset+q])-> storage_offset + ID_FROM_INT(p, variable_positions[offset+q])->func.offset + sizeof_variable(ID_FROM_INT(p, variable_positions[offset+q]
2653e82001-07-02Henrik Grubbström (Grubba)  )->run_time_type)-1,
0626282001-07-02Henrik Grubbström (Grubba)  offset, offset+size-1);
66e2cf2001-06-10Henrik Grubbström (Grubba)  }
68b6951999-09-15Fredrik Hübinette (Hubbe)  } } variable_positions[offset+q]=e; } }
0d202a1995-10-20Fredrik Hübinette (Hubbe)  }
3c58e51999-09-22Henrik Grubbström (Grubba)  for(e=0;e<p->num_identifier_index;e++)
0d202a1995-10-20Fredrik Hübinette (Hubbe)  { if(p->identifier_index[e] > p->num_identifier_references) fatal("Program->identifier_indexes[%ld] is wrong\n",(long)e); } } #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) 
cb67042001-12-12Martin Stjernholm /* Note: This function is misnamed, since it's run after both passes. /mast */
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) struct program *end_first_pass(int finish)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
0ffa001998-01-13Fredrik Hübinette (Hubbe)  int e;
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct program *prog;
0ffa001998-01-13Fredrik Hübinette (Hubbe)  struct pike_string *s;
bad5162000-06-23Fredrik Hübinette (Hubbe)  debug_malloc_touch(Pike_compiler->fake_object); debug_malloc_touch(Pike_compiler->fake_object->storage);
648a1a2000-06-22Fredrik Hübinette (Hubbe) 
0ffa001998-01-13Fredrik Hübinette (Hubbe)  MAKE_CONSTANT_SHARED_STRING(s,"__INIT"); /* Collect references to inherited __INIT functions */
bad5162000-06-23Fredrik Hübinette (Hubbe)  for(e=Pike_compiler->new_program->num_inherits-1;e;e--)
0ffa001998-01-13Fredrik Hübinette (Hubbe)  { int id;
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->new_program->inherits[e].inherit_level!=1) continue;
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  id=low_reference_inherited_identifier(0, e, s, SEE_STATIC);
0ffa001998-01-13Fredrik Hübinette (Hubbe)  if(id!=-1) {
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->init_node=mknode(F_COMMA_EXPR,
0ffa001998-01-13Fredrik Hübinette (Hubbe)  mkcastnode(void_type_string,
87c9d21998-04-09Fredrik Hübinette (Hubbe)  mkapplynode(mkidentifiernode(id),0)),
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->init_node);
0ffa001998-01-13Fredrik Hübinette (Hubbe)  } }
5267b71995-08-09Fredrik Hübinette (Hubbe)  /* * Define the __INIT function, but only if there was any code * to initialize. */
0ffa001998-01-13Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->init_node)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
a5787d1999-03-03Fredrik Hübinette (Hubbe)  e=dooptcode(s,
3d78821999-11-06Henrik Grubbström (Grubba)  mknode(F_COMMA_EXPR,
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->init_node,mknode(F_RETURN,mkintnode(0),0)),
a5787d1999-03-03Fredrik Hübinette (Hubbe)  function_type_string, ID_STATIC);
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->init_node=0;
a5787d1999-03-03Fredrik Hübinette (Hubbe)  }else{ e=-1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->new_program->lfuns[LFUN___INIT]=e;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  free_string(s);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  pop_compiler_frame(); /* Pop __INIT local variables */
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->num_parse_error > 0)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { prog=0; }else{
bad5162000-06-23Fredrik Hübinette (Hubbe)  prog=Pike_compiler->new_program;
8c83371998-04-16Fredrik Hübinette (Hubbe)  add_ref(prog);
5580691996-06-21Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
624d091996-02-24Fredrik Hübinette (Hubbe)  check_program(prog);
2acdd31995-10-29Fredrik Hübinette (Hubbe)  if(l_flag) dump_program_desc(prog);
0d202a1995-10-20Fredrik Hübinette (Hubbe) #endif
5580691996-06-21Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->new_program->flags |= PROGRAM_PASS_1_DONE;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(finish) {
f3c7152001-04-14Fredrik Hübinette (Hubbe)  if(Pike_compiler->new_program->flags & PROGRAM_USES_PARENT) { Pike_compiler->new_program->parent_info_storage = add_xstorage(sizeof(struct parent_info), ALIGNOF(struct parent_info), 0); }else{ /* Cause errors if used hopefully */ Pike_compiler->new_program->parent_info_storage=-1; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  fixate_program();
3b7d182001-09-26Fredrik Hübinette (Hubbe)  if(Pike_compiler->num_parse_error) { free_program(prog); prog=0; }else{ optimize_program(Pike_compiler->new_program); Pike_compiler->new_program->flags |= PROGRAM_FINISHED; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
a786431999-11-18Martin Stjernholm  #ifdef PROGRAM_BUILD_DEBUG fprintf (stderr, "%.*sfinishing program %d (pass=%d)\n",
bad5162000-06-23Fredrik Hübinette (Hubbe)  compilation_depth, " ", Pike_compiler->new_program->id, Pike_compiler->compiler_pass);
a786431999-11-18Martin Stjernholm #endif
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  toss_compilation_resources();
5267b71995-08-09Fredrik Hübinette (Hubbe) 
cb67042001-12-12Martin Stjernholm #if 0
aed42d1999-12-29Martin Stjernholm  CDFPRINTF((stderr,
cb67042001-12-12Martin Stjernholm  "th(%ld) end_first_pass(): " "compilation_depth:%d, Pike_compiler->compiler_pass:%d\n",
bad5162000-06-23Fredrik Hübinette (Hubbe)  (long)th_self(), compilation_depth, Pike_compiler->compiler_pass));
cb67042001-12-12Martin Stjernholm #endif
aed42d1999-12-29Martin Stjernholm 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(!Pike_compiler->compiler_frame && (Pike_compiler->compiler_pass==2 || !prog) && resolve_cache)
aed42d1999-12-29Martin Stjernholm  { free_mapping(dmalloc_touch(struct mapping *, resolve_cache)); resolve_cache=0; }
f807f01999-11-11Henrik Grubbström (Grubba) #ifdef SHARED_NODES /* free(node_hash.table); */ #endif /* SHARED_NODES */
5c8e891995-10-29Fredrik Hübinette (Hubbe) #define POP #include "compilation.h"
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
fb2f661998-11-05Fredrik Hübinette (Hubbe)  exit_type_stack();
05590d1998-04-23Fredrik Hübinette (Hubbe) 
b3cca72001-06-14Henrik Grubbström (Grubba)  CDFPRINTF((stderr,
cb67042001-12-12Martin Stjernholm  "th(%ld) %p end_first_pass(%d): " "threads_disabled:%d, compilation_depth:%d\n", (long)th_self(), prog, finish, threads_disabled, compilation_depth));
b3cca72001-06-14Henrik Grubbström (Grubba) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  compilation_depth--;
a91ca01998-07-10Henrik Grubbström (Grubba)  exit_threads_disable(NULL);
ea32c11998-04-13Henrik Grubbström (Grubba) 
a8ef6e1996-12-03Fredrik Hübinette (Hubbe)  free_all_nodes();
5f05c11999-12-27Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  return prog; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) /* * Finish this program, returning the newly built program */
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT struct program *debug_end_program(void)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) { return end_first_pass(1); }
5267b71995-08-09Fredrik Hübinette (Hubbe) /* * Allocate needed for this program in the object structure. * An offset to the data is returned. */
b819352000-08-14Henrik Grubbström (Grubba) PMOD_EXPORT size_t low_add_storage(size_t size, size_t alignment, ptrdiff_t modulo_orig)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
d3b06f2000-08-10Henrik Grubbström (Grubba)  ptrdiff_t offset; ptrdiff_t modulo;
2ad3c01999-09-16Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(!size) return Pike_compiler->new_program->storage_needed;
2ad3c01999-09-16Fredrik Hübinette (Hubbe) 
90e9781999-01-31Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG if(alignment <=0 || (alignment & (alignment-1)) || alignment > 256)
69bb402000-08-17Henrik Grubbström (Grubba)  fatal("Alignment must be 1,2,4,8,16,32,64,128 or 256 not %ld\n", PTRDIFF_T_TO_LONG(alignment));
90e9781999-01-31Fredrik Hübinette (Hubbe) #endif
648a1a2000-06-22Fredrik Hübinette (Hubbe)  modulo=( modulo_orig /* +OFFSETOF(object,storage) */ ) % alignment;
b1c8031999-09-15Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  offset=DO_ALIGN(Pike_compiler->new_program->storage_needed-modulo,alignment)+modulo;
90e9781999-01-31Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(!Pike_compiler->new_program->storage_needed) { /* Shouldn't Pike_compiler->new_program->storage_needed be set here?
29338d1999-09-29Henrik Grubbström (Grubba)  * Otherwise the debug code below ought to be trigged. * But since it isn't, I guess this is dead code? * /grubba 1999-09-28
eb071e1999-09-28Fredrik Hübinette (Hubbe)  * * No, the below offset represents the storage in the beginning * of obj->storage which is not used because of alignment constraints. * However, for historical reasons, prog->storage_offset needs to * contain this unused space as well. This means that the real * space used by all variables in an object is really: * o->prog->storage_needed - o->prog->inherits[0].storage_offset, * This can also be written as STORAGE_NEEDED(o->prog) * STORAGE_NEEDED() is defined in program.h. * /Hubbe 1999-09-29
0ee2331999-09-29Henrik Grubbström (Grubba)  * * Oops, seems I read the test below the wrong way around. * /grubba 1999-09-29
29338d1999-09-29Henrik Grubbström (Grubba)  */
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->new_program->inherits[0].storage_offset=offset;
29338d1999-09-29Henrik Grubbström (Grubba)  }
90e9781999-01-31Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->new_program->alignment_needed<alignment)
b819352000-08-14Henrik Grubbström (Grubba)  Pike_compiler->new_program->alignment_needed = DO_NOT_WARN((unsigned INT8)alignment);
90e9781999-01-31Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(offset < Pike_compiler->new_program->storage_needed)
1994981998-04-07Fredrik Hübinette (Hubbe)  fatal("add_storage failed horribly!\n");
b1c8031999-09-15Fredrik Hübinette (Hubbe) 
648a1a2000-06-22Fredrik Hübinette (Hubbe)  if( (offset /* + OFFSETOF(object,storage) */ - modulo_orig ) % alignment )
454d541999-09-18Fredrik Hübinette (Hubbe)  fatal("add_storage failed horribly(2) %ld %ld %ld %ld!\n",
d3b06f2000-08-10Henrik Grubbström (Grubba)  DO_NOT_WARN((long)offset),
648a1a2000-06-22Fredrik Hübinette (Hubbe)  (long)0 /* + OFFSETOF(object,storage) */,
63540d2000-08-15Henrik Grubbström (Grubba)  DO_NOT_WARN((long)modulo_orig),
d3b06f2000-08-10Henrik Grubbström (Grubba)  DO_NOT_WARN((long)alignment));
27ae842000-02-07Per Hedbor 
1994981998-04-07Fredrik Hübinette (Hubbe) #endif
b1c8031999-09-15Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->new_program->storage_needed = offset + size;
b1c8031999-09-15Fredrik Hübinette (Hubbe) 
b819352000-08-14Henrik Grubbström (Grubba)  return (size_t) offset;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
f3c7152001-04-14Fredrik Hübinette (Hubbe) /* * Internal function. * Adds object storage that will *not* be inherited. */ static size_t add_xstorage(size_t size, size_t alignment, ptrdiff_t modulo_orig) { ptrdiff_t offset, modulo, available; int e; if(!size) return Pike_compiler->new_program->xstorage; modulo=( modulo_orig /* +OFFSETOF(object,storage) */ ) % alignment; offset=DO_ALIGN(Pike_compiler->new_program->xstorage-modulo,alignment)+modulo; Pike_compiler->new_program->xstorage = offset + size; /* Move all inherits to make room */ available = Pike_compiler->new_program->inherits[0].storage_offset;
21fdac2001-05-02Henrik Grubbström (Grubba)  if(available < (ptrdiff_t)(offset+size))
f3c7152001-04-14Fredrik Hübinette (Hubbe)  { available= DO_ALIGN( ((offset + size) - available), Pike_compiler->new_program->alignment_needed); for(e=0;e<Pike_compiler->new_program->num_inherits;e++) Pike_compiler->new_program->inherits[e].storage_offset+=available; Pike_compiler->new_program->storage_needed+=available; } return (size_t) offset; }
763f682001-03-12Fredrik Hübinette (Hubbe) typedef void (*oldhandlertype)(struct object *);
b5dc812001-07-12Fredrik Hübinette (Hubbe) static void compat_event_handler(int e)
763f682001-03-12Fredrik Hübinette (Hubbe) { oldhandlertype handler;
d0787c2001-09-20Fredrik Hübinette (Hubbe)  debug_malloc_touch(Pike_fp->current_object);
763f682001-03-12Fredrik Hübinette (Hubbe)  handler=((oldhandlertype *)Pike_fp->context.prog->program)[e]; if(handler) handler(Pike_fp->current_object);
d0787c2001-09-20Fredrik Hübinette (Hubbe)  debug_malloc_touch(Pike_fp->current_object);
763f682001-03-12Fredrik Hübinette (Hubbe) } static void add_compat_event_handler(void) { if(Pike_compiler->new_program->event_handler != compat_event_handler) { unsigned int e,d; unsigned char *tmp=(unsigned char *)&Pike_compiler->new_program->event_handler;
6d727b2001-07-08Henrik Grubbström (Grubba)  for(d=0;d<NUM_PROG_EVENTS;d++) { /* FIXME: This looks like it might be broken. */
b5dc812001-07-12Fredrik Hübinette (Hubbe)  /* Broken how? -Hubbe */
6d727b2001-07-08Henrik Grubbström (Grubba) #ifdef HAVE_COMPUTED_GOTO add_to_program(Pike_compiler->new_program->event_handler); #else /* !HAVE_COMPUTED_GOTO */
763f682001-03-12Fredrik Hübinette (Hubbe)  for(e=0;e<sizeof(Pike_compiler->new_program->event_handler);e++) add_to_program(tmp[e]);
6d727b2001-07-08Henrik Grubbström (Grubba) #endif /* HAVE_COMPUTED_GOTO */ }
763f682001-03-12Fredrik Hübinette (Hubbe)  Pike_compiler->new_program->event_handler=compat_event_handler; } }
1994981998-04-07Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe) /* * set a callback used to initialize clones of this program * the init function is called at clone time
03bcb92001-03-12Fredrik Hübinette (Hubbe)  * This function is obsolete, use pike_set_prog_event_callback instead.
5267b71995-08-09Fredrik Hübinette (Hubbe)  */
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void set_init_callback(void (*init)(struct object *))
5267b71995-08-09Fredrik Hübinette (Hubbe) {
763f682001-03-12Fredrik Hübinette (Hubbe)  add_compat_event_handler(); ((oldhandlertype *)Pike_compiler->new_program->program)[PROG_EVENT_INIT]=init;
5267b71995-08-09Fredrik Hübinette (Hubbe) } /* * set a callback used to de-initialize clones of this program * the exit function is called at destruct
03bcb92001-03-12Fredrik Hübinette (Hubbe)  * This function is obsolete, use pike_set_prog_event_callback instead.
5267b71995-08-09Fredrik Hübinette (Hubbe)  */
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void set_exit_callback(void (*exit)(struct object *))
5267b71995-08-09Fredrik Hübinette (Hubbe) {
763f682001-03-12Fredrik Hübinette (Hubbe)  add_compat_event_handler(); ((oldhandlertype *)Pike_compiler->new_program->program)[PROG_EVENT_EXIT]=exit;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
d4828c1997-07-17Fredrik Hübinette (Hubbe) /*
e2d9e62000-06-10Martin Stjernholm  * This callback is used by the gc to traverse all references to * objects. It should call some gc_recurse_* function exactly once for * each reference that the pike internals doesn't know about. * * If a reference is shared between objects, it should be traversed * once for every instance sharing it. * * The callback might be called more than once for the same instance * during a gc pass. The gc assumes that the references are enumerated * in the same order in that case.
03bcb92001-03-12Fredrik Hübinette (Hubbe)  * * This function is obsolete, use pike_set_prog_event_callback instead.
d4828c1997-07-17Fredrik Hübinette (Hubbe)  */
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void set_gc_recurse_callback(void (*m)(struct object *))
d4828c1997-07-17Fredrik Hübinette (Hubbe) {
763f682001-03-12Fredrik Hübinette (Hubbe)  add_compat_event_handler(); ((oldhandlertype *)Pike_compiler->new_program->program)[PROG_EVENT_GC_RECURSE]=m;
d4828c1997-07-17Fredrik Hübinette (Hubbe) }
f0c3d31998-04-05Fredrik Hübinette (Hubbe) /*
e2d9e62000-06-10Martin Stjernholm  * This callback is used by the gc to count all references to objects. * It should call gc_check, gc_check_(weak_)svalues or * gc_check_(weak_)short_svalue exactly once for each reference that * the pike internals doesn't know about. * * If a reference is shared between objects, it should be counted once * for all shared instances. The return value from gc_check is useful * to ensure this; it's zero when called the first time for its * argument.
03bcb92001-03-12Fredrik Hübinette (Hubbe)  * * This function is obsolete, use pike_set_prog_event_callback instead.
f0c3d31998-04-05Fredrik Hübinette (Hubbe)  */
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void set_gc_check_callback(void (*m)(struct object *))
f0c3d31998-04-05Fredrik Hübinette (Hubbe) {
763f682001-03-12Fredrik Hübinette (Hubbe)  add_compat_event_handler(); ((oldhandlertype *)Pike_compiler->new_program->program)[PROG_EVENT_GC_CHECK]=m;
f0c3d31998-04-05Fredrik Hübinette (Hubbe) }
b5dc812001-07-12Fredrik Hübinette (Hubbe) void pike_set_prog_event_callback(void (*cb)(int))
03bcb92001-03-12Fredrik Hübinette (Hubbe) { #ifdef PIKE_DEBUG if(Pike_compiler->new_program->event_handler) fatal("Program already has an event handler!\n"); #endif Pike_compiler->new_program->event_handler=cb; }
a5d45c2001-05-26Henrik Grubbström (Grubba) void pike_set_prog_optimize_callback(node *(*opt)(node *)) { #ifdef PIKE_DEBUG if(Pike_compiler->new_program->optimize) fatal("Program already has an optimize handler!\n"); #endif Pike_compiler->new_program->optimize = opt; }
d429a71998-02-24Fredrik Hübinette (Hubbe) int low_reference_inherited_identifier(struct program_state *q, int e,
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  struct pike_string *name, int flags)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
bad5162000-06-23Fredrik Hübinette (Hubbe)  struct program *np=(q?q:Pike_compiler)->new_program;
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct reference funp; struct program *p; int i,d;
d429a71998-02-24Fredrik Hübinette (Hubbe)  p=np->inherits[e].prog;
5267b71995-08-09Fredrik Hübinette (Hubbe)  i=find_shared_string_identifier(name,p);
c0e4461998-06-23Fredrik Hübinette (Hubbe)  if(i==-1) {
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  i=really_low_find_shared_string_identifier(name,p, flags);
c0e4461998-06-23Fredrik Hübinette (Hubbe)  if(i==-1) return -1; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  if(p->identifier_references[i].id_flags & ID_HIDDEN)
5267b71995-08-09Fredrik Hübinette (Hubbe)  return -1;
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  if(p->identifier_references[i].id_flags & ID_PRIVATE) if(!(flags & SEE_PRIVATE)) return -1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  funp=p->identifier_references[i];
0d202a1995-10-20Fredrik Hübinette (Hubbe)  funp.inherit_offset+=e;
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  funp.id_flags|=ID_HIDDEN;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
d429a71998-02-24Fredrik Hübinette (Hubbe)  for(d=0;d<(int)np->num_identifier_references;d++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
cd86322000-07-06Fredrik Hübinette (Hubbe)  struct reference *refp; refp=np->identifier_references+d;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
cd86322000-07-06Fredrik Hübinette (Hubbe)  if(!MEMCMP((char *)refp,(char *)&funp,sizeof funp)) return d;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
d429a71998-02-24Fredrik Hübinette (Hubbe)  if(q) low_add_to_identifier_references(q,funp); else add_to_identifier_references(funp); return np->num_identifier_references -1;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
ba8c392000-06-26Henrik Grubbström (Grubba) int find_inherit(struct program *p, struct pike_string *name)
9a3e732000-06-26Henrik Grubbström (Grubba) { int e;
ba8c392000-06-26Henrik Grubbström (Grubba) #if 0 fprintf(stderr, "find_inherit(0x%08lx, \"%s\")...\n", (unsigned long)p, name->str); #endif /* 0 */ for(e = p->num_inherits-1; e>0; e--) { #if 0 fprintf(stderr, " %04d: %04d %s\n", e, p->inherits[e].inherit_level, p->inherits[e].name?p->inherits[e].name->str:"NULL"); #endif /* 0 */ if (p->inherits[e].inherit_level > 1) continue;
9a3e732000-06-26Henrik Grubbström (Grubba)  if (name == p->inherits[e].name) return e; } return 0; }
a005eb1999-03-04Fredrik Hübinette (Hubbe) node *reference_inherited_identifier(struct pike_string *super_name,
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_string *function_name)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
a005eb1999-03-04Fredrik Hübinette (Hubbe)  int n,e,id;
bad5162000-06-23Fredrik Hübinette (Hubbe)  struct program_state *state=Pike_compiler->previous;
a005eb1999-03-04Fredrik Hübinette (Hubbe)  struct program *p;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(function_name!=debug_findstring(function_name)) fatal("reference_inherited_function on nonshared string.\n"); #endif
a005eb1999-03-04Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  p=Pike_compiler->new_program;
a005eb1999-03-04Fredrik Hübinette (Hubbe) 
d429a71998-02-24Fredrik Hübinette (Hubbe)  for(e=p->num_inherits-1;e>0;e--)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
d429a71998-02-24Fredrik Hübinette (Hubbe)  if(p->inherits[e].inherit_level!=1) continue; if(!p->inherits[e].name) continue;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(super_name)
d429a71998-02-24Fredrik Hübinette (Hubbe)  if(super_name != p->inherits[e].name)
5267b71995-08-09Fredrik Hübinette (Hubbe)  continue;
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  id=low_reference_inherited_identifier(0, e, function_name, SEE_STATIC);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
a005eb1999-03-04Fredrik Hübinette (Hubbe)  if(id!=-1) return mkidentifiernode(id);
d429a71998-02-24Fredrik Hübinette (Hubbe) 
a005eb1999-03-04Fredrik Hübinette (Hubbe)  if(ISCONSTSTR(function_name,"`->") || ISCONSTSTR(function_name,"`[]")) {
f807f01999-11-11Henrik Grubbström (Grubba)  return mknode(F_MAGIC_INDEX,mknewintnode(e),mknewintnode(0));
a005eb1999-03-04Fredrik Hübinette (Hubbe)  }
d429a71998-02-24Fredrik Hübinette (Hubbe) 
a005eb1999-03-04Fredrik Hübinette (Hubbe)  if(ISCONSTSTR(function_name,"`->=") || ISCONSTSTR(function_name,"`[]=")) {
f807f01999-11-11Henrik Grubbström (Grubba)  return mknode(F_MAGIC_SET_INDEX,mknewintnode(e),mknewintnode(0));
a005eb1999-03-04Fredrik Hübinette (Hubbe)  }
cbe1132001-12-16Martin Stjernholm  if(ISCONSTSTR(function_name,"_indices")) { return mknode(F_MAGIC_INDICES,mknewintnode(e),mknewintnode(0)); } if(ISCONSTSTR(function_name,"_values")) { return mknode(F_MAGIC_VALUES,mknewintnode(e),mknewintnode(0)); }
a005eb1999-03-04Fredrik Hübinette (Hubbe)  } for(n=0;n<compilation_depth;n++,state=state->previous)
d429a71998-02-24Fredrik Hübinette (Hubbe)  {
a005eb1999-03-04Fredrik Hübinette (Hubbe)  struct program *p=state->new_program;
27ae842000-02-07Per Hedbor 
a005eb1999-03-04Fredrik Hübinette (Hubbe)  for(e=p->num_inherits-1;e>0;e--) { if(p->inherits[e].inherit_level!=1) continue; if(!p->inherits[e].name) continue;
27ae842000-02-07Per Hedbor 
a005eb1999-03-04Fredrik Hübinette (Hubbe)  if(super_name) if(super_name != p->inherits[e].name) continue;
27ae842000-02-07Per Hedbor 
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  id=low_reference_inherited_identifier(state,e,function_name,SEE_STATIC);
a005eb1999-03-04Fredrik Hübinette (Hubbe)  if(id!=-1)
ff88db2000-07-12Henrik Grubbström (Grubba)  return mkexternalnode(p, id);
a005eb1999-03-04Fredrik Hübinette (Hubbe)  if(ISCONSTSTR(function_name,"`->") || ISCONSTSTR(function_name,"`[]")) {
55aa4a2000-01-27Fredrik Hübinette (Hubbe)  return mknode(F_MAGIC_INDEX, mknewintnode(e),mknewintnode(n+1));
a005eb1999-03-04Fredrik Hübinette (Hubbe)  }
27ae842000-02-07Per Hedbor 
a005eb1999-03-04Fredrik Hübinette (Hubbe)  if(ISCONSTSTR(function_name,"`->=") || ISCONSTSTR(function_name,"`[]=")) {
55aa4a2000-01-27Fredrik Hübinette (Hubbe)  return mknode(F_MAGIC_SET_INDEX, mknewintnode(e),mknewintnode(n+1));
a005eb1999-03-04Fredrik Hübinette (Hubbe)  }
cbe1132001-12-16Martin Stjernholm  if(ISCONSTSTR(function_name,"_indices")) { return mknode(F_MAGIC_INDICES, mknewintnode(e),mknewintnode(n+1)); } if(ISCONSTSTR(function_name,"_values")) { return mknode(F_MAGIC_VALUES, mknewintnode(e),mknewintnode(n+1)); }
a005eb1999-03-04Fredrik Hübinette (Hubbe)  }
d429a71998-02-24Fredrik Hübinette (Hubbe)  } return 0; }
06983f1996-09-22Fredrik Hübinette (Hubbe) void rename_last_inherit(struct pike_string *n)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->new_program->inherits[Pike_compiler->new_program->num_inherits].name) free_string(Pike_compiler->new_program->inherits[Pike_compiler->new_program->num_inherits].name); copy_shared_string(Pike_compiler->new_program->inherits[Pike_compiler->new_program->num_inherits].name,
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  n);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
342fef2000-08-23Fredrik Hübinette (Hubbe) static int locate_parent_state(struct program_state **state, struct inherit **i, int *parent_identifier, int depth) { int result=1; if(depth<=0) return depth; while(depth-->0) { if( (*i)->parent_offset != -17) { int tmp=(*i)->parent_identifier; if( (*i)->parent_offset > 0) { int po=(*i)->parent_offset; *parent_identifier = (*state)->parent_identifier; *state = (*state)->previous; result++; fprintf(stderr,"INHERIT: state=state->previous (po=%d)\n",po); if(po>1) { *i=INHERIT_FROM_INT( (*state)->new_program, *parent_identifier); result+=locate_parent_state(state,i,parent_identifier, po-1); } } if(tmp != -1) { if( *parent_identifier == -4711) { *parent_identifier = tmp; }else{ *parent_identifier = tmp + INHERIT_FROM_INT( (*state)->new_program, *parent_identifier)->identifier_level; } } }else{ fprintf(stderr,"INHERIT: Bailout!\n"); return result+depth+1; } *i = INHERIT_FROM_INT( (*state)->new_program, *parent_identifier); } return result; } static int find_depth(struct program_state *state, struct inherit *i, int parent_identifier, int depth) { #if 0 int e; struct inherit *oi; for(e=0;e<=parent_offset;e++) state=state->previous; oi=INHERIT_FROM_INT(state->new_program, parent_identifier); parent_offset+=i->parent_offset; #endif return locate_parent_state(&state, &i, &parent_identifier, depth); }
5267b71995-08-09Fredrik Hübinette (Hubbe) /* * make this program inherit another program */
5582a82000-08-28Fredrik Hübinette (Hubbe) void low_inherit(struct program *p, struct object *parent, int parent_identifier, int parent_offset, INT32 flags, struct pike_string *name)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
d3b06f2000-08-10Henrik Grubbström (Grubba)  int e; ptrdiff_t inherit_offset, storage_offset;
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct inherit inherit;
02a79a2000-09-04Fredrik Hübinette (Hubbe) #if 0
0f2b442001-12-14Martin Stjernholm  fprintf(stderr,"%p low_inherit(pid=%d, parent=%p, parid=%d, " "paroff=%d, flags=0x%x, name=%s);\n", Pike_compiler->new_program, p ? p->id : 0,
02a79a2000-09-04Fredrik Hübinette (Hubbe)  parent, parent_identifier, parent_offset, flags, name? name->str : ""); #endif
a359742001-12-16Martin Stjernholm  CDFPRINTF((stderr, "th(%ld) %p inherit %p\n", (long) th_self(), Pike_compiler->new_program, p));
02a79a2000-09-04Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(!p) { yyerror("Illegal program pointer."); return; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
0f2b442001-12-14Martin Stjernholm #ifdef PIKE_DEBUG if (p == placeholder_program) fatal("Trying to inherit placeholder_program.\n"); #endif
22d7992001-06-23Fredrik Hübinette (Hubbe)  if(p->flags & PROGRAM_NEEDS_PARENT)
1994251999-09-06Fredrik Hübinette (Hubbe)  {
342fef2000-08-23Fredrik Hübinette (Hubbe)  struct program_state *state=Pike_compiler;
1994251999-09-06Fredrik Hübinette (Hubbe)  if(!parent && !parent_offset) { yyerror("Parent pointer lost, cannot inherit!");
b1dd8f1999-09-06Henrik Grubbström (Grubba)  /* We inherit it anyway, to avoid causing more errors */
1994251999-09-06Fredrik Hübinette (Hubbe)  }
342fef2000-08-23Fredrik Hübinette (Hubbe)  #if 0
0f2b442001-12-14Martin Stjernholm  /* FIXME: we don't really need to set this flag on ALL
342fef2000-08-23Fredrik Hübinette (Hubbe)  * previous compilations, but I'm too lazy to figure out * exactly how deep down we need to go... */ for(e=0;e<compilation_depth;e++,state=state->previous) state->new_program->flags |= PROGRAM_USES_PARENT; #endif
1994251999-09-06Fredrik Hübinette (Hubbe)  }
342fef2000-08-23Fredrik Hübinette (Hubbe)  /* parent offset was increased by 42 for above test.. */
3139891999-09-06Henrik Grubbström (Grubba)  if(parent_offset)
342fef2000-08-23Fredrik Hübinette (Hubbe)  parent_offset-=42;
1994251999-09-06Fredrik Hübinette (Hubbe) 
bcf9461998-01-27Fredrik Hübinette (Hubbe)  if(!(p->flags & (PROGRAM_FINISHED | PROGRAM_PASS_1_DONE))) { yyerror("Cannot inherit program which is not fully compiled yet."); return; }
bad5162000-06-23Fredrik Hübinette (Hubbe)  inherit_offset = Pike_compiler->new_program->num_inherits;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
90e9781999-01-31Fredrik Hübinette (Hubbe)  /* alignment magic */
9386f71999-09-15Fredrik Hübinette (Hubbe)  storage_offset=p->inherits[0].storage_offset % p->alignment_needed;
1f5bfe1999-09-28Fredrik Hübinette (Hubbe)  storage_offset=low_add_storage(STORAGE_NEEDED(p),
90e9781999-01-31Fredrik Hübinette (Hubbe)  p->alignment_needed,
b1c8031999-09-15Fredrik Hübinette (Hubbe)  storage_offset);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
1f5bfe1999-09-28Fredrik Hübinette (Hubbe)  /* Without this, the inherit becomes skewed */
27ae842000-02-07Per Hedbor  storage_offset-=p->inherits[0].storage_offset;
1f5bfe1999-09-28Fredrik Hübinette (Hubbe) 
5c8e891995-10-29Fredrik Hübinette (Hubbe)  for(e=0; e<(int)p->num_inherits; e++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { inherit=p->inherits[e];
8c83371998-04-16Fredrik Hübinette (Hubbe)  add_ref(inherit.prog);
bad5162000-06-23Fredrik Hübinette (Hubbe)  inherit.identifier_level += Pike_compiler->new_program->num_identifier_references;
5267b71995-08-09Fredrik Hübinette (Hubbe)  inherit.storage_offset += storage_offset; inherit.inherit_level ++;
342fef2000-08-23Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(!e) {
61e9a01998-01-25Fredrik Hübinette (Hubbe)  if(parent)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  {
9e52381998-03-01Fredrik Hübinette (Hubbe)  if(parent->next == parent) {
f3c7152001-04-14Fredrik Hübinette (Hubbe) #if 0
9e52381998-03-01Fredrik Hübinette (Hubbe)  struct object *o;
342fef2000-08-23Fredrik Hübinette (Hubbe)  inherit.parent_offset=0; for(o=Pike_compiler->fake_object;o!=parent;o=o->parent)
9e52381998-03-01Fredrik Hübinette (Hubbe)  {
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(!o) fatal("low_inherit with odd Pike_compiler->fake_object as parent!\n");
9e52381998-03-01Fredrik Hübinette (Hubbe) #endif inherit.parent_offset++; }
f3c7152001-04-14Fredrik Hübinette (Hubbe) #else struct program_state *state=Pike_compiler; inherit.parent_offset=0; for(;state->fake_object!=parent;state=state->previous) { #ifdef PIKE_DEBUG if(!state->fake_object) fatal("low_inherit with odd Pike_compiler->fake_object as parent!\n"); #endif inherit.parent_offset++; } #endif
9e52381998-03-01Fredrik Hübinette (Hubbe)  }else{ inherit.parent=parent; inherit.parent_identifier=parent_identifier;
342fef2000-08-23Fredrik Hübinette (Hubbe)  inherit.parent_offset=-17;
9e52381998-03-01Fredrik Hübinette (Hubbe)  }
61e9a01998-01-25Fredrik Hübinette (Hubbe)  }else{
342fef2000-08-23Fredrik Hübinette (Hubbe)  inherit.parent_offset=parent_offset;
bcd5741999-03-17Fredrik Hübinette (Hubbe)  inherit.parent_identifier=parent_identifier;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
1994981998-04-07Fredrik Hübinette (Hubbe)  }else{
5f05c11999-12-27Fredrik Hübinette (Hubbe)  if(!inherit.parent)
1994981998-04-07Fredrik Hübinette (Hubbe)  {
5f05c11999-12-27Fredrik Hübinette (Hubbe)  if(parent && parent->next != parent && inherit.parent_offset)
1994981998-04-07Fredrik Hübinette (Hubbe)  {
342fef2000-08-23Fredrik Hübinette (Hubbe)  /* Fake object */
5f05c11999-12-27Fredrik Hübinette (Hubbe)  struct object *par=parent; int e,pid=parent_identifier;
342fef2000-08-23Fredrik Hübinette (Hubbe) 
5f05c11999-12-27Fredrik Hübinette (Hubbe)  for(e=1;e<inherit.parent_offset;e++)
1994981998-04-07Fredrik Hübinette (Hubbe)  {
5f05c11999-12-27Fredrik Hübinette (Hubbe)  struct inherit *in; if(!par->prog) { par=0;
342fef2000-08-23Fredrik Hübinette (Hubbe)  pid=-1;
5f05c11999-12-27Fredrik Hübinette (Hubbe)  break; }
27ae842000-02-07Per Hedbor 
5f05c11999-12-27Fredrik Hübinette (Hubbe)  in=INHERIT_FROM_INT(par->prog, pid);
342fef2000-08-23Fredrik Hübinette (Hubbe)  switch(in->parent_offset)
5f05c11999-12-27Fredrik Hübinette (Hubbe)  {
342fef2000-08-23Fredrik Hübinette (Hubbe)  default: { struct external_variable_context tmp; struct inherit *in2=in; while(in2->identifier_level >= in->identifier_level) in2--; tmp.o=par; tmp.inherit=in2; tmp.parent_identifier=pid; find_external_context(&tmp, in->parent_offset);
5222e92000-08-24Henrik Grubbström (Grubba)  par = tmp.o; pid = tmp.parent_identifier;
342fef2000-08-23Fredrik Hübinette (Hubbe)  } break; case -17:
5222e92000-08-24Henrik Grubbström (Grubba)  pid = in->parent_identifier; par = in->parent;
342fef2000-08-23Fredrik Hübinette (Hubbe)  break; case -18:
f3c7152001-04-14Fredrik Hübinette (Hubbe)  if(par->prog->flags & PROGRAM_USES_PARENT) { pid = PARENT_INFO(par)->parent_identifier; par = PARENT_INFO(par)->parent; }else{ pid=-1; par=0; }
5f05c11999-12-27Fredrik Hübinette (Hubbe)  }
1994981998-04-07Fredrik Hübinette (Hubbe)  }
27ae842000-02-07Per Hedbor 
5f05c11999-12-27Fredrik Hübinette (Hubbe)  inherit.parent=par;
342fef2000-08-23Fredrik Hübinette (Hubbe)  inherit.parent_offset=-17;
1994981998-04-07Fredrik Hübinette (Hubbe)  } }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
8c83371998-04-16Fredrik Hübinette (Hubbe)  if(inherit.parent) add_ref(inherit.parent);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
d2c6081996-11-07Fredrik Hübinette (Hubbe)  if(name) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(e==0) {
3c0c281998-01-26Fredrik Hübinette (Hubbe)  copy_shared_string(inherit.name,name);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  } else if(inherit.name) { struct pike_string *s; s=begin_shared_string(inherit.name->len + name->len + 2); MEMCPY(s->str,name->str,name->len); MEMCPY(s->str+name->len,"::",2); MEMCPY(s->str+name->len+2,inherit.name->str,inherit.name->len); inherit.name=end_shared_string(s); } else { inherit.name=0; } }else{ inherit.name=0;
d2c6081996-11-07Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  add_to_inherits(inherit);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
5c8e891995-10-29Fredrik Hübinette (Hubbe)  for (e=0; e < (int)p->num_identifier_references; e++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { struct reference fun;
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *name;
5267b71995-08-09Fredrik Hübinette (Hubbe)  fun = p->identifier_references[e]; /* Make a copy */ name=ID_FROM_PTR(p,&fun)->name; fun.inherit_offset += inherit_offset;
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  if (fun.id_flags & ID_NOMASK)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
3b7d182001-09-26Fredrik Hübinette (Hubbe)  Pike_compiler->check_final++;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
9f1f302001-09-27Per Hedbor 
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  if(fun.id_flags & ID_PRIVATE) fun.id_flags|=ID_HIDDEN;
5580691996-06-21Fredrik Hübinette (Hubbe) 
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  if (fun.id_flags & ID_PUBLIC) fun.id_flags |= flags & ~ID_PRIVATE;
5267b71995-08-09Fredrik Hübinette (Hubbe)  else
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  fun.id_flags |= flags;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  fun.id_flags |= ID_INHERITED;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  add_to_identifier_references(fun);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void do_inherit(struct svalue *s,
61e9a01998-01-25Fredrik Hübinette (Hubbe)  INT32 flags, struct pike_string *name) { struct program *p=program_from_svalue(s);
5582a82000-08-28Fredrik Hübinette (Hubbe)  low_inherit(p, s->type == T_FUNCTION ? s->u.object : 0, s->type == T_FUNCTION ? s->subtype : -1, 0, flags, name);
61e9a01998-01-25Fredrik Hübinette (Hubbe) } void compiler_do_inherit(node *n, INT32 flags, struct pike_string *name) {
086acc1999-09-11Fredrik Hübinette (Hubbe)  struct program *p; struct identifier *i;
5582a82000-08-28Fredrik Hübinette (Hubbe)  INT32 numid=-1, offset=0;
27ae842000-02-07Per Hedbor 
2416d81998-01-27Fredrik Hübinette (Hubbe)  if(!n) { yyerror("Unable to inherit"); return; }
61e9a01998-01-25Fredrik Hübinette (Hubbe)  switch(n->token) {
086acc1999-09-11Fredrik Hübinette (Hubbe)  case F_IDENTIFIER:
bad5162000-06-23Fredrik Hübinette (Hubbe)  p=Pike_compiler->new_program;
086acc1999-09-11Fredrik Hübinette (Hubbe)  offset=0;
f807f01999-11-11Henrik Grubbström (Grubba)  numid=n->u.id.number;
086acc1999-09-11Fredrik Hübinette (Hubbe)  goto continue_inherit;
27ae842000-02-07Per Hedbor 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  case F_EXTERNAL: {
342fef2000-08-23Fredrik Hübinette (Hubbe)  struct program_state *state = Pike_compiler;
ff88db2000-07-12Henrik Grubbström (Grubba) 
5582a82000-08-28Fredrik Hübinette (Hubbe)  offset = 0;
ff88db2000-07-12Henrik Grubbström (Grubba)  while (state && (state->new_program->id != n->u.integer.a)) { state = state->previous; offset++; } if (!state) { yyerror("Failed to resolv external constant.\n"); return; } p = state->new_program; numid = n->u.integer.b;
61e9a01998-01-25Fredrik Hübinette (Hubbe)  }
086acc1999-09-11Fredrik Hübinette (Hubbe)  continue_inherit:
61e9a01998-01-25Fredrik Hübinette (Hubbe)  i=ID_FROM_INT(p, numid);
27ae842000-02-07Per Hedbor 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  if(IDENTIFIER_IS_CONSTANT(i->identifier_flags)) {
454d541999-09-18Fredrik Hübinette (Hubbe)  struct svalue *s=&PROG_FROM_INT(p, numid)-> constants[i->func.offset].sval;
61e9a01998-01-25Fredrik Hübinette (Hubbe)  if(s->type != T_PROGRAM) {
2416d81998-01-27Fredrik Hübinette (Hubbe)  do_inherit(s,flags,name);
61e9a01998-01-25Fredrik Hübinette (Hubbe)  return; }else{ p=s->u.program; } }else{ yyerror("Inherit identifier is not a constant program"); return; }
5582a82000-08-28Fredrik Hübinette (Hubbe)  low_inherit(p, 0, numid, offset+42, flags, name);
61e9a01998-01-25Fredrik Hübinette (Hubbe)  break; default:
086acc1999-09-11Fredrik Hübinette (Hubbe)  resolv_class(n);
cd86322000-07-06Fredrik Hübinette (Hubbe)  do_inherit(Pike_sp-1, flags, name);
61e9a01998-01-25Fredrik Hübinette (Hubbe)  pop_stack(); } }
27ae842000-02-07Per Hedbor 
9036e82001-08-16Martin Stjernholm int call_handle_inherit(struct pike_string *s)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
9036e82001-08-16Martin Stjernholm  int args;
5267b71995-08-09Fredrik Hübinette (Hubbe)  reference_shared_string(s); push_string(s);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  ref_push_string(lex.current_file);
9036e82001-08-16Martin Stjernholm  if (error_handler && error_handler->prog) { ref_push_object(error_handler); args = 3; } else args = 2;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9036e82001-08-16Martin Stjernholm  if (safe_apply_handler("handle_inherit", error_handler, compat_handler, args, BIT_PROGRAM|BIT_FUNCTION|BIT_ZERO)) if (Pike_sp[-1].type != T_INT) return 1; else { pop_stack(); if (!s->size_shift) my_yyerror("Couldn't find program: %s",s->str); else yyerror("Couldn't find program"); } else { struct svalue thrown = throw_value; throw_value.type = T_INT; my_yyerror("Error finding program"); push_svalue(&thrown); low_safe_apply_handler("compile_exception", error_handler, compat_handler, 1);
9f516a2001-12-16Martin Stjernholm  if (SAFE_IS_ZERO(sp-1)) yy_describe_exception(&thrown);
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_stack();
9036e82001-08-16Martin Stjernholm  free_svalue(&thrown);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
9036e82001-08-16Martin Stjernholm  return 0; } void simple_do_inherit(struct pike_string *s, INT32 flags, struct pike_string *name) { if (!call_handle_inherit(s)) return;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(name) { free_string(s); s=name; }
cd86322000-07-06Fredrik Hübinette (Hubbe)  do_inherit(Pike_sp-1, flags, s);
d2c6081996-11-07Fredrik Hübinette (Hubbe)  free_string(s);
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_stack(); } /* * Return the index of the identifier found, otherwise -1. */
06983f1996-09-22Fredrik Hübinette (Hubbe) int isidentifier(struct pike_string *s)
5267b71995-08-09Fredrik Hübinette (Hubbe) { INT32 e;
bad5162000-06-23Fredrik Hübinette (Hubbe)  for(e=Pike_compiler->new_program->num_identifier_references-1;e>=0;e--)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->new_program->identifier_references[e].id_flags & ID_HIDDEN) continue;
27ae842000-02-07Per Hedbor 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(ID_FROM_INT(Pike_compiler->new_program, e)->name == s)
5267b71995-08-09Fredrik Hübinette (Hubbe)  return e; } return -1; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) /* argument must be a shared string */
d4828c1997-07-17Fredrik Hübinette (Hubbe) int low_define_variable(struct pike_string *name,
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *type,
d4828c1997-07-17Fredrik Hübinette (Hubbe)  INT32 flags,
de1d7d2000-07-10Henrik Grubbström (Grubba)  size_t offset,
d4828c1997-07-17Fredrik Hübinette (Hubbe)  INT32 run_time_type) { int n;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
d4828c1997-07-17Fredrik Hübinette (Hubbe)  struct identifier dummy; struct reference ref;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->new_program->flags & (PROGRAM_FIXED | PROGRAM_OPTIMIZED))
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  fatal("Attempting to add variable to fixed program\n");
22edc21998-01-29Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->compiler_pass==2)
a4a1722000-12-05Per Hedbor  fatal("Internal error: Not allowed to add more identifiers during second compiler pass.\n"
05bfe21998-07-20Henrik Grubbström (Grubba)  "Added identifier: \"%s\"\n", name->str);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #endif
d4828c1997-07-17Fredrik Hübinette (Hubbe)  copy_shared_string(dummy.name, name);
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(dummy.type, type);
eff2b02001-07-03Henrik Grubbström (Grubba)  if (flags & ID_ALIAS) { dummy.identifier_flags = IDENTIFIER_ALIAS; } else { dummy.identifier_flags = 0; }
d4828c1997-07-17Fredrik Hübinette (Hubbe)  dummy.run_time_type=run_time_type;
bad5162000-06-23Fredrik Hübinette (Hubbe)  dummy.func.offset=offset - Pike_compiler->new_program->inherits[0].storage_offset;
be478c1997-08-30Henrik Grubbström (Grubba) #ifdef PROFILING
6189631998-11-12Fredrik Hübinette (Hubbe)  dummy.self_time=0;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  dummy.num_calls=0;
a2a8801998-03-18Per Hedbor  dummy.total_time=0;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #endif
be478c1997-08-30Henrik Grubbström (Grubba) 
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  ref.id_flags=flags;
bad5162000-06-23Fredrik Hübinette (Hubbe)  ref.identifier_offset=Pike_compiler->new_program->num_identifiers;
d4828c1997-07-17Fredrik Hübinette (Hubbe)  ref.inherit_offset=0;
05590d1998-04-23Fredrik Hübinette (Hubbe)  add_to_variable_index(ref.identifier_offset);
27ae842000-02-07Per Hedbor 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  add_to_identifiers(dummy);
27ae842000-02-07Per Hedbor 
bad5162000-06-23Fredrik Hübinette (Hubbe)  n=Pike_compiler->new_program->num_identifier_references;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  add_to_identifier_references(ref);
05590d1998-04-23Fredrik Hübinette (Hubbe) 
d4828c1997-07-17Fredrik Hübinette (Hubbe)  return n; }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT int map_variable(char *name,
d4828c1997-07-17Fredrik Hübinette (Hubbe)  char *type, INT32 flags,
de1d7d2000-07-10Henrik Grubbström (Grubba)  size_t offset,
d4828c1997-07-17Fredrik Hübinette (Hubbe)  INT32 run_time_type) { int ret;
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_string *n; struct pike_type *t;
a786431999-11-18Martin Stjernholm  #ifdef PROGRAM_BUILD_DEBUG fprintf (stderr, "%.*sdefining variable (pass=%d): %s %s\n",
bad5162000-06-23Fredrik Hübinette (Hubbe)  compilation_depth, " ", Pike_compiler->compiler_pass, type, name);
a786431999-11-18Martin Stjernholm #endif
d4828c1997-07-17Fredrik Hübinette (Hubbe)  n=make_shared_string(name); t=parse_type(type); ret=low_define_variable(n,t,flags,offset,run_time_type); free_string(n);
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(t);
d4828c1997-07-17Fredrik Hübinette (Hubbe)  return ret; }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT int quick_map_variable(char *name,
e2d9e62000-06-10Martin Stjernholm  int name_length,
de1d7d2000-07-10Henrik Grubbström (Grubba)  size_t offset,
e2d9e62000-06-10Martin Stjernholm  char *type, int type_length, INT32 run_time_type, INT32 flags) { int ret;
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_string *n; struct pike_type *t;
e2d9e62000-06-10Martin Stjernholm  #ifdef PROGRAM_BUILD_DEBUG fprintf (stderr, "%.*sdefining variable (pass=%d): %s %s\n",
bad5162000-06-23Fredrik Hübinette (Hubbe)  compilation_depth, " ", Pike_compiler->compiler_pass, type, name);
e2d9e62000-06-10Martin Stjernholm #endif
8a2a522001-03-03Henrik Grubbström (Grubba)  n = make_shared_binary_string(name, name_length); #ifdef USE_PIKE_TYPE t = make_pike_type(type); #else /* !USE_PIKE_TYPE */ t = make_shared_binary_string(type, type_length); #endif /* USE_PIKE_TYPE */
e2d9e62000-06-10Martin Stjernholm  ret=low_define_variable(n,t,flags,offset,run_time_type); free_string(n);
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(t);
e2d9e62000-06-10Martin Stjernholm  return ret; }
5267b71995-08-09Fredrik Hübinette (Hubbe) /* argument must be a shared string */
06983f1996-09-22Fredrik Hübinette (Hubbe) int define_variable(struct pike_string *name,
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *type,
5267b71995-08-09Fredrik Hübinette (Hubbe)  INT32 flags) {
61e9a01998-01-25Fredrik Hübinette (Hubbe)  int n, run_time_type;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(name!=debug_findstring(name)) fatal("define_variable on nonshared string.\n"); #endif
a786431999-11-18Martin Stjernholm #ifdef PROGRAM_BUILD_DEBUG { struct pike_string *d = describe_type (type); fprintf (stderr, "%.*sdefining variable (pass=%d): %s ",
bad5162000-06-23Fredrik Hübinette (Hubbe)  compilation_depth, " ", Pike_compiler->compiler_pass, d->str);
a786431999-11-18Martin Stjernholm  free_string (d); push_string (name);
cd86322000-07-06Fredrik Hübinette (Hubbe)  print_svalue (stderr, --Pike_sp);
a786431999-11-18Martin Stjernholm  putc ('\n', stderr); } #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(type == void_type_string) yyerror("Variables can't be of type void");
27ae842000-02-07Per Hedbor 
5267b71995-08-09Fredrik Hübinette (Hubbe)  n = isidentifier(name);
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->new_program->flags & PROGRAM_PASS_1_DONE)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  { if(n==-1) yyerror("Pass2: Variable disappeared!");
a786431999-11-18Martin Stjernholm  else {
eff2b02001-07-03Henrik Grubbström (Grubba)  struct identifier *id=ID_FROM_INT(Pike_compiler->new_program,n);
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(id->type);
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(id->type, type);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  return n;
a786431999-11-18Martin Stjernholm  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->new_program->flags & (PROGRAM_FIXED | PROGRAM_OPTIMIZED))
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  fatal("Attempting to add variable to fixed program\n"); #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(n != -1) {
1994251999-09-06Fredrik Hübinette (Hubbe)  /* not inherited */
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->new_program->identifier_references[n].inherit_offset == 0)
1994251999-09-06Fredrik Hübinette (Hubbe)  {
e774391999-12-31Henrik Grubbström (Grubba)  if (!((IDENTIFIERP(n)->id_flags | flags) & ID_EXTERN)) { my_yyerror("Identifier '%s' defined twice.",name->str); return n; } if (flags & ID_EXTERN) { /* FIXME: Check type */ return n; }
1994251999-09-06Fredrik Hübinette (Hubbe)  }
e774391999-12-31Henrik Grubbström (Grubba)  if (!(IDENTIFIERP(n)->id_flags & ID_EXTERN)) { if (IDENTIFIERP(n)->id_flags & ID_NOMASK) my_yyerror("Illegal to redefine 'nomask/final' " "variable/functions \"%s\"", name->str);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(!(IDENTIFIERP(n)->id_flags & ID_INLINE) || Pike_compiler->compiler_pass!=1)
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  {
eff2b02001-07-03Henrik Grubbström (Grubba)  int n2; if(ID_FROM_INT(Pike_compiler->new_program, n)->type != type && !pike_types_le(type, ID_FROM_INT(Pike_compiler->new_program, n)->type)) { if (!match_types(ID_FROM_INT(Pike_compiler->new_program, n)->type, type)) { my_yyerror("Illegal to redefine inherited variable '%s' " "with different type.", name->str); return n; } else { yywarning("Redefining inherited variable '%s' " "with different type.", name->str); } }
9eaa6e2000-02-12Fredrik Hübinette (Hubbe) 
8aae6d1999-08-19Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(!IDENTIFIER_IS_VARIABLE(ID_FROM_INT(Pike_compiler->new_program, n)->
e774391999-12-31Henrik Grubbström (Grubba)  identifier_flags)) { my_yyerror("Illegal to redefine inherited variable " "with different type.");
eff2b02001-07-03Henrik Grubbström (Grubba)  return n;
e774391999-12-31Henrik Grubbström (Grubba)  }
eff2b02001-07-03Henrik Grubbström (Grubba)  if ((ID_FROM_INT(Pike_compiler->new_program, n)->run_time_type != PIKE_T_MIXED) && (ID_FROM_INT(Pike_compiler->new_program, n)->run_time_type != compile_type_to_runtime_type(type))) { my_yyerror("Illegal to redefine inherited variable " "with different type."); return n; } /* Copy the variable reference, so that we can change the * compile-time type. */ n2 = low_define_variable(name, type, (flags | ID_ALIAS) & ~ID_EXTERN, ID_FROM_INT(Pike_compiler->new_program, n)-> func.offset + INHERIT_FROM_INT(Pike_compiler->new_program, n)->storage_offset, ID_FROM_INT(Pike_compiler->new_program, n)-> run_time_type);
901cf82001-07-03Henrik Grubbström (Grubba)  /* Hide the old variable. */ Pike_compiler->new_program->identifier_references[n].id_flags |= ID_STATIC|ID_PRIVATE;
eff2b02001-07-03Henrik Grubbström (Grubba)  return n2;
e774391999-12-31Henrik Grubbström (Grubba)  }
61e9a01998-01-25Fredrik Hübinette (Hubbe)  } }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  run_time_type=compile_type_to_runtime_type(type);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  switch(run_time_type) {
2ba9191999-10-23Fredrik Hübinette (Hubbe) #ifdef AUTO_BIGNUM
0957531999-10-25Fredrik Hübinette (Hubbe) #if 0
659ccc1999-10-25Fredrik Hübinette (Hubbe)  case T_OBJECT: /* This is to allow room for integers in variables declared as * 'object', however, this could be changed in the future to only * make room for integers if the variable was declared as * 'object(Gmp.mpz)' /Hubbe */
0957531999-10-25Fredrik Hübinette (Hubbe) #endif
2ba9191999-10-23Fredrik Hübinette (Hubbe)  case T_INT: #endif
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case T_FUNCTION: case T_PROGRAM: run_time_type = T_MIXED;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
27ae842000-02-07Per Hedbor 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  n=low_define_variable(name,type,flags,
1994981998-04-07Fredrik Hübinette (Hubbe)  low_add_storage(sizeof_variable(run_time_type),
90e9781999-01-31Fredrik Hübinette (Hubbe)  alignof_variable(run_time_type),0),
61e9a01998-01-25Fredrik Hübinette (Hubbe)  run_time_type);
27ae842000-02-07Per Hedbor 
5267b71995-08-09Fredrik Hübinette (Hubbe)  return n; }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT int simple_add_variable(char *name,
5740881998-01-01Fredrik Hübinette (Hubbe)  char *type, INT32 flags) { INT32 ret;
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_string *name_s; struct pike_type *type_s;
babd872001-02-23Henrik Grubbström (Grubba)  name_s = make_shared_string(name); type_s = parse_type(type);
27ae842000-02-07Per Hedbor 
5740881998-01-01Fredrik Hübinette (Hubbe)  ret=define_variable(name_s, type_s, flags); free_string(name_s);
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(type_s);
5740881998-01-01Fredrik Hübinette (Hubbe)  return ret; }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT int add_constant(struct pike_string *name,
d2c6081996-11-07Fredrik Hübinette (Hubbe)  struct svalue *c, INT32 flags) { int n;
2d12341997-03-10Fredrik Hübinette (Hubbe)  struct identifier dummy; struct reference ref;
d2c6081996-11-07Fredrik Hübinette (Hubbe) 
a786431999-11-18Martin Stjernholm #ifdef PROGRAM_BUILD_DEBUG { if (c) {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *t = get_type_of_svalue(c);
a786431999-11-18Martin Stjernholm  struct pike_string *d = describe_type (t); fprintf (stderr, "%.*sdefining constant (pass=%d): %s ",
d68a072001-02-20Henrik Grubbström (Grubba)  compilation_depth, " ", Pike_compiler->compiler_pass, d->str); free_type(t);
a786431999-11-18Martin Stjernholm  free_string (d); } else fprintf (stderr, "%.*sdeclaring constant (pass=%d): ",
d68a072001-02-20Henrik Grubbström (Grubba)  compilation_depth, " ", Pike_compiler->compiler_pass);
a786431999-11-18Martin Stjernholm  push_string (name);
cd86322000-07-06Fredrik Hübinette (Hubbe)  print_svalue (stderr, --Pike_sp);
a786431999-11-18Martin Stjernholm  putc ('\n', stderr); } #endif
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
d2c6081996-11-07Fredrik Hübinette (Hubbe)  if(name!=debug_findstring(name))
e43ca21996-11-15Fredrik Hübinette (Hubbe)  fatal("define_constant on nonshared string.\n");
d2c6081996-11-07Fredrik Hübinette (Hubbe) #endif
84387d2001-09-24Fredrik Hübinette (Hubbe)  do { if(c && c->type == T_FUNCTION && c->subtype != FUNCTION_BUILTIN && c->u.object->prog) { struct identifier *id=ID_FROM_INT(c->u.object->prog, c->subtype);
3b7d182001-09-26Fredrik Hübinette (Hubbe)  if(c->u.object->prog == Pike_compiler->new_program && !c->u.object->prog->identifier_references[c->subtype].inherit_offset)
84387d2001-09-24Fredrik Hübinette (Hubbe)  { if(id->identifier_flags & IDENTIFIER_FUNCTION) { return define_function(name, id->type, flags, id->identifier_flags | IDENTIFIER_ALIAS, & id->func, id->opt_flags); }
8c70ba2001-09-28Fredrik Hübinette (Hubbe)  else if((id->identifier_flags & IDENTIFIER_CONSTANT) &&
84387d2001-09-24Fredrik Hübinette (Hubbe)  id->func.offset != -1) { c=& Pike_compiler->new_program->constants[id->func.offset].sval; } } else {
8c70ba2001-09-28Fredrik Hübinette (Hubbe)  if((id->identifier_flags & IDENTIFIER_CONSTANT) && id->func.offset != -1 && INHERIT_FROM_INT(c->u.object->prog, c->subtype)->prog-> constants[id->func.offset].sval.type == T_PROGRAM)
84387d2001-09-24Fredrik Hübinette (Hubbe)  { /* In this one case we allow fake objects to enter the * mainstream... */ break; } } } if(c && !svalues_are_constant(c,1,BIT_MIXED,0))
a359742001-12-16Martin Stjernholm  yyerror("Constant values may not have references this_object()");
84387d2001-09-24Fredrik Hübinette (Hubbe)  }while(0);
d2c6081996-11-07Fredrik Hübinette (Hubbe) 
84387d2001-09-24Fredrik Hübinette (Hubbe)  n = isidentifier(name);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->new_program->flags & PROGRAM_PASS_1_DONE)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  { if(n==-1) { yyerror("Pass2: Constant disappeared!"); }else{ struct identifier *id;
bad5162000-06-23Fredrik Hübinette (Hubbe)  id=ID_FROM_INT(Pike_compiler->new_program,n);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(id->func.offset>=0) {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *s;
bad5162000-06-23Fredrik Hübinette (Hubbe)  struct svalue *c=&PROG_FROM_INT(Pike_compiler->new_program,n)->
454d541999-09-18Fredrik Hübinette (Hubbe)  constants[id->func.offset].sval;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  s=get_type_of_svalue(c);
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(id->type);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  id->type=s; }
a786431999-11-18Martin Stjernholm  else { #ifdef PIKE_DEBUG if (!c) fatal("Can't declare constant during second compiler pass\n");
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #endif
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(id->type);
a786431999-11-18Martin Stjernholm  id->type = get_type_of_svalue(c); id->run_time_type = c->type; id->func.offset = store_constant(c, 0, 0); }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  return n; } }
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->new_program->flags & (PROGRAM_FIXED | PROGRAM_OPTIMIZED))
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  fatal("Attempting to add constant to fixed program\n");
22edc21998-01-29Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->compiler_pass==2)
a4a1722000-12-05Per Hedbor  fatal("Internal error: Not allowed to add more identifiers during second compiler pass.\n");
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #endif
2d12341997-03-10Fredrik Hübinette (Hubbe)  copy_shared_string(dummy.name, name);
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  dummy.identifier_flags = IDENTIFIER_CONSTANT;
a786431999-11-18Martin Stjernholm  if (c) { dummy.type = get_type_of_svalue(c); dummy.run_time_type=c->type; dummy.func.offset=store_constant(c, 0, 0);
f3c7152001-04-14Fredrik Hübinette (Hubbe)  dummy.opt_flags=OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND; if(c->type == PIKE_T_PROGRAM && (c->u.program->flags & PROGRAM_CONSTANT)) dummy.opt_flags=0;
a786431999-11-18Martin Stjernholm  } else {
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(dummy.type, mixed_type_string);
a786431999-11-18Martin Stjernholm  dummy.run_time_type=T_MIXED; dummy.func.offset=-1;
f3c7152001-04-14Fredrik Hübinette (Hubbe)  dummy.opt_flags=0;
a786431999-11-18Martin Stjernholm  }
2d12341997-03-10Fredrik Hübinette (Hubbe) 
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  ref.id_flags=flags;
bad5162000-06-23Fredrik Hübinette (Hubbe)  ref.identifier_offset=Pike_compiler->new_program->num_identifiers;
2d12341997-03-10Fredrik Hübinette (Hubbe)  ref.inherit_offset=0;
a2a8801998-03-18Per Hedbor #ifdef PROFILING
6189631998-11-12Fredrik Hübinette (Hubbe)  dummy.self_time=0;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  dummy.num_calls=0;
a2a8801998-03-18Per Hedbor  dummy.total_time=0;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #endif add_to_identifiers(dummy);
2d12341997-03-10Fredrik Hübinette (Hubbe) 
d2c6081996-11-07Fredrik Hübinette (Hubbe)  if(n != -1) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(IDENTIFIERP(n)->id_flags & ID_NOMASK)
d2c6081996-11-07Fredrik Hübinette (Hubbe)  my_yyerror("Illegal to redefine 'nomask' identifier \"%s\"", name->str);
86d54d2001-11-08Fredrik Hübinette (Hubbe)  if(!TEST_COMPAT(7,2) &&
e037dc2001-10-02Fredrik Hübinette (Hubbe)  IDENTIFIER_IS_VARIABLE(ID_FROM_INT(Pike_compiler->new_program,
2c98352001-09-25Fredrik Hübinette (Hubbe)  n)->identifier_flags)) {
e037dc2001-10-02Fredrik Hübinette (Hubbe)  my_yyerror("Illegal to redefine variable \"%s\" as constant.",
2c98352001-09-25Fredrik Hübinette (Hubbe)  name->str); }
1994251999-09-06Fredrik Hübinette (Hubbe)  /* not inherited */
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->new_program->identifier_references[n].inherit_offset == 0)
1994251999-09-06Fredrik Hübinette (Hubbe)  {
d2c6081996-11-07Fredrik Hübinette (Hubbe)  my_yyerror("Identifier '%s' defined twice.",name->str);
1994251999-09-06Fredrik Hübinette (Hubbe)  return n; }
d2c6081996-11-07Fredrik Hübinette (Hubbe) 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  if(!(IDENTIFIERP(n)->id_flags & ID_INLINE)) { /* override */
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->new_program->identifier_references[n]=ref;
61e9a01998-01-25Fredrik Hübinette (Hubbe)  return n; }
d2c6081996-11-07Fredrik Hübinette (Hubbe)  }
bad5162000-06-23Fredrik Hübinette (Hubbe)  n=Pike_compiler->new_program->num_identifier_references;
61e9a01998-01-25Fredrik Hübinette (Hubbe)  add_to_identifier_references(ref);
d2c6081996-11-07Fredrik Hübinette (Hubbe)  return n; }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT int simple_add_constant(char *name,
0683be1997-01-26Fredrik Hübinette (Hubbe)  struct svalue *c, INT32 flags) { INT32 ret; struct pike_string *id; id=make_shared_string(name); ret=add_constant(id, c, flags); free_string(id); return ret; }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT int add_integer_constant(char *name,
e43ca21996-11-15Fredrik Hübinette (Hubbe)  INT32 i, INT32 flags) { struct svalue tmp; tmp.u.integer=i; tmp.type=T_INT; tmp.subtype=NUMBER_NUMBER;
0683be1997-01-26Fredrik Hübinette (Hubbe)  return simple_add_constant(name, &tmp, flags);
e43ca21996-11-15Fredrik Hübinette (Hubbe) }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT int quick_add_integer_constant(char *name,
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  int name_length, INT32 i, INT32 flags) { struct svalue tmp; struct pike_string *id; INT32 ret; tmp.u.integer=i; tmp.type=T_INT; tmp.subtype=NUMBER_NUMBER; id=make_shared_binary_string(name,name_length); ret=add_constant(id, &tmp, flags); free_string(id); return ret; }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT int add_float_constant(char *name,
0683be1997-01-26Fredrik Hübinette (Hubbe)  double f, INT32 flags) { struct svalue tmp; tmp.type=T_FLOAT;
1f88bf2001-09-24Henrik Grubbström (Grubba)  tmp.u.float_number = DO_NOT_WARN((FLOAT_TYPE)f);
0683be1997-01-26Fredrik Hübinette (Hubbe)  tmp.subtype=0; return simple_add_constant(name, &tmp, flags); }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT int add_string_constant(char *name,
0683be1997-01-26Fredrik Hübinette (Hubbe)  char *str, INT32 flags) { INT32 ret; struct svalue tmp; tmp.type=T_STRING; tmp.subtype=0; tmp.u.string=make_shared_string(str); ret=simple_add_constant(name, &tmp, flags); free_svalue(&tmp); return ret; }
e43ca21996-11-15Fredrik Hübinette (Hubbe) 
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT int add_program_constant(char *name,
5c0a101997-02-06Fredrik Hübinette (Hubbe)  struct program *p, INT32 flags) { INT32 ret; struct svalue tmp; tmp.type=T_PROGRAM; tmp.subtype=0; tmp.u.program=p; ret=simple_add_constant(name, &tmp, flags); return ret; }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT int add_object_constant(char *name,
f0c3d31998-04-05Fredrik Hübinette (Hubbe)  struct object *o, INT32 flags) { INT32 ret; struct svalue tmp; tmp.type=T_OBJECT; tmp.subtype=0; tmp.u.object=o; ret=simple_add_constant(name, &tmp, flags); return ret; }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT int add_function_constant(char *name, void (*cfun)(INT32), char * type, INT16 flags)
c152401997-02-10Fredrik Hübinette (Hubbe) { struct svalue s; INT32 ret; s.type=T_FUNCTION; s.subtype=FUNCTION_BUILTIN; s.u.efun=make_callable(cfun, name, type, flags, 0, 0); ret=simple_add_constant(name, &s, 0); free_svalue(&s); return ret; }
7901142000-08-15Henrik Grubbström (Grubba) PMOD_EXPORT int debug_end_class(char *name, ptrdiff_t namelen, INT32 flags)
5c0a101997-02-06Fredrik Hübinette (Hubbe) { INT32 ret; struct svalue tmp;
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  struct pike_string *id;
5c0a101997-02-06Fredrik Hübinette (Hubbe)  tmp.type=T_PROGRAM; tmp.subtype=0; tmp.u.program=end_program();
f839fa1997-02-28Fredrik Hübinette (Hubbe)  if(!tmp.u.program) fatal("Failed to initialize class '%s'\n",name);
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  id=make_shared_binary_string(name,namelen); ret=add_constant(id, &tmp, flags); free_string(id);
5c0a101997-02-06Fredrik Hübinette (Hubbe)  free_svalue(&tmp); return ret; }
5267b71995-08-09Fredrik Hübinette (Hubbe) /* * define a new function * if func isn't given, it is supposed to be a prototype. */
06983f1996-09-22Fredrik Hübinette (Hubbe) INT32 define_function(struct pike_string *name,
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *type,
1ef5572000-08-30Henrik Grubbström (Grubba)  unsigned INT8 flags, unsigned INT8 function_flags, union idptr *func, unsigned INT16 opt_flags)
5267b71995-08-09Fredrik Hübinette (Hubbe) { struct identifier *funp,fun; struct reference ref;
51059b1999-12-26Henrik Grubbström (Grubba)  struct svalue *lfun_type;
5267b71995-08-09Fredrik Hübinette (Hubbe)  INT32 i;
a786431999-11-18Martin Stjernholm #ifdef PROGRAM_BUILD_DEBUG { struct pike_string *d = describe_type (type); fprintf (stderr, "%.*sdefining function (pass=%d): %s ",
bad5162000-06-23Fredrik Hübinette (Hubbe)  compilation_depth, " ", Pike_compiler->compiler_pass, d->str);
a786431999-11-18Martin Stjernholm  free_string (d); push_string (name);
cd86322000-07-06Fredrik Hübinette (Hubbe)  print_svalue (stderr, --Pike_sp);
a786431999-11-18Martin Stjernholm  putc ('\n', stderr); } #endif
a2a8801998-03-18Per Hedbor #ifdef PROFILING
6189631998-11-12Fredrik Hübinette (Hubbe)  fun.self_time=0;
a2a8801998-03-18Per Hedbor  fun.num_calls=0; fun.total_time=0; #endif
51059b1999-12-26Henrik Grubbström (Grubba)  /* If this is an lfun, match against the predefined type. */ if ((lfun_type = low_mapping_string_lookup(lfun_types, name))) { #ifdef PIKE_DEBUG if (lfun_type->type != T_TYPE) { fatal("Bad entry in lfun_types for key \"%s\"\n", name->str); } #endif /* PIKE_DEBUG */
4b9d802001-02-21Henrik Grubbström (Grubba)  if (!pike_types_le(type, lfun_type->u.type)) { if (!match_types(type, lfun_type->u.type)) { yytype_error("Function type mismatch", lfun_type->u.type, type, 0);
51059b1999-12-26Henrik Grubbström (Grubba)  } else if (lex.pragmas & ID_STRICT_TYPES) {
4b9d802001-02-21Henrik Grubbström (Grubba)  yytype_error("Function type mismatch", lfun_type->u.type, type,
51059b1999-12-26Henrik Grubbström (Grubba)  YYTE_IS_WARNING); } } }
7c429f2000-04-06Fredrik Hübinette (Hubbe)  if(function_flags & IDENTIFIER_C_FUNCTION)
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->new_program->flags |= PROGRAM_HAS_C_METHODS;
7c429f2000-04-06Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  i=isidentifier(name); if(i >= 0) { /* already defined */
bad5162000-06-23Fredrik Hübinette (Hubbe)  funp=ID_FROM_INT(Pike_compiler->new_program, i); ref=Pike_compiler->new_program->identifier_references[i];
5267b71995-08-09Fredrik Hübinette (Hubbe) 
2acdd31995-10-29Fredrik Hübinette (Hubbe)  if(ref.inherit_offset == 0) /* not inherited */
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
51059b1999-12-26Henrik Grubbström (Grubba) 
1994251999-09-06Fredrik Hübinette (Hubbe)  if( !( IDENTIFIER_IS_FUNCTION(funp->identifier_flags) && ( (!func || func->offset == -1) || (funp->func.offset == -1))))
2acdd31995-10-29Fredrik Hübinette (Hubbe)  {
1994251999-09-06Fredrik Hübinette (Hubbe)  my_yyerror("Identifier '%s' defined twice.",name->str);
2acdd31995-10-29Fredrik Hübinette (Hubbe)  return i; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  /* match types against earlier prototype or vice versa */
0d202a1995-10-20Fredrik Hübinette (Hubbe)  if(!match_types(type, funp->type))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
51f0e02000-08-10Henrik Grubbström (Grubba)  if (!(flags & ID_VARIANT)) { my_yyerror("Prototype doesn't match for function %s.",name->str); }
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
ae95031999-04-07Fredrik Hübinette (Hubbe)  /* We modify the old definition if it is in this program */
12bdcd1999-04-08Fredrik Hübinette (Hubbe) 
ae95031999-04-07Fredrik Hübinette (Hubbe)  if(ref.inherit_offset==0)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
ae95031999-04-07Fredrik Hübinette (Hubbe)  if(func) funp->func = *func;
23c6752000-07-29Fredrik Hübinette (Hubbe) #if 0 /* prototypes does not override non-prototypes, ok? */
ae95031999-04-07Fredrik Hübinette (Hubbe)  else funp->func.offset = -1;
23c6752000-07-29Fredrik Hübinette (Hubbe) #endif
27ae842000-02-07Per Hedbor 
ae95031999-04-07Fredrik Hübinette (Hubbe)  funp->identifier_flags=function_flags;
a786431999-11-18Martin Stjernholm 
e07bed2000-08-31Henrik Grubbström (Grubba)  funp->opt_flags &= opt_flags;
1ef5572000-08-30Henrik Grubbström (Grubba) 
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(funp->type);
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(funp->type, type);
ae95031999-04-07Fredrik Hübinette (Hubbe)  }else{
1994251999-09-06Fredrik Hübinette (Hubbe) 
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  if((ref.id_flags & ID_NOMASK) #if 0 && !(funp->func.offset == -1) #endif ) { my_yyerror("Illegal to redefine 'nomask' function %s.",name->str); }
27ae842000-02-07Per Hedbor 
8aae6d1999-08-19Fredrik Hübinette (Hubbe) 
12bdcd1999-04-08Fredrik Hübinette (Hubbe)  if(ref.id_flags & ID_INLINE) {
ae95031999-04-07Fredrik Hübinette (Hubbe)  goto make_a_new_def;
12bdcd1999-04-08Fredrik Hübinette (Hubbe)  }
27ae842000-02-07Per Hedbor 
ae95031999-04-07Fredrik Hübinette (Hubbe)  /* Otherwise we make a new definition */ copy_shared_string(fun.name, name);
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(fun.type, type);
27ae842000-02-07Per Hedbor 
ae95031999-04-07Fredrik Hübinette (Hubbe)  fun.run_time_type=T_FUNCTION;
27ae842000-02-07Per Hedbor 
ae95031999-04-07Fredrik Hübinette (Hubbe)  fun.identifier_flags=function_flags; if(function_flags & IDENTIFIER_C_FUNCTION)
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->new_program->flags |= PROGRAM_HAS_C_METHODS;
27ae842000-02-07Per Hedbor 
ae95031999-04-07Fredrik Hübinette (Hubbe)  if(func) fun.func = *func; else fun.func.offset = -1;
27ae842000-02-07Per Hedbor 
1ef5572000-08-30Henrik Grubbström (Grubba)  fun.opt_flags = opt_flags;
bad5162000-06-23Fredrik Hübinette (Hubbe)  ref.identifier_offset=Pike_compiler->new_program->num_identifiers;
ae95031999-04-07Fredrik Hübinette (Hubbe)  add_to_identifiers(fun);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
27ae842000-02-07Per Hedbor 
ae95031999-04-07Fredrik Hübinette (Hubbe)  ref.inherit_offset = 0; ref.id_flags = flags;
8b81572000-01-15Fredrik Hübinette (Hubbe) #if 0
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->new_program->identifier_references[i]=ref;
8b81572000-01-15Fredrik Hübinette (Hubbe) #else { int z; /* This loop could possibly be optimized by looping over * each inherit and looking up 'name' in each inherit * and then see if should be overwritten * /Hubbe */
bad5162000-06-23Fredrik Hübinette (Hubbe)  for(z=0;z<Pike_compiler->new_program->num_identifier_references;z++)
8b81572000-01-15Fredrik Hübinette (Hubbe)  { /* Do zapp hidden identifiers */
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->new_program->identifier_references[z].id_flags & ID_HIDDEN)
8b81572000-01-15Fredrik Hübinette (Hubbe)  continue; /* Do not zapp inline ('local') identifiers */
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->new_program->identifier_references[z].inherit_offset && (Pike_compiler->new_program->identifier_references[z].id_flags & ID_INLINE))
8b81572000-01-15Fredrik Hübinette (Hubbe)  continue; /* Do not zapp functions with the wrong name... */
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(ID_FROM_INT(Pike_compiler->new_program, z)->name != name)
8b81572000-01-15Fredrik Hübinette (Hubbe)  continue;
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->new_program->identifier_references[z]=ref;
8b81572000-01-15Fredrik Hübinette (Hubbe)  } #ifdef PIKE_DEBUG
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(MEMCMP(Pike_compiler->new_program->identifier_references+i, &ref,sizeof(ref)))
8b81572000-01-15Fredrik Hübinette (Hubbe)  fatal("New function overloading algorithm failed!\n"); #endif } #endif
ae95031999-04-07Fredrik Hübinette (Hubbe)  return i;
61e9a01998-01-25Fredrik Hübinette (Hubbe)  }
ae95031999-04-07Fredrik Hübinette (Hubbe) make_a_new_def:
5267b71995-08-09Fredrik Hübinette (Hubbe) 
12bdcd1999-04-08Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->compiler_pass==2)
a4a1722000-12-05Per Hedbor  fatal("Internal error: Not allowed to add more identifiers during second compiler pass.\n");
22edc21998-01-29Fredrik Hübinette (Hubbe) #endif
61e9a01998-01-25Fredrik Hübinette (Hubbe)  /* define a new function */
5267b71995-08-09Fredrik Hübinette (Hubbe) 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  copy_shared_string(fun.name, name);
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(fun.type, type);
27ae842000-02-07Per Hedbor 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  fun.identifier_flags=function_flags; fun.run_time_type=T_FUNCTION;
27ae842000-02-07Per Hedbor 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  if(func) fun.func = *func; else fun.func.offset = -1;
27ae842000-02-07Per Hedbor 
1ef5572000-08-30Henrik Grubbström (Grubba)  fun.opt_flags = opt_flags;
bad5162000-06-23Fredrik Hübinette (Hubbe)  i=Pike_compiler->new_program->num_identifiers;
27ae842000-02-07Per Hedbor 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  add_to_identifiers(fun);
27ae842000-02-07Per Hedbor 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  ref.id_flags = flags; ref.identifier_offset = i; ref.inherit_offset = 0;
ae95031999-04-07Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  i=Pike_compiler->new_program->num_identifier_references;
61e9a01998-01-25Fredrik Hübinette (Hubbe)  add_to_identifier_references(ref);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  return i; }
c0e4461998-06-23Fredrik Hübinette (Hubbe) int really_low_find_shared_string_identifier(struct pike_string *name, struct program *prog,
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  int flags)
c0e4461998-06-23Fredrik Hübinette (Hubbe) { struct reference *funp; struct identifier *fun; int i,t;
66b6741999-03-15Fredrik Hübinette (Hubbe) 
aed42d1999-12-29Martin Stjernholm #if 0
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  CDFPRINTF((stderr,"th(%ld) Trying to find %s flags=%d\n", (long)th_self(),name->str, flags));
aed42d1999-12-29Martin Stjernholm #endif
66b6741999-03-15Fredrik Hübinette (Hubbe) 
5dbbf81999-07-01Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG if (!prog) { fatal("really_low_find_shared_string_identifier(\"%s\", NULL, %d)\n"
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  "prog is NULL!\n", name->str, flags);
5dbbf81999-07-01Henrik Grubbström (Grubba)  } #endif /* PIKE_DEBUG */
c0e4461998-06-23Fredrik Hübinette (Hubbe)  for(i=0;i<(int)prog->num_identifier_references;i++) { funp = prog->identifier_references + i; if(funp->id_flags & ID_HIDDEN) continue;
66b6741999-03-15Fredrik Hübinette (Hubbe)  if(funp->id_flags & ID_STATIC)
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  if(!(flags & SEE_STATIC))
c0e4461998-06-23Fredrik Hübinette (Hubbe)  continue; fun = ID_FROM_PTR(prog, funp); /* if(fun->func.offset == -1) continue; * Prototype */ if(!is_same_string(fun->name,name)) continue; if(funp->id_flags & ID_INHERITED) { if(funp->id_flags & ID_PRIVATE) continue; for(t=0; t>=0 && t<(int)prog->num_identifier_references; t++) { struct reference *funpb; struct identifier *funb;
27ae842000-02-07Per Hedbor 
c0e4461998-06-23Fredrik Hübinette (Hubbe)  if(t==i) continue; funpb=prog->identifier_references+t;
66b6741999-03-15Fredrik Hübinette (Hubbe)  if(funpb->id_flags & ID_HIDDEN) continue;
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  if(funpb->id_flags & ID_STATIC) if(!(flags & SEE_STATIC)) continue;
c0e4461998-06-23Fredrik Hübinette (Hubbe)  if((funpb->id_flags & ID_INHERITED) && t<i) continue; funb=ID_FROM_PTR(prog,funpb); /* if(funb->func.offset == -1) continue; * prototype */ if(fun->name==funb->name) t=-10; } if(t < 0) continue; } return i; } return -1; }
c0fb642000-08-10Henrik Grubbström (Grubba) int low_find_lfun(struct program *p, ptrdiff_t lfun)
abac4e2000-02-16Henrik Grubbström (Grubba) {
286afb2001-02-05Henrik Grubbström (Grubba)  struct pike_string *lfun_name = lfun_strings[lfun];
abac4e2000-02-16Henrik Grubbström (Grubba)  unsigned int flags = 0; return really_low_find_shared_string_identifier(lfun_name, dmalloc_touch(struct program *, p),
9a3e732000-06-26Henrik Grubbström (Grubba)  SEE_STATIC);
abac4e2000-02-16Henrik Grubbström (Grubba) }
286afb2001-02-05Henrik Grubbström (Grubba) int lfun_lookup_id(struct pike_string *lfun_name) { struct svalue *id = low_mapping_string_lookup(lfun_ids, lfun_name); if (!id) return -1; if (id->type == T_INT) return id->u.integer; my_yyerror("Bad entry in lfun lookup table for %s.", lfun_name->str); return -1; }
5267b71995-08-09Fredrik Hübinette (Hubbe) /* * lookup the number of a function in a program given the name in * a shared_string */
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) int low_find_shared_string_identifier(struct pike_string *name, struct program *prog)
5267b71995-08-09Fredrik Hübinette (Hubbe) { int max,min,tst; struct identifier *fun;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(prog->flags & PROGRAM_FIXED)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  unsigned short *funindex = prog->identifier_index;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(!funindex) fatal("No funindex in fixed program\n"); #endif
27ae842000-02-07Per Hedbor 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  max = prog->num_identifier_index;
5267b71995-08-09Fredrik Hübinette (Hubbe)  min = 0; while(max != min) { tst=(max + min) >> 1; fun = ID_FROM_INT(prog, funindex[tst]); if(is_same_string(fun->name,name)) return funindex[tst]; if(my_order_strcmp(fun->name, name) > 0) max=tst; else min=tst+1; } }else{
c0e4461998-06-23Fredrik Hübinette (Hubbe)  return really_low_find_shared_string_identifier(name,prog,0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } return -1; } #ifdef FIND_FUNCTION_HASHSIZE #if FIND_FUNCTION_HASHSIZE == 0 #undef FIND_FUNCTION_HASHSIZE #endif #endif #ifdef FIND_FUNCTION_HASHSIZE struct ff_hash {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *name;
5267b71995-08-09Fredrik Hübinette (Hubbe)  int id; int fun; }; static struct ff_hash cache[FIND_FUNCTION_HASHSIZE]; #endif
06983f1996-09-22Fredrik Hübinette (Hubbe) int find_shared_string_identifier(struct pike_string *name,
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct program *prog) {
c55b911999-03-07Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG if (!prog) { fatal("find_shared_string_identifier(): No program!\n" "Identifier: %s%s%s\n", name?"\"":"", name?name->str:"NULL", name?"\"":""); } #endif /* PIKE_DEBUG */
5267b71995-08-09Fredrik Hübinette (Hubbe) #ifdef FIND_FUNCTION_HASHSIZE
5985c12000-10-25Fredrik Hübinette (Hubbe)  if(prog -> flags & PROGRAM_FIXED #if FIND_FUNCTION_HASH_TRESHOLD - 0 && prog->num_identifier_index >= FIND_FUNCTION_HASH_TRESHOLD #endif )
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
d3b06f2000-08-10Henrik Grubbström (Grubba)  size_t hashval; hashval = my_hash_string(name); hashval += prog->id; hashval %= FIND_FUNCTION_HASHSIZE;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(is_same_string(cache[hashval].name,name) && cache[hashval].id==prog->id) return cache[hashval].fun; if(cache[hashval].name) free_string(cache[hashval].name); copy_shared_string(cache[hashval].name,name); cache[hashval].id=prog->id; return cache[hashval].fun=low_find_shared_string_identifier(name,prog); } #endif /* FIND_FUNCTION_HASHSIZE */ return low_find_shared_string_identifier(name,prog); }
6f3ad02001-07-02Martin Stjernholm PMOD_EXPORT int find_identifier(const char *name,struct program *prog)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *n;
0b9d1c1998-05-15Henrik Grubbström (Grubba)  if(!prog) { if (strlen(name) < 1024) {
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Lookup of identifier %s in destructed object.\n", name);
0b9d1c1998-05-15Henrik Grubbström (Grubba)  } else {
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Lookup of long identifier in destructed object.\n");
0b9d1c1998-05-15Henrik Grubbström (Grubba)  } }
5267b71995-08-09Fredrik Hübinette (Hubbe)  n=findstring(name); if(!n) return -1; return find_shared_string_identifier(n,prog); }
06983f1996-09-22Fredrik Hübinette (Hubbe) int store_prog_string(struct pike_string *str)
5267b71995-08-09Fredrik Hübinette (Hubbe) { unsigned int i;
bad5162000-06-23Fredrik Hübinette (Hubbe)  for (i=0;i<Pike_compiler->new_program->num_strings;i++) if (Pike_compiler->new_program->strings[i] == str)
5267b71995-08-09Fredrik Hübinette (Hubbe)  return i; reference_shared_string(str);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  add_to_strings(str);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return i; }
454d541999-09-18Fredrik Hübinette (Hubbe) int store_constant(struct svalue *foo, int equal, struct pike_string *constant_name)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
454d541999-09-18Fredrik Hübinette (Hubbe)  struct program_constant tmp;
5267b71995-08-09Fredrik Hübinette (Hubbe)  unsigned int e;
5d3fd91999-12-14Fredrik Hübinette (Hubbe)  JMP_BUF tmp2;
27ae842000-02-07Per Hedbor 
5d3fd91999-12-14Fredrik Hübinette (Hubbe)  if(SETJMP(tmp2))
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  {
9036e82001-08-16Martin Stjernholm  struct svalue zero, thrown = throw_value; throw_value.type = T_INT;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
5d3fd91999-12-14Fredrik Hübinette (Hubbe)  yyerror("Couldn't store constant.");
454d541999-09-18Fredrik Hübinette (Hubbe) 
9036e82001-08-16Martin Stjernholm  push_svalue(&thrown); low_safe_apply_handler("compile_exception", error_handler, compat_handler, 1);
9f516a2001-12-16Martin Stjernholm  if (SAFE_IS_ZERO(sp-1)) yy_describe_exception(&thrown);
b34c9f2001-08-15Martin Stjernholm  pop_stack();
9036e82001-08-16Martin Stjernholm  free_svalue(&thrown);
b34c9f2001-08-15Martin Stjernholm 
5d3fd91999-12-14Fredrik Hübinette (Hubbe)  zero.type = T_INT; zero.subtype = NUMBER_NUMBER; zero.u.integer=0;
6bee1c1999-12-14Fredrik Hübinette (Hubbe)  UNSETJMP(tmp2);
5d3fd91999-12-14Fredrik Hübinette (Hubbe)  return store_constant(&zero, equal, constant_name); }else{
bad5162000-06-23Fredrik Hübinette (Hubbe)  for(e=0;e<Pike_compiler->new_program->num_constants;e++)
5d3fd91999-12-14Fredrik Hübinette (Hubbe)  {
bad5162000-06-23Fredrik Hübinette (Hubbe)  struct program_constant *c= Pike_compiler->new_program->constants+e;
5d3fd91999-12-14Fredrik Hübinette (Hubbe)  if((equal ? is_equal(& c->sval,foo) : is_eq(& c->sval,foo)) && c->name == constant_name) { UNSETJMP(tmp2); return e; } } assign_svalue_no_free(&tmp.sval,foo); if((tmp.name=constant_name)) add_ref(constant_name);
27ae842000-02-07Per Hedbor 
5d3fd91999-12-14Fredrik Hübinette (Hubbe)  add_to_constants(tmp); UNSETJMP(tmp2); return e; }
5267b71995-08-09Fredrik Hübinette (Hubbe) }
a36d821998-05-25Henrik Grubbström (Grubba) /* * program examination functions available from Pike. */ struct array *program_indices(struct program *p) { int e; int n = 0; struct array *res; for (e = p->num_identifier_references; e--; ) { struct identifier *id; if (p->identifier_references[e].id_flags & ID_HIDDEN) { continue; } id = ID_FROM_INT(p, e); if (IDENTIFIER_IS_CONSTANT(id->identifier_flags)) {
afbda12001-12-06Henrik Grubbström (Grubba)  struct program *p2 = PROG_FROM_INT(p, e); struct svalue *val = &p2->constants[id->func.offset].sval; if ((val->type != T_PROGRAM) || !(val->u.program->flags & PROGRAM_USES_PARENT)) { ref_push_string(ID_FROM_INT(p, e)->name); n++; }
a36d821998-05-25Henrik Grubbström (Grubba)  } } f_aggregate(n);
cd86322000-07-06Fredrik Hübinette (Hubbe)  res = Pike_sp[-1].u.array;
a36d821998-05-25Henrik Grubbström (Grubba)  add_ref(res); pop_stack(); return(res); } struct array *program_values(struct program *p) { int e; int n = 0; struct array *res; for(e = p->num_identifier_references; e--; ) { struct identifier *id; if (p->identifier_references[e].id_flags & ID_HIDDEN) { continue; } id = ID_FROM_INT(p, e); if (IDENTIFIER_IS_CONSTANT(id->identifier_flags)) { struct program *p2 = PROG_FROM_INT(p, e);
afbda12001-12-06Henrik Grubbström (Grubba)  struct svalue *val = &p2->constants[id->func.offset].sval; if ((val->type != T_PROGRAM) || !(val->u.program->flags & PROGRAM_USES_PARENT)) { push_svalue(val); n++; }
a36d821998-05-25Henrik Grubbström (Grubba)  } } f_aggregate(n);
cd86322000-07-06Fredrik Hübinette (Hubbe)  res = Pike_sp[-1].u.array;
a36d821998-05-25Henrik Grubbström (Grubba)  add_ref(res); pop_stack(); return(res); }
e435831998-05-25Henrik Grubbström (Grubba) void program_index_no_free(struct svalue *to, struct program *p, struct svalue *ind) { int e; struct pike_string *s; if (ind->type != T_STRING) {
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Can't index a program with a %s (expected string)\n",
e435831998-05-25Henrik Grubbström (Grubba)  get_name_of_type(ind->type)); } s = ind->u.string;
1994251999-09-06Fredrik Hübinette (Hubbe)  e=find_shared_string_identifier(s, p); if(e!=-1) { struct identifier *id; id=ID_FROM_INT(p, e);
e435831998-05-25Henrik Grubbström (Grubba)  if (IDENTIFIER_IS_CONSTANT(id->identifier_flags)) { struct program *p2 = PROG_FROM_INT(p, e);
afbda12001-12-06Henrik Grubbström (Grubba)  struct svalue *val = &p2->constants[id->func.offset].sval;
abe2ac2001-12-06Henrik Grubbström (Grubba)  assign_svalue_no_free(to, val); return;
e435831998-05-25Henrik Grubbström (Grubba)  } }
1994251999-09-06Fredrik Hübinette (Hubbe)  to->type=T_INT; to->subtype=NUMBER_UNDEFINED; to->u.integer=0;
e435831998-05-25Henrik Grubbström (Grubba) }
5267b71995-08-09Fredrik Hübinette (Hubbe) /* * Line number support routines, now also tells what file we are in */
1016021999-10-28Fredrik Hübinette (Hubbe) 
58ef5e1999-10-19Fredrik Hübinette (Hubbe) int get_small_number(char **q)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
bd2eee2000-03-28Fredrik Hübinette (Hubbe)  /* This is a workaround for buggy cc & Tru64 */
5267b71995-08-09Fredrik Hübinette (Hubbe)  int ret;
bd2eee2000-03-28Fredrik Hübinette (Hubbe)  ret=*(signed char *)*q; (*q)++; switch(ret)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { case -127: ret=EXTRACT_WORD((unsigned char*)*q); *q+=2; return ret; case -128: ret=EXTRACT_INT((unsigned char*)*q); *q+=4; return ret; default: return ret; } } void start_line_numbering(void) {
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->last_file)
ea32c11998-04-13Henrik Grubbström (Grubba)  {
bad5162000-06-23Fredrik Hübinette (Hubbe)  free_string(Pike_compiler->last_file); Pike_compiler->last_file=0;
ea32c11998-04-13Henrik Grubbström (Grubba)  }
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->last_pc=Pike_compiler->last_line=0;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) static void insert_small_number(INT32 a)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
4dba522001-07-11Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG int start = Pike_compiler->new_program->num_linenumbers; #endif /* PIKE_DEBUG */
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(a>-127 && a<127) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  add_to_linenumbers(a);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else if(a>=-32768 && a<32768){
aeeef31998-01-16Fredrik Hübinette (Hubbe)  add_to_linenumbers(-127);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  ins_short(a, add_to_linenumbers);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  add_to_linenumbers(-128); ins_int(a, add_to_linenumbers);
27ae842000-02-07Per Hedbor  }
4dba522001-07-11Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG { unsigned char *tmp = Pike_compiler->new_program->linenumbers + start;
50edc82001-07-13Henrik Grubbström (Grubba)  INT32 res = get_small_number((char **)&tmp);
4dba522001-07-11Henrik Grubbström (Grubba)  if (a != res) { tmp = Pike_compiler->new_program->linenumbers + start; fprintf(stderr, "0x%p: %02x %02x %02x %02x %02x\n", tmp, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4]); fatal("insert_small_number failed: %d (0x%08x) != %d (0x%08x)\n", a, a, res, res); } } #endif /* PIKE_DEBUG */
5267b71995-08-09Fredrik Hübinette (Hubbe) }
06983f1996-09-22Fredrik Hübinette (Hubbe) void store_linenumber(INT32 current_line, struct pike_string *current_file)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
1016021999-10-28Fredrik Hübinette (Hubbe) /* if(!store_linenumbers) fatal("Fnord.\n"); */ #ifdef PIKE_DEBUG
ae2d702001-10-06Fredrik Hübinette (Hubbe)  if(a_flag)
1016021999-10-28Fredrik Hübinette (Hubbe)  { INT32 line=0, off=0;
50edc82001-07-13Henrik Grubbström (Grubba)  size_t len = 0; INT32 shift = 0;
1016021999-10-28Fredrik Hübinette (Hubbe)  char *file=0;
bad5162000-06-23Fredrik Hübinette (Hubbe)  char *cnt=Pike_compiler->new_program->linenumbers;
1016021999-10-28Fredrik Hübinette (Hubbe) 
ae2d702001-10-06Fredrik Hübinette (Hubbe)  if (a_flag > 50) {
50edc82001-07-13Henrik Grubbström (Grubba)  fprintf(stderr, "store_line_number(%d, \"%s\")\n", current_line, current_file->str); fprintf(stderr, " last_line:%d last_file:\"%s\"\n", Pike_compiler->last_line, Pike_compiler->last_file?Pike_compiler->last_file->str:""); } while(cnt < Pike_compiler->new_program->linenumbers + Pike_compiler->new_program->num_linenumbers)
1016021999-10-28Fredrik Hübinette (Hubbe)  {
50edc82001-07-13Henrik Grubbström (Grubba)  char *start = cnt;
1016021999-10-28Fredrik Hübinette (Hubbe)  if(*cnt == 127) {
50edc82001-07-13Henrik Grubbström (Grubba)  cnt++; len = get_small_number(&cnt); shift = *cnt; file = ++cnt; cnt += len<<shift;
ae2d702001-10-06Fredrik Hübinette (Hubbe)  if (a_flag > 10) {
50edc82001-07-13Henrik Grubbström (Grubba)  fprintf(stderr, "Filename entry:\n" " len: %d, shift: %d\n", len, shift); }
1016021999-10-28Fredrik Hübinette (Hubbe)  } off+=get_small_number(&cnt); line+=get_small_number(&cnt);
ae2d702001-10-06Fredrik Hübinette (Hubbe)  if (a_flag > 100) {
50edc82001-07-13Henrik Grubbström (Grubba)  fprintf(stderr, " off: %d, line: %d\n" " raw: ", off, line); for (;start < cnt; start++) { fprintf(stderr, "%02x ", *((unsigned char *)start)); } fprintf(stderr, "\n"); }
1016021999-10-28Fredrik Hübinette (Hubbe)  }
27ae842000-02-07Per Hedbor 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->last_line != line || Pike_compiler->last_pc != off ||
50edc82001-07-13Henrik Grubbström (Grubba)  (Pike_compiler->last_file && file && memcmp(Pike_compiler->last_file->str, file, len<<shift)))
1016021999-10-28Fredrik Hübinette (Hubbe)  { fatal("Line numbering out of whack\n"
50edc82001-07-13Henrik Grubbström (Grubba)  " (line : %d ?= %d)!\n" " ( pc : %d ?= %d)!\n" " (shift: %d ?= %d)!\n" " (len : %d ?= %d)!\n" " (file : %s ?= %s)!\n",
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->last_line, line, Pike_compiler->last_pc, off,
50edc82001-07-13Henrik Grubbström (Grubba)  Pike_compiler->last_file?Pike_compiler->last_file->size_shift:0, shift, Pike_compiler->last_file?Pike_compiler->last_file->len:0, len,
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->last_file?Pike_compiler->last_file->str:"N/A",
1016021999-10-28Fredrik Hübinette (Hubbe)  file?file:"N/A"); } } #endif
50edc82001-07-13Henrik Grubbström (Grubba)  if(Pike_compiler->last_line != current_line || Pike_compiler->last_file != current_file)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
50edc82001-07-13Henrik Grubbström (Grubba)  if((Pike_compiler->last_file != current_file) ||
1302b12001-08-14Martin Stjernholm  (DO_NOT_WARN((INT32)(PIKE_PC - Pike_compiler->last_pc)) == 127))
5267b71995-08-09Fredrik Hübinette (Hubbe)  { char *tmp;
50edc82001-07-13Henrik Grubbström (Grubba)  INT32 remain = DO_NOT_WARN((INT32)current_file->len)<< current_file->size_shift;
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->last_file) free_string(Pike_compiler->last_file);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  add_to_linenumbers(127);
50edc82001-07-13Henrik Grubbström (Grubba)  insert_small_number(DO_NOT_WARN((INT32)current_file->len)); add_to_linenumbers(current_file->size_shift); for(tmp=current_file->str; remain-- > 0; tmp++)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  add_to_linenumbers(*tmp);
bad5162000-06-23Fredrik Hübinette (Hubbe)  copy_shared_string(Pike_compiler->last_file, current_file);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
1302b12001-08-14Martin Stjernholm  insert_small_number(DO_NOT_WARN((INT32)(PIKE_PC-Pike_compiler->last_pc)));
bad5162000-06-23Fredrik Hübinette (Hubbe)  insert_small_number(current_line-Pike_compiler->last_line);
50edc82001-07-13Henrik Grubbström (Grubba)  Pike_compiler->last_line = current_line;
1302b12001-08-14Martin Stjernholm  Pike_compiler->last_pc = DO_NOT_WARN((INT32)PIKE_PC);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
4f985f2001-06-30Martin Stjernholm /* Returns the file where the program is defined. The line of the * class start is written to linep, or 0 if the program is the top * level of the file. */
50edc82001-07-13Henrik Grubbström (Grubba) PMOD_EXPORT struct pike_string *get_program_line(struct program *prog, INT32 *linep)
4f985f2001-06-30Martin Stjernholm {
50edc82001-07-13Henrik Grubbström (Grubba)  char *cnt; size_t len = 0; INT32 shift = 0; char *file = NULL;
4f985f2001-06-30Martin Stjernholm  if(prog == Pike_compiler->new_program) {
50edc82001-07-13Henrik Grubbström (Grubba)  struct pike_string *optimizer;
4f985f2001-06-30Martin Stjernholm  linep[0]=0;
50edc82001-07-13Henrik Grubbström (Grubba)  MAKE_CONSTANT_SHARED_STRING(optimizer, "Optimizer"); return optimizer;
4f985f2001-06-30Martin Stjernholm  } cnt = prog->linenumbers; if (cnt < prog->linenumbers + prog->num_linenumbers) { if (*cnt == 127) {
50edc82001-07-13Henrik Grubbström (Grubba)  cnt++; len = get_small_number(&cnt); shift = *cnt; file = ++cnt; cnt += len<<shift;
4f985f2001-06-30Martin Stjernholm  }
50edc82001-07-13Henrik Grubbström (Grubba)  get_small_number(&cnt); /* Ignore the offset */
4f985f2001-06-30Martin Stjernholm  *linep = get_small_number(&cnt); } else *linep = 0;
50edc82001-07-13Henrik Grubbström (Grubba)  if (file) { struct pike_string *str = begin_wide_shared_string(len, shift); memcpy(str->str, file, len<<shift); return end_shared_string(str); } else { struct pike_string *dash; MAKE_CONSTANT_SHARED_STRING(dash, "-"); return dash; }
4f985f2001-06-30Martin Stjernholm }
376e472001-09-10Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG /* Same as get_program_line but only used for debugging, * returns a char* * This is important because this function may be called * after the shared string table has expired. */ char *debug_get_program_line(struct program *prog, INT32 *linep) { char *cnt; size_t len = 0; INT32 shift = 0; char *file = NULL; static char buffer[1025]; if(prog == Pike_compiler->new_program) { linep[0]=0; return "optimizer"; } cnt = prog->linenumbers; if (cnt < prog->linenumbers + prog->num_linenumbers) { if (*cnt == 127) { cnt++; len = get_small_number(&cnt); shift = *cnt; file = ++cnt; cnt += len<<shift; } get_small_number(&cnt); /* Ignore the offset */ *linep = get_small_number(&cnt); } else *linep = 0; if (file) { if(shift) { PCHARP from=MKPCHARP(file, shift); size_t ptr=0; while(ptr < NELEM(buffer)-20 && EXTRACT_PCHARP(from)) { if(EXTRACT_PCHARP(from) > 255) { sprintf(buffer+ptr,"\\0x%x",EXTRACT_PCHARP(from)); ptr+=strlen(buffer+ptr); }else{ buffer[ptr++]=EXTRACT_PCHARP(from); } INC_PCHARP(from, 1); } buffer[ptr]=0; return buffer; }else{ return file; } } else { return "-"; } } #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) /* * return the file in which we were executing. * pc should be the program counter, prog the current * program, and line will be initialized to the line * in that file. */
50edc82001-07-13Henrik Grubbström (Grubba) PMOD_EXPORT struct pike_string *get_line(PIKE_OPCODE_T *pc, struct program *prog, INT32 *linep)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
50edc82001-07-13Henrik Grubbström (Grubba)  static char *file = NULL; static char *cnt;
9e52381998-03-01Fredrik Hübinette (Hubbe)  static INT32 off,line,pid;
50edc82001-07-13Henrik Grubbström (Grubba)  static size_t len; static INT32 shift;
d3b06f2000-08-10Henrik Grubbström (Grubba)  ptrdiff_t offset;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
ecbfc82001-07-18Henrik Grubbström (Grubba)  linep[0] = 0;
4f985f2001-06-30Martin Stjernholm  if (prog == 0) {
50edc82001-07-13Henrik Grubbström (Grubba)  struct pike_string *unknown_program; MAKE_CONSTANT_SHARED_STRING(unknown_program, "Unknown program"); return unknown_program;
4f985f2001-06-30Martin Stjernholm  }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(prog == Pike_compiler->new_program)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
50edc82001-07-13Henrik Grubbström (Grubba)  struct pike_string *optimizer; MAKE_CONSTANT_SHARED_STRING(optimizer, "Optimizer"); return optimizer;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
ecbfc82001-07-18Henrik Grubbström (Grubba) #ifdef PIKE_USE_MACHINE_CODE
86d54d2001-11-08Fredrik Hübinette (Hubbe)  if( (long)pc > (long)prog->program) offset = pc - prog->program; else offset = (long) pc;
ecbfc82001-07-18Henrik Grubbström (Grubba) #else offset = pc - prog->program; #endif if ((offset > (ptrdiff_t)prog->num_program) || (offset < 0)) { struct pike_string *not_found; MAKE_CONSTANT_SHARED_STRING(not_found, "Line not found"); return not_found; }
9e52381998-03-01Fredrik Hübinette (Hubbe)  if(prog->id != pid || offset < off) { cnt=prog->linenumbers; off=line=0; pid=prog->id;
50edc82001-07-13Henrik Grubbström (Grubba)  file = 0;
342c042000-12-01Fredrik Hübinette (Hubbe)  }else{ goto fromold;
9e52381998-03-01Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  while(cnt < prog->linenumbers + prog->num_linenumbers) { if(*cnt == 127) {
50edc82001-07-13Henrik Grubbström (Grubba)  cnt++; len = get_small_number(&cnt); shift = *cnt; file = ++cnt; cnt += len<<shift;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } off+=get_small_number(&cnt);
342c042000-12-01Fredrik Hübinette (Hubbe)  if(off > offset) break;
4dba522001-07-11Henrik Grubbström (Grubba)  fromold:
d3a3132000-12-01Henrik Grubbström (Grubba)  line+=get_small_number(&cnt);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } linep[0]=line;
50edc82001-07-13Henrik Grubbström (Grubba)  if (!file) { struct pike_string *not_found; MAKE_CONSTANT_SHARED_STRING(not_found, "Line not found"); return not_found; } else { struct pike_string *res = begin_wide_shared_string(len, shift); memcpy(res->str, file, len<<shift); return end_shared_string(res); }
5267b71995-08-09Fredrik Hübinette (Hubbe) }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) void my_yyerror(char *fmt,...) ATTRIBUTE((format(printf,1,2)))
5267b71995-08-09Fredrik Hübinette (Hubbe) { va_list args;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  char buf[8192];
52cf141998-05-15Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  va_start(args,fmt);
52cf141998-05-15Henrik Grubbström (Grubba)  #ifdef HAVE_VSNPRINTF vsnprintf(buf, 8190, fmt, args); #else /* !HAVE_VSNPRINTF */ VSPRINTF(buf, fmt, args); #endif /* HAVE_VSNPRINTF */
5267b71995-08-09Fredrik Hübinette (Hubbe) 
d3b06f2000-08-10Henrik Grubbström (Grubba)  if((size_t)strlen(buf) >= (size_t)sizeof(buf))
8780ce1998-04-19Per Hedbor  fatal("Buffer overflow in my_yyerror.\n");
5267b71995-08-09Fredrik Hübinette (Hubbe)  yyerror(buf); va_end(args); }
b34c9f2001-08-15Martin Stjernholm void yy_describe_exception(struct svalue *thrown) { /* FIXME: Doesn't handle wide string error messages. */ struct pike_string *s = 0; if ((thrown->type == T_ARRAY) && thrown->u.array->size && (thrown->u.array->item[0].type == T_STRING)) { /* Old-style backtrace */ s = thrown->u.array->item[0].u.string; } else if (thrown->type == T_OBJECT) { struct generic_error_struct *ge; if ((ge = (struct generic_error_struct *) get_storage(thrown->u.object, generic_error_program))) { s = ge->desc; } } if (s && !s->size_shift) { extern void f_string_trim_all_whites(INT32 args); ref_push_string(s); f_string_trim_all_whites(1); push_constant_text("\n"); push_constant_text(" "); f_replace(3); my_yyerror(sp[-1].u.string->str); pop_stack(); } }
eaa4da2001-10-04Fredrik Hübinette (Hubbe) extern void yyparse(void);
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
eaa4da2001-10-04Fredrik Hübinette (Hubbe) #define do_yyparse() do { \ struct svalue *save_sp=Pike_sp; \ yyparse(); /* Parse da program */ \ if(save_sp != Pike_sp) \
cb67042001-12-12Martin Stjernholm  fatal("yyparse() left %"PRINTPTRDIFFT"d droppings on the stack!\n", \ Pike_sp - save_sp); \
eaa4da2001-10-04Fredrik Hübinette (Hubbe) }while(0) #else #define do_yyparse() yyparse()
0ee27b1998-04-14Fredrik Hübinette (Hubbe) #endif
eaa4da2001-10-04Fredrik Hübinette (Hubbe) 
86d54d2001-11-08Fredrik Hübinette (Hubbe) struct Supporter *current_supporter=0;
0f2b442001-12-14Martin Stjernholm int force_resolve = 0;
86d54d2001-11-08Fredrik Hübinette (Hubbe)  #ifdef PIKE_DEBUG struct supporter_marker { struct supporter_marker *next; void *data;
cb67042001-12-12Martin Stjernholm  int level, verified;
86d54d2001-11-08Fredrik Hübinette (Hubbe) }; #undef EXIT_BLOCK #define EXIT_BLOCK(P) #undef COUNT_OTHER #define COUNT_OTHER() #undef INIT_BLOCK
cb67042001-12-12Martin Stjernholm #define INIT_BLOCK(X) do { (X)->level = (X)->verified = 0; }while(0)
86d54d2001-11-08Fredrik Hübinette (Hubbe) PTR_HASH_ALLOC(supporter_marker, 128); static int supnum; #define SNUM(X) (get_supporter_marker((X))->level)
cb67042001-12-12Martin Stjernholm static void mark_supporters(struct Supporter *s)
86d54d2001-11-08Fredrik Hübinette (Hubbe) { struct supporter_marker *m; if(!s) return; debug_malloc_touch(s); m=get_supporter_marker(s);
cb67042001-12-12Martin Stjernholm 
86d54d2001-11-08Fredrik Hübinette (Hubbe)  if(m->level) return;
cb67042001-12-12Martin Stjernholm  m->level = -1;
86d54d2001-11-08Fredrik Hübinette (Hubbe)  if(s->magic != 0x500b0127) { #ifdef DEBUG_MALLOC describe(s); #endif fatal("This is not a supporter (addr=%p, magic=%x)!\n",s,s->magic); }
cb67042001-12-12Martin Stjernholm  mark_supporters(s->dependants); mark_supporters(s->next_dependant); m->level=supnum++; mark_supporters(s->previous); mark_supporters(s->depends_on); } static void low_verify_supporters(struct Supporter *s) { struct Supporter *ss; struct supporter_marker *m; if(!s) return; debug_malloc_touch(s); m=get_supporter_marker(s); if(m->verified) return; m->verified = 1;
86d54d2001-11-08Fredrik Hübinette (Hubbe)  low_verify_supporters(s->dependants); low_verify_supporters(s->next_dependant);
cb67042001-12-12Martin Stjernholm #if 0
0f2b442001-12-14Martin Stjernholm  fprintf(stderr, "low_verify_supporters %p%s, level %d: "
cb67042001-12-12Martin Stjernholm  "previous %p, depends_on %p, dependants %p, next_dependant %p\n",
0f2b442001-12-14Martin Stjernholm  s, s == current_supporter ? " == current_supporter" : "", m->level, s->previous, s->depends_on, s->dependants, s->next_dependant);
cb67042001-12-12Martin Stjernholm #endif
86d54d2001-11-08Fredrik Hübinette (Hubbe)  if(s->previous && SNUM(s->previous) <= m->level) fatal("Que, numbers out of whack1\n"); if(s->depends_on && SNUM(s->depends_on) <= m->level) fatal("Que, numbers out of whack2\n");
0f2b442001-12-14Martin Stjernholm  for(ss=s->dependants;ss;ss=ss->next_dependant) { if (ss->depends_on != s) fatal("Dependant hasn't got depends_on set properly.\n");
86d54d2001-11-08Fredrik Hübinette (Hubbe)  if(SNUM(ss) >= m->level) fatal("Que, numbers out of whack3\n");
0f2b442001-12-14Martin Stjernholm  } low_verify_supporters(s->previous); low_verify_supporters(s->depends_on);
86d54d2001-11-08Fredrik Hübinette (Hubbe) } void verify_supporters() { if(d_flag) { supnum=1; init_supporter_marker_hash();
cb67042001-12-12Martin Stjernholm  #if 0 fprintf(stderr, "verify_supporters start\n"); #endif mark_supporters(current_supporter);
86d54d2001-11-08Fredrik Hübinette (Hubbe)  low_verify_supporters(current_supporter); #ifdef DO_PIKE_CLEANUP { size_t e=0; struct supporter_marker *h; for(e=0;e<supporter_marker_hash_table_size;e++) while(supporter_marker_hash_table[e]) remove_supporter_marker(supporter_marker_hash_table[e]->data); } #endif exit_supporter_marker_hash();
cb67042001-12-12Martin Stjernholm  #if 0 fprintf(stderr, "verify_supporters end\n"); #endif
86d54d2001-11-08Fredrik Hübinette (Hubbe)  } } #else #define verify_supporters(); #endif void init_supporter(struct Supporter *s,
c6cf602001-12-13Martin Stjernholm  supporter_callback *fun,
86d54d2001-11-08Fredrik Hübinette (Hubbe)  void *data) { verify_supporters(); #ifdef PIKE_DEBUG s->magic = 0x500b0127; #endif s->previous=current_supporter; current_supporter=s; s->depends_on=0; s->dependants=0; s->next_dependant=0; s->fun=fun; s->data=data; s->prog=0; verify_supporters(); } int unlink_current_supporter(struct Supporter *c) { int ret=0; #ifdef PIKE_DEBUG if(c != current_supporter) fatal("Previous unlink failed.\n"); #endif debug_malloc_touch(c); verify_supporters(); if(c->depends_on) {
0f2b442001-12-14Martin Stjernholm #ifdef PIKE_DEBUG struct Supporter *s; for (s = c->depends_on->dependants; s; s = s->next_dependant) if (s == c) fatal("Dependant already linked in.\n"); #endif
86d54d2001-11-08Fredrik Hübinette (Hubbe)  ret++; c->next_dependant = c->depends_on->dependants; c->depends_on->dependants=c; } current_supporter=c->previous; verify_supporters(); return ret; }
0f2b442001-12-14Martin Stjernholm void free_supporter(struct Supporter *c) { verify_supporters(); if (c->depends_on) { struct Supporter **s; for (s = &c->depends_on->dependants; *s; s = &(*s)->next_dependant) if (*s == c) {*s = c->next_dependant; break;} c->depends_on = 0; } verify_supporters(); }
c6cf602001-12-13Martin Stjernholm int call_dependants(struct Supporter *s, int finish)
86d54d2001-11-08Fredrik Hübinette (Hubbe) {
c6cf602001-12-13Martin Stjernholm  int ok = 1;
86d54d2001-11-08Fredrik Hübinette (Hubbe)  struct Supporter *tmp; verify_supporters(); while((tmp=s->dependants)) { s->dependants=tmp->next_dependant;
c6cf602001-12-13Martin Stjernholm #ifdef PIKE_DEBUG
86d54d2001-11-08Fredrik Hübinette (Hubbe)  tmp->next_dependant=0; #endif verify_supporters();
c6cf602001-12-13Martin Stjernholm  if (!tmp->fun(tmp->data, finish)) ok = 0;
86d54d2001-11-08Fredrik Hübinette (Hubbe)  verify_supporters(); }
c6cf602001-12-13Martin Stjernholm  return ok;
86d54d2001-11-08Fredrik Hübinette (Hubbe) } int report_compiler_dependency(struct program *p) { int ret=0; struct Supporter *c,*cc; verify_supporters();
9f516a2001-12-16Martin Stjernholm  if (force_resolve) return 0;
86d54d2001-11-08Fredrik Hübinette (Hubbe)  for(cc=current_supporter;cc;cc=cc->previous) {
cb67042001-12-12Martin Stjernholm  if(cc->prog &&
86d54d2001-11-08Fredrik Hübinette (Hubbe)  !(cc->prog->flags & PROGRAM_PASS_1_DONE)) { c=cc->depends_on; if(!c) c=cc->previous; for(;c;c=c->previous) { if(c->prog == p) { cc->depends_on=c; verify_supporters(); ret++; /* dependency registred */ } } } } verify_supporters(); return ret; }
eaa4da2001-10-04Fredrik Hübinette (Hubbe) struct compilation {
86d54d2001-11-08Fredrik Hübinette (Hubbe)  struct Supporter supporter;
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  struct pike_string *prog; struct object *handler; int major, minor; struct program *target; struct object *placeholder;
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct program *p;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  struct lex save_lex;
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  int save_depth;
e0837a1999-07-01Fredrik Hübinette (Hubbe)  int saved_threads_disabled;
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  struct object *saved_handler; struct object *saved_compat_handler; dynamic_buffer used_modules_save; INT32 num_used_modules_save; struct mapping *resolve_cache_save;
aa68b12001-03-19Fredrik Hübinette (Hubbe) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  struct svalue default_module; };
1167b02001-06-14Henrik Grubbström (Grubba) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe) static void free_compilation(struct compilation *c) { debug_malloc_touch(c); free_string(c->prog); if(c->handler) free_object(c->handler); if(c->target) free_program(c->target); if(c->placeholder) free_object(c->placeholder); free_svalue(& c->default_module);
0f2b442001-12-14Martin Stjernholm  free_supporter(&c->supporter);
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  free((char *)c);
86d54d2001-11-08Fredrik Hübinette (Hubbe)  verify_supporters();
eaa4da2001-10-04Fredrik Hübinette (Hubbe) }
1167b02001-06-14Henrik Grubbström (Grubba) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe) static void run_init(struct compilation *c) { debug_malloc_touch(c); c->save_depth=compilation_depth; compilation_depth=-1;
1167b02001-06-14Henrik Grubbström (Grubba) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  c->saved_handler = error_handler; if((error_handler = c->handler)) add_ref(error_handler);
1167b02001-06-14Henrik Grubbström (Grubba) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  c->saved_compat_handler = compat_handler;
ac87152000-09-25Fredrik Hübinette (Hubbe)  compat_handler=0;
10e16f1999-11-04Henrik Grubbström (Grubba) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  c->used_modules_save = used_modules; c->num_used_modules_save = Pike_compiler->num_used_modules;
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->num_used_modules=0;
05590d1998-04-23Fredrik Hübinette (Hubbe) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  c->resolve_cache_save = resolve_cache; resolve_cache = 0;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  c->save_lex=lex;
acbf0a1999-02-20Henrik Grubbström (Grubba) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  lex.current_line=1; lex.current_file=make_shared_string("-");
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  if (runtime_options & RUNTIME_STRICT_TYPES) {
fdb0121999-12-05Henrik Grubbström (Grubba)  lex.pragmas = ID_STRICT_TYPES; } else { lex.pragmas = 0; }
5c8e891995-10-29Fredrik Hübinette (Hubbe) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  lex.end = c->prog->str + (c->prog->len << c->prog->size_shift); switch(c->prog->size_shift) { case 0: lex.current_lexer = yylex0; break; case 1: lex.current_lexer = yylex1; break; case 2: lex.current_lexer = yylex2; break; default: fatal("Program has bad shift %d!\n", c->prog->size_shift); break; } lex.pos=c->prog->str; } static void run_init2(struct compilation *c) { debug_malloc_touch(c); Pike_compiler->compiler = c;
4d7b181999-12-07Fredrik Hübinette (Hubbe)  initialize_buf(&used_modules);
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  use_module(& c->default_module); Pike_compiler->compat_major=PIKE_MAJOR_VERSION; Pike_compiler->compat_minor=PIKE_MINOR_VERSION; if(c->major>=0) change_compiler_compatibility(c->major, c->minor); } static void run_exit(struct compilation *c) { debug_malloc_touch(c); toss_buffer(&used_modules); used_modules = c->used_modules_save; #ifdef PIKE_DEBUG if(Pike_compiler->num_used_modules) fatal("Failed to pop modules properly.\n"); #endif Pike_compiler->num_used_modules = c->num_used_modules_save ; #ifdef PIKE_DEBUG if (compilation_depth != -1) { fprintf(stderr, "compile(): compilation_depth is %d\n", compilation_depth); } #endif /* PIKE_DEBUG */ compilation_depth=c->save_depth; #ifdef PIKE_DEBUG if (resolve_cache) free_mapping(resolve_cache); #endif resolve_cache = c->resolve_cache_save; if (error_handler) free_object(error_handler); error_handler = c->saved_handler; if (compat_handler) free_object(compat_handler); compat_handler = c->saved_compat_handler; free_string(lex.current_file); lex=c->save_lex;
86d54d2001-11-08Fredrik Hübinette (Hubbe)  verify_supporters();
eaa4da2001-10-04Fredrik Hübinette (Hubbe) } static void zap_placeholder(struct compilation *c) { /* fprintf(stderr, "Destructing placeholder.\n"); */ if (c->placeholder->storage) { yyerror("Placeholder already has storage!");
c6cf602001-12-13Martin Stjernholm #if 0 fprintf(stderr, "Placeholder already has storage!\n" "placeholder: %p, storage: %p, prog: %p\n", c->placeholder, c->placeholder->storage, c->placeholder->prog); #endif
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  debug_malloc_touch(c->placeholder); destruct(c->placeholder); } else { /* FIXME: Is this correct? */ /* It would probably be nicer if it was possible to just call * destruct on the object, but this works too. -Hubbe */ free_program(c->placeholder->prog); c->placeholder->prog = NULL; debug_malloc_touch(c->placeholder); } free_object(c->placeholder); c->placeholder=0;
86d54d2001-11-08Fredrik Hübinette (Hubbe)  verify_supporters();
eaa4da2001-10-04Fredrik Hübinette (Hubbe) } static int run_pass1(struct compilation *c) { int ret=0; debug_malloc_touch(c); run_init(c);
cb67042001-12-12Martin Stjernholm #if 0
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  CDFPRINTF((stderr, "th(%ld) compile() starting compilation_depth=%d\n", (long)th_self(),compilation_depth));
cb67042001-12-12Martin Stjernholm #endif
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  if(c->placeholder && c->placeholder->prog != null_program) Pike_error("Placeholder object is not a null_program clone!\n");
a359742001-12-16Martin Stjernholm  debug_malloc_touch(c->placeholder);
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  if(c->target && !(c->target->flags & PROGRAM_VIRGIN)) Pike_error("Placeholder program is not virgin!\n");
cb67042001-12-12Martin Stjernholm  low_start_new_program(c->target,0,0,0); c->supporter.prog = Pike_compiler->new_program;
eaa4da2001-10-04Fredrik Hübinette (Hubbe) 
cb67042001-12-12Martin Stjernholm  CDFPRINTF((stderr, "th(%ld) %p run_pass1() start: " "threads_disabled:%d, compilation_depth:%d\n", (long)th_self(), Pike_compiler->new_program, threads_disabled, compilation_depth));
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  Pike_compiler->compiler_pass=1; run_init2(c);
4d7b181999-12-07Fredrik Hübinette (Hubbe) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  if(c->placeholder)
aa68b12001-03-19Fredrik Hübinette (Hubbe)  {
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  if(c->placeholder->prog != null_program)
aa68b12001-03-19Fredrik Hübinette (Hubbe)  { yyerror("Placeholder argument is not a null_program clone!");
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  c->placeholder=0; debug_malloc_touch(c->placeholder);
aa68b12001-03-19Fredrik Hübinette (Hubbe)  }else{
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  free_program(c->placeholder->prog); add_ref(c->placeholder->prog=Pike_compiler->new_program); debug_malloc_touch(c->placeholder);
aa68b12001-03-19Fredrik Hübinette (Hubbe)  } }
cb67042001-12-12Martin Stjernholm #if 0
b3cca72001-06-14Henrik Grubbström (Grubba)  CDFPRINTF((stderr, "th(%ld) compile(): First pass\n", (long)th_self()));
cb67042001-12-12Martin Stjernholm #endif
f06a821999-07-02Henrik Grubbström (Grubba) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  do_yyparse(); /* Parse da program */
5267b71995-08-09Fredrik Hübinette (Hubbe) 
4f985f2001-06-30Martin Stjernholm  if (!Pike_compiler->new_program->num_linenumbers) { /* The lexer didn't write an initial entry. */ store_linenumber(0, lex.current_file); #ifdef DEBUG_MALLOC if(strcmp(lex.current_file->str,"-")) debug_malloc_name(Pike_compiler->new_program, lex.current_file->str, 0); #endif }
cb67042001-12-12Martin Stjernholm  CDFPRINTF((stderr, "th(%ld) %p run_pass1() done for %s\n", (long)th_self(), Pike_compiler->new_program, lex.current_file->str));
b3cca72001-06-14Henrik Grubbström (Grubba) 
86d54d2001-11-08Fredrik Hübinette (Hubbe)  ret=unlink_current_supporter(& c->supporter);
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  c->p=end_first_pass(0);
aed42d1999-12-29Martin Stjernholm 
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  run_exit(c); if(c->placeholder)
aa68b12001-03-19Fredrik Hübinette (Hubbe)  {
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  if(!c->p || (c->placeholder->storage))
aa68b12001-03-19Fredrik Hübinette (Hubbe)  {
a359742001-12-16Martin Stjernholm  debug_malloc_touch(c->placeholder);
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  zap_placeholder(c);
21fdac2001-05-02Henrik Grubbström (Grubba)  } else {
a359742001-12-16Martin Stjernholm #ifdef PIKE_DEBUG if (c->placeholder->prog != c->p) fatal("Placeholder object got wrong program after first pass.\n"); #endif debug_malloc_touch(c->placeholder);
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  c->placeholder->storage=c->p->storage_needed ? (char *)xalloc(c->p->storage_needed) :
aa68b12001-03-19Fredrik Hübinette (Hubbe)  (char *)0;
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  call_c_initializers(c->placeholder);
aa68b12001-03-19Fredrik Hübinette (Hubbe)  } }
86d54d2001-11-08Fredrik Hübinette (Hubbe)  verify_supporters();
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  return ret; }
76fb831999-07-01Henrik Grubbström (Grubba) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe) void run_pass2(struct compilation *c) { debug_malloc_touch(c);
a359742001-12-16Martin Stjernholm  debug_malloc_touch(c->placeholder);
86d54d2001-11-08Fredrik Hübinette (Hubbe) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  run_init(c); low_start_new_program(c->p,0,0,0); free_program(c->p); c->p=0;
86d54d2001-11-08Fredrik Hübinette (Hubbe) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  Pike_compiler->compiler_pass=2;
86d54d2001-11-08Fredrik Hübinette (Hubbe) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  run_init2(c);
cb67042001-12-12Martin Stjernholm  CDFPRINTF((stderr, "th(%ld) %p run_pass2() start: " "threads_disabled:%d, compilation_depth:%d\n", (long)th_self(), Pike_compiler->new_program, threads_disabled, compilation_depth));
86d54d2001-11-08Fredrik Hübinette (Hubbe)  verify_supporters();
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  do_yyparse(); /* Parse da program */
cb67042001-12-12Martin Stjernholm  CDFPRINTF((stderr, "th(%ld) %p run_pass2() done for %s\n", (long)th_self(), Pike_compiler->new_program, lex.current_file->str));
86d54d2001-11-08Fredrik Hübinette (Hubbe)  verify_supporters();
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  c->p=end_program();
86d54d2001-11-08Fredrik Hübinette (Hubbe) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  run_exit(c); }
f06a821999-07-02Henrik Grubbström (Grubba) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe) static void run_cleanup(struct compilation *c, int delayed) { debug_malloc_touch(c);
a359742001-12-16Martin Stjernholm  debug_malloc_touch(c->placeholder);
eaa4da2001-10-04Fredrik Hübinette (Hubbe) #if 0 /* FIXME */ if (threads_disabled != c->saved_threads_disabled) { fatal("compile(): threads_disabled:%d saved_threads_disabled:%d\n", threads_disabled, c->saved_threads_disabled); } #endif /* PIKE_DEBUG */
4d7b181999-12-07Fredrik Hübinette (Hubbe) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  exit_threads_disable(NULL);
ac87152000-09-25Fredrik Hübinette (Hubbe) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  CDFPRINTF((stderr,
cb67042001-12-12Martin Stjernholm  "th(%ld) %p run_cleanup(): threads_disabled:%d, compilation_depth:%d\n",
c6cf602001-12-13Martin Stjernholm  (long)th_self(), c->target, threads_disabled, compilation_depth));
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  if (!c->p) { /* fprintf(stderr, "Destructing placeholder.\n"); */
a359742001-12-16Martin Stjernholm  if(c->placeholder) { debug_malloc_touch(c->placeholder);
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  zap_placeholder(c);
a359742001-12-16Martin Stjernholm  }
b3cca72001-06-14Henrik Grubbström (Grubba) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  if(delayed && c->target)
121f822001-06-28Fredrik Hübinette (Hubbe)  {
c6cf602001-12-13Martin Stjernholm  struct program *p = c->target; /* Free the constants in the failed program, to untangle the * cyclic references we might have to this program, typically * in parent pointers in nested classes. */ if (p->constants) { int i; for (i = 0; i < p->num_constants; i++) { free_svalue(&p->constants[i].sval); p->constants[i].sval.type = T_INT; } }
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  /* We have to notify the master object that * a previous compile() actually failed, even * if we did not know it at the time */
c6cf602001-12-13Martin Stjernholm  CDFPRINTF((stderr, "th(%ld) %p unregistering failed delayed compile.\n", (long) th_self(), p)); ref_push_program(p);
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  SAFE_APPLY_MASTER("unregister",1);
ae2d702001-10-06Fredrik Hübinette (Hubbe)  pop_stack();
c6cf602001-12-13Martin Stjernholm  #ifdef PIKE_DEBUG if (p->refs > 1) { fprintf(stderr, "Warning: Program still got %d " "external refs after unregister:\n", p->refs - 1); locate_references(p); } #endif
121f822001-06-28Fredrik Hübinette (Hubbe)  }
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  } else { if (c->placeholder) {
c6cf602001-12-13Martin Stjernholm  if (c->target->flags & PROGRAM_FINISHED) { JMP_BUF rec; /* Initialize the placeholder. */
a359742001-12-16Martin Stjernholm #ifdef PIKE_DEBUG if (c->placeholder->prog != c->p) fatal("Placeholder object got wrong program after second pass.\n"); #endif
c6cf602001-12-13Martin Stjernholm  if(SETJMP(rec)) { struct svalue thrown = throw_value;
a359742001-12-16Martin Stjernholm  debug_malloc_touch(c->placeholder);
c6cf602001-12-13Martin Stjernholm  throw_value.type = T_INT; push_svalue(&thrown); low_safe_apply_handler("compile_exception", error_handler, compat_handler, 1);
9f516a2001-12-16Martin Stjernholm  if (SAFE_IS_ZERO(sp-1)) yy_describe_exception(&thrown);
c6cf602001-12-13Martin Stjernholm  pop_stack(); free_svalue(&thrown); zap_placeholder(c); }else{
a359742001-12-16Martin Stjernholm  debug_malloc_touch(c->placeholder);
c6cf602001-12-13Martin Stjernholm  call_pike_initializers(c->placeholder,0); } UNSETJMP(rec);
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  }
a359742001-12-16Martin Stjernholm  else { debug_malloc_touch(c->placeholder); zap_placeholder(c); }
aed42d1999-12-29Martin Stjernholm  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
86d54d2001-11-08Fredrik Hübinette (Hubbe)  verify_supporters(); }
c6cf602001-12-13Martin Stjernholm static int call_delayed_pass2(struct compilation *cc, int finish)
86d54d2001-11-08Fredrik Hübinette (Hubbe) {
c6cf602001-12-13Martin Stjernholm  int ok = 0;
86d54d2001-11-08Fredrik Hübinette (Hubbe)  debug_malloc_touch(cc);
cb67042001-12-12Martin Stjernholm 
c6cf602001-12-13Martin Stjernholm  CDFPRINTF((stderr, "th(%ld) %p %s delayed compile.\n", (long) th_self(), cc->p, finish ? "continuing" : "cleaning up"));
cb67042001-12-12Martin Stjernholm 
c6cf602001-12-13Martin Stjernholm  if(finish && cc->p) run_pass2(cc);
86d54d2001-11-08Fredrik Hübinette (Hubbe)  run_cleanup(cc,1); debug_malloc_touch(cc);
c6cf602001-12-13Martin Stjernholm 
86d54d2001-11-08Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG if(cc->supporter.dependants) fatal("Que???\n"); #endif
c6cf602001-12-13Martin Stjernholm  if(cc->p) { ok = finish; free_program(cc->p); /* later */ } CDFPRINTF((stderr, "th(%ld) %p delayed compile %s.\n", (long) th_self(), cc->target, ok ? "done" : "failed"));
86d54d2001-11-08Fredrik Hübinette (Hubbe)  free_compilation(cc); verify_supporters();
c6cf602001-12-13Martin Stjernholm  return ok;
eaa4da2001-10-04Fredrik Hübinette (Hubbe) }
5c8e891995-10-29Fredrik Hübinette (Hubbe) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe) struct program *compile(struct pike_string *aprog, struct object *ahandler,/* error handler */ int amajor, int aminor, struct program *atarget, struct object *aplaceholder) {
c6cf602001-12-13Martin Stjernholm  int delay, dependants_ok = 1;
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  struct program *ret;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  ONERROR tmp; #endif struct compilation *c=ALLOC_STRUCT(compilation);
86d54d2001-11-08Fredrik Hübinette (Hubbe)  verify_supporters();
a359742001-12-16Martin Stjernholm  CDFPRINTF((stderr, "th(%ld) %p compile() enter, placeholder=%p\n", (long) th_self(), atarget, aplaceholder));
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  debug_malloc_touch(c); add_ref(c->prog=aprog); if((c->handler=ahandler)) add_ref(ahandler); c->major=amajor; c->minor=aminor; if((c->target=atarget)) add_ref(atarget); if((c->placeholder=aplaceholder)) add_ref(aplaceholder); c->default_module.type=T_INT; if(c->handler) { safe_apply(c->handler,"get_default_module",0);
9f516a2001-12-16Martin Stjernholm  if(SAFE_IS_ZERO(Pike_sp-1))
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  { pop_stack(); ref_push_mapping(get_builtin_constants()); } }else{ ref_push_mapping(get_builtin_constants());
4751d41998-04-14Henrik Grubbström (Grubba)  }
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  free_svalue(& c->default_module); c->default_module=Pike_sp[-1]; Pike_sp--;
ea32c11998-04-13Henrik Grubbström (Grubba) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  SET_ONERROR(tmp, fatal_on_error,"Compiler exited with longjump!\n");
05590d1998-04-23Fredrik Hübinette (Hubbe) #endif
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  low_init_threads_disable(); c->saved_threads_disabled = threads_disabled;
86d54d2001-11-08Fredrik Hübinette (Hubbe)  init_supporter(& c->supporter,
c6cf602001-12-13Martin Stjernholm  (supporter_callback *) call_delayed_pass2,
86d54d2001-11-08Fredrik Hübinette (Hubbe)  (void *)c);
eaa4da2001-10-04Fredrik Hübinette (Hubbe) 
86d54d2001-11-08Fredrik Hübinette (Hubbe)  delay=run_pass1(c) && c->p;
c6cf602001-12-13Martin Stjernholm  dependants_ok = call_dependants(& c->supporter, !!c->p );
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  /* FIXME */
0f19431999-11-29Fredrik Hübinette (Hubbe)  UNSET_ONERROR(tmp);
0ee27b1998-04-14Fredrik Hübinette (Hubbe) #endif
269dd92001-05-23Henrik Grubbström (Grubba) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  if(delay) {
a359742001-12-16Martin Stjernholm  CDFPRINTF((stderr, "th(%ld) %p compile() finish later, placeholder=%p.\n", (long) th_self(), c->target, c->placeholder));
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  /* finish later */
ae2d702001-10-06Fredrik Hübinette (Hubbe)  add_ref(c->p);
86d54d2001-11-08Fredrik Hübinette (Hubbe)  verify_supporters();
ae2d702001-10-06Fredrik Hübinette (Hubbe)  return c->p; /* freed later */
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  }else{ /* finish now */ if(c->p) run_pass2(c); debug_malloc_touch(c); run_cleanup(c,0); ret=c->p;
269dd92001-05-23Henrik Grubbström (Grubba) 
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  debug_malloc_touch(c); free_compilation(c);
c6cf602001-12-13Martin Stjernholm  if (!dependants_ok) { CDFPRINTF((stderr, "th(%ld) %p compile() reporting failure " "since a dependant failed.\n", (long) th_self(), c->target)); if (ret) free_program(ret);
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  throw_error_object(low_clone(compilation_error_program), 0, 0, 0, "Compilation failed.\n");
c6cf602001-12-13Martin Stjernholm  } if(!ret) { CDFPRINTF((stderr, "th(%ld) %p compile() failed.\n", (long) th_self(), c->target)); throw_error_object(low_clone(compilation_error_program), 0, 0, 0, "Compilation failed.\n"); }
ae2d702001-10-06Fredrik Hübinette (Hubbe)  debug_malloc_touch(ret);
86d54d2001-11-08Fredrik Hübinette (Hubbe)  verify_supporters();
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  return ret;
aa68b12001-03-19Fredrik Hübinette (Hubbe)  }
eaa4da2001-10-04Fredrik Hübinette (Hubbe) }
0ee27b1998-04-14Fredrik Hübinette (Hubbe) 
1ef5572000-08-30Henrik Grubbström (Grubba) PMOD_EXPORT int pike_add_function2(char *name, void (*cfun)(INT32), char *type, unsigned INT8 flags, unsigned INT16 opt_flags)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
e964ae1998-04-08Fredrik Hübinette (Hubbe)  int ret;
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_string *name_tmp; struct pike_type *type_tmp;
5267b71995-08-09Fredrik Hübinette (Hubbe)  union idptr tmp;
27ae842000-02-07Per Hedbor 
5267b71995-08-09Fredrik Hübinette (Hubbe)  name_tmp=make_shared_string(name); type_tmp=parse_type(type); if(cfun) { tmp.c_fun=cfun;
e964ae1998-04-08Fredrik Hübinette (Hubbe)  ret=define_function(name_tmp, type_tmp, flags, IDENTIFIER_C_FUNCTION,
1ef5572000-08-30Henrik Grubbström (Grubba)  &tmp, opt_flags);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{
e964ae1998-04-08Fredrik Hübinette (Hubbe)  ret=define_function(name_tmp, type_tmp, flags, IDENTIFIER_C_FUNCTION,
1ef5572000-08-30Henrik Grubbström (Grubba)  0, opt_flags);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } free_string(name_tmp);
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(type_tmp);
e964ae1998-04-08Fredrik Hübinette (Hubbe)  return ret;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT int quick_add_function(char *name,
1ef5572000-08-30Henrik Grubbström (Grubba)  int name_length, void (*cfun)(INT32), char *type, int type_length, unsigned INT8 flags, unsigned INT16 opt_flags)
45ee5d1999-02-10Fredrik Hübinette (Hubbe) { int ret;
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_string *name_tmp; struct pike_type *type_tmp;
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  union idptr tmp;
8aae6d1999-08-19Fredrik Hübinette (Hubbe) /* fprintf(stderr,"ADD_FUNC: %s\n",name); */
8a2a522001-03-03Henrik Grubbström (Grubba)  name_tmp = make_shared_binary_string(name, name_length); #ifdef USE_PIKE_TYPE type_tmp = make_pike_type(type); #else /* !USE_PIKE_TYPE */ type_tmp = make_shared_binary_string(type, type_length); #endif /* USE_PIKE_TYPE */
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  if(cfun) { tmp.c_fun=cfun; ret=define_function(name_tmp, type_tmp, flags, IDENTIFIER_C_FUNCTION,
1ef5572000-08-30Henrik Grubbström (Grubba)  &tmp, opt_flags);
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  }else{ ret=define_function(name_tmp, type_tmp, flags, IDENTIFIER_C_FUNCTION,
1ef5572000-08-30Henrik Grubbström (Grubba)  0, opt_flags);
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  } free_string(name_tmp);
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(type_tmp);
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  return ret; }
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
be478c1997-08-30Henrik Grubbström (Grubba) void check_all_programs(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) { struct program *p; for(p=first_program;p;p=p->next)
624d091996-02-24Fredrik Hübinette (Hubbe)  check_program(p);
5d0e211997-04-10Fredrik Hübinette (Hubbe)  #ifdef FIND_FUNCTION_HASHSIZE { unsigned long e; for(e=0;e<FIND_FUNCTION_HASHSIZE;e++) { if(cache[e].name) { check_string(cache[e].name); if(cache[e].id<0 || cache[e].id > current_program_id)
1f64351997-04-14Fredrik Hübinette (Hubbe)  fatal("Error in find_function_cache[%ld].id\n",(long)e);
5d0e211997-04-10Fredrik Hübinette (Hubbe) 
d2a0841997-04-10Fredrik Hübinette (Hubbe)  if(cache[e].fun < -1 || cache[e].fun > 65536)
1f64351997-04-14Fredrik Hübinette (Hubbe)  fatal("Error in find_function_cache[%ld].fun\n",(long)e);
5d0e211997-04-10Fredrik Hübinette (Hubbe)  } } } #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) } #endif
90e9781999-01-31Fredrik Hübinette (Hubbe) #undef THIS
60d9872000-03-23Fredrik Hübinette (Hubbe) #define THIS ((struct pike_trampoline *)(CURRENT_STORAGE))
4218011999-01-31Fredrik Hübinette (Hubbe) struct program *pike_trampoline_program=0; static void apply_trampoline(INT32 args) {
a4a1722000-12-05Per Hedbor  Pike_error("Internal error: Trampoline magic failed!\n");
4218011999-01-31Fredrik Hübinette (Hubbe) }
23dec62001-09-02Henrik Grubbström (Grubba) static void not_trampoline(INT32 args) { pop_n_elems(args); if (!THIS->frame || !THIS->frame->current_object || !THIS->frame->current_object->prog) { push_int(1); } else { push_int(0); } }
90e9781999-01-31Fredrik Hübinette (Hubbe) static void init_trampoline(struct object *o) { THIS->frame=0; } static void exit_trampoline(struct object *o) { if(THIS->frame) {
fa21262001-08-31Fredrik Hübinette (Hubbe)  free_pike_scope(THIS->frame);
90e9781999-01-31Fredrik Hübinette (Hubbe)  THIS->frame=0; } } static void gc_check_frame(struct pike_frame *f) {
d9d6f02001-06-30Martin Stjernholm  if(f->flags & PIKE_FRAME_MALLOCED_LOCALS)
90e9781999-01-31Fredrik Hübinette (Hubbe)  {
d9d6f02001-06-30Martin Stjernholm  if(f->current_object)
2eb2d62001-08-20Martin Stjernholm  debug_gc_check2(f->current_object, T_PIKE_FRAME, f,
d9d6f02001-06-30Martin Stjernholm  " as current_object in trampoline frame"); if(f->context.prog)
2eb2d62001-08-20Martin Stjernholm  debug_gc_check2(f->context.prog, T_PIKE_FRAME, f,
d9d6f02001-06-30Martin Stjernholm  " as context.prog in trampoline frame"); if(f->context.parent)
2eb2d62001-08-20Martin Stjernholm  debug_gc_check2(f->context.parent, T_PIKE_FRAME, f,
d9d6f02001-06-30Martin Stjernholm  " as context.parent in trampoline frame");
9ddbf22001-05-10Fredrik Hübinette (Hubbe)  if(f->flags & PIKE_FRAME_MALLOCED_LOCALS)
2eb2d62001-08-20Martin Stjernholm  debug_gc_check_svalues2(f->locals, f->num_locals, T_PIKE_FRAME, f,
d9d6f02001-06-30Martin Stjernholm  " in locals of trampoline frame");
2eb2d62001-08-20Martin Stjernholm  if(f->scope && !debug_gc_check2(f->scope, T_PIKE_FRAME, f,
d9d6f02001-06-30Martin Stjernholm  " as scope frame of trampoline frame")) gc_check_frame(f->scope);
90e9781999-01-31Fredrik Hübinette (Hubbe)  } } static void gc_check_trampoline(struct object *o) {
d9d6f02001-06-30Martin Stjernholm  if (THIS->frame && !debug_gc_check2(THIS->frame, T_OBJECT, o, " as trampoline frame")) gc_check_frame(THIS->frame);
90e9781999-01-31Fredrik Hübinette (Hubbe) }
a5bd2b2000-06-10Martin Stjernholm static void gc_recurse_frame(struct pike_frame *f)
90e9781999-01-31Fredrik Hübinette (Hubbe) {
e2d9e62000-06-10Martin Stjernholm  if(f->current_object) gc_recurse_object(f->current_object); if(f->context.prog) gc_recurse_program(f->context.prog); if(f->context.parent) gc_recurse_object(f->context.parent);
9ddbf22001-05-10Fredrik Hübinette (Hubbe)  if(f->flags & PIKE_FRAME_MALLOCED_LOCALS) gc_recurse_svalues(f->locals,f->num_locals);
a5bd2b2000-06-10Martin Stjernholm  if(f->scope) gc_recurse_frame(f->scope);
90e9781999-01-31Fredrik Hübinette (Hubbe) }
a5bd2b2000-06-10Martin Stjernholm static void gc_recurse_trampoline(struct object *o)
90e9781999-01-31Fredrik Hübinette (Hubbe) {
7872612001-07-02Martin Stjernholm  if (THIS->frame) gc_recurse_frame(THIS->frame);
90e9781999-01-31Fredrik Hübinette (Hubbe) }
eaa4da2001-10-04Fredrik Hübinette (Hubbe) /* This placeholder should is used * in the first compiler pass to take the place * of unknown things */ struct program *placeholder_program; struct object *placeholder_object; void placeholder_index(INT32 args) { pop_n_elems(args); ref_push_object(Pike_fp->current_object); }
4218011999-01-31Fredrik Hübinette (Hubbe) void init_program(void) {
51059b1999-12-26Henrik Grubbström (Grubba)  int i; struct svalue key; struct svalue val;
286afb2001-02-05Henrik Grubbström (Grubba)  struct svalue id;
1c1c5e2001-04-08Fredrik Hübinette (Hubbe)  init_program_blocks();
9e26861999-12-31Martin Stjernholm  MAKE_CONSTANT_SHARED_STRING(this_program_string,"this_program");
286afb2001-02-05Henrik Grubbström (Grubba)  lfun_ids = allocate_mapping(NUM_LFUNS);
51059b1999-12-26Henrik Grubbström (Grubba)  lfun_types = allocate_mapping(NUM_LFUNS); for (i=0; i < NUM_LFUNS; i++) {
286afb2001-02-05Henrik Grubbström (Grubba)  lfun_strings[i] = make_shared_string(lfun_names[i]);
aad99b2001-03-28Fredrik Hübinette (Hubbe)  id.type = T_INT;
286afb2001-02-05Henrik Grubbström (Grubba)  id.u.integer = i;
aad99b2001-03-28Fredrik Hübinette (Hubbe)  key.type = T_STRING;
286afb2001-02-05Henrik Grubbström (Grubba)  key.u.string = lfun_strings[i]; mapping_insert(lfun_ids, &key, &id);
aad99b2001-03-28Fredrik Hübinette (Hubbe)  val.type = T_TYPE;
4b9d802001-02-21Henrik Grubbström (Grubba)  val.u.type = make_pike_type(raw_lfun_types[i]);
51059b1999-12-26Henrik Grubbström (Grubba)  mapping_insert(lfun_types, &key, &val);
4b9d802001-02-21Henrik Grubbström (Grubba)  free_type(val.u.type);
51059b1999-12-26Henrik Grubbström (Grubba)  }
4218011999-01-31Fredrik Hübinette (Hubbe)  start_new_program();
bad5162000-06-23Fredrik Hübinette (Hubbe)  debug_malloc_touch(Pike_compiler->fake_object); debug_malloc_touch(Pike_compiler->fake_object->storage);
90e9781999-01-31Fredrik Hübinette (Hubbe)  ADD_STORAGE(struct pike_trampoline);
4218011999-01-31Fredrik Hübinette (Hubbe)  add_function("`()",apply_trampoline,"function(mixed...:mixed)",0);
23dec62001-09-02Henrik Grubbström (Grubba)  add_function("`!",not_trampoline,"function(:int)",0);
90e9781999-01-31Fredrik Hübinette (Hubbe)  set_init_callback(init_trampoline); set_exit_callback(exit_trampoline); set_gc_check_callback(gc_check_trampoline);
a5bd2b2000-06-10Martin Stjernholm  set_gc_recurse_callback(gc_recurse_trampoline);
bad5162000-06-23Fredrik Hübinette (Hubbe)  debug_malloc_touch(Pike_compiler->fake_object); debug_malloc_touch(Pike_compiler->fake_object->storage);
4218011999-01-31Fredrik Hübinette (Hubbe)  pike_trampoline_program=end_program();
aa68b12001-03-19Fredrik Hübinette (Hubbe)  { struct svalue s; start_new_program(); null_program=end_program(); s.type=T_PROGRAM; s.u.program=null_program; low_add_constant("__null_program",&s);
c2be512001-03-21Fredrik Hübinette (Hubbe)  debug_malloc_touch(null_program);
aa68b12001-03-19Fredrik Hübinette (Hubbe)  }
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  { struct svalue s; start_new_program(); add_function("`()",placeholder_index,"function(mixed...:object)",0); add_function("`[]",placeholder_index,"function(mixed:object)",0); placeholder_program=end_program(); placeholder_object=fast_clone_object(placeholder_program,0); s.type=T_OBJECT; s.u.object=placeholder_object; low_add_constant("__placeholder_object",&s); debug_malloc_touch(placeholder_object); }
4218011999-01-31Fredrik Hübinette (Hubbe) }
be478c1997-08-30Henrik Grubbström (Grubba) void cleanup_program(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) { int e;
51059b1999-12-26Henrik Grubbström (Grubba) 
9e26861999-12-31Martin Stjernholm  free_string(this_program_string);
51059b1999-12-26Henrik Grubbström (Grubba)  free_mapping(lfun_types);
286afb2001-02-05Henrik Grubbström (Grubba)  free_mapping(lfun_ids); for (e=0; e < NUM_LFUNS; e++) { free_string(lfun_strings[e]); }
61e9a01998-01-25Fredrik Hübinette (Hubbe) #ifdef FIND_FUNCTION_HASHSIZE
5267b71995-08-09Fredrik Hübinette (Hubbe)  for(e=0;e<FIND_FUNCTION_HASHSIZE;e++) { if(cache[e].name) { free_string(ca