e576bb2002-10-11Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information.
ab6f442011-04-25Martin Stjernholm || $Id$
e576bb2002-10-11Martin Nilsson */
aedfb12002-10-09Martin Nilsson 
07513e1996-10-04Fredrik Hübinette (Hubbe) #include "global.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "constants.h"
bb55f81997-03-16Fredrik Hübinette (Hubbe) #include "pike_macros.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "program.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "pike_types.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "stralloc.h"
9aa6fa1997-05-19Fredrik Hübinette (Hubbe) #include "pike_memory.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "interpret.h"
244ce61997-01-26Fredrik Hübinette (Hubbe) #include "mapping.h"
b2d3e42000-12-01Fredrik Hübinette (Hubbe) #include "pike_error.h"
37775c2004-04-06Martin Nilsson #include "pike_security.h"
5e83442008-05-11Martin Stjernholm #include "gc.h"
45ee5d1999-02-10Fredrik Hübinette (Hubbe) #include "block_alloc.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) 
5f61da2000-04-13Fredrik Hübinette (Hubbe) struct mapping *builtin_constants = 0;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
1e93882003-08-20Martin Stjernholm #ifdef PIKE_DEBUG struct callable *first_callable = NULL; #endif
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT struct mapping *get_builtin_constants(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
244ce61997-01-26Fredrik Hübinette (Hubbe)  return builtin_constants;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
06983f1996-09-22Fredrik Hübinette (Hubbe) void low_add_efun(struct pike_string *name, struct svalue *fun)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
244ce61997-01-26Fredrik Hübinette (Hubbe)  struct svalue s;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
244ce61997-01-26Fredrik Hübinette (Hubbe)  s.type=T_STRING; s.subtype=0; s.u.string=name;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
244ce61997-01-26Fredrik Hübinette (Hubbe)  if(fun) { mapping_insert(builtin_constants, &s, fun); }else{ map_delete(builtin_constants, &s);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
0929a02002-09-12Marcus Comstedt void low_add_constant(const char *name, struct svalue *fun)
cecf511997-02-06Fredrik Hübinette (Hubbe) { struct pike_string *p; p=make_shared_string(name); low_add_efun(p, fun); free_string(p); }
7abd892004-12-30Henrik Grubbström (Grubba) void add_pike_string_constant(const char *name, const char *str, int len) { struct pike_string *key = make_shared_string(name); struct pike_string *val = make_shared_binary_string(str, len); mapping_string_insert_string(builtin_constants, key, val); free_string(val); free_string(key); }
0929a02002-09-12Marcus Comstedt PMOD_EXPORT void add_global_program(const char *name, struct program *p)
cecf511997-02-06Fredrik Hübinette (Hubbe) { struct svalue s; s.type=T_PROGRAM; s.subtype=0; s.u.program=p;
ac0bdd2007-04-17Henrik Grubbström (Grubba)  low_add_constant(name, p?&s:NULL);
cecf511997-02-06Fredrik Hübinette (Hubbe) }
1e93882003-08-20Martin Stjernholm #undef INIT_BLOCK #define INIT_BLOCK(X) do { \ DO_IF_DEBUG (DOUBLELINK (first_callable, X)); \ } while (0)
45ee5d1999-02-10Fredrik Hübinette (Hubbe) #undef EXIT_BLOCK #define EXIT_BLOCK(X) do { \
1e93882003-08-20Martin Stjernholm  DO_IF_DEBUG (DOUBLEUNLINK (first_callable, X)); \
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(X->type); \
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  free_string(X->name); \
d9a93b2001-07-01Fredrik Hübinette (Hubbe)  X->name=0; \
45637c2001-04-07Fredrik Hübinette (Hubbe)  EXIT_PIKE_MEMOBJ(X); \
45ee5d1999-02-10Fredrik Hübinette (Hubbe) }while(0)
1e93882003-08-20Martin Stjernholm 
3aab372002-11-24Martin Stjernholm BLOCK_ALLOC_FILL_PAGES(callable,2)
45ee5d1999-02-10Fredrik Hübinette (Hubbe) 
c39e432001-08-02Fredrik Hübinette (Hubbe) int global_callable_flags=0;
45ee5d1999-02-10Fredrik Hübinette (Hubbe) /* Eats one ref to 'type' and 'name' */
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT struct callable *low_make_callable(c_fun fun,
167da22008-06-18Henrik Grubbström (Grubba)  struct pike_string *name, struct pike_type *type, int flags, optimize_fun optimize, docode_fun docode)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  struct callable *f=alloc_callable();
45637c2001-04-07Fredrik Hübinette (Hubbe)  INIT_PIKE_MEMOBJ(f);
5267b71995-08-09Fredrik Hübinette (Hubbe)  f->function=fun;
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  f->name=name; f->type=type;
48a6242003-05-31Martin Stjernholm  f->prog=Pike_compiler->new_program;
5267b71995-08-09Fredrik Hübinette (Hubbe)  f->flags=flags;
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  f->docode=docode; f->optimize=optimize;
c39e432001-08-02Fredrik Hübinette (Hubbe)  f->internal_flags = global_callable_flags;
044c621999-04-14Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG {
167da22008-06-18Henrik Grubbström (Grubba)  struct pike_type *z = NULL; add_ref(type); type = check_splice_call(name, type, 1, mixed_type_string, NULL, CALL_INHIBIT_WARNINGS); if (type) { z = new_get_return_type(type, CALL_INHIBIT_WARNINGS); free_type(type); }
babd872001-02-23Henrik Grubbström (Grubba)  f->may_return_void = (z == void_type_string);
a1fd452002-12-12Martin Nilsson  if(!z) Pike_fatal("Function has no valid return type.\n");
3699402001-02-20Henrik Grubbström (Grubba)  free_type(z);
044c621999-04-14Fredrik Hübinette (Hubbe)  }
d9a93b2001-07-01Fredrik Hübinette (Hubbe)  f->runs=0;
044c621999-04-14Fredrik Hübinette (Hubbe) #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  return f; }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT struct callable *make_callable(c_fun fun,
0929a02002-09-12Marcus Comstedt  const char *name, const char *type,
7e877a2003-04-02Martin Stjernholm  int flags,
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  optimize_fun optimize, docode_fun docode)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
babd872001-02-23Henrik Grubbström (Grubba)  return low_make_callable(fun, make_shared_string(name), parse_type(type), flags, optimize, docode);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
0929a02002-09-12Marcus Comstedt PMOD_EXPORT struct callable *add_efun2(const char *name,
4d7b181999-12-07Fredrik Hübinette (Hubbe)  c_fun fun,
0929a02002-09-12Marcus Comstedt  const char *type,
7e877a2003-04-02Martin Stjernholm  int flags,
4d7b181999-12-07Fredrik Hübinette (Hubbe)  optimize_fun optimize, docode_fun docode)
5267b71995-08-09Fredrik Hübinette (Hubbe) { struct svalue s;
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *n;
4d7b181999-12-07Fredrik Hübinette (Hubbe)  struct callable *ret;
5267b71995-08-09Fredrik Hübinette (Hubbe)  n=make_shared_string(name); s.type=T_FUNCTION;
bdb5091996-09-25Fredrik Hübinette (Hubbe)  s.subtype=FUNCTION_BUILTIN;
4d7b181999-12-07Fredrik Hübinette (Hubbe)  ret=s.u.efun=make_callable(fun, name, type, flags, optimize, docode);
5267b71995-08-09Fredrik Hübinette (Hubbe)  low_add_efun(n, &s); free_svalue(&s); free_string(n);
4d7b181999-12-07Fredrik Hübinette (Hubbe)  return ret;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
7e877a2003-04-02Martin Stjernholm PMOD_EXPORT struct callable *add_efun(const char *name, c_fun fun, const char *type, int flags)
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) {
4d7b181999-12-07Fredrik Hübinette (Hubbe)  return add_efun2(name,fun,type,flags,0,0);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) }
0929a02002-09-12Marcus Comstedt PMOD_EXPORT struct callable *quick_add_efun(const char *name, ptrdiff_t name_length,
51f0e02000-08-10Henrik Grubbström (Grubba)  c_fun fun,
0929a02002-09-12Marcus Comstedt  const char *type, ptrdiff_t type_length,
7e877a2003-04-02Martin Stjernholm  int flags,
51f0e02000-08-10Henrik Grubbström (Grubba)  optimize_fun optimize, docode_fun docode)
45ee5d1999-02-10Fredrik Hübinette (Hubbe) { struct svalue s;
3699402001-02-20Henrik Grubbström (Grubba)  struct pike_string *n; struct pike_type *t;
4d7b181999-12-07Fredrik Hübinette (Hubbe)  struct callable *ret;
45ee5d1999-02-10Fredrik Hübinette (Hubbe) 
3866ad2004-05-18David Gourdelier #ifdef PIKE_DEBUG
85649e2004-01-13Martin Nilsson  if(simple_mapping_string_lookup(builtin_constants, name)) Pike_fatal("%s added as efun more than once.\n", name); #endif
8a2a522001-03-03Henrik Grubbström (Grubba)  n = make_shared_binary_string(name, name_length); t = make_pike_type(type);
45ee5d1999-02-10Fredrik Hübinette (Hubbe) #ifdef DEBUG check_type_string(t); #endif s.type=T_FUNCTION; s.subtype=FUNCTION_BUILTIN; add_ref(n);
4d7b181999-12-07Fredrik Hübinette (Hubbe)  ret=s.u.efun=low_make_callable(fun, n, t, flags, optimize, docode);
85649e2004-01-13Martin Nilsson  mapping_string_insert(builtin_constants, n, &s);
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  free_svalue(&s); free_string(n);
4d7b181999-12-07Fredrik Hübinette (Hubbe)  return ret;
45ee5d1999-02-10Fredrik Hübinette (Hubbe) }
1eb9852008-05-11Martin Stjernholm PMOD_EXPORT void visit_callable (struct callable *c, int action)
5e83442008-05-11Martin Stjernholm { switch (action) { #ifdef PIKE_DEBUG default: Pike_fatal ("Unknown visit action %d.\n", action); case VISIT_NORMAL: case VISIT_COMPLEX_ONLY: break; #endif case VISIT_COUNT_BYTES: mc_counted_bytes += sizeof (struct callable); break; } if (!(action & VISIT_COMPLEX_ONLY)) { visit_type_ref (c->type, REF_TYPE_NORMAL); visit_string_ref (c->name, REF_TYPE_NORMAL); } /* Looks like the c->prog isn't refcounted..? */ /* visit_program_ref (c->prog, REF_TYPE_NORMAL); */ }
d9a93b2001-07-01Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG void present_constant_profiling(void) { struct callable_block *b;
8a46702001-08-31Martin Stjernholm  size_t e;
d9a93b2001-07-01Fredrik Hübinette (Hubbe)  for(b=callable_blocks;b;b=b->next) { for(e=0;e<NELEM(b->x);e++) { if(b->x[e].name) {
8a46702001-08-31Martin Stjernholm  fprintf(stderr,"%010ld @E@: %s\n",b->x[e].runs, b->x[e].name->str);
d9a93b2001-07-01Fredrik Hübinette (Hubbe)  } } } } #endif
d8073b2002-01-27Martin Stjernholm void init_builtin_constants(void) {
e8b3c22006-01-14Martin Nilsson  builtin_constants = allocate_mapping(300);
d8073b2002-01-27Martin Stjernholm }
1c5b342003-03-26Martin Nilsson void exit_builtin_constants(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
5b7b061999-04-08Fredrik Hübinette (Hubbe) #ifdef DO_PIKE_CLEANUP
244ce61997-01-26Fredrik Hübinette (Hubbe)  if(builtin_constants)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
244ce61997-01-26Fredrik Hübinette (Hubbe)  free_mapping(builtin_constants); builtin_constants=0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
5b7b061999-04-08Fredrik Hübinette (Hubbe) #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) }