From 005bf43ed23f10785f9df8bc5f9eede0ccc2e2d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Sat, 29 Sep 2001 01:47:04 -0700 Subject: [PATCH] some fixes for arr[*]+=integer; Rev: src/docode.c:1.135 Rev: src/interpret_functions.h:1.96 Rev: src/testsuite.in:1.455 Rev: src/treeopt.in:1.66 --- src/docode.c | 183 +++++++++++++++++++++++++++++--------- src/interpret_functions.h | 18 ++-- src/testsuite.in | 95 +++++++++++++++++++- src/treeopt.in | 8 +- 4 files changed, 251 insertions(+), 53 deletions(-) diff --git a/src/docode.c b/src/docode.c index 840b7b041d..0953ae9f12 100644 --- a/src/docode.c +++ b/src/docode.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: docode.c,v 1.134 2001/09/29 06:19:26 hubbe Exp $"); +RCSID("$Id: docode.c,v 1.135 2001/09/29 08:47:03 hubbe Exp $"); #include "las.h" #include "program.h" #include "pike_types.h" @@ -521,6 +521,27 @@ static int do_encode_automap_arg_list(node *n, } } +static void emit_builtin_svalue(char *func) +{ + INT32 tmp1; + struct pike_string *n1=make_shared_string(func); + node *n=find_module_identifier(n1,0); + free_string(n1); + + switch(n?n->token:0) + { + case F_CONSTANT: + tmp1=store_constant(&n->u.sval, + n->tree_info & OPT_EXTERNAL_DEPEND, + n->name); + emit1(F_CONSTANT, DO_NOT_WARN((INT32)tmp1)); + break; + + default: + my_yyerror("docode: Failed to make svalue for builtin %s",func); + } + free_node(n); +} static int do_docode2(node *n, INT16 flags) { @@ -718,22 +739,11 @@ static int do_docode2(node *n, INT16 flags) case F_MULT_EQ: case F_MOD_EQ: case F_DIV_EQ: - tmp1=do_docode(CAR(n),DO_LVALUE); -#ifdef PIKE_DEBUG - if(tmp1 != 2) - fatal("HELP! FATAL INTERNAL COMPILER ERROR (7)\n"); -#endif - - if(CAR(n)->token == F_AUTO_MAP_MARKER || CDR(n)->token == F_AUTO_MAP_MARKER) { char *opname; - struct pike_string *opstr; - node *op; - emit0(F_MARK); - if(CAR(n)->token == F_AUTO_MAP_MARKER) { int depth=0; @@ -743,11 +753,14 @@ static int do_docode2(node *n, INT16 flags) depth++; tmp=CAR(tmp); } + tmp1=do_docode(tmp,DO_LVALUE); + emit0(F_MARK); emit0(F_MARK); emit0(F_LTOSVAL); emit1(F_NUMBER,depth); emit_apply_builtin("__builtin.automap_marker"); }else{ + tmp1=do_docode(CAR(n),DO_LVALUE); emit0(F_LTOSVAL); } @@ -768,17 +781,8 @@ static int do_docode2(node *n, INT16 flags) opname="`make gcc happy"; } - opstr=findstring(opname); - if(!opstr || !(op=find_module_identifier(opstr, 0))) - { - my_yyerror("Failed to find operator %s\n",opname); - do_pop(2); - return 1; - } - - code_expression(op, 0, "assignment"); - free_node(op); - emit0(F_SWAP); + emit_builtin_svalue(opname); + emit2(F_REARRANGE,1,1); if(CDR(n)->token == F_AUTO_MAP) { @@ -788,6 +792,12 @@ static int do_docode2(node *n, INT16 flags) } emit_apply_builtin("__automap__"); }else{ + tmp1=do_docode(CAR(n),DO_LVALUE); +#ifdef PIKE_DEBUG + if(tmp1 != 2) + fatal("HELP! FATAL INTERNAL COMPILER ERROR (7)\n"); +#endif + if(n->token == F_ADD_EQ && (flags & DO_POP)) { code_expression(CDR(n), 0, "assignment"); @@ -987,35 +997,125 @@ static int do_docode2(node *n, INT16 flags) case F_INC: case F_POST_INC: - tmp1=do_docode(CAR(n),DO_LVALUE); + if(CAR(n)->token == F_AUTO_MAP_MARKER) + { + int depth=0; + int ret=0; + node *tmp=CAR(n); + while(tmp->token == F_AUTO_MAP_MARKER) + { + depth++; + tmp=CAR(tmp); + } + + tmp1=do_docode(tmp,DO_LVALUE); + if(n->token == F_POST_INC) + { + emit0(F_LTOSVAL); + emit2(F_REARRANGE,1,2); + ret++; + flags|=DO_POP; + } + #ifdef PIKE_DEBUG - if(tmp1 != 2) - fatal("HELP! FATAL INTERNAL COMPILER ERROR (1)\n"); + if(tmp1 != 2) + fatal("HELP! FATAL INTERNAL COMPILER ERROR (1)\n"); #endif - if(flags & DO_POP) - { - emit0(F_INC_AND_POP); - return 0; + emit0(F_MARK); + emit0(F_MARK); + emit0(F_LTOSVAL); + emit1(F_NUMBER, depth); + emit_apply_builtin("__builtin.automap_marker"); + emit_builtin_svalue("`+"); + emit2(F_REARRANGE,1,1); + emit1(F_NUMBER, 1); + emit_apply_builtin("__automap__"); + + if(flags & DO_POP) + { + emit0(F_ASSIGN_AND_POP); + }else{ + emit0(F_ASSIGN); + ret++; + } + return ret; }else{ - emit0(n->token); - return 1; + tmp1=do_docode(CAR(n),DO_LVALUE); +#ifdef PIKE_DEBUG + if(tmp1 != 2) + fatal("HELP! FATAL INTERNAL COMPILER ERROR (1)\n"); +#endif + + if(flags & DO_POP) + { + emit0(F_INC_AND_POP); + return 0; + }else{ + emit0(n->token); + return 1; + } } case F_DEC: case F_POST_DEC: - tmp1=do_docode(CAR(n),DO_LVALUE); + if(CAR(n)->token == F_AUTO_MAP_MARKER) + { + int depth=0; + int ret=0; + node *tmp=CAR(n); + while(tmp->token == F_AUTO_MAP_MARKER) + { + depth++; + tmp=CAR(tmp); + } + + tmp1=do_docode(tmp,DO_LVALUE); + if(n->token == F_POST_DEC) + { + emit0(F_LTOSVAL); + emit2(F_REARRANGE,1,2); + ret++; + flags|=DO_POP; + } + #ifdef PIKE_DEBUG - if(tmp1 != 2) - fatal("HELP! FATAL INTERNAL COMPILER ERROR (2)\n"); + if(tmp1 != 2) + fatal("HELP! FATAL INTERNAL COMPILER ERROR (1)\n"); #endif - if(flags & DO_POP) - { - emit0(F_DEC_AND_POP); - return 0; + + emit0(F_MARK); + emit0(F_MARK); + emit0(F_LTOSVAL); + emit1(F_NUMBER, depth); + emit_apply_builtin("__builtin.automap_marker"); + emit_builtin_svalue("`-"); + emit2(F_REARRANGE,1,1); + emit1(F_NUMBER, 1); + emit_apply_builtin("__automap__"); + + if(flags & DO_POP) + { + emit0(F_ASSIGN_AND_POP); + }else{ + emit0(F_ASSIGN); + ret++; + } + return ret; }else{ - emit0(n->token); - return 1; + tmp1=do_docode(CAR(n),DO_LVALUE); +#ifdef PIKE_DEBUG + if(tmp1 != 2) + fatal("HELP! FATAL INTERNAL COMPILER ERROR (2)\n"); +#endif + if(flags & DO_POP) + { + emit0(F_DEC_AND_POP); + return 0; + }else{ + emit0(n->token); + return 1; + } } case F_FOR: @@ -2056,7 +2156,6 @@ static int do_docode2(node *n, INT16 flags) return 1; case F_AUTO_MAP_MARKER: - if(flags & DO_LVALUE) return do_docode(CAR(n), flags); yyerror("[*] not supported here.\n"); emit0(F_CONST0); return 1; diff --git a/src/interpret_functions.h b/src/interpret_functions.h index 3ac1ad6904..1e28ae25b0 100644 --- a/src/interpret_functions.h +++ b/src/interpret_functions.h @@ -1,5 +1,5 @@ /* - * $Id: interpret_functions.h,v 1.95 2001/09/29 06:19:27 hubbe Exp $ + * $Id: interpret_functions.h,v 1.96 2001/09/29 08:47:03 hubbe Exp $ * * Opcode definitions for the interpreter. */ @@ -198,11 +198,16 @@ OPCODE1(F_CONSTANT, "constant", { print_return_value(); }); -OPCODE0(F_SWAP,"swap",{ - struct svalue tmp; - tmp=Pike_sp[-2]; - Pike_sp[-2]=Pike_sp[-1]; - Pike_sp[-1]=tmp; + +/* Generic swap instruction: + * swaps the arg1 top values with the arg2 values beneath + */ +OPCODE2(F_REARRANGE,"rearrange",{ + int e; + check_stack(arg2); + MEMCPY(Pike_sp,Pike_sp-arg1-arg2,sizeof(struct svalue)*arg2); + MEMMOVE(Pike_sp-arg1-arg2,Pike_sp-arg1,sizeof(struct svalue)*arg1); + MEMCPY(Pike_sp-arg2,Pike_sp,sizeof(struct svalue)*arg2); }); /* The rest of the basic 'push value' instructions */ @@ -583,6 +588,7 @@ OPCODE0(F_LTOSVAL, "lvalue to svalue", { dmalloc_touch_svalue(Pike_sp-1); lvalue_to_svalue_no_free(Pike_sp, Pike_sp-2); Pike_sp++; + print_return_value(); }); OPCODE0(F_LTOSVAL2, "ltosval2", { diff --git a/src/testsuite.in b/src/testsuite.in index e681582994..d2e27e0d08 100644 --- a/src/testsuite.in +++ b/src/testsuite.in @@ -1,4 +1,4 @@ -test_true([["$Id: testsuite.in,v 1.454 2001/09/28 00:01:45 hubbe Exp $"]]); +test_true([["$Id: testsuite.in,v 1.455 2001/09/29 08:47:03 hubbe Exp $"]]); cond([[all_constants()->_verify_internals]], [[ @@ -1750,11 +1750,15 @@ dnl test_compile_error([[void foo() { return destruct(this_object()); }]]) test_any([[class foo { constant x=17; }; class bar { inherit foo; constant x=18; }; return bar()->x;]],18) test_program([[inline string foo(string s){ while(s[0] == ' ' || s[0] == '\t') s = s[1..]; return(s); } string a() { return foo(" bar"); }]]) + +// lambda function tests + test_true([[lambda(int x) { return lambda() { return x; };}]]) test_eq([[lambda(int x) { return lambda() { return x; };}(4)()]],4) test_eq([[lambda(int x) { return lambda() { return x; };}(17)()]],17) test_eq([[lambda(int x) { return lambda() { return lambda() { return x; };};}(17)()()]],17) +// local function tests test_eq(120, [[ lambda() { @@ -1771,6 +1775,32 @@ test_eq([[function f; { {int _i = i; f = lambda(int j) { return _i+j; }; } int FEL; } return f(17);]]); +test_any([[ + int x,y,z; + function p; + void foo() { y+=7; }; + void bar() + { + foo(); + void gazonk() + { + foo(); + void quux() + { + foo(); + y+=4711; + }; + p=quux; + }; + + gazonk(); + gazonk(); + }; + foo(); + bar(); + p(); + return y; +]], 7 * 5 + 4711 ) test_any([[ int x=1; @@ -1779,6 +1809,7 @@ test_any([[ return x; ]], 11) +// implicit lambda tests test_any([[ int x=1; void for10(function f) { for(int e=0;e<10;e++) f(); }; @@ -1997,9 +2028,71 @@ test_any_equal([[ ]], [[ ({ ({15,25}), ({35,45}) }) ]]) +test_any_equal([[ + mixed a=({1,2,3}); + a[*] += -2; + return a; +]], [[ ({-1,0,1}) ]]) + +test_any_equal([[ + mixed a=({1,2,3}); + a[*] += -1; + return a; +]], [[ ({0,1,2}) ]]) + +test_any_equal([[ + mixed a=({1,2,3}); + a[*] += 0; + return a; +]], [[ ({1,2,3}) ]]) + +test_any_equal([[ + mixed a=({1,2,3}); + a[*] += 1; + return a; +]], [[ ({2,3,4}) ]]) + +test_any_equal([[ + mixed a=({1,2,3}); + a[*] += 2; + return a; +]], [[ ({3,4,5}) ]]) + + +test_any_equal([[ + mixed a=({1,2,3}); + return a[*] += -2; +]], [[ ({-1,0,1}) ]]) + +test_any_equal([[ + mixed a=({1,2,3}); + return a[*] += -1; +]], [[ ({0,1,2}) ]]) + +test_any_equal([[ + mixed a=({1,2,3}); + return a[*] += 0; +]], [[ ({1,2,3}) ]]) + +test_any_equal([[ + mixed a=({1,2,3}); + return a[*] += 1; +]], [[ ({2,3,4}) ]]) + +test_any_equal([[ + mixed a=({1,2,3}); + return a[*] += 2; +]], [[ ({3,4,5}) ]]) + test_equal([[ "foo"[ ({ 2,0,1,2 })[*] ] ]], [[ ({ 'o', 'f', 'o', 'o' }) ]]) +test_equal([[ ({ ({1}), ({2}), ({3}) })[*][0] ]], + [[ ({ 1,2,3 }) ]]) + +test_equal([[ ({ ({1,2}), ({3,4}), ({5,6}) })[*][ ({0,1,1})[*] ] ]], + [[ ({ 1,4,6 }) ]]) + // map tests test_any_equal(array a = ({({1,0,0}),({1,1,0}),({0,1,1})}); return map(a,`[],1);, ({0,1,1})) diff --git a/src/treeopt.in b/src/treeopt.in index 98bd6df357..b7cc0c3196 100644 --- a/src/treeopt.in +++ b/src/treeopt.in @@ -1,6 +1,6 @@ // -*- c -*- // -// $Id: treeopt.in,v 1.65 2001/09/07 03:15:07 hubbe Exp $ +// $Id: treeopt.in,v 1.66 2001/09/29 08:47:04 hubbe Exp $ // // The tree optimizer // @@ -733,7 +733,7 @@ F_NOT(F_NE(0, 1), *): // a += 0 -> a -F_ADD_EQ(0, 1 = F_CONSTANT[$$->u.sval.type == T_INT] +F_ADD_EQ(0 [ $$->token != F_AUTO_MAP_MARKER ], 1 = F_CONSTANT[$$->u.sval.type == T_INT] [!($$->u.sval.u.integer)]): $0; @@ -748,8 +748,8 @@ F_ADD_EQ(0, 1 = F_CONSTANT[$$->u.sval.type == T_INT] F_DEC($0, -); -// a += 0 -> a -F_SUB_EQ(0, 1 = F_CONSTANT[$$->u.sval.type == T_INT] +// a -= 0 -> a +F_SUB_EQ(0 [ $$->token != F_AUTO_MAP_MARKER ], 1 = F_CONSTANT[$$->u.sval.type == T_INT] [!($$->u.sval.u.integer)]): $0; -- GitLab