--- parser3/src/main/compile.y 2009/04/17 12:00:08 1.232 +++ parser3/src/main/compile.y 2009/05/01 11:42:14 1.236 @@ -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.232 2009/04/17 12:00:08 misha Exp $ + $Id: compile.y,v 1.236 2009/05/01 11:42:14 misha Exp $ */ /** @@ -317,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; @@ -340,6 +343,22 @@ 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 || (count>4 && PC.in_call_value)){ // optimisations for popular simple cases + O(*yyval, + (count==4 && 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 + if(count>4) + P(*$$, *diving_code, 4/*offset*/); // copy tail + } 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 @@ -347,6 +366,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 */ }; @@ -449,7 +469,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. @@ -488,14 +508,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); @@ -591,7 +609,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;