--- parser3/src/main/compile.y 2009/04/17 09:11:15 1.231 +++ parser3/src/main/compile.y 2009/05/09 10:45:43 1.237 @@ -5,7 +5,7 @@ Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexander Petrosyan (http://design.ru/paf) - $Id: compile.y,v 1.231 2009/04/17 09:11:15 misha Exp $ + $Id: compile.y,v 1.237 2009/05/09 10:45:43 misha Exp $ */ /** @@ -251,7 +251,6 @@ maybe_string: empty | STRING; code_method: '@' STRING bracketed_maybe_strings maybe_bracketed_strings maybe_comment '\n' { PC.class_add(); PC.explicit_result=false; - PC.write_to_result=false; YYSTYPE params_names_code=$3; ArrayString* params_names=0; @@ -294,9 +293,6 @@ code_method: '@' STRING bracketed_maybe_ // fill in the code method.parser_code=$8; - // write to $result was detected in method's code during compilation - method.write_to_result=PC.write_to_result; - // register in class const String& name=*LA2S(*$2); PC.cclass->add_method(PC.alias_method(name), method); @@ -321,10 +317,13 @@ action: get | put | call; get: get_value { $$=$1; /* stack: resulting value */ - changetail_or_append(*$$, - OP::OP_GET_ELEMENT, false, /*->*/OP::OP_GET_ELEMENT__WRITE, - /*or */OP::OP_WRITE_VALUE - ); /* value=pop; wcontext.write(value) */ +#ifdef OPTIMIZE_BYTECODE_GET_ELEMENT + if(!replace_top_opcode(*$$, OP::OP_VALUE__GET_ELEMENT, OP::OP_VALUE__GET_ELEMENT__WRITE)) +#endif + changetail_or_append(*$$, + OP::OP_GET_ELEMENT, false, /*->*/OP::OP_GET_ELEMENT__WRITE, + /*or */OP::OP_WRITE_VALUE + ); /* value=pop; wcontext.write(value) */ }; get_value: '$' get_name_value { $$=$2 }; get_name_value: name_without_curly_rdive EON | name_in_curly_rdive; @@ -344,6 +343,20 @@ name_without_curly_rdive_read: name_with /* skip over... */ diving_code->count()>=4?4/*OP::OP_VALUE+origin+string+OP::OP_GET_ELEMENTx*/:3/*OP::OP_+origin+string*/); } else { +#ifdef OPTIMIZE_BYTECODE_GET_ELEMENT + size_t count=diving_code->count(); + if(count==4){ // optimisations for popular simple cases + O(*yyval, + (PC.in_call_value) // ^call + ? OP::OP_VALUE__GET_ELEMENT_OR_OPERATOR // OP_VALUE+origin+string+OP_GET_ELEMENT -> OP_VALUE__GET_ELEMENT_OR_OPERATOR+origin+string + : OP::OP_VALUE__GET_ELEMENT // OP_VALUE+origin+string+OP_GET_ELEMENT -> OP_VALUE__GET_ELEMENT+origin+string + ); + P(*$$, *diving_code, 1/*offset*/, 2/*limit*/); // copy origin+value + } else { + O(*yyval, OP::OP_WITH_READ); /* stack: starting context */ + P(*$$, *diving_code); + } +#else O(*yyval, OP::OP_WITH_READ); /* stack: starting context */ // ^if ELEMENT -> ^if ELEMENT_OR_OPERATOR @@ -351,6 +364,7 @@ name_without_curly_rdive_read: name_with if(PC.in_call_value && diving_code->count()==4) diving_code->put(4-1, OP::OP_GET_ELEMENT_OR_OPERATOR); P(*$$, *diving_code); +#endif } /* diving code; stack: current context */ }; @@ -379,8 +393,6 @@ name_expr_wdive_root: name_expr_dive_cod /* skip over... */ diving_code->count()>=4?4/*OP::OP_VALUE+origin+string+OP::OP_GET_ELEMENTx*/:3/*OP::OP_+origin+string*/); } else { - if(first_name && *first_name==RESULT_VAR_NAME) - PC.write_to_result=true; O(*$$, OP::OP_WITH_ROOT); /* stack: starting context */ P(*$$, *diving_code); } @@ -455,7 +467,7 @@ call_value: '^' { $$=$3; /* with_xxx,diving code; stack: context,method_junction */ YYSTYPE params_code=$5; - if(params_code->count()==4) { // probably [] case. [OP::OP_VALUE+origin+Void+STORE_PARAM] + if(params_code->count()==3) { // probably [] case. [OP::OP_VALUE+origin+Void] if(Value* value=LA2V(*params_code)) // it is OP_VALUE+origin+value? if(value->is_void()) // value is VVoid? params_code=0; // ^zzz[] case. don't append lone empty param. @@ -494,14 +506,12 @@ store_curly_param_parts: ; store_code_param_part: code_param_value { $$=$1; - O(*$$, OP::OP_STORE_PARAM); }; store_expr_param_part: expr_value { YYSTYPE expr_code=$1; if(expr_code->count()==3 - && (*expr_code)[0].code==OP::OP_VALUE) { // optimizing (double/bool/incidently 'string' too) case. [OP::OP_VALUE+origin+Double] + && (*expr_code)[0].code==OP::OP_VALUE) { // optimizing (double/bool/incidently 'string' too) case. [OP::OP_VALUE+origin+Double]. no evaluating $$=expr_code; - O(*$$, OP::OP_STORE_PARAM); // no evaluating } else { ArrayOperation* code=N(); O(*code, OP::OP_PREPARE_TO_EXPRESSION); @@ -597,7 +607,12 @@ class_static_prefix: STRING ':' { YYERROR; } } +#ifdef OPTIMIZE_BYTECODE_GET_CLASS + // OP_VALUE+origin+string+OP_GET_CLASS -> OP_VALUE__GET_CLASS+origin+string + replace_top_opcode(*$$, OP::OP_VALUE, OP::OP_VALUE__GET_CLASS, true/*assert if top opcode != OP_VALUE*/) +#else O(*$$, OP::OP_GET_CLASS); +#endif }; class_constructor_prefix: class_static_prefix ':' { $$=$1;