--- parser3/src/main/execute.C 2003/03/26 07:45:23 1.295.2.27.2.10 +++ parser3/src/main/execute.C 2003/04/03 10:48:25 1.295.2.27.2.19 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char* IDENT_EXECUTE_C="$Date: 2003/03/26 07:45:23 $"; +static const char* IDENT_EXECUTE_C="$Date: 2003/04/03 10:48:25 $"; #include "pa_opcode.h" #include "pa_array.h" @@ -23,8 +23,7 @@ static const char* IDENT_EXECUTE_C="$Dat #include "pa_vimage.h" #include "pa_wwrapper.h" -// #define DEBUG_EXECUTE -#define PA_DEBUG_NO_STACK_TRACE +//#define DEBUG_EXECUTE #ifdef DEBUG_EXECUTE char *opcode_name[]={ @@ -71,20 +70,20 @@ void debug_printf(SAPI_Info& sapi_info, void debug_dump(SAPI_Info& sapi_info, int level, ArrayOperation& ops) { Array_iterator i(ops); while(i.has_next()) { - Operation op=i.next(); + OPCODE opcode=i.next().code(); - if(op.code==OP_VALUE || op.code==OP_STRING__WRITE) { - Value* value=i.next().value; + if(opcode==OP_VALUE || opcode==OP_STRING__WRITE) { + Value& value=*i.next().value; debug_printf(sapi_info, "%*s%s" " \"%s\" %s", - level*4, "", opcode_name[op.code], - value->get_string()->cstr(), value->type()); + level*4, "", opcode_name[opcode], + value.get_string()->cstr(), value.type()); continue; } - debug_printf(sapi_info, "%*s%s", level*4, "", opcode_name[op.code]); + debug_printf(sapi_info, "%*s%s", level*4, "", opcode_name[opcode]); - switch(op.code) { + switch(opcode) { case OP_CURLY_CODE__STORE_PARAM: case OP_EXPR_CODE__STORE_PARAM: case OP_CURLY_CODE__CONSTRUCT: @@ -103,41 +102,36 @@ void debug_dump(SAPI_Info& sapi_info, in // Request void Request::execute(ArrayOperation& ops) { -// _asm int 3; + register Stack& stack=this->stack; // helps a lot on MSVC: 'esi' + + const String* debug_name=0; Operation::Info debug_info; //bool is_debug_junction=false; + try{ #ifdef DEBUG_EXECUTE debug_printf(sapi_info, "source----------------------------\n"); debug_dump(sapi_info, 0, ops); debug_printf(sapi_info, "execution-------------------------\n"); #endif - Array_iterator i(ops); - Value* value; - Value* a; Value* b; - - const String* name; - Value* ncontext; - - ArrayOperation* local_ops; - - while(i.has_next()) { + for(Array_iterator i(ops); i.has_next(); ) { if(get_interrupted()) { set_interrupted(false); throw Exception("parser.interrupted", 0, "execution stopped"); } + Operation::Info opinfo=i.next().info; - Operation op=i.next(); #ifdef DEBUG_EXECUTE - debug_printf(sapi_info, "%d:%s", stack.top_index()+1, opcode_name[op.code]); + debug_printf(sapi_info, "%d:%s", stack.top_index()+1, opcode_name[opinfo.code()]); #endif - switch(op.code) { + switch(opinfo.code()) { // param in next instruction case OP_VALUE: { - value=i.next().value; + debug_info=opinfo; + Value& value=*i.next().value; #ifdef DEBUG_EXECUTE - debug_printf(sapi_info, " \"%s\" %s", value->get_string()->cstr(), value->type()); + debug_printf(sapi_info, " \"%s\" %s", value.get_string()->cstr(), value.type()); #endif stack.push(value); break; @@ -147,31 +141,31 @@ void Request::execute(ArrayOperation& op // maybe they do ^class:method[] call, remember the fact wcontext->set_somebody_entered_some_class(); - name=stack.pop().string(); - value=classes().get(*name); + const String& name=stack.pop().string(); + Value* value=classes().get(name); if(!value) throw Exception("parser.runtime", - name, + &name, "class is undefined"); - stack.push(value); + stack.push(*value); break; } // OP_WITH case OP_WITH_ROOT: { - stack.push(method_frame); + stack.push(*method_frame); break; } case OP_WITH_SELF: { - stack.push(&get_self()); + stack.push(get_self()); break; } case OP_WITH_READ: { - stack.push(rcontext); + stack.push(*rcontext); break; } case OP_WITH_WRITE: @@ -181,17 +175,17 @@ void Request::execute(ArrayOperation& op 0, "$.name outside of $name[...]"); - stack.push(wcontext); + stack.push(*wcontext); break; } // OTHER ACTIONS BUT WITHs case OP_CONSTRUCT_VALUE: { - value=stack.pop().value; - name=stack.pop().string(); - ncontext=stack.pop().value; - ncontext->put_element(*name, value, false); + Value& value=stack.pop().value(); + const String& name=stack.pop().string(); debug_name=&name; + Value& ncontext=stack.pop().value(); + ncontext.put_element(name, &value, false); break; } case OP_CONSTRUCT_EXPR: @@ -199,51 +193,51 @@ void Request::execute(ArrayOperation& op // see OP_PREPARE_TO_EXPRESSION wcontext->set_in_expression(false); - value=stack.pop().value; - name=stack.pop().string(); - ncontext=stack.pop().value; - ncontext->put_element(*name, value->as_expr_result(), false); + Value& value=stack.pop().value(); + const String& name=stack.pop().string(); debug_name=&name; + Value& ncontext=stack.pop().value(); + ncontext.put_element(name, &value.as_expr_result(), false); break; } case OP_CURLY_CODE__CONSTRUCT: { - local_ops=i.next().ops; + ArrayOperation& 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.count()); + debug_dump(sapi_info, 1, local_ops); #endif - value=new VJunction(new Junction( + Value& value=*new VJunction(new Junction( get_self(), 0, method_frame, rcontext, wcontext, - local_ops)); + &local_ops)); - name=stack.pop().string(); - ncontext=stack.pop().value; - ncontext->put_element(*name, value, false); + const String& name=stack.pop().string(); debug_name=&name; + Value& ncontext=stack.pop().value(); + ncontext.put_element(name, &value, false); break; } case OP_NESTED_CODE: { - local_ops=i.next().ops; + ArrayOperation& 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.count()); + debug_dump(sapi_info, 1, local_ops); #endif stack.push(local_ops); break; } case OP_WRITE_VALUE: { - value=stack.pop().value; - write_assign_lang(*value); + Value& value=stack.pop().value(); + write_assign_lang(value); break; } case OP_WRITE_EXPR_RESULT: { - value=stack.pop().value; - write_no_lang(*value->as_expr_result()); + Value& value=stack.pop().value(); + write_no_lang(value.as_expr_result()); // must be after write(result) and // see OP_PREPARE_TO_EXPRESSION @@ -252,7 +246,7 @@ void Request::execute(ArrayOperation& op } case OP_STRING__WRITE: { - value=i.next().value; + Value* value=i.next().value; #ifdef DEBUG_EXECUTE debug_printf(sapi_info, " \"%s\"", value->get_string()->cstr()); #endif @@ -262,28 +256,34 @@ void Request::execute(ArrayOperation& op case OP_GET_ELEMENT_OR_OPERATOR: { - value=get_element(true); + const String& name=stack.pop().string(); debug_name=&name; + Value& ncontext=stack.pop().value(); + Value& value=get_element(ncontext, name, true); stack.push(value); break; } case OP_GET_ELEMENT: { - value=get_element(false); + const String& name=stack.pop().string(); debug_name=&name; + Value& ncontext=stack.pop().value(); + Value& value=get_element(ncontext, name, false); stack.push(value); break; } case OP_GET_ELEMENT__WRITE: { - value=get_element(false); - write_assign_lang(*value); + const String& name=stack.pop().string(); debug_name=&name; + Value& ncontext=stack.pop().value(); + Value& value=get_element(ncontext, name, false); + write_assign_lang(value); break; } case OP_OBJECT_POOL: { - local_ops=i.next().ops; + ArrayOperation& local_ops=*i.next().ops; WContext *saved_wcontext=wcontext; String::Language saved_lang=flang; @@ -291,55 +291,55 @@ void Request::execute(ArrayOperation& op WWrapper local(0/*empty*/, wcontext); wcontext=&local; - execute(*local_ops); + execute(local_ops); - value=&wcontext->result().as_value(); + stack.push(wcontext->result().as_value()); flang=saved_lang; wcontext=saved_wcontext; - stack.push(value); break; } case OP_STRING_POOL: { - local_ops=i.next().ops; + ArrayOperation& local_ops=*i.next().ops; WContext *saved_wcontext=wcontext; WWrapper local(0 /*empty*/, wcontext); wcontext=&local; - execute(*local_ops); + execute(local_ops); + Value* value; // from "$a $b" part of expression taking only string value, // ignoring any other content of wcontext if(const String* string=wcontext->get_string()) value=new VString(*string); else value=new VVoid; + stack.push(*value); wcontext=saved_wcontext; - stack.push(value); break; } // CALL case OP_STORE_PARAM: { - value=stack.pop().value; - VMethodFrame *frame=stack.top_value().method_frame; + Value& value=stack.pop().value(); + VMethodFrame& frame=stack.top_value().method_frame(); // this op is executed from CALL local_ops only, so may skip the check "method_frame_to_fill==0" - frame->store_param(*value); + frame.store_param(value); break; } case OP_CURLY_CODE__STORE_PARAM: case OP_EXPR_CODE__STORE_PARAM: { // code - local_ops=i.next().ops; - VMethodFrame *frame=stack.top_value().method_frame; + ArrayOperation& local_ops=*i.next().ops; + VMethodFrame& frame=stack.top_value().method_frame(); #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.count()); + debug_dump(sapi_info, 1, local_ops); #endif // when they evaluate expression parameter, // the object expression result @@ -348,15 +348,15 @@ void Request::execute(ArrayOperation& op // hence, we zero junction.wcontext here, and later // in .process we would test that field // in decision "which wwrapper to use" - value=new VJunction(new Junction( + Value& value=*new VJunction(new Junction( get_self(), 0, method_frame, rcontext, - op.code==OP_EXPR_CODE__STORE_PARAM?0:wcontext, - local_ops)); + opinfo.code()==OP_EXPR_CODE__STORE_PARAM?0:wcontext, + &local_ops)); // store param // this op is executed from CALL local_ops only, so can not check method_frame_to_fill==0 - frame->store_param(*value); + frame.store_param(value); break; } @@ -375,7 +375,8 @@ void Request::execute(ArrayOperation& op case OP_CALL: case OP_CALL__WRITE: { - local_ops=i.next().ops; + //is_debug_junction=true; + ArrayOperation* local_ops=i.next().ops; #ifdef DEBUG_EXECUTE debug_printf(sapi_info, " (%d)\n", local_ops?local_ops->count():0); if(local_ops) @@ -383,14 +384,20 @@ void Request::execute(ArrayOperation& op debug_printf(sapi_info, "->\n"); #endif - value=stack.pop().value; + Value& value=stack.pop().value(); - Junction* junction=value->get_junction(); - if(!junction) - throw Exception("parser.runtime", - 0, - "(%s) not a method or junction, can not call it", - value->type()); + Junction* junction=value.get_junction(); + if(!junction) { + if(value.is("void")) + throw Exception("parser.runtime", + 0, + "undefined method"); + else + throw Exception("parser.runtime", + 0, + "is '%s', not a method or junction, can not call it", + value.type()); + } /* no check needed, code compiled the way that that's impossible // check: // that this is method-junction, not a code-junction @@ -400,15 +407,15 @@ void Request::execute(ArrayOperation& op if(!junction->method) throw Exception("parser.runtime", - "(%s) is code junction, can not call it", - value->type()); + "is '%s', it is code junction, can not call it", + value.type()); */ VMethodFrame frame(*junction, method_frame/*caller*/); if(local_ops){ // store param code goes here - stack.push(&frame); // argument for *STORE_PARAM ops + stack.push(frame); // argument for *STORE_PARAM ops execute(*local_ops); - stack.pop().value; + stack.pop().value(); } frame.fill_unspecified_params(); VMethodFrame *saved_method_frame=method_frame; @@ -454,26 +461,16 @@ void Request::execute(ArrayOperation& op if( method.call_type==Method::CT_ANY || method.call_type==call_type) { // allowed call type? -#ifndef PA_DEBUG_NO_STACK_TRACE - try { -#endif - method_frame=&frame; - if(method.native_code) { // native code? - method.check_actual_numbered_params( - frame.junction.self, - /*frame.name(), */frame.numbered_params()); - method.native_code( - *this, - /*frame.name(), */frame.numbered_params()); // execute it - } else // parser code, execute it - recoursion_checked_execute(/*frame.name(), */*method.parser_code); -#ifndef PA_DEBUG_NO_STACK_TRACE - } catch(...) { - // record it to stack trace - exception_trace.push(frame.name()); - rethrow; - } -#endif + method_frame=&frame; + if(method.native_code) { // native code? + method.check_actual_numbered_params( + frame.junction.self, + /*frame.name(), */frame.numbered_params()); + method.native_code( + *this, + *frame.numbered_params()); // execute it + } else // parser code, execute it + recoursion_checked_execute(/*frame.name(), */*method.parser_code); } else throw Exception("parser.runtime", 0, //&frame.name(), @@ -487,66 +484,67 @@ void Request::execute(ArrayOperation& op rcontext=saved_rcontext; method_frame=saved_method_frame; - if(op.code==OP_CALL__WRITE) { + if(opinfo.code()==OP_CALL__WRITE) { write_assign_lang(result); } else { // OP_CALL - stack.push(&result.as_value()); + stack.push(result.as_value()); } #ifdef DEBUG_EXECUTE debug_printf(sapi_info, "<-returned"); #endif + //is_debug_junction=false; break; } // expression ops: unary case OP_NEG: { - a=stack.pop().value; - value=new VDouble(-a->as_double()); + Value& a=stack.pop().value(); + Value& value=*new VDouble(-a.as_double()); stack.push(value); break; } case OP_INV: { - a=stack.pop().value; - value=new VDouble(~a->as_int()); + Value& a=stack.pop().value(); + Value& value=*new VDouble(~a.as_int()); stack.push(value); break; } case OP_NOT: { - a=stack.pop().value; - value=new VBool(!a->as_bool()); + Value& a=stack.pop().value(); + Value& value=*new VBool(!a.as_bool()); stack.push(value); break; } case OP_DEF: { - a=stack.pop().value; - value=new VBool(a->is_defined()); + Value& a=stack.pop().value(); + Value& value=*new VBool(a.is_defined()); stack.push(value); break; } case OP_IN: { - a=stack.pop().value; - const String& path=a->as_string(); - value=new VBool(request_info.uri && *request_info.uri && path.this_starts(request_info.uri)); + Value& a=stack.pop().value(); + const String& path=a.as_string(); + Value& value=*new VBool(request_info.uri && *request_info.uri && path.this_starts(request_info.uri)); stack.push(value); break; } case OP_FEXISTS: { - a=stack.pop().value; - value=new VBool(file_readable(absolute(a->as_string()))); + Value& a=stack.pop().value(); + Value& value=*new VBool(file_readable(absolute(a.as_string()))); stack.push(value); break; } case OP_DEXISTS: { - a=stack.pop().value; - value=new VBool(dir_readable(absolute(a->as_string()))); + Value& a=stack.pop().value(); + Value& value=*new VBool(dir_readable(absolute(a.as_string()))); stack.push(value); break; } @@ -554,254 +552,254 @@ void Request::execute(ArrayOperation& op // expression ops: binary case OP_SUB: { - b=stack.pop().value; a=stack.pop().value; - value=new VDouble(a->as_double() - b->as_double()); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + Value& value=*new VDouble(a.as_double() - b.as_double()); stack.push(value); break; } case OP_ADD: { - b=stack.pop().value; a=stack.pop().value; - value=new VDouble(a->as_double() + b->as_double()); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + Value& value=*new VDouble(a.as_double() + b.as_double()); stack.push(value); break; } case OP_MUL: { - b=stack.pop().value; a=stack.pop().value; - value=new VDouble(a->as_double() * b->as_double()); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + Value& value=*new VDouble(a.as_double() * b.as_double()); stack.push(value); break; } case OP_DIV: { - b=stack.pop().value; a=stack.pop().value; + Value& b=stack.pop().value(); Value& a=stack.pop().value(); - double a_double=a->as_double(); - double b_double=b->as_double(); + double a_double=a.as_double(); + double b_double=b.as_double(); if(b_double == 0) { - //const String* problem_source=b->as_string(); + //const String* problem_source=b.as_string(); throw Exception("number.zerodivision", 0, //problem_source, "Division by zero"); } - value=new VDouble(a_double / b_double); + Value& value=*new VDouble(a_double / b_double); stack.push(value); break; } case OP_MOD: { - b=stack.pop().value; a=stack.pop().value; + Value& b=stack.pop().value(); Value& a=stack.pop().value(); - double a_double=a->as_double(); - double b_double=b->as_double(); + double a_double=a.as_double(); + double b_double=b.as_double(); if(b_double == 0) { - //const String* problem_source=b->as_string(); + //const String* problem_source=b.as_string(); throw Exception("number.zerodivision", 0, //problem_source, "Modulus by zero"); } - value=new VDouble(fmod(a_double, b_double)); + Value& value=*new VDouble(fmod(a_double, b_double)); stack.push(value); break; } case OP_INTDIV: { - b=stack.pop().value; a=stack.pop().value; + Value& b=stack.pop().value(); Value& a=stack.pop().value(); - int a_int=a->as_int(); - int b_int=b->as_int(); + int a_int=a.as_int(); + int b_int=b.as_int(); if(b_int == 0) { - //const String* problem_source=b->as_string(); + //const String* problem_source=b.as_string(); throw Exception("number.zerodivision", 0, //problem_source, "Division by zero"); } - value=new VInt(a_int / b_int); + Value& value=*new VInt(a_int / b_int); stack.push(value); break; } case OP_BIN_SL: { - b=stack.pop().value; a=stack.pop().value; - value=new VInt( - a->as_int() << - b->as_int()); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + Value& value=*new VInt( + a.as_int() << + b.as_int()); stack.push(value); break; } case OP_BIN_SR: { - b=stack.pop().value; a=stack.pop().value; - value=new VInt( - a->as_int() >> - b->as_int()); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + Value& value=*new VInt( + a.as_int() >> + b.as_int()); stack.push(value); break; } case OP_BIN_AND: { - b=stack.pop().value; a=stack.pop().value; - value=new VInt( - a->as_int() & - b->as_int()); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + Value& value=*new VInt( + a.as_int() & + b.as_int()); stack.push(value); break; } case OP_BIN_OR: { - b=stack.pop().value; a=stack.pop().value; - value=new VInt( - a->as_int() | - b->as_int()); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + Value& value=*new VInt( + a.as_int() | + b.as_int()); stack.push(value); break; } case OP_BIN_XOR: { - b=stack.pop().value; a=stack.pop().value; - value=new VInt( - a->as_int() ^ - b->as_int()); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + Value& value=*new VInt( + a.as_int() ^ + b.as_int()); stack.push(value); break; } case OP_LOG_AND: { - local_ops=stack.pop().ops; a=stack.pop().value; + ArrayOperation& local_ops=stack.pop().ops(); Value& a=stack.pop().value(); bool result; - if(a->as_bool()) { - execute(*local_ops); - b=stack.pop().value; - result=b->as_bool(); + if(a.as_bool()) { + execute(local_ops); + Value& b=stack.pop().value(); + result=b.as_bool(); } else result=false; - value=new VBool(result); + Value& value=*new VBool(result); stack.push(value); break; } case OP_LOG_OR: { - local_ops=stack.pop().ops; a=stack.pop().value; + ArrayOperation& local_ops=stack.pop().ops(); Value& a=stack.pop().value(); bool result; - if(a->as_bool()) + if(a.as_bool()) result=true; else { - execute(*local_ops); - b=stack.pop().value; - result=b->as_bool(); + execute(local_ops); + Value& b=stack.pop().value(); + result=b.as_bool(); } - value=new VBool(result); + Value& value=*new VBool(result); stack.push(value); break; } case OP_LOG_XOR: { - b=stack.pop().value; a=stack.pop().value; - value=new VBool(a->as_bool() ^ b->as_bool()); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + Value& value=*new VBool(a.as_bool() ^ b.as_bool()); stack.push(value); break; } case OP_NUM_LT: { - b=stack.pop().value; a=stack.pop().value; - double result=a->as_double() - b->as_double(); - value=new VBool(result < 0.0); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + double result=a.as_double() - b.as_double(); + Value& value=*new VBool(result < 0.0); stack.push(value); break; } case OP_NUM_GT: { - b=stack.pop().value; a=stack.pop().value; - double result=a->as_double() - b->as_double(); - value=new VBool(result > 0.0); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + double result=a.as_double() - b.as_double(); + Value& value=*new VBool(result > 0.0); stack.push(value); break; } case OP_NUM_LE: { - b=stack.pop().value; a=stack.pop().value; - double result=a->as_double() - b->as_double(); - value=new VBool(result <= 0.0); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + double result=a.as_double() - b.as_double(); + Value& value=*new VBool(result <= 0.0); stack.push(value); break; } case OP_NUM_GE: { - b=stack.pop().value; a=stack.pop().value; - double result=a->as_double() - b->as_double(); - value=new VBool(result >= 0.0); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + double result=a.as_double() - b.as_double(); + Value& value=*new VBool(result >= 0.0); stack.push(value); break; } case OP_NUM_EQ: { - b=stack.pop().value; a=stack.pop().value; - double result=a->as_double() - b->as_double(); - value=new VBool(result == 0.0); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + double result=a.as_double() - b.as_double(); + Value& value=*new VBool(result == 0.0); stack.push(value); break; } case OP_NUM_NE: { - b=stack.pop().value; a=stack.pop().value; - double result=a->as_double() - b->as_double(); - value=new VBool(result != 0.0); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + double result=a.as_double() - b.as_double(); + Value& value=*new VBool(result != 0.0); stack.push(value); break; } case OP_STR_LT: { - b=stack.pop().value; a=stack.pop().value; - value=new VBool(a->as_string() < b->as_string()); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + Value& value=*new VBool(a.as_string() < b.as_string()); stack.push(value); break; } case OP_STR_GT: { - b=stack.pop().value; a=stack.pop().value; - value=new VBool(a->as_string() > b->as_string()); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + Value& value=*new VBool(a.as_string() > b.as_string()); stack.push(value); break; } case OP_STR_LE: { - b=stack.pop().value; a=stack.pop().value; - value=new VBool(a->as_string() <= b->as_string()); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + Value& value=*new VBool(a.as_string() <= b.as_string()); stack.push(value); break; } case OP_STR_GE: { - b=stack.pop().value; a=stack.pop().value; - value=new VBool(a->as_string() >= b->as_string()); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + Value& value=*new VBool(a.as_string() >= b.as_string()); stack.push(value); break; } case OP_STR_EQ: { - b=stack.pop().value; a=stack.pop().value; - value=new VBool(a->as_string() == b->as_string()); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + Value& value=*new VBool(a.as_string() == b.as_string()); stack.push(value); break; } case OP_STR_NE: { - b=stack.pop().value; a=stack.pop().value; - value=new VBool(a->as_string() != b->as_string()); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + Value& value=*new VBool(a.as_string() != b.as_string()); stack.push(value); break; } case OP_IS: { - b=stack.pop().value; a=stack.pop().value; - value=new VBool(a->is(b->as_string().cstr())); + Value& b=stack.pop().value(); Value& a=stack.pop().value(); + Value& value=*new VBool(a.is(b.as_string().cstr())); stack.push(value); break; } @@ -809,18 +807,23 @@ void Request::execute(ArrayOperation& op default: throw Exception(0, 0, - "invalid opcode %d", op.code); + "invalid opcode %d", opinfo.code()); } } + } catch(...) { + // record it to stack trace + //if(is_debug_junction) + if(debug_name) + exception_trace.push(Trace(debug_name, debug_info)); + rethrow; + } } /** @todo cache|prepare junctions @bug ^superbase:method would dynamically call ^base:method if there is any */ -Value* Request::get_element(bool can_call_operator) { - const String& name=*stack.pop().string(); //remember_name=name; - Value* ncontext=stack.pop().value; +Value& Request::get_element(Value& ncontext, const String& name, bool can_call_operator) { Value* value=0; if(can_call_operator) { if(Method* method=main_class.get_method(name)) // looking operator of that name FIRST @@ -830,7 +833,7 @@ Value* Request::get_element(bool can_cal if(!value) { if(!wcontext->get_constructing() // not constructing && wcontext->get_somebody_entered_some_class() ) // ^class:method - if(VStateless_class *called_class=ncontext->get_class()) + if(VStateless_class *called_class=ncontext.get_class()) if(VStateless_class *read_class=rcontext->get_class()) if(read_class->derived_from(*called_class)) // current derived from called if(Value* base=get_self().base()) { // doing DYNAMIC call @@ -840,15 +843,15 @@ Value* Request::get_element(bool can_cal } } if(!value) - value=ncontext->get_element(name, *ncontext, false); + value=ncontext.get_element(name, ncontext, false); if(value && wcontext->get_constructing()) if(Junction* junction=value->get_junction()) { - if(junction->self.get_class()!=ncontext) + if(junction->self.get_class()!=&ncontext) throw Exception("parser.runtime", &name, "constructor must be declared in class '%s'", - ncontext->get_class()->name_cstr()); + ncontext.get_class()->name_cstr()); } value_ready: @@ -857,7 +860,7 @@ value_ready: else value=new VVoid; - return value; + return *value; } /** @param intercept_string