From 388e5d9d18c25f40f6a6362da78b59e01b49670b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?=
 <grubba@grubba.org>
Date: Fri, 30 May 2008 13:20:44 +0200
Subject: [PATCH] It is now possible to return a reference to the current
 inherit in this object. The third argument to program_magic_identifier()
 should now be -1 when no inherit has been specified (0 is now reserved for
 referring to the current inherit). This is also reflected in the F_THIS node.
 The F_THIS opcode is now used exclusively to refer to specific inherits. Use
 the F_THIS_OBJECT opcode to refer to the current object.

Rev: src/docode.c:1.201
Rev: src/interpret_functions.h:1.204
Rev: src/language.yacc:1.426
Rev: src/las.c:1.415
Rev: src/peep.in:1.83
Rev: src/program.c:1.710
---
 src/docode.c              |  4 +--
 src/interpret_functions.h | 15 ++------
 src/language.yacc         | 76 +++++++++++++++++++--------------------
 src/las.c                 | 10 ++++--
 src/peep.in               |  4 +--
 src/program.c             | 14 +++++---
 6 files changed, 58 insertions(+), 65 deletions(-)

diff --git a/src/docode.c b/src/docode.c
index 4ff6c24e73..4e4e6040fe 100644
--- a/src/docode.c
+++ b/src/docode.c
@@ -2,7 +2,7 @@
 || 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: docode.c,v 1.200 2008/05/15 15:13:04 grubba Exp $
+|| $Id: docode.c,v 1.201 2008/05/30 11:20:44 grubba Exp $
 */
 
 #include "global.h"
@@ -934,7 +934,7 @@ static int do_docode2(node *n, int flags)
       if (!state) {
 	my_yyerror("Program parent %d lost during compiling.", n->u.integer.a);
 	emit1(F_NUMBER,0);
-      } else if (!level && !inh) {
+      } else if (!level && (inh < 0)) {
 	emit1(F_THIS_OBJECT, 0);
       } else {
 	emit2(F_THIS, level, inh);
diff --git a/src/interpret_functions.h b/src/interpret_functions.h
index c3a2274345..4c15243727 100644
--- a/src/interpret_functions.h
+++ b/src/interpret_functions.h
@@ -2,7 +2,7 @@
 || 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: interpret_functions.h,v 1.203 2008/05/15 15:13:03 grubba Exp $
+|| $Id: interpret_functions.h,v 1.204 2008/05/30 11:20:44 grubba Exp $
 */
 
 /*
@@ -2669,17 +2669,8 @@ OPCODE2(F_THIS, "this", I_UPDATE_SP, {
 	     arg1,
 	     loc.inherit->identifier_level));
     });
-    if (loc.o->prog && arg2) {
-      /* FIXME: Might want to be able refer to the non overloaded object
-       *        (ie arg2 == 0) in the future.
-       *	/grubba 2004-12-19
-       */
-      ref_push_object_inherit(loc.o,
-			      (loc.inherit - loc.o->prog->inherits) + arg2);
-    } else {
-      /* Destructed or top-level. */
-      ref_push_object(loc.o);
-    }
+    ref_push_object_inherit(loc.o,
+			    (loc.inherit - loc.o->prog->inherits) + arg2);
     print_return_value();
 });
 
diff --git a/src/language.yacc b/src/language.yacc
index c7ea22e84d..dc5e9a8923 100644
--- a/src/language.yacc
+++ b/src/language.yacc
@@ -2,7 +2,7 @@
 || 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: language.yacc,v 1.425 2008/05/24 15:14:12 grubba Exp $
+|| $Id: language.yacc,v 1.426 2008/05/30 11:20:41 grubba Exp $
 */
 
 %pure_parser
@@ -3875,7 +3875,7 @@ low_idents: TOK_IDENTIFIER
     {
       /* done, nothing to do here */
     }else if(!($$=find_module_identifier(Pike_compiler->last_identifier,1)) &&
-	     !($$ = program_magic_identifier (Pike_compiler, 0, 0,
+	     !($$ = program_magic_identifier (Pike_compiler, 0, -1,
 					      Pike_compiler->last_identifier, 0))) {
       if((Pike_compiler->flags & COMPILATION_FORCE_RESOLVE) ||
 	 (Pike_compiler->compiler_pass==2)) {
@@ -3952,50 +3952,46 @@ low_idents: TOK_IDENTIFIER
   }
   | inherit_specifier TOK_IDENTIFIER
   {
-    if ($1 >= 0) {
-      int id;
+    int id;
 
-      if(Pike_compiler->last_identifier) free_string(Pike_compiler->last_identifier);
-      copy_shared_string(Pike_compiler->last_identifier, $2->u.sval.u.string);
+    if(Pike_compiler->last_identifier) free_string(Pike_compiler->last_identifier);
+    copy_shared_string(Pike_compiler->last_identifier, $2->u.sval.u.string);
 
-      if ($1 > 0)
-	id = low_reference_inherited_identifier(inherit_state,
-						$1,
-						Pike_compiler->last_identifier,
-						SEE_STATIC);
-      else
-	id = really_low_find_shared_string_identifier(Pike_compiler->last_identifier,
-						      inherit_state->new_program,
-						      SEE_STATIC|SEE_PRIVATE);
+    if ($1 > 0)
+      id = low_reference_inherited_identifier(inherit_state,
+					      $1,
+					      Pike_compiler->last_identifier,
+					      SEE_STATIC);
+    else
+      id = really_low_find_shared_string_identifier(Pike_compiler->last_identifier,
+						    inherit_state->new_program,
+						    SEE_STATIC|SEE_PRIVATE);
 
-      if (id != -1) {
-	if (inherit_depth > 0) {
-	  $$ = mkexternalnode(inherit_state->new_program, id);
-	} else {
-	  $$ = mkidentifiernode(id);
-	}
-      } else if (($$ = program_magic_identifier (inherit_state, inherit_depth, $1,
-						 Pike_compiler->last_identifier, 1))) {
-	/* All done. */
+    if (id != -1) {
+      if (inherit_depth > 0) {
+	$$ = mkexternalnode(inherit_state->new_program, id);
+      } else {
+	$$ = mkidentifiernode(id);
       }
-      else {
-	if ((Pike_compiler->flags & COMPILATION_FORCE_RESOLVE) ||
-	    (Pike_compiler->compiler_pass == 2)) {
-	  if (inherit_state->new_program->inherits[$1].name) {
-	    my_yyerror("Undefined identifier %S::%S.",
-		       inherit_state->new_program->inherits[$1].name,
-		       Pike_compiler->last_identifier);
-	  } else {
-	    my_yyerror("Undefined identifier %S.",
-		       Pike_compiler->last_identifier);
-	  }
-	  $$=0;
+    } else if (($$ = program_magic_identifier (inherit_state, inherit_depth, $1,
+					       Pike_compiler->last_identifier, 1))) {
+      /* All done. */
+    }
+    else {
+      if ((Pike_compiler->flags & COMPILATION_FORCE_RESOLVE) ||
+	  (Pike_compiler->compiler_pass == 2)) {
+	if (($1 >= 0) && inherit_state->new_program->inherits[$1].name) {
+	  my_yyerror("Undefined identifier %S::%S.",
+		     inherit_state->new_program->inherits[$1].name,
+		     Pike_compiler->last_identifier);
+	} else {
+	  my_yyerror("Undefined identifier %S.",
+		     Pike_compiler->last_identifier);
 	}
-	else
-	  $$=mknode(F_UNDEFINED,0,0);
+	$$=0;
       }
-    } else {
-      $$=0;
+      else
+	$$=mknode(F_UNDEFINED,0,0);
     }
 
     free_node($2);
diff --git a/src/las.c b/src/las.c
index 1367dd3885..0ae4b4d3b9 100644
--- a/src/las.c
+++ b/src/las.c
@@ -2,7 +2,7 @@
 || 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: las.c,v 1.414 2008/05/24 21:45:48 grubba Exp $
+|| $Id: las.c,v 1.415 2008/05/30 11:20:44 grubba Exp $
 */
 
 #include "global.h"
@@ -1215,7 +1215,7 @@ node *debug_mkthisnode(struct program *parent_prog, int inherit_num)
   node *res;
 
 #ifdef PIKE_DEBUG
-  if ((inherit_num < 0) || (inherit_num > 65535)) {
+  if ((inherit_num < -1) || (inherit_num > 65535)) {
     Pike_fatal("This is bad: %p, %d\n", parent_prog, inherit_num);
   }
 #endif /* PIKE_DEBUG */
@@ -1223,7 +1223,11 @@ node *debug_mkthisnode(struct program *parent_prog, int inherit_num)
   res = mkemptynode();
   res->token = F_THIS;
   type_stack_mark();
-  push_object_type(!!inherit_num, parent_prog->inherits[inherit_num].prog->id);
+  if (inherit_num >= 0) {
+    push_object_type(1, parent_prog->inherits[inherit_num].prog->id);
+  } else {
+    push_object_type(0, parent_prog->id);
+  }
   res->type = pop_unfinished_type();
   res->tree_info = res->node_info = OPT_NOT_CONST;
 
diff --git a/src/peep.in b/src/peep.in
index 5d751685ff..543e670537 100644
--- a/src/peep.in
+++ b/src/peep.in
@@ -1,7 +1,7 @@
 // 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: peep.in,v 1.82 2008/01/29 20:05:34 grubba Exp $
+// $Id: peep.in,v 1.83 2008/05/30 11:20:44 grubba Exp $
 
 NOP :
 POP_N_ELEMS (0) : 
@@ -614,5 +614,3 @@ CONST_1 ASSIGN_GLOBAL COMPL : CONST_1 ASSIGN_GLOBAL_AND_POP($2a) CONST0
 CONST0 COMPL : CONST_1
 CONST0 ASSIGN_LOCAL COMPL : CLEAR_LOCAL($2a) CONST_1
 CONST0 ASSIGN_GLOBAL COMPL : CONST0 ASSIGN_GLOBAL_AND_POP($2a) CONST_1
-
-THIS [!$1a && !$1b]: THIS_OBJECT(0)
diff --git a/src/program.c b/src/program.c
index fd2c675313..577b354474 100644
--- a/src/program.c
+++ b/src/program.c
@@ -2,7 +2,7 @@
 || 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: program.c,v 1.709 2008/05/29 16:32:55 grubba Exp $
+|| $Id: program.c,v 1.710 2008/05/30 11:20:43 grubba Exp $
 */
 
 #include "global.h"
@@ -1728,9 +1728,13 @@ struct node_s *resolve_identifier(struct pike_string *ident)
 
 /* If the identifier is recognized as one of the magic identifiers,
  * like "this", "this_program" or "`->" when preceded by ::, then a
- * suitable node is returned, NULL otherwise. inherit_num is -1 when
- * accessing all inherits (i.e. when :: is used without any identifier
- * before). */
+ * suitable node is returned, NULL otherwise.
+ *
+ * inherit_num is -1 when no specific inherit has been specified; ie
+ * either when the identifier has no prefix (colon_colon_ref == 0) or
+ * when the identifier has the prefix :: without any preceding identifier
+ * (colon_colon_ref == 1).
+ */
 struct node_s *program_magic_identifier (struct program_state *state,
 					 int state_depth, int inherit_num,
 					 struct pike_string *ident,
@@ -1741,7 +1745,7 @@ struct node_s *program_magic_identifier (struct program_state *state,
 	   state_depth, inherit_num, ident->str, colon_colon_ref);
 #endif
 
-  if (!inherit_num || (!TEST_COMPAT(7,6) && (inherit_num > 0))) {
+  if ((inherit_num == -1) || (!TEST_COMPAT(7,6) && (inherit_num >= 0))) {
     if (ident == this_string) {
       /* Handle this. */
       return mkthisnode(state->new_program, inherit_num);
-- 
GitLab