--- parser3/src/main/execute.C 2003/02/17 10:44:55 1.295.2.11 +++ parser3/src/main/execute.C 2003/03/12 10:47:13 1.295.2.26 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char* IDENT_EXECUTE_C="$Date: 2003/02/17 10:44:55 $"; +static const char* IDENT_EXECUTE_C="$Date: 2003/03/12 10:47:13 $"; #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]); @@ -99,59 +91,55 @@ void debug_dump(SAPI_Info& sapi_info, in case OP_OBJECT_POOL: case OP_STRING_POOL: case OP_CALL: - ArrayOperation& local_ops=*i.next().ops; - debug_dump(sapi_info, level+1, local_ops); + case OP_CALL__WRITE: + if(ArrayOperation* local_ops=i.next().ops.get()) + debug_dump(sapi_info, pool, level+1, *local_ops); } } } #endif -/*#define stack.push(value) stack.push(value.get()) -#define stack.pop().value static_cast(stack.pop()) - -#define stack.push(value) stack.push(value) -#define stack.pop().string static_cast(stack.pop())->as_string(&pool()).get() -#define POP_CODE() static_cast(stack.pop()) -*/ // Request void Request::execute(ArrayOperation& ops) { // _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; + ValuePtr ncontext; + + ArrayOperationPtr local_ops; + while(i.has_next()) { - if(interrupted()) + if(get_interrupted()) { + set_interrupted(false); throw Exception("parser.interrupted", Exception::undefined_source, "execution stopped"); + } Operation& op=i.next(); #ifdef DEBUG_EXECUTE 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; @@ -161,7 +149,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", @@ -192,7 +180,7 @@ void Request::execute(ArrayOperation& op { if(wcontext==method_frame) throw Exception("parser.runtime", - Exception::undefined_source, + Exception::undefined_source, "$.name outside of $name[...]"); stack.push(ValuePtr(wcontext)); @@ -203,8 +191,8 @@ void Request::execute(ArrayOperation& op case OP_CONSTRUCT_VALUE: { value=stack.pop().value; - name=stack.pop().string; - ncontext=stack.pop().value.get(); + name=stack.pop().string(pool()); + ncontext=stack.pop().value; ncontext->put_element(name, value, false); break; } @@ -214,8 +202,8 @@ void Request::execute(ArrayOperation& op wcontext->set_in_expression(false); value=stack.pop().value; - name=stack.pop().string; - ncontext=stack.pop().value.get(); + name=stack.pop().string(pool()); + ncontext=stack.pop().value; ncontext->put_element(name, value->as_expr_result(), false); break; } @@ -224,7 +212,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, @@ -233,8 +221,8 @@ void Request::execute(ArrayOperation& op wcontext, local_ops)))); - name=stack.pop().string; - ncontext=stack.pop().value.get(); + name=stack.pop().string(pool()); + ncontext=stack.pop().value; ncontext->put_element(name, value, false); break; } @@ -243,7 +231,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; @@ -300,9 +288,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); @@ -319,7 +307,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); @@ -340,7 +328,7 @@ void Request::execute(ArrayOperation& op case OP_STORE_PARAM: { value=stack.pop().value; - VMethodFrame *frame=static_cast(stack.top_value().unknown); + VMethodFrame *frame=static_cast(stack.top_value().ptr); // this op is executed from CALL local_ops only, so may skip the check "method_frame_to_fill==0" frame->store_param(value); break; @@ -350,10 +338,10 @@ void Request::execute(ArrayOperation& op { // code local_ops=i.next().ops; - VMethodFrame *frame=static_cast(stack.top_value().unknown); + 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 @@ -391,8 +379,9 @@ 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_printf(sapi_info, " (%d)\n", local_ops?local_ops->count():0); + if(local_ops) + debug_dump(sapi_info, pool(), 1, *local_ops); debug_printf(sapi_info, "->\n"); #endif @@ -417,7 +406,7 @@ void Request::execute(ArrayOperation& op value->type()); */ - VMethodFrame frame(pool(), last_get_element_name, *junction, method_frame/*caller*/); + VMethodFrame frame(pool(), last_get_element_name, *junction, method_frame/*caller*/); frame.ref(); if(local_ops){ // store param code goes here stack.push(&frame); // argument for *STORE_PARAM ops execute(*local_ops); @@ -467,7 +456,9 @@ void Request::execute(ArrayOperation& op if( method.call_type==Method::CT_ANY || method.call_type==call_type) { // allowed call type? +#if _MSC_VER & !defined(_DEBUG) try { +#endif method_frame=&frame; if(method.native_code) { // native code? method.check_actual_numbered_params( @@ -478,11 +469,13 @@ void Request::execute(ArrayOperation& op frame.name(), frame.numbered_params()); // execute it } else // parser code, execute it recoursion_checked_execute(frame.name(), *method.parser_code); +#if _MSC_VER & !defined(_DEBUG) } catch(...) { // record it to stack trace exception_trace.push(frame.name()); rethrow; } +#endif } else throw Exception("parser.runtime", frame.name(), @@ -496,11 +489,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 @@ -777,42 +765,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; } @@ -837,13 +825,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 @@ -862,10 +850,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: @@ -916,7 +905,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 @@ -928,7 +917,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 @@ -980,15 +969,13 @@ StringPtr Request::execute_method(ValueP WContext *saved_wcontext=wcontext; Junction local_junction(aself, &method, 0,0,0, ArrayOperationPtr(0)); - VMethodFrame local_frame(pool(), method.name, local_junction, method_frame/*caller*/); + VMethodFrame local_frame(pool(), method.name, local_junction, method_frame/*caller*/); local_frame.ref(); if(optional_param && local_frame.can_store_param()) { local_frame.store_param(optional_param); local_frame.fill_unspecified_params(); } local_frame.set_self(aself); rcontext=wcontext=method_frame=&local_frame; - // preventing local object from deletes - local_frame.ref(); // prevent non-string writes for better error reporting if(do_return_string) @@ -1009,20 +996,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,