--- parser3/src/main/execute.C 2015/09/28 22:26:13 1.376 +++ parser3/src/main/execute.C 2016/07/20 17:01:48 1.384 @@ -1,7 +1,7 @@ /** @file Parser: executor part of request class. - Copyright (c) 2001-2012 Art. Lebedev Studio (http://www.artlebedev.com) + Copyright (c) 2001-2015 Art. Lebedev Studio (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) */ @@ -21,7 +21,7 @@ #include "pa_vimage.h" #include "pa_wwrapper.h" -volatile const char * IDENT_EXECUTE_C="$Id: execute.C,v 1.376 2015/09/28 22:26:13 moko Exp $" IDENT_PA_OPCODE_H IDENT_PA_OPERATION_H IDENT_PA_VCODE_FRAME_H IDENT_PA_WWRAPPER_H; +volatile const char * IDENT_EXECUTE_C="$Id: execute.C,v 1.384 2016/07/20 17:01:48 moko Exp $" IDENT_PA_OPCODE_H IDENT_PA_OPERATION_H IDENT_PA_VCODE_FRAME_H IDENT_PA_WWRAPPER_H; //#define DEBUG_EXECUTE @@ -185,6 +185,7 @@ void debug_dump(SAPI_Info& sapi_info, in opcode==OP::OP_VALUE || opcode==OP::OP_STRING__WRITE || opcode==OP::OP_VALUE__GET_CLASS + || opcode==OP::OP_VALUE__GET_BASE_CLASS #ifdef OPTIMIZE_BYTECODE_GET_ELEMENT || opcode==OP::OP_VALUE__GET_ELEMENT || opcode==OP::OP_VALUE__GET_ELEMENT__WRITE @@ -280,21 +281,33 @@ void Request::execute(ArrayOperation& op } case OP::OP_VALUE__GET_CLASS: { - // maybe they do ^class:method[] call, remember the fact - wcontext->set_somebody_entered_some_class(); + debug_origin=i.next().origin; + const String& name=*i.next().value->get_string(); debug_name=&name; + + DEBUG_PRINT_STRING(name) + + VStateless_class* vclass=get_class(name); + if(!vclass) + throw Exception(PARSER_RUNTIME, &name, "class is undefined"); + + stack.push(*vclass); + break; + } + + case OP::OP_VALUE__GET_BASE_CLASS: + { + // ^class:method[] call debug_origin=i.next().origin; const String& name=*i.next().value->get_string(); debug_name=&name; DEBUG_PRINT_STRING(name) - Value* class_value=get_class(name); - if(!class_value) - throw Exception(PARSER_RUNTIME, - &name, - "class is undefined"); + VStateless_class* vclass=get_class(name); + if(!vclass) + throw Exception(PARSER_RUNTIME, &name, "class is undefined"); - stack.push(*class_value); + stack.push(*new VBaseClassWrapper(*vclass, get_self())); break; } @@ -307,19 +320,19 @@ void Request::execute(ArrayOperation& op Value* value=0; if(VStateless_class* vclass=ncontext.get_class()){ - if(name==class_element_name){ + if(SYMBOLS_EQ(name,CLASS_SYMBOL)){ value=vclass; - } else if(name==class_name_element_name){ - value=new VString(vclass->name()); + } else if(SYMBOLS_EQ(name,CLASS_NAME_SYMBOL)){ + value=new VString(*new String(vclass->type())); } } else { - // Value - if(name==class_element_name){ + // VJunction is without class, returning self + if(SYMBOLS_EQ(name,CLASS_SYMBOL)){ value=&ncontext; - }else if(name==class_name_element_name){ + } else if(SYMBOLS_EQ(name,CLASS_NAME_SYMBOL)){ value=new VString(*new String(ncontext.type())); } - }; + } if(opcode==OP::OP_GET_ELEMENT__SPECIAL){ stack.push(*value); } else { @@ -348,9 +361,7 @@ void Request::execute(ArrayOperation& op case OP::OP_WITH_WRITE: { if(wcontext==method_frame) - throw Exception(PARSER_RUNTIME, - 0, - "$.name outside of $name[...]"); + throw Exception(PARSER_RUNTIME, 0, "$.name outside of $name[...]"); stack.push(*wcontext); break; @@ -451,9 +462,7 @@ void Request::execute(ArrayOperation& op Value& ncontext=stack.pop().value(); if(const VJunction* vjunction=ncontext.put_element(name, &value)) if(vjunction!=PUT_ELEMENT_REPLACED_ELEMENT) - throw Exception(PARSER_RUNTIME, - 0, - "property value can not be code, use [] or () brackets"); + throw Exception(PARSER_RUNTIME, 0, "property value can not be code, use [] or () brackets"); break; } @@ -883,11 +892,9 @@ void Request::execute(ArrayOperation& op DEBUG_PRINT_STRING(class_name) - Value* class_value=get_class(class_name); - if(!class_value) - throw Exception(PARSER_RUNTIME, - &class_name, - "class is undefined"); + VStateless_class* vclass=get_class(class_name); + if(!vclass) + throw Exception(PARSER_RUNTIME, &class_name, "class is undefined"); debug_origin=i.next().origin; Value& vconstructor_name=*i.next().value; @@ -895,12 +902,9 @@ void Request::execute(ArrayOperation& op DEBUG_PRINT_STRING(constructor_name) - Junction* constructor_junction=get_element(*class_value, constructor_name).get_junction(); + Junction* constructor_junction=get_element(*vclass, constructor_name).get_junction(); if(!constructor_junction) - throw Exception(PARSER_RUNTIME, - &constructor_name, - "constructor must be declared in class '%s'", - class_value->get_class()->name_cstr()); + throw Exception(PARSER_RUNTIME, &constructor_name, "constructor must be declared in class '%s'", vclass->type()); ArrayOperation* local_ops=i.next().ops; DEBUG_PRINT_OPS(local_ops) @@ -908,7 +912,7 @@ void Request::execute(ArrayOperation& op Value *result; { - Value& object=construct(*class_value, *constructor_junction->method); + Value& object=construct(*vclass, *constructor_junction->method); VConstructorFrame frame(*constructor_junction->method, method_frame, object); METHOD_FRAME_ACTION(op_call(frame)); object.enable_default_setter(); @@ -1257,8 +1261,7 @@ void Request::execute(ArrayOperation& op method_frame=saved_method_frame; -Value& Request::construct(Value &class_value, const Method &method){ - VStateless_class& called_class=*class_value.get_class(); +Value& Request::construct(VStateless_class &called_class, const Method &method){ if(method.call_type!=Method::CT_STATIC) { // this is a constructor call @@ -1269,7 +1272,7 @@ Value& Request::construct(Value &class_v throw Exception(PARSER_RUNTIME, 0, //&frame.name(), "is not a constructor, system class '%s' can be constructed only implicitly", - called_class.name().cstr()); + called_class.type()); } else throw Exception(PARSER_RUNTIME, 0, //&frame.name(), @@ -1331,28 +1334,16 @@ void Request::op_call_write(VMethodFrame } Value& Request::get_element(Value& ncontext, const String& name) { -#ifdef FEATURE_GET_ELEMENT4CALL Value* value=ncontext.get_element(name); return *(value ? &process_to_value(*value) : VVoid::get()); } -Value& Request::get_element4call(Value& ncontext, const String& name) { -#endif - if(wcontext->get_somebody_entered_some_class()) // ^class:method - 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 - Value *value=called_class->get_element(get_self(), name); - return *(value ? &process_to_value(*value) : VVoid::get()); - } - #ifdef FEATURE_GET_ELEMENT4CALL +Value& Request::get_element4call(Value& ncontext, const String& name) { Value* value=ncontext.get_element4call(name); -#else - Value* value=ncontext.get_element(name); -#endif return *(value ? &process_to_value(*value) : VVoid::get()); } +#endif void Request::put_element(Value& ncontext, const String& name, Value* value) { // put_element can return property-setting-junction @@ -1640,6 +1631,7 @@ const String* Request::get_method_filena case OP::OP_VALUE: case OP::OP_STRING__WRITE: case OP::OP_VALUE__GET_CLASS: + case OP::OP_VALUE__GET_BASE_CLASS: #ifdef OPTIMIZE_BYTECODE_GET_OBJECT_ELEMENT case OP::OP_GET_OBJECT_ELEMENT: case OP::OP_GET_OBJECT_ELEMENT__WRITE: @@ -1658,6 +1650,17 @@ const String* Request::get_method_filena case OP::OP_WITH_SELF__VALUE__GET_ELEMENT: case OP::OP_WITH_SELF__VALUE__GET_ELEMENT__WRITE: #endif + +#ifdef FEATURE_GET_ELEMENT4CALL + case OP::OP_GET_ELEMENT4CALL: +#ifdef OPTIMIZE_BYTECODE_GET_OBJECT_ELEMENT + case OP::OP_GET_OBJECT_ELEMENT4CALL: +#endif +#ifdef OPTIMIZE_BYTECODE_GET_OBJECT_VAR_ELEMENT + case OP::OP_GET_OBJECT_VAR_ELEMENT4CALL: +#endif +#endif // FEATURE_GET_ELEMENT4CALL + #ifdef OPTIMIZE_BYTECODE_CONSTRUCT case OP::OP_WITH_ROOT__VALUE__CONSTRUCT_EXPR: case OP::OP_WITH_ROOT__VALUE__CONSTRUCT_VALUE: