--- parser3/src/main/execute.C 2009/05/04 09:26:00 1.332 +++ parser3/src/main/execute.C 2009/05/19 08:44:00 1.334 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char * const IDENT_EXECUTE_C="$Date: 2009/05/04 09:26:00 $"; +static const char * const IDENT_EXECUTE_C="$Date: 2009/05/19 08:44:00 $"; #include "pa_opcode.h" #include "pa_array.h" @@ -46,6 +46,10 @@ char *opcode_name[]={ "GET_ELEMENT_OR_OPERATOR", #endif "GET_ELEMENT", +#ifdef OPTIMIZE_BYTECODE_GET_ELEMENT_FIELD + "GET_ELEMENT_FIELD", + "GET_ELEMENT_FIELD__WRITE", +#endif #ifdef OPTIMIZE_BYTECODE_GET_ELEMENT "VALUE__GET_ELEMENT", #endif @@ -76,10 +80,10 @@ void va_debug_printf(SAPI_Info& sapi_inf } void debug_printf(SAPI_Info& sapi_info, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - va_debug_printf(sapi_info, fmt, args); - va_end(args); + va_list args; + va_start(args, fmt); + va_debug_printf(sapi_info, fmt, args); + va_end(args); } void debug_dump(SAPI_Info& sapi_info, int level, ArrayOperation& ops) { @@ -87,6 +91,23 @@ void debug_dump(SAPI_Info& sapi_info, in while(i.has_next()) { OP::OPCODE opcode=i.next().code; +#if defined(OPTIMIZE_BYTECODE_GET_ELEMENT_FIELD) && defined(OPTIMIZE_BYTECODE_USE_TWO_OPERANDS_INSTRUCTIONS) + if( + opcode==OP::OP_GET_ELEMENT_FIELD + || opcode==OP::OP_GET_ELEMENT_FIELD__WRITE + ){ + i.next(); // skip origin + Value& value1=*i.next().value; + i.next(); // skip origin + Value& value2=*i.next().value; + debug_printf(sapi_info, + "%*s%s" + " \"%s\" \"%s\"", + level*4, "", opcode_name[opcode], + value1.get_string()->cstr(), value2.get_string()->cstr()); + continue; + } +#endif if( opcode==OP::OP_VALUE || opcode==OP::OP_STRING__WRITE @@ -98,6 +119,10 @@ void debug_dump(SAPI_Info& sapi_info, in || opcode==OP::OP_VALUE__GET_ELEMENT__WRITE || opcode==OP::OP_VALUE__GET_ELEMENT_OR_OPERATOR #endif +#if defined(OPTIMIZE_BYTECODE_GET_ELEMENT_FIELD) && !defined(OPTIMIZE_BYTECODE_USE_TWO_OPERANDS_INSTRUCTIONS) + || opcode==OP::OP_GET_ELEMENT_FIELD + || opcode==OP::OP_GET_ELEMENT_FIELD__WRITE +#endif ) { Operation::Origin origin=i.next().origin; Value& value=*i.next().value; @@ -344,6 +369,39 @@ void Request::execute(ArrayOperation& op } #endif +#ifdef OPTIMIZE_BYTECODE_GET_ELEMENT_FIELD + case OP::OP_GET_ELEMENT_FIELD: + case OP::OP_GET_ELEMENT_FIELD__WRITE: + { + debug_origin=i.next().origin; + const String& context_name=*i.next().value->get_string(); debug_name=&context_name; +#ifdef DEBUG_EXECUTE + debug_printf(sapi_info, " \"%s\" ", context_name.cstr()); +#endif + Value& object=get_element(*rcontext, context_name); + +#ifndef OPTIMIZE_BYTECODE_USE_TWO_OPERANDS_INSTRUCTIONS + i.next(); // skip OP_VALUE +#endif + + debug_origin=i.next().origin; + const String& field_name=*i.next().value->get_string(); debug_name=&field_name; +#ifdef DEBUG_EXECUTE + debug_printf(sapi_info, " \"%s\" ", field_name.cstr()); +#endif + Value& value=get_element(object, field_name); + + i.next(); // skip last OP_GET_ELEMENT + + if(opcode==OP::OP_GET_ELEMENT_FIELD){ + stack.push(value); + } else { + write_assign_lang(value); + } + break; + } +#endif + case OP::OP_GET_ELEMENT: { const String& name=stack.pop().string(); debug_name=&name; @@ -1009,7 +1067,7 @@ void Request::op_call(VMethodFrame& fram 0, "is not allowed to be called %s", call_type==Method::CT_STATIC?"statically":"dynamically"); - + RESTORE_CONTEXT //return &frame; } @@ -1028,9 +1086,12 @@ void Request::op_call_write(VMethodFrame const Method& method=*junction.method; Method::Call_type call_type=junction.self.get_class()==&junction.self ? Method::CT_STATIC : Method::CT_DYNAMIC; - if( method.call_type==Method::CT_ANY || method.call_type==call_type) { // allowed call type? - method.check_actual_numbered_params(junction.self, frame.numbered_params()); - method.native_code(*this, *frame.numbered_params()); // execute it + if(method.call_type==Method::CT_ANY || method.call_type==call_type) { // allowed call type? + if(method.native_code) { // native code? + method.check_actual_numbered_params(junction.self, frame.numbered_params()); + method.native_code(*this, *frame.numbered_params()); // execute it + } else // parser code, execute it + recoursion_checked_execute(*method.parser_code); } else throw Exception(PARSER_RUNTIME, 0, @@ -1109,7 +1170,7 @@ void Request::put_element(Value& ncontex nothing goes to wcontext. used in @c (expression) params evaluation - using the fact it's either string_ or value_ result requested to speed up checkes + using the fact it's either string_ or value_ result requested to speed up checkes */ StringOrValue Request::process(Value& input_value, bool intercept_string) { Junction* junction=input_value.get_junction();