diff --git a/src/ChangeLog b/src/ChangeLog index 41124fce848bf58e67ff11e10cc336c510793fce..4d038a46b31f727bff532abd4d01f6a0061b1ace 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,13 @@ +Mon Mar 10 16:58:06 1997 Fredrik Hubinette <hubbe@cytocin.hubbe.net> + + * docode.c (do_cond_jump): optimized || and && + * program.c (add_constant): constants are now redefinable + * interpret.c: F_EQ_OR now works, added F_EQ_AND + +Sun Mar 9 01:44:03 1997 Fredrik Hubinette <hubbe@cytocin.hubbe.net> + + * peephole optimized fixed and improved + Sat Mar 8 04:31:29 1997 Fredrik Hubinette <hubbe@cytocin.hubbe.net> * added new efuns `[] and `-> diff --git a/src/docode.c b/src/docode.c index 12e2c9f2aee32e4156e2b728c04a8908c7d93429..9cff5c51433b611b710d527654f76b74e94e266b 100644 --- a/src/docode.c +++ b/src/docode.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: docode.c,v 1.13 1997/03/09 09:11:10 hubbe Exp $"); +RCSID("$Id: docode.c,v 1.14 1997/03/11 03:36:39 hubbe Exp $"); #include "las.h" #include "program.h" #include "language.h" @@ -158,8 +158,6 @@ int do_docode(node *n,INT16 flags) } -void do_jump_when_zero(node *n,int j); - static int is_efun(node *n, c_fun fun) { return n && n->token == F_CONSTANT && @@ -167,102 +165,66 @@ static int is_efun(node *n, c_fun fun) n->u.sval.u.efun->function == fun; } -void do_jump_when_non_zero(node *n,int j) +void do_cond_jump(node *n, int label, int iftrue, int flags) { - if(!node_is_tossable(n)) + iftrue=!!iftrue; + if((flags & DO_POP) && node_is_tossable(n)) { - if(node_is_true(n)) + int t,f; + t=!!node_is_true(n); + f=!!node_is_false(n); + if(t || f) { - do_jump(F_BRANCH,j); + if(t == iftrue) do_jump(F_BRANCH, label); return; } - - if(node_is_false(n)) - return; } switch(n->token) { - case F_APPLY: - if(is_efun(CAR(n), f_not)) - { - do_jump_when_zero(CDR(n), j); - return; - } - break; - - case F_NOT: - do_jump_when_zero(CAR(n), j); - return; - case F_LAND: - { - int tmp=alloc_label(); - do_jump_when_zero(CAR(n), tmp); - do_jump_when_non_zero(CDR(n), j); - emit(F_LABEL,tmp); - return; - } - case F_LOR: - do_jump_when_non_zero(CAR(n), j); - do_jump_when_non_zero(CDR(n), j); - return; - } - - if(do_docode(n, DO_NOT_COPY)!=1) - fatal("Infernal compiler skiterror.\n"); - do_jump(F_BRANCH_WHEN_NON_ZERO,j); -} - -void do_jump_when_zero(node *n,int j) -{ - if(!node_is_tossable(n)) - { - if(node_is_true(n)) - return; - - if(node_is_false(n)) + if(iftrue == (n->token==F_LAND)) { - do_jump(F_BRANCH,j); - return; + int tmp=alloc_label(); + do_cond_jump(CAR(n), tmp, !iftrue, flags | DO_POP); + do_cond_jump(CDR(n), label, iftrue, flags); + emit(F_LABEL,tmp); + }else{ + do_cond_jump(CAR(n), label, iftrue, flags); + do_cond_jump(CDR(n), label, iftrue, flags); } - } - - switch(n->token) - { + return; + case F_APPLY: - if(is_efun(CAR(n), f_not)) - { - do_jump_when_non_zero(CDR(n), j); - return; - } - break; + if(!is_efun(CAR(n), f_not)) break; case F_NOT: - do_jump_when_non_zero(CAR(n), j); - return; - - case F_LOR: - { - int tmp=alloc_label(); - do_jump_when_non_zero(CAR(n), tmp); - do_jump_when_zero(CDR(n), j); - emit(F_LABEL,tmp); + if(!(flags & DO_POP)) break; + do_cond_jump(CDR(n), label , !iftrue, flags | DO_NOT_COPY); return; } - case F_LAND: - do_jump_when_zero(CAR(n), j); - do_jump_when_zero(CDR(n), j); - return; - } - - if(do_docode(n, DO_NOT_COPY)!=1) + if(do_docode(n, flags&DO_NOT_COPY)!=1) fatal("Infernal compiler skiterror.\n"); - do_jump(F_BRANCH_WHEN_ZERO,j); + + if(flags & DO_POP) + { + if(iftrue) + do_jump(F_BRANCH_WHEN_NON_ZERO, label); + else + do_jump(F_BRANCH_WHEN_ZERO, label); + }else{ + if(iftrue) + do_jump(F_LOR, label); + else + do_jump(F_LAND, label); + } } +#define do_jump_when_zero(N,L) do_cond_jump(N,L,0,DO_POP|DO_NOT_COPY) +#define do_jump_when_non_zero(N,L) do_cond_jump(N,L,1,DO_POP|DO_NOT_COPY) + static INT32 count_cases(node *n) { INT32 ret; @@ -503,11 +465,9 @@ static int do_docode2(node *n,int flags) case F_LAND: case F_LOR: - if(do_docode(CAR(n),0)!=1) - fatal("Compiler internal error.\n"); - tmp1=do_jump(n->token,-1); - if(do_docode(CDR(n),0)!=1) - fatal("Compiler internal error.\n"); + tmp1=alloc_label(); + do_cond_jump(CAR(n), tmp1, n->token == F_LOR, 0); + if(do_docode(CDR(n),0)!=1) fatal("Compiler internal error.\n"); emit(F_LABEL,tmp1); return 1; diff --git a/src/interpret.c b/src/interpret.c index 81bd795b92274ca3ecc615e95e6c3a5e33bff408..dd2f2b027f91255f41cbf5d60ace62847ad4ae3d 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: interpret.c,v 1.30 1997/03/09 09:11:11 hubbe Exp $"); +RCSID("$Id: interpret.c,v 1.31 1997/03/11 03:36:39 hubbe Exp $"); #include "interpret.h" #include "object.h" #include "program.h" @@ -882,7 +882,7 @@ static void eval_instruction(unsigned char *pc) break; CASE(F_EQ_OR); - if(is_eq(sp-2,sp-1)) + if(!is_eq(sp-2,sp-1)) { pop_n_elems(2); pc+=sizeof(INT32); @@ -893,6 +893,18 @@ static void eval_instruction(unsigned char *pc) } break; + CASE(F_EQ_AND); + if(is_eq(sp-2,sp-1)) + { + pop_n_elems(2); + pc+=sizeof(INT32); + }else{ + pop_n_elems(2); + push_int(0); + DOJUMP(); + } + break; + CASE(F_CATCH); if(o_catch(pc+sizeof(INT32))) return; /* There was a return inside the evaluated code */ diff --git a/src/interpret.h b/src/interpret.h index d57a09be959bdfd451609a3ee4956fd18f068765..c9a47e19c18d3db1282aabfcca60ac8d03c31cf8 100644 --- a/src/interpret.h +++ b/src/interpret.h @@ -33,6 +33,7 @@ struct frame #endif #define pop_stack() do{ free_svalue(--sp); debug_check_stack(); }while(0) + #define push_program(P) do{ struct program *_=(P); sp->u.program=_; sp++->type=T_PROGRAM; }while(0) #define push_int(I) do{ INT32 _=(I); sp->u.integer=_;sp->type=T_INT;sp++->subtype=NUMBER_NUMBER; }while(0) #define push_mapping(M) do{ struct mapping *_=(M); sp->u.mapping=_; sp++->type=T_MAPPING; }while(0) @@ -42,6 +43,14 @@ struct frame #define push_object(O) do{ struct object *_=(O); sp->u.object=_; sp++->type=T_OBJECT; }while(0) #define push_float(F) do{ float _=(F); sp->u.float_number=_; sp++->type=T_FLOAT; }while(0) #define push_text(T) push_string(make_shared_string((T))) + +#define ref_push_program(P) do{ struct program *_=(P); _->refs++; sp->u.program=_; sp++->type=T_PROGRAM; }while(0) +#define ref_push_mapping(M) do{ struct mapping *_=(M); _->refs++; sp->u.mapping=_; sp++->type=T_MAPPING; }while(0) +#define ref_push_array(A) do{ struct array *_=(A); _->refs++; sp->u.array=_ ;sp++->type=T_ARRAY; }while(0) +#define ref_push_multiset(L) do{ struct multiset *_=(L); _->refs++; sp->u.multiset=_; sp++->type=T_MULTISET; }while(0) +#define ref_push_string(S) do{ struct pike_string *_=(S); _->refs++; sp->subtype=0; sp->u.string=_; sp++->type=T_STRING; }while(0) +#define ref_push_object(O) do{ struct object *_=(O); _->refs++; sp->u.object=_; sp++->type=T_OBJECT; }while(0) + #define push_svalue(S) do { struct svalue *_=(S); assign_svalue_no_free(sp,_); sp++; }while(0) #define APPLY_MASTER(FUN,ARGS) \ diff --git a/src/language.yacc b/src/language.yacc index 5122e1f040d97973c37461a265279cf1f300b3a3..cfa95af187e43da089eafbc37b6f642cb569286f 100644 --- a/src/language.yacc +++ b/src/language.yacc @@ -56,7 +56,7 @@ %token F_AND F_OR F_XOR %token F_LSH F_RSH %token F_LAND F_LOR -%token F_EQ_OR +%token F_EQ_OR F_EQ_AND %token F_SWITCH F_SSCANF F_CATCH %token F_CAST @@ -158,7 +158,7 @@ /* This is the grammar definition of Pike. */ #include "global.h" -RCSID("$Id: language.yacc,v 1.29 1997/03/09 09:11:11 hubbe Exp $"); +RCSID("$Id: language.yacc,v 1.30 1997/03/11 03:36:40 hubbe Exp $"); #ifdef HAVE_MEMORY_H #include <memory.h> #endif diff --git a/src/lex.c b/src/lex.c index d69d0a1695d719119cc6fc998cf38f93d2552600..248d9dc15f4fbb6774950bdc1abd7bf431c6a9d7 100644 --- a/src/lex.c +++ b/src/lex.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: lex.c,v 1.17 1997/03/09 09:11:12 hubbe Exp $"); +RCSID("$Id: lex.c,v 1.18 1997/03/11 03:36:41 hubbe Exp $"); #include "language.h" #include "array.h" #include "lex.h" @@ -144,21 +144,16 @@ struct keyword instr_names[]= { "!=", F_NE }, { "%", F_MOD }, { "%=", F_MOD_EQ }, -{ "& global", F_GLOBAL_LVALUE, 1 }, -{ "& local", F_LOCAL_LVALUE, 1 }, +{ "& global", F_GLOBAL_LVALUE, I_HASARG }, +{ "& local", F_LOCAL_LVALUE, I_HASARG }, { "&", F_AND }, -{ "&&", F_LAND, 1 }, { "&=", F_AND_EQ }, { "*", F_MULTIPLY }, { "*=", F_MULT_EQ }, { "+", F_ADD }, -{ "++Loop", F_INC_LOOP, 1 }, -{ "++Loop!=", F_INC_NEQ_LOOP, 1 }, { "++x", F_INC }, { "+=", F_ADD_EQ }, { "-", F_SUBTRACT }, -{ "--Loop", F_DEC_LOOP, 1 }, -{ "--Loop!=", F_DEC_NEQ_LOOP, 1 }, { "--x", F_DEC }, { "-=", F_SUB_EQ }, { "/", F_DIVIDE }, @@ -183,19 +178,16 @@ struct keyword instr_names[]= { "arg+=512", F_PREFIX_512 }, { "arg+=768", F_PREFIX_768 }, { "assign and pop", F_ASSIGN_AND_POP }, -{ "assign global", F_ASSIGN_GLOBAL, 1 }, -{ "assign global and pop", F_ASSIGN_GLOBAL_AND_POP, 1 }, -{ "assign local", F_ASSIGN_LOCAL, 1 }, -{ "assign local and pop", F_ASSIGN_LOCAL_AND_POP, 1 }, +{ "assign global", F_ASSIGN_GLOBAL, I_HASARG }, +{ "assign global and pop", F_ASSIGN_GLOBAL_AND_POP, I_HASARG }, +{ "assign local", F_ASSIGN_LOCAL, I_HASARG }, +{ "assign local and pop", F_ASSIGN_LOCAL_AND_POP, I_HASARG }, { "assign", F_ASSIGN }, -{ "branch non zero", F_BRANCH_WHEN_NON_ZERO, 1 }, -{ "branch when zero", F_BRANCH_WHEN_ZERO, 1 }, { "break", F_BREAK }, { "case", F_CASE }, { "cast", F_CAST }, -{ "catch", F_CATCH, 1 }, { "const-1", F_CONST_1 }, -{ "constant", F_CONSTANT, 1 }, +{ "constant", F_CONSTANT, I_HASARG }, { "continue", F_CONTINUE }, { "copy_value", F_COPY_VALUE }, { "default", F_DEFAULT }, @@ -203,37 +195,57 @@ struct keyword instr_names[]= { "dumb return", F_DUMB_RETURN }, { "float number", F_FLOAT }, { "for", F_FOR }, -{ "foreach", F_FOREACH, 1 }, -{ "global", F_GLOBAL, 1 }, +{ "global", F_GLOBAL, I_HASARG }, { "index", F_INDEX }, -{ "->", F_ARROW, 1 }, +{ "->", F_ARROW, I_HASARG }, { "clear string subtype", F_CLEAR_STRING_SUBTYPE }, -{ "arrow string", F_ARROW_STRING, 1 }, +{ "arrow string", F_ARROW_STRING, I_HASARG }, { "indirect", F_INDIRECT }, -{ "jump", F_BRANCH, 1 }, -{ "local function call",F_CALL_LFUN, 1 }, -{ "local function call and pop",F_CALL_LFUN_AND_POP, 1 }, -{ "local function", F_LFUN, 1 }, -{ "local", F_LOCAL, 1 }, -{ "mark & local", F_MARK_AND_LOCAL, 1 }, + +{ "branch", F_BRANCH, I_ISJUMP }, +{ "branch non zero", F_BRANCH_WHEN_NON_ZERO, I_ISJUMP }, +{ "branch when zero", F_BRANCH_WHEN_ZERO, I_ISJUMP }, +{ "branch if <", F_BRANCH_WHEN_LT, I_ISJUMP }, +{ "branch if >", F_BRANCH_WHEN_GT, I_ISJUMP }, +{ "branch if <=", F_BRANCH_WHEN_LE, I_ISJUMP }, +{ "branch if >=", F_BRANCH_WHEN_GE, I_ISJUMP }, +{ "branch if ==", F_BRANCH_WHEN_EQ, I_ISJUMP }, +{ "branch if !=", F_BRANCH_WHEN_NE, I_ISJUMP }, +{ "++Loop", F_INC_LOOP, I_ISJUMP }, +{ "++Loop!=", F_INC_NEQ_LOOP, I_ISJUMP }, +{ "--Loop", F_DEC_LOOP, I_ISJUMP }, +{ "--Loop!=", F_DEC_NEQ_LOOP, I_ISJUMP }, +{ "&&", F_LAND, I_ISJUMP }, +{ "||", F_LOR, I_ISJUMP }, +{ "==||", F_EQ_OR, I_ISJUMP }, +{ "==&&", F_EQ_AND, I_ISJUMP }, +{ "catch", F_CATCH, I_ISJUMP }, +{ "foreach", F_FOREACH, I_ISJUMP }, +{ "data", F_POINTER, I_ISPOINTER }, + +{ "local function call",F_CALL_LFUN, I_HASARG }, +{ "local function call and pop",F_CALL_LFUN_AND_POP, I_HASARG }, +{ "local function", F_LFUN, I_HASARG }, +{ "local", F_LOCAL, I_HASARG }, +{ "mark & local", F_MARK_AND_LOCAL, I_HASARG }, { "ltosval2", F_LTOSVAL2 }, { "lvalue to svalue", F_LTOSVAL }, { "lvalue_list", F_LVALUE_LIST }, { "mark", F_MARK }, { "mark mark", F_MARK2 }, -{ "negative number", F_NEG_NUMBER, 1 }, -{ "number", F_NUMBER, 1 }, +{ "negative number", F_NEG_NUMBER, I_HASARG }, +{ "number", F_NUMBER, I_HASARG }, { "pop", F_POP_VALUE }, -{ "pop_n_elems", F_POP_N_ELEMS, 1 }, +{ "pop_n_elems", F_POP_N_ELEMS, I_HASARG }, { "push 0", F_CONST0 }, { "push 1", F_CONST1 }, { "push 0x7fffffff", F_BIGNUM }, { "range", F_RANGE }, { "return", F_RETURN }, { "return 0", F_RETURN_0 }, -{ "sscanf", F_SSCANF, 1 }, -{ "string", F_STRING, 1 }, -{ "switch", F_SWITCH, 1 }, +{ "sscanf", F_SSCANF, I_HASARG }, +{ "string", F_STRING, I_HASARG }, +{ "switch", F_SWITCH, I_HASARG }, { "unary minus", F_NEGATE }, { "while", F_WHILE }, { "x++ and pop", F_INC_AND_POP }, @@ -242,38 +254,29 @@ struct keyword instr_names[]= { "x--", F_POST_DEC }, { "|", F_OR }, { "|=", F_OR_EQ }, -{ "||", F_LOR, 1 }, { "~", F_COMPL }, { "label", F_LABEL,1 }, -{ "data", F_POINTER, 1 }, -{ "align", F_ALIGN, 1 }, -{ "call", F_APPLY, 1 }, -{ "clear local", F_CLEAR_LOCAL, 1 }, -{ "clear 2 local", F_CLEAR_2_LOCAL, 1 }, -{ "++local", F_INC_LOCAL, 1 }, -{ "++local and pop", F_INC_LOCAL_AND_POP, 1 }, -{ "local++", F_POST_INC_LOCAL, 1 }, -{ "--local", F_DEC_LOCAL, 1 }, -{ "--local and pop", F_DEC_LOCAL_AND_POP, 1 }, -{ "local--", F_POST_DEC_LOCAL, 1 }, -{ "branch if <", F_BRANCH_WHEN_LT, 1 }, -{ "branch if >", F_BRANCH_WHEN_GT, 1 }, -{ "branch if <=", F_BRANCH_WHEN_LE, 1 }, -{ "branch if >=", F_BRANCH_WHEN_GE, 1 }, -{ "branch if ==", F_BRANCH_WHEN_EQ, 1 }, -{ "branch if !=", F_BRANCH_WHEN_NE, 1 }, +{ "align", F_ALIGN, I_HASARG }, +{ "call", F_APPLY, I_HASARG }, +{ "clear local", F_CLEAR_LOCAL, I_HASARG }, +{ "clear 2 local", F_CLEAR_2_LOCAL, I_HASARG }, +{ "++local", F_INC_LOCAL, I_HASARG }, +{ "++local and pop", F_INC_LOCAL_AND_POP, I_HASARG }, +{ "local++", F_POST_INC_LOCAL, I_HASARG }, +{ "--local", F_DEC_LOCAL, I_HASARG }, +{ "--local and pop", F_DEC_LOCAL_AND_POP, I_HASARG }, +{ "local--", F_POST_DEC_LOCAL, I_HASARG }, { "sizeof", F_SIZEOF }, -{ "sizeof local", F_SIZEOF_LOCAL, 1 }, +{ "sizeof local", F_SIZEOF_LOCAL, I_HASARG }, { "throw(0)", F_THROW_ZERO }, -{ "string index", F_STRING_INDEX, 1 }, -{ "local index", F_LOCAL_INDEX, 1 }, -{ "int index", F_POS_INT_INDEX, 1 }, -{ "-int index", F_NEG_INT_INDEX, 1 }, -{ "apply and pop", F_APPLY_AND_POP, 1 }, -{ "2 locals", F_2_LOCALS, 1 }, -{ "byte", F_BYTE, 1 }, +{ "string index", F_STRING_INDEX, I_HASARG }, +{ "local index", F_LOCAL_INDEX, I_HASARG }, +{ "int index", F_POS_INT_INDEX, I_HASARG }, +{ "-int index", F_NEG_INT_INDEX, I_HASARG }, +{ "apply and pop", F_APPLY_AND_POP, I_HASARG }, +{ "2 locals", F_2_LOCALS, I_HASARG }, +{ "byte", F_BYTE, I_HASARG }, { "nop", F_NOP }, -{ "==||", F_EQ_OR, 1 }, }; struct instr instrs[F_MAX_INSTR - F_OFFSET]; @@ -298,7 +301,7 @@ void init_lex() fatal("Duplicate name for %s\n",instr_names[i].word); instrs[instr_names[i].token - F_OFFSET].name = instr_names[i].word; - instrs[instr_names[i].token - F_OFFSET].hasarg=instr_names[i].hasarg; + instrs[instr_names[i].token - F_OFFSET].flags=instr_names[i].flags; } reswords=create_hash_table(); diff --git a/src/lex.h b/src/lex.h index 381f0786a62c84b5b40033774ab164a21cc4bb37..e5d0f5ba7649e8436dce6e286e7e02d75ee85454 100644 --- a/src/lex.h +++ b/src/lex.h @@ -12,16 +12,22 @@ struct keyword { char *word; int token; - int hasarg; + int flags; }; +#define I_HASARG 1 +#define I_POINTER 2 +#define I_JUMP 4 +#define I_ISPOINTER 3 +#define I_ISJUMP 7 + struct instr { #ifdef DEBUG long runs; long compiles; #endif - int hasarg; + int flags; char *name; }; diff --git a/src/peep.c b/src/peep.c index 9a3124daff9bcfce961d315ef634fb7a95634392..c287b6498373f828b8e801361f7de3ba39d750b4 100644 --- a/src/peep.c +++ b/src/peep.c @@ -24,7 +24,10 @@ static void asm_opt(void); dynamic_buffer instrbuf; -static int hasarg(int opcode) { return instrs[opcode-F_OFFSET].hasarg; } +static int hasarg(int opcode) +{ + return instrs[opcode-F_OFFSET].flags & I_HASARG; +} void init_bytecode() { @@ -138,27 +141,6 @@ static void ins_f_byte_with_arg(unsigned int a,unsigned INT32 b) ins_byte(b, A_PROGRAM); } -#define BRANCH_CASES \ - F_BRANCH_WHEN_EQ: \ - case F_BRANCH_WHEN_NE: \ - case F_BRANCH_WHEN_LT: \ - case F_BRANCH_WHEN_LE: \ - case F_BRANCH_WHEN_GT: \ - case F_BRANCH_WHEN_GE: \ - case F_BRANCH_WHEN_ZERO: \ - case F_BRANCH_WHEN_NON_ZERO: \ - case F_BRANCH: \ - case F_INC_LOOP: \ - case F_DEC_LOOP: \ - case F_INC_NEQ_LOOP: \ - case F_DEC_NEQ_LOOP: \ - case F_LAND: \ - case F_LOR: \ - case F_EQ_OR: \ - case F_CATCH: \ - case F_FOREACH - - void assemble(void) { INT32 e,d,length,max_label,tmp; @@ -193,10 +175,8 @@ void assemble(void) for(e=0;e<length;e++) { - switch(c[e].opcode) + if(instrs[c[e].opcode-F_OFFSET].flags & I_POINTER) { - case BRANCH_CASES: - case F_POINTER: while(1) { int tmp,tmp2; @@ -282,24 +262,33 @@ void assemble(void) labels[c->arg]=PC; break; - case BRANCH_CASES: - ins_f_byte(c->opcode); - - case F_POINTER: + default: + switch(instrs[c->opcode - F_OFFSET].flags) + { + case I_ISJUMP: + ins_f_byte(c->opcode); + case I_ISPOINTER: #ifdef DEBUG - if(c->arg > max_label || c->arg < 0) fatal("Jump to unknown label?\n"); + if(c->arg > max_label || c->arg < 0) fatal("Jump to unknown label?\n"); #endif - tmp=PC; - ins_int(jumps[c->arg],A_PROGRAM); - jumps[c->arg]=tmp; - break; + tmp=PC; + ins_int(jumps[c->arg],A_PROGRAM); + jumps[c->arg]=tmp; + break; - default: - if(hasarg(c->opcode)) + case I_HASARG: ins_f_byte_with_arg(c->opcode, c->arg); - else + break; + + case 0: ins_f_byte(c->opcode); - break; + break; + +#ifdef DEBUG + default: + fatal("Unknown instruction type.\n"); +#endif + } } c++; diff --git a/src/peep.in b/src/peep.in index 3fab269e3d2ab8c1d046d72ec376ad533bdde213..49481badcf9ce7e4030f8cbc0366708c2889ecec 100644 --- a/src/peep.in +++ b/src/peep.in @@ -95,6 +95,7 @@ LE BRANCH_WHEN_ZERO: BRANCH_WHEN_GT ($2a) GE BRANCH_WHEN_ZERO: BRANCH_WHEN_LT ($2a) EQ LOR: EQ_OR ($2a) +EQ LAND: EQ_AND ($2a) EQ NOT: NE NE NOT: EQ diff --git a/src/program.c b/src/program.c index fb7b81f151532f0551267bd7bc06a8413c33e179..f9984d738676b8f3fd0489a4860bc0da3343bb10 100644 --- a/src/program.c +++ b/src/program.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: program.c,v 1.25 1997/03/07 05:21:47 hubbe Exp $"); +RCSID("$Id: program.c,v 1.26 1997/03/11 03:36:42 hubbe Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -966,6 +966,8 @@ int add_constant(struct pike_string *name, INT32 flags) { int n; + struct identifier dummy; + struct reference ref; #ifdef DEBUG if(name!=debug_findstring(name)) @@ -975,38 +977,34 @@ int add_constant(struct pike_string *name, setup_fake_program(); n = isidentifier(name); + copy_shared_string(dummy.name, name); + dummy.type = get_type_of_svalue(c); + + dummy.flags = IDENTIFIER_CONSTANT; + dummy.run_time_type=c->type; + + dummy.func.offset=store_constant(c, 0); + + ref.flags=flags; + ref.identifier_offset=fake_program.num_identifiers; + ref.inherit_offset=0; + + add_to_mem_block(A_IDENTIFIERS, (char *)&dummy, sizeof dummy); + fake_program.num_identifiers ++; + if(n != -1) { - setup_fake_program(); - if (IDENTIFIERP(n)->flags & ID_NOMASK) my_yyerror("Illegal to redefine 'nomask' identifier \"%s\"", name->str); if(PROG_FROM_INT(& fake_program, n) == &fake_program) my_yyerror("Identifier '%s' defined twice.",name->str); - } else { - struct identifier dummy; - struct reference ref; - - copy_shared_string(dummy.name, name); - dummy.type = get_type_of_svalue(c); - - dummy.flags = IDENTIFIER_CONSTANT; - dummy.run_time_type=c->type; - - dummy.func.offset=store_constant(c, 0); - - ref.flags=flags; - ref.identifier_offset=areas[A_IDENTIFIERS].s.len / sizeof dummy; - ref.inherit_offset=0; - - add_to_mem_block(A_IDENTIFIERS, (char *)&dummy, sizeof dummy); - fake_program.num_identifiers ++; + fake_program.identifier_references[n]=ref; + } else { n=areas[A_IDENTIFIER_REFERENCES].s.len / sizeof ref; add_to_mem_block(A_IDENTIFIER_REFERENCES, (char *)&ref, sizeof ref); fake_program.num_identifier_references ++; - } return n; diff --git a/src/testsuite.in b/src/testsuite.in index ccc03668444df682352d9116bfe6ac19edb04987..b860ea9a346e4f34ada0f07deef9db39e331ea1f 100644 --- a/src/testsuite.in +++ b/src/testsuite.in @@ -1,4 +1,5 @@ -test_true([["$Id: testsuite.in,v 1.34 1997/03/09 09:11:13 hubbe Exp $"]]) +test_true([["$Id: testsuite.in,v 1.35 1997/03/11 03:36:42 hubbe Exp $"]]) +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"); }]]) test_true([[lambda(function f) {return 1;}(object_program(this_object()));]]) test_eq([[class { int `()(){ return 4711; } }()(); ]],4711)