--- parser3/src/main/execute.C 2002/04/22 09:20:29 1.238 +++ parser3/src/main/execute.C 2002/04/22 10:15:12 1.239 @@ -4,7 +4,7 @@ Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) - $Id: execute.C,v 1.238 2002/04/22 09:20:29 paf Exp $ + $Id: execute.C,v 1.239 2002/04/22 10:15:12 paf Exp $ */ #include "pa_opcode.h" @@ -111,49 +111,6 @@ void debug_dump(Pool& pool, int level, c #define POP_NAME() static_cast(stack.pop())->as_string() #define POP_CODE() static_cast(stack.pop()) -/** - Helps preventing evaluation of junctions in outdated context - - To stop situations like this: -@code - @main[] - ^method1[] - ^method2[] - - @method1[] - $junction{ - some code - } - - @method2[] - ^junction[] -@endcode - - All Junctions, generated by OP_CURLY_CODE__CONSTRUCT are registered here, - and on scope exit got cleaned - there Junction::root becomes 0, - which later in Request::process triggers exception -*/ -class Auto_junction_cleaner { -public: - Auto_junction_cleaner () : junctions(0) {} - ~Auto_junction_cleaner () { - if(junctions) { - Array_iter i(*junctions); - while(i.has_next()) - static_cast(i.next())->change_context(0); - // someday free junctions - } - } - void register_junction(Pool& apool, Junction& ajunction) { - if(!junctions) - junctions=new(apool) Array(apool); - if(junctions) - *junctions+=&ajunction; - } -private: - Array *junctions; -}; - void Request::execute(const Array& ops) { // _asm int 3; #ifdef DEBUG_EXECUTE @@ -162,7 +119,6 @@ void Request::execute(const Array& ops) debug_printf(pool(), "execution-------------------------\n"); #endif - Auto_junction_cleaner junction_cleaner; const String *last_get_element_name=0; Array_iter i(ops); @@ -254,11 +210,10 @@ void Request::execute(const Array& ops) #endif Junction& j=*NEW Junction(pool(), *self, 0, 0, - root, - rcontext, - wcontext, + 0, + 0, + 0, local_ops); - junction_cleaner.register_junction(pool(), j); value=NEW VJunction(j); const String& name=POP_NAME(); @@ -905,28 +860,28 @@ StringOrValue Request::process(Value& in debug_printf(pool(), "ja->\n"); #endif - if(!junction->root) - throw Exception("parser.runtime", - 0, - "junction used outside of context"); - PUSH(self); PUSH(root); PUSH(rcontext); PUSH(wcontext); - + + WContext *jwcontext; self=&junction->self; - root=junction->root; - rcontext=junction->rcontext; + if(junction->root) { + root=junction->root; + rcontext=junction->rcontext; + jwcontext=junction->wcontext; + } else + jwcontext=wcontext; // for expression method params // wcontext is set 0 // using the fact in decision "which wwrapper to use" - bool using_code_frame=intercept_string && junction->wcontext; + bool using_code_frame=intercept_string && jwcontext; if(using_code_frame) { // almost plain wwrapper about junction wcontext, // BUT intercepts string writes - VCodeFrame local(pool(), *junction->wcontext); + VCodeFrame local(pool(), *jwcontext); wcontext=&local; // execute it