|
|
| version 1.295.2.9, 2003/02/04 08:29:26 | version 1.295.2.13, 2003/02/17 15:34:19 |
|---|---|
| Line 23 static const char* IDENT_EXECUTE_C="$Dat | Line 23 static const char* IDENT_EXECUTE_C="$Dat |
| #include "pa_vimage.h" | #include "pa_vimage.h" |
| #include "pa_wwrapper.h" | #include "pa_wwrapper.h" |
| //#define DEBUG_EXECUTE | #define DEBUG_EXECUTE |
| //#define DEBUG_STRING_APPENDS_VS_EXPANDS | //#define DEBUG_STRING_APPENDS_VS_EXPANDS |
| Line 62 char *opcode_name[]={ | Line 62 char *opcode_name[]={ |
| "IS" | "IS" |
| }; | }; |
| void va_debug_printf(Pool& pool, const char* fmt,va_list args) { | void va_debug_printf(SAPI_Info& sapi_info, const char* fmt,va_list args) { |
| char buf[MAX_STRING]; | char buf[MAX_STRING]; |
| vsnprintf(buf, MAX_STRING, fmt, args); | vsnprintf(buf, MAX_STRING, fmt, args); |
| SAPI::log(pool, "%s", buf); | SAPI::log(sapi_info, "%s", buf); |
| } | } |
| void debug_printf(Pool& pool, const char* fmt, ...) { | void debug_printf(SAPI_Info& sapi_info, const char* fmt, ...) { |
| va_list args; | va_list args; |
| va_start(args,fmt); | va_start(args, fmt); |
| va_debug_printf(pool,fmt,args); | va_debug_printf(sapi_info, fmt, args); |
| va_end(args); | va_end(args); |
| } | } |
| void debug_dump(Pool& pool, int level, const Array& ops) { | void debug_dump(SAPI_Info& sapi_info, int level, ArrayOperation& ops) { |
| Array_iterator i(ops); | Array_iterator<Operation> i(ops); |
| while(i.has_next()) { | while(i.has_next()) { |
| Operation op; | Operation& op=i.next(); |
| op.cast=i.next(); | |
| if(op.code==OP_VALUE || op.code==OP_STRING__WRITE) { | if(op.code==OP_VALUE || op.code==OP_STRING__WRITE) { |
| Value* value=i.next().value; | ValuePtr value=i.next().value; |
| debug_printf(pool, | debug_printf(sapi_info, |
| "%*s%s" | "%*s%s" |
| " \"%s\" %s", | " \"%s\" %s", |
| level*4, "", opcode_name[op.code], | level*4, "", opcode_name[op.code], |
| value->get_string()->cstr(), value->type()); | value->get_string(0)->cstr().get(), value->type()); |
| continue; | continue; |
| } | } |
| debug_printf(pool, "%*s%s", level*4, "", opcode_name[op.code]); | debug_printf(sapi_info, "%*s%s", level*4, "", opcode_name[op.code]); |
| switch(op.code) { | switch(op.code) { |
| case OP_CURLY_CODE__STORE_PARAM: | case OP_CURLY_CODE__STORE_PARAM: |
| Line 100 void debug_dump(Pool& pool, int level, c | Line 99 void debug_dump(Pool& pool, int level, c |
| case OP_OBJECT_POOL: | case OP_OBJECT_POOL: |
| case OP_STRING_POOL: | case OP_STRING_POOL: |
| case OP_CALL: | case OP_CALL: |
| local_ops=i.next().ops; | case OP_CALL__WRITE: |
| debug_dump(pool, level+1, *local_ops); | if(ArrayOperation* local_ops=i.next().ops.get()) |
| debug_dump(sapi_info, level+1, *local_ops); | |
| } | } |
| } | } |
| } | } |
| #endif | #endif |
| /*#define stack.push(value) stack.push(value.get()) | |
| #define stack.pop().value static_cast<Value* >(stack.pop()) | |
| #define stack.push(value) stack.push(value) | |
| #define stack.pop().string static_cast<Value* >(stack.pop())->as_string(&pool()).get() | |
| #define POP_CODE() static_cast<Array *>(stack.pop()) | |
| */ | |
| // Request | // Request |
| void Request::execute(ArrayOperation& ops) { | void Request::execute(ArrayOperation& ops) { |
| // _asm int 3; | // _asm int 3; |
| #ifdef DEBUG_EXECUTE | #ifdef DEBUG_EXECUTE |
| debug_printf("source----------------------------\n"); | debug_printf(sapi_info, "source----------------------------\n"); |
| debug_dump(0, ops); | debug_dump(sapi_info, 0, ops); |
| debug_printf("execution-------------------------\n"); | debug_printf(sapi_info, "execution-------------------------\n"); |
| #endif | #endif |
| StringPtr last_get_element_name(0); | StringPtr last_get_element_name(0); |
| Line 134 void Request::execute(ArrayOperation& op | Line 127 void Request::execute(ArrayOperation& op |
| Operation& op=i.next(); | Operation& op=i.next(); |
| #ifdef DEBUG_EXECUTE | #ifdef DEBUG_EXECUTE |
| debug_printf("%d:%s", stack.top_index()+1, opcode_name[op.code]); | debug_printf(sapi_info, "%d:%s", stack.top_index()+1, opcode_name[op.code]); |
| #endif | #endif |
| ValuePtr value; | ValuePtr value; |
| Line 152 void Request::execute(ArrayOperation& op | Line 145 void Request::execute(ArrayOperation& op |
| { | { |
| value=i.next().value; | value=i.next().value; |
| #ifdef DEBUG_EXECUTE | #ifdef DEBUG_EXECUTE |
| debug_printf(" \"%s\" %s", value->get_string()->cstr(), value->type()); | debug_printf(sapi_info, " \"%s\" %s", value->get_string(0)->cstr().get(), value->type()); |
| #endif | #endif |
| stack.push(value); | stack.push(value); |
| break; | break; |
| Line 162 void Request::execute(ArrayOperation& op | Line 155 void Request::execute(ArrayOperation& op |
| // maybe they do ^class:method[] call, remember the fact | // maybe they do ^class:method[] call, remember the fact |
| wcontext->set_somebody_entered_some_class(); | wcontext->set_somebody_entered_some_class(); |
| name=stack.pop().string; | name=stack.pop().string(); |
| value=classes().get(name); | value=classes().get(name); |
| if(!value) | if(!value) |
| throw Exception("parser.runtime", | throw Exception("parser.runtime", |
| Line 204 void Request::execute(ArrayOperation& op | Line 197 void Request::execute(ArrayOperation& op |
| case OP_CONSTRUCT_VALUE: | case OP_CONSTRUCT_VALUE: |
| { | { |
| value=stack.pop().value; | value=stack.pop().value; |
| name=stack.pop().string; | name=stack.pop().string(); |
| ncontext=stack.pop().value.get(); | ncontext=stack.pop().value.get(); |
| ncontext->put_element(name, value, false); | ncontext->put_element(name, value, false); |
| break; | break; |
| Line 215 void Request::execute(ArrayOperation& op | Line 208 void Request::execute(ArrayOperation& op |
| wcontext->set_in_expression(false); | wcontext->set_in_expression(false); |
| value=stack.pop().value; | value=stack.pop().value; |
| name=stack.pop().string; | name=stack.pop().string(); |
| ncontext=stack.pop().value.get(); | ncontext=stack.pop().value.get(); |
| ncontext->put_element(name, value->as_expr_result(), false); | ncontext->put_element(name, value->as_expr_result(), false); |
| break; | break; |
| Line 224 void Request::execute(ArrayOperation& op | Line 217 void Request::execute(ArrayOperation& op |
| { | { |
| local_ops=i.next().ops; | local_ops=i.next().ops; |
| #ifdef DEBUG_EXECUTE | #ifdef DEBUG_EXECUTE |
| debug_printf(" (%d)\n", local_ops->count()); | debug_printf(sapi_info, " (%d)\n", local_ops->count()); |
| debug_dump(1, *local_ops); | debug_dump(sapi_info, 1, *local_ops); |
| #endif | #endif |
| value=ValuePtr(new VJunction(JunctionPtr(new Junction( | value=ValuePtr(new VJunction(JunctionPtr(new Junction( |
| get_self(), 0, | get_self(), 0, |
| Line 234 void Request::execute(ArrayOperation& op | Line 227 void Request::execute(ArrayOperation& op |
| wcontext, | wcontext, |
| local_ops)))); | local_ops)))); |
| name=stack.pop().string; | name=stack.pop().string(); |
| ncontext=stack.pop().value.get(); | ncontext=stack.pop().value.get(); |
| ncontext->put_element(name, value, false); | ncontext->put_element(name, value, false); |
| break; | break; |
| Line 243 void Request::execute(ArrayOperation& op | Line 236 void Request::execute(ArrayOperation& op |
| { | { |
| local_ops=i.next().ops; | local_ops=i.next().ops; |
| #ifdef DEBUG_EXECUTE | #ifdef DEBUG_EXECUTE |
| debug_printf(" (%d)\n", local_ops->count()); | debug_printf(sapi_info, " (%d)\n", local_ops->count()); |
| debug_dump(1, *local_ops); | debug_dump(sapi_info, 1, *local_ops); |
| #endif | #endif |
| stack.push(local_ops); | stack.push(local_ops); |
| break; | break; |
| Line 269 void Request::execute(ArrayOperation& op | Line 262 void Request::execute(ArrayOperation& op |
| { | { |
| value=i.next().value; | value=i.next().value; |
| #ifdef DEBUG_EXECUTE | #ifdef DEBUG_EXECUTE |
| debug_printf(" \"%s\"", value->get_string(0).cstr()); | debug_printf(sapi_info, " \"%s\"", value->get_string(0)->cstr().get()); |
| #endif | #endif |
| write_no_lang(*value->get_string(0)); | write_no_lang(*value->get_string(0)); |
| break; | break; |
| Line 341 void Request::execute(ArrayOperation& op | Line 334 void Request::execute(ArrayOperation& op |
| case OP_STORE_PARAM: | case OP_STORE_PARAM: |
| { | { |
| value=stack.pop().value; | value=stack.pop().value; |
| VMethodFrame *frame=static_cast<VMethodFrame *>(stack.top_value().unknown); | VMethodFrame *frame=static_cast<VMethodFrame *>(stack.top_value().ptr); |
| // this op is executed from CALL local_ops only, so may skip the check "method_frame_to_fill==0" | // 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; | break; |
| Line 351 void Request::execute(ArrayOperation& op | Line 344 void Request::execute(ArrayOperation& op |
| { | { |
| // code | // code |
| local_ops=i.next().ops; | local_ops=i.next().ops; |
| VMethodFrame *frame=static_cast<VMethodFrame *>(stack.top_value().unknown); | VMethodFrame *frame=static_cast<VMethodFrame *>(stack.top_value().ptr); |
| #ifdef DEBUG_EXECUTE | #ifdef DEBUG_EXECUTE |
| debug_printf(" (%d)\n", local_ops->count()); | debug_printf(sapi_info, " (%d)\n", local_ops->count()); |
| debug_dump(1, *local_ops); | debug_dump(sapi_info, 1, *local_ops); |
| #endif | #endif |
| // when they evaluate expression parameter, | // when they evaluate expression parameter, |
| // the object expression result | // the object expression result |
| Line 392 void Request::execute(ArrayOperation& op | Line 385 void Request::execute(ArrayOperation& op |
| { | { |
| local_ops=i.next().ops; | local_ops=i.next().ops; |
| #ifdef DEBUG_EXECUTE | #ifdef DEBUG_EXECUTE |
| debug_printf(" (%d)\n", local_ops->count()); | debug_printf(sapi_info, " (%d)\n", local_ops?local_ops->count():0); |
| debug_dump(1, *local_ops); | if(local_ops) |
| debug_dump(sapi_info, 1, *local_ops); | |
| debug_printf("->\n"); | debug_printf(sapi_info, "->\n"); |
| #endif | #endif |
| value=stack.pop().value; | value=stack.pop().value; |
| Line 418 void Request::execute(ArrayOperation& op | Line 412 void Request::execute(ArrayOperation& op |
| value->type()); | 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 | 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); | execute(*local_ops); |
| Line 443 void Request::execute(ArrayOperation& op | Line 437 void Request::execute(ArrayOperation& op |
| throw Exception("parser.runtime", | throw Exception("parser.runtime", |
| frame.name(), | frame.name(), |
| "is not a constructor, system class '%s' can be constructed only implicitly", | "is not a constructor, system class '%s' can be constructed only implicitly", |
| called_class->name()->cstr().get()); | (char*)called_class->name()->cstr()); |
| frame.write(new_self, | frame.write(new_self, |
| String::UL_CLEAN // not used, always an object, not string | String::UL_CLEAN // not used, always an object, not string |
| Line 509 void Request::execute(ArrayOperation& op | Line 503 void Request::execute(ArrayOperation& op |
| } | } |
| #ifdef DEBUG_EXECUTE | #ifdef DEBUG_EXECUTE |
| debug_printf("<-returned"); | debug_printf(sapi_info, "<-returned"); |
| #endif | #endif |
| break; | break; |
| } | } |
| Line 838 void Request::execute(ArrayOperation& op | Line 832 void Request::execute(ArrayOperation& op |
| @bug ^superbase:method would dynamically call ^base:method if there is any | @bug ^superbase:method would dynamically call ^base:method if there is any |
| */ | */ |
| ValuePtr Request::get_element(StringPtr& remember_name, bool can_call_operator) { | ValuePtr Request::get_element(StringPtr& remember_name, bool can_call_operator) { |
| StringPtr name=stack.pop().string; remember_name=name; | StringPtr name=stack.pop().string(); remember_name=name; |
| Value* ncontext=stack.pop().value.get(); | Value* ncontext=stack.pop().value.get(); |
| ValuePtr value(0); | ValuePtr value(0); |
| if(can_call_operator) { | if(can_call_operator) { |
| Line 895 StringOrValue Request::process(ValuePtr | Line 889 StringOrValue Request::process(ValuePtr |
| if(junction && junction->code) { // is it a code-junction? | if(junction && junction->code) { // is it a code-junction? |
| // process it | // process it |
| #ifdef DEBUG_EXECUTE | #ifdef DEBUG_EXECUTE |
| debug_printf("ja->\n"); | debug_printf(sapi_info, "ja->\n"); |
| #endif | #endif |
| if(!junction->method_frame) | if(!junction->method_frame) |
| Line 943 StringOrValue Request::process(ValuePtr | Line 937 StringOrValue Request::process(ValuePtr |
| method_frame=saved_method_frame; | method_frame=saved_method_frame; |
| #ifdef DEBUG_EXECUTE | #ifdef DEBUG_EXECUTE |
| debug_printf("<-ja returned"); | debug_printf(sapi_info, "<-ja returned"); |
| #endif | #endif |
| } else { | } else { |
| result.set_value(input_value); | result.set_value(input_value); |
| Line 981 StringPtr Request::execute_method(ValueP | Line 975 StringPtr Request::execute_method(ValueP |
| WContext *saved_wcontext=wcontext; | WContext *saved_wcontext=wcontext; |
| Junction local_junction(aself, &method, 0,0,0, ArrayOperationPtr(0)); | 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()) { | if(optional_param && local_frame.can_store_param()) { |
| local_frame.store_param(optional_param); | local_frame.store_param(optional_param); |
| local_frame.fill_unspecified_params(); | local_frame.fill_unspecified_params(); |
| Line 991 StringPtr Request::execute_method(ValueP | Line 985 StringPtr Request::execute_method(ValueP |
| // prevent non-string writes for better error reporting | // prevent non-string writes for better error reporting |
| if(do_return_string) | if(do_return_string) |
| wcontext->write(pool(), ValuePtr(new VVoid)); | wcontext->write(pool(), ValuePtr(&local_frame)); |
| // execute! | // execute! |
| execute(*method.parser_code); | execute(*method.parser_code); |
| Line 1021 StringPtr Request::execute_nonvirtual_me | Line 1015 StringPtr Request::execute_nonvirtual_me |
| if(method) | if(method) |
| return execute_method(ValuePtr(&aclass), *method, optional_param, do_return_string); | return execute_method(ValuePtr(&aclass), *method, optional_param, do_return_string); |
| else | else |
| return 0; | return StringPtr(0); |
| } | } |
| StringPtr Request::execute_virtual_method(ValuePtr aself, | StringPtr Request::execute_virtual_method(ValuePtr aself, |
| Line 1031 StringPtr Request::execute_virtual_metho | Line 1025 StringPtr Request::execute_virtual_metho |
| if(const Method *method=junction->method) | if(const Method *method=junction->method) |
| return execute_method(aself, *method, VStringPtr(0)/*no params*/, true); | return execute_method(aself, *method, VStringPtr(0)/*no params*/, true); |
| return 0; | return StringPtr(0); |
| } | } |