Branch: Tag:

2003-08-03

2003-08-03 02:34:46 by Martin Stjernholm <mast@lysator.liu.se>

Adapted this_object() to the fact that it doesn't always access the
lexically surrounding parent objects.

Rev: src/builtin_functions.c:1.499
Rev: src/interpret_functions.h:1.153

2:   || 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. - || $Id: builtin_functions.c,v 1.498 2003/08/02 01:08:43 mast Exp $ + || $Id: builtin_functions.c,v 1.499 2003/08/03 02:34:46 mast Exp $   */      #include "global.h" - RCSID("$Id: builtin_functions.c,v 1.498 2003/08/02 01:08:43 mast Exp $"); + RCSID("$Id: builtin_functions.c,v 1.499 2003/08/03 02:34:46 mast Exp $");   #include "interpret.h"   #include "svalue.h"   #include "pike_macros.h"
1841:    *!    *! @[level] might be used to access the object of a surrounding    *! class: The object at level 0 is the current object, the object -  *! at level 1 is the one belonging to the class surrounding the -  *! current class, and so on. +  *! at level 1 is the one belonging to the class that surrounds +  *! the class that the object comes from, and so on. +  *! +  *! @note +  *! As opposed to a qualified @expr{this@} reference such as +  *! @expr{global::this@}, this function doesn't always access the +  *! objects belonging to the lexically surrounding classes. If the +  *! class containing the call has been inherited then the objects +  *! surrounding the inheriting class are accessed.    */   void f_this_object(INT32 args)   { -  int level; +  int level, l; +  struct object *o; +     if (args) {    if (Pike_sp[-args].type != T_INT || Pike_sp[-args].u.integer < 0)    SIMPLE_BAD_ARG_ERROR ("this_object", 1, "a non-negative integer");
1856:    level = 0;       pop_n_elems(args); -  if(Pike_fp) -  { -  struct object *o = Pike_fp->current_object; -  for (; level > 0; level--) { +  +  o = Pike_fp->current_object; +  for (l = 0; l < level; l++) {    struct program *p = o->prog;    if (!p) -  Pike_error ("Cannot get the parent object of a destructed object.\n"); +  Pike_error ("Object %d level(s) up is destructed - cannot get the parent.\n", l);    if (!(p->flags & PROGRAM_USES_PARENT))    /* FIXME: Ought to write out the object here. */ -  Pike_error ("Object lacks parent reference.\n"); +  Pike_error ("Object %d level(s) up lacks parent reference.\n", l);    o = PARENT_INFO(o)->parent;    }    ref_push_object(o); -  }else{ -  /* Shouldn't this generate an error? /mast */ -  push_int(0); +    } - } +       static node *optimize_this_object(node *n)   { -  int id; +  int level = 0;       if (CDR (n)) {    struct program_state *state = Pike_compiler;
1890:    return NULL;    }    else { -  int level; +  int i;   #ifdef PIKE_DEBUG    if (CDR (n)->u.sval.type != T_INT || CDR (n)->u.sval.u.integer < 0)    Pike_fatal ("The type check for this_object() failed.\n");   #endif    level = CDR (n)->u.sval.u.integer; -  if (level > compilation_depth) { -  my_yyerror ("There is no surrounding class %d levels out.", level); -  return NULL; -  } -  for (; level > 0; level--, state = state->previous) +  for (i = MIN (level, compilation_depth); i; i--, state = state->previous)    state->new_program->flags |= PROGRAM_USES_PARENT | PROGRAM_NEEDS_PARENT; -  id = state->new_program->id; +     }    } -  else id = Pike_compiler->new_program->id; +     -  +  /* We can only improve the type when accessing the innermost object: +  * Since this_object always follows the object pointers it might not +  * access the lexically surrounding objects. Thus the +  * PROGRAM_USES_PARENT stuff above is a bit of a long shot, but it's +  * better than nothing. */ +  if (!level) {    free_type(n->type);    type_stack_mark(); -  +     /* We are rather sure that we contain ourselves... */    /* push_object_type(1, Pike_compiler->new_program->id); */    /* But it did not work yet, so... */ -  push_object_type(0, id); +  push_object_type(0, Pike_compiler->new_program->id);    n->type = pop_unfinished_type();    if (n->parent) {    n->parent->node_info |= OPT_TYPE_NOT_FIXED;    } -  +  } +     return NULL;   }   
1935:    Pike_fatal ("The type check for this_object() failed.\n");   #endif    level = CDR (n)->u.sval.u.integer; - #ifdef PIKE_DEBUG -  if (level > compilation_depth) -  Pike_fatal ("this_object level too high. " -  "Expected this to be caught by optimize_this_object.\n"); - #endif +     }    }    else level = 0;