pike.git / src / builtin.cmod

version» Context lines:

pike.git/src/builtin.cmod:1835:    *!    *! @item @expr{void _destruct()@}/@expr{void destroy()@}    *! These lfuns will not be present as the act of them    *! being proxied would likely confuse the proxied object.    *! @enddl    *!    *! @note    *! The same proxy class will be returned if this function    *! is called with the same program multiple times.    */ - PIKEFUN program ProxyFactory(program p) -  optflags OPT_TRY_OPTIMIZE; -  rawtype tFunc(tSetvar(0, tPrg(tObj)), tVar(0)); + PMOD_EXPORT struct program *proxy_factory(struct program *p, +  const char *var_name, +  int program_id)   {    struct array *a;    int i = 0;    struct pike_type *fun_type;    union idptr ptr;    int j;    struct svalue *cached; -  +  int var_flags = ID_LOCAL;       ref_push_program(p);    if (proxy_lookup &&    (cached = low_mapping_lookup(proxy_lookup, Pike_sp-1))) { -  push_svalue(cached); -  return; +  /* NB: This cache isn't a 100% sound, as it doesn't +  * take into account var_name and program_id. +  * On the other hand they are only available by +  * calling this function directly, ie by C-code +  * that presumably knows what it is doing. +  */ +  pop_stack(); +  if (TYPEOF(*cached) == PIKE_T_PROGRAM) { +  add_ref(cached->u.program); +  return cached->u.program;    } -  +  return NULL; +  }    /* NB: Keep the program on the stack, we will use it    * later when we update the proxy_lookup cache.    */       enter_compiler(NULL, 0); -  +  if (program_id) { +  START_NEW_PROGRAM_ID (STDIO_FD_REF); +  } else {    start_new_program(); -  +  }       /* Constant #0: The mapping from local reference # to external d:o. */    /* NB: Over allocation. */    /* NB: For the lookup to work as intended all functions that use    * this array *need* to be declared ID_LOCAL to avoid being    * renumbered when overloaded.    */    push_int((p->num_identifier_references+1) * 3);    push_int(-1);    f_allocate(2);    a = Pike_sp[-1].u.array;    store_constant(Pike_sp-1, 0, NULL);       /* Constant #1: The program that we intend to wrap. */    ref_push_program(p);    store_constant(Pike_sp-1, 0, NULL);       /* Reference #0: The variable that we store the proxied object in. */    /* NB: Use a name that will not clash. */ -  +  if (var_name) { +  push_text(var_name); +  var_flags = ID_LOCAL; +  } else {    push_string(make_shared_static_string("proxied_obj\0", 12, eightbit)); -  +  var_flags = ID_LOCAL|ID_PROTECTED|ID_PRIVATE|ID_HIDDEN; +  }    type_stack_mark();    push_object_type(0, p->id);    fun_type = pop_unfinished_type(); -  define_variable(Pike_sp[-1].u.string, fun_type, -  ID_LOCAL|ID_PROTECTED|ID_PRIVATE|ID_HIDDEN); +  define_variable(Pike_sp[-1].u.string, fun_type, var_flags);    free_type(fun_type);    pop_stack();       /* Add proxy functions for the references. */    for (i = 0; i < p->num_identifier_references; i++) {    struct reference *ref = PTR_FROM_INT(p, i);    struct identifier *id;    if (ref->id_flags & ID_HIDDEN) continue;    id = ID_FROM_PTR(p, ref);    if (IDENTIFIER_IS_ALIAS(id->identifier_flags)) {
pike.git/src/builtin.cmod:2017:    fun_type = pop_unfinished_type();    ptr.c_fun = f_proxy_create;    j = define_function(lfun_strings[LFUN_CREATE], fun_type, ID_PROTECTED,    IDENTIFIER_C_FUNCTION, &ptr, 0);    free_type(fun_type);       p = end_program();    exit_compiler();       if (p) { -  push_program(p); +  ref_push_program(p);       if (!proxy_lookup) {    proxy_lookup = allocate_mapping(10);    mapping_set_flags(proxy_lookup, MAPPING_WEAK_INDICES);    }       mapping_insert(proxy_lookup, Pike_sp-2, Pike_sp-1); -  +  +  pop_stack(); +  } +  +  pop_stack(); +  +  return p; + } + PIKEFUN program ProxyFactory(program p) +  optflags OPT_TRY_OPTIMIZE; +  rawtype tFunc(tSetvar(0, tPrg(tObj)), tVar(0)); + { +  struct program *res = proxy_factory(p, NULL, 0); +  +  if (res) { +  push_program(res);    } else {    push_undefined();    }   }      /*! @decl int(8..8)|int(16..16)|int(32..32) width(string s)    *! @belongs String    *!    *! Returns the width of a string.    *!