--- parser3/src/main/execute.C 2003/02/17 15:34:19 1.295.2.13 +++ parser3/src/main/execute.C 2003/03/04 10:15:01 1.295.2.22 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char* IDENT_EXECUTE_C="$Date: 2003/02/17 15:34:19 $"; +static const char* IDENT_EXECUTE_C="$Date: 2003/03/04 10:15:01 $"; #include "pa_opcode.h" #include "pa_array.h" @@ -23,15 +23,7 @@ static const char* IDENT_EXECUTE_C="$Dat #include "pa_vimage.h" #include "pa_wwrapper.h" -#define DEBUG_EXECUTE -//#define DEBUG_STRING_APPENDS_VS_EXPANDS - - -#ifdef DEBUG_STRING_APPENDS_VS_EXPANDS -ulong wcontext_result_size=0; -#endif - - +// #define DEBUG_EXECUTE #ifdef DEBUG_EXECUTE char *opcode_name[]={ @@ -75,7 +67,7 @@ void debug_printf(SAPI_Info& sapi_info, va_end(args); } -void debug_dump(SAPI_Info& sapi_info, int level, ArrayOperation& ops) { +void debug_dump(SAPI_Info& sapi_info, Pool& pool, int level, ArrayOperation& ops) { Array_iterator i(ops); while(i.has_next()) { Operation& op=i.next(); @@ -86,7 +78,7 @@ void debug_dump(SAPI_Info& sapi_info, in "%*s%s" " \"%s\" %s", level*4, "", opcode_name[op.code], - value->get_string(0)->cstr().get(), value->type()); + value->get_string(&pool)->cstr().get(), value->type()); continue; } debug_printf(sapi_info, "%*s%s", level*4, "", opcode_name[op.code]); @@ -101,7 +93,7 @@ void debug_dump(SAPI_Info& sapi_info, in case OP_CALL: case OP_CALL__WRITE: if(ArrayOperation* local_ops=i.next().ops.get()) - debug_dump(sapi_info, level+1, *local_ops); + debug_dump(sapi_info, pool, level+1, *local_ops); } } } @@ -113,12 +105,21 @@ void Request::execute(ArrayOperation& op // _asm int 3; #ifdef DEBUG_EXECUTE debug_printf(sapi_info, "source----------------------------\n"); - debug_dump(sapi_info, 0, ops); + debug_dump(sapi_info, pool(), 0, ops); debug_printf(sapi_info, "execution-------------------------\n"); #endif StringPtr last_get_element_name(0); Array_iterator i(ops); + ValuePtr value; + ValuePtr a; ValuePtr b; + //ArrayOperationPtr b_code; + + StringPtr name; + Value* ncontext; + + ArrayOperationPtr local_ops; + while(i.has_next()) { if(interrupted()) throw Exception("parser.interrupted", @@ -130,22 +131,13 @@ void Request::execute(ArrayOperation& op debug_printf(sapi_info, "%d:%s", stack.top_index()+1, opcode_name[op.code]); #endif - ValuePtr value; - ValuePtr a; ValuePtr b; - //ArrayOperationPtr b_code; - - StringPtr name; - Value* ncontext; - - ArrayOperationPtr local_ops; - switch(op.code) { // param in next instruction case OP_VALUE: { value=i.next().value; #ifdef DEBUG_EXECUTE - debug_printf(sapi_info, " \"%s\" %s", value->get_string(0)->cstr().get(), value->type()); + debug_printf(sapi_info, " \"%s\" %s", value->get_string(&pool())->cstr().get(), value->type()); #endif stack.push(value); break; @@ -155,7 +147,7 @@ void Request::execute(ArrayOperation& op // maybe they do ^class:method[] call, remember the fact wcontext->set_somebody_entered_some_class(); - name=stack.pop().string(); + name=stack.pop().string(pool()); value=classes().get(name); if(!value) throw Exception("parser.runtime", @@ -197,7 +189,7 @@ void Request::execute(ArrayOperation& op case OP_CONSTRUCT_VALUE: { value=stack.pop().value; - name=stack.pop().string(); + name=stack.pop().string(pool()); ncontext=stack.pop().value.get(); ncontext->put_element(name, value, false); break; @@ -208,7 +200,7 @@ void Request::execute(ArrayOperation& op wcontext->set_in_expression(false); value=stack.pop().value; - name=stack.pop().string(); + name=stack.pop().string(pool()); ncontext=stack.pop().value.get(); ncontext->put_element(name, value->as_expr_result(), false); break; @@ -218,7 +210,7 @@ void Request::execute(ArrayOperation& op local_ops=i.next().ops; #ifdef DEBUG_EXECUTE debug_printf(sapi_info, " (%d)\n", local_ops->count()); - debug_dump(sapi_info, 1, *local_ops); + debug_dump(sapi_info, pool(), 1, *local_ops); #endif value=ValuePtr(new VJunction(JunctionPtr(new Junction( get_self(), 0, @@ -227,7 +219,7 @@ void Request::execute(ArrayOperation& op wcontext, local_ops)))); - name=stack.pop().string(); + name=stack.pop().string(pool()); ncontext=stack.pop().value.get(); ncontext->put_element(name, value, false); break; @@ -237,7 +229,7 @@ void Request::execute(ArrayOperation& op local_ops=i.next().ops; #ifdef DEBUG_EXECUTE debug_printf(sapi_info, " (%d)\n", local_ops->count()); - debug_dump(sapi_info, 1, *local_ops); + debug_dump(sapi_info, pool(), 1, *local_ops); #endif stack.push(local_ops); break; @@ -294,9 +286,9 @@ void Request::execute(ArrayOperation& op local_ops=i.next().ops; WContext *saved_wcontext=wcontext; - uchar saved_lang= flang; + String_UL saved_lang=flang; flang=String::UL_PASS_APPENDED; - WWrapper local(ValuePtr(0)/*empty*/, wcontext); + WWrapper local(ValuePtr(0)/*empty*/, wcontext); local.ref(); wcontext=&local; execute(*local_ops); @@ -313,7 +305,7 @@ void Request::execute(ArrayOperation& op local_ops=i.next().ops; WContext *saved_wcontext=wcontext; - WWrapper local(ValuePtr(0) /*empty*/, wcontext); + WWrapper local(ValuePtr(0) /*empty*/, wcontext); local.ref(); wcontext=&local; execute(*local_ops); @@ -347,7 +339,7 @@ void Request::execute(ArrayOperation& op VMethodFrame *frame=static_cast(stack.top_value().ptr); #ifdef DEBUG_EXECUTE debug_printf(sapi_info, " (%d)\n", local_ops->count()); - debug_dump(sapi_info, 1, *local_ops); + debug_dump(sapi_info, pool(), 1, *local_ops); #endif // when they evaluate expression parameter, // the object expression result @@ -387,7 +379,7 @@ void Request::execute(ArrayOperation& op #ifdef DEBUG_EXECUTE debug_printf(sapi_info, " (%d)\n", local_ops?local_ops->count():0); if(local_ops) - debug_dump(sapi_info, 1, *local_ops); + debug_dump(sapi_info, pool(), 1, *local_ops); debug_printf(sapi_info, "->\n"); #endif @@ -491,11 +483,6 @@ void Request::execute(ArrayOperation& op rcontext=saved_rcontext; method_frame=saved_method_frame; -#ifdef DEBUG_STRING_APPENDS_VS_EXPANDS - if(const String *s=value->get_string()) - wcontext_result_size+=s->used_rows()*sizeof(String::Chunk::Row); -#endif - if(op.code==OP_CALL__WRITE) { write_assign_lang(result, last_get_element_name); } else { // OP_CALL @@ -772,42 +759,42 @@ void Request::execute(ArrayOperation& op case OP_STR_LT: { b=stack.pop().value; a=stack.pop().value; - value=ValuePtr(new VBool(a->as_string(&pool()) < b->as_string(&pool()))); + value=ValuePtr(new VBool(*a->as_string(&pool()) < *b->as_string(&pool()))); stack.push(value); break; } case OP_STR_GT: { b=stack.pop().value; a=stack.pop().value; - value=ValuePtr(new VBool(a->as_string(&pool()) > b->as_string(&pool()))); + value=ValuePtr(new VBool(*a->as_string(&pool()) > *b->as_string(&pool()))); stack.push(value); break; } case OP_STR_LE: { b=stack.pop().value; a=stack.pop().value; - value=ValuePtr(new VBool(a->as_string(&pool()) <= b->as_string(&pool()))); + value=ValuePtr(new VBool(*a->as_string(&pool()) <= *b->as_string(&pool()))); stack.push(value); break; } case OP_STR_GE: { b=stack.pop().value; a=stack.pop().value; - value=ValuePtr(new VBool(a->as_string(&pool()) >= b->as_string(&pool()))); + value=ValuePtr(new VBool(*a->as_string(&pool()) >= *b->as_string(&pool()))); stack.push(value); break; } case OP_STR_EQ: { b=stack.pop().value; a=stack.pop().value; - value=ValuePtr(new VBool(a->as_string(&pool()) == b->as_string(&pool()))); + value=ValuePtr(new VBool(*a->as_string(&pool()) == *b->as_string(&pool()))); stack.push(value); break; } case OP_STR_NE: { b=stack.pop().value; a=stack.pop().value; - value=ValuePtr(new VBool(a->as_string(&pool()) != b->as_string(&pool()))); + value=ValuePtr(new VBool(*a->as_string(&pool()) != *b->as_string(&pool()))); stack.push(value); break; } @@ -832,13 +819,13 @@ void Request::execute(ArrayOperation& op @bug ^superbase:method would dynamically call ^base:method if there is any */ ValuePtr Request::get_element(StringPtr& remember_name, bool can_call_operator) { - StringPtr name=stack.pop().string(); remember_name=name; - Value* ncontext=stack.pop().value.get(); - ValuePtr value(0); + StringPtr name=stack.pop().string(pool()); remember_name=name; + ValuePtr ncontext=stack.pop().value; + ValuePtr value; if(can_call_operator) { - if(Method* method=main_class->get_method(name)) // looking operator of that name FIRST + if(MethodPtr method=main_class->get_method(name)) // looking operator of that name FIRST value=ValuePtr(new VJunction(JunctionPtr(new Junction( - main_class, method, 0,0,0, ArrayOperationPtr(0))))); + main_class, method.get(), 0,0,0, ArrayOperationPtr(0))))); } if(!value) { if(!wcontext->get_constructing() // not constructing @@ -857,10 +844,11 @@ ValuePtr Request::get_element(StringPtr& if(value && wcontext->get_constructing()) if(JunctionPtr junction=value->get_junction()) { - if(junction->self->get_class()!=ncontext) + if(junction->self->get_class()!=ncontext.get()) throw Exception("parser.runtime", name, - "constructor must be declared in class %s", ncontext->get_class()->name_cstr()); + "constructor must be declared in class '%s'", + ncontext->get_class()->name_cstr()); } value_ready: @@ -911,7 +899,7 @@ StringOrValue Request::process(ValuePtr if(using_code_frame) { // almost plain wwrapper about junction wcontext, // BUT intercepts string writes - VCodeFrame local(*junction->wcontext, junction->wcontext); + VCodeFrame local(*junction->wcontext, junction->wcontext); local.ref(); wcontext=&local; // execute it @@ -923,7 +911,7 @@ StringOrValue Request::process(ValuePtr result.set_string(wcontext->get_string(&pool())); } else { // plain wwrapper - WWrapper local(ValuePtr(0)/*empty*/, wcontext); + WWrapper local(ValuePtr(0)/*empty*/, wcontext); local.ref(); wcontext=&local; // execute it @@ -1002,20 +990,16 @@ StringPtr Request::execute_method(ValueP return result; } -StringPtr Request::execute_nonvirtual_method(VStateless_class& aclass, +Request::Execute_nonvirtual_method_result +Request::execute_nonvirtual_method(VStateless_class& aclass, StringPtr method_name, VStringPtr optional_param, - bool do_return_string, - const Method **return_method) { - - const Method *method=aclass.get_method(method_name); - StringPtr result(0); - if(return_method) - *return_method=method; - - if(method) - return execute_method(ValuePtr(&aclass), *method, optional_param, do_return_string); - else - return StringPtr(0); + bool do_return_string) { + Execute_nonvirtual_method_result result; + result.method=aclass.get_method(method_name); + if(result.method) + result.string=execute_method(ValuePtr(&aclass), *result.method, optional_param, + do_return_string); + return result; } StringPtr Request::execute_virtual_method(ValuePtr aself,