comparison libinterp/octave-value/ov-classdef.cc @ 15968:cdeb6eb656be classdef

Move property/method access check down to cdef_property/cdef_method classes. * libinterp/octave-value/ov-classdef.h (cdef_property::cdef_property_rep::get_value, cdef_property::cdef_property_rep::set_value): Add arguments (do_check_access and who) to control access checking and pass down to gripe utility function. (cdef_property::get_value, cdef_property::set_value): Likewise. (cdef_method::cdef_method_rep::execute): Likewise. (cdef_method::execute): Likewise. (cdef_property::check_get_access, cdef_property::check_set_access): Move implementation to cdef_property::cdef_property_rep. (cdef_property::cdef_property_rep::check_get_access, cdef_property::cdef_property_rep::check_set_access): New methods, moved from cdef_property. (cdef_method::check_access): Move implementation to cdef_method::cdef_method_rep. (cdef_method::cdef_method_rep::check_access): New method, moved from cdef_method. (cdef_property::cdef_property_rep::wrap): New method. (cdef_method::cdef_method_rep::wrap): New method. * libinterp/octave-value/ov-classdef.cc (cdef_property::cdef_property_rep::get_value, cdef_property::cdef_property_rep::set_value): Add arguments (do_check_access and who) to control access checking and pass down to gripe utility function. (cdef_property::cdef_property_rep::check_get_access, (cdef_method::cdef_method_rep::execute): Likewise. cdef_property::cdef_property_rep::check_set_access): New methods, moved from cdef_property. (cdef_method::cdef_method_rep::check_access): New method, moved from cdef_method. (class_fevalStatic, octave_classdef_superclass_ref::do_multi_index_op, cdef_object_scalar::subsref, cdef_class::cdef_class_rep::subsref_meta, cdef_class::cdef_class_rep::construct_object): Do not check access, let cdef_method::execute handle it. (class_getConstant, cdef_object_scalar::subsref, cdef_object_scalar::subsasgn, cdef_class::cdef_class_rep::subsref_meta): Do not check get/set access, let cdef_property::get_value and cdef_property::set_value handle it. (cdef_class::cdef_class_rep::delete_object): Execute "delete" method without access checking.
author Michael Goffioul <michael.goffioul@gmail.com>
date Sun, 20 Jan 2013 23:03:17 -0500
parents 4aedc32e3f4d
children 14aa0b5a980c
comparison
equal deleted inserted replaced
15967:24ceda35d146 15968:cdeb6eb656be
469 { 469 {
470 cdef_method meth = cls.find_method (meth_name); 470 cdef_method meth = cls.find_method (meth_name);
471 471
472 if (meth.ok ()) 472 if (meth.ok ())
473 { 473 {
474 if (meth.check_access ()) 474 if (meth.is_static ())
475 { 475 retval = meth.execute (args.splice (0, 2), nargout,
476 if (meth.is_static ()) 476 true, "fevalStatic");
477 retval = meth.execute (args.splice (0, 2), nargout); 477 else
478 else 478 error ("fevalStatic: method `%s' is not static",
479 error ("fevalStatic: method `%s' is not static", 479 meth_name.c_str ());
480 meth_name.c_str ());
481 }
482 else
483 gripe_method_access ("fevalStatic", meth);
484 } 480 }
485 else 481 else
486 error ("fevalStatic: method not found: %s", 482 error ("fevalStatic: method not found: %s",
487 meth_name.c_str ()); 483 meth_name.c_str ());
488 } 484 }
515 { 511 {
516 cdef_property prop = cls.find_property (prop_name); 512 cdef_property prop = cls.find_property (prop_name);
517 513
518 if (prop.ok ()) 514 if (prop.ok ())
519 { 515 {
520 if (prop.check_get_access ()) 516 if (prop.is_constant ())
521 { 517 retval(0) = prop.get_value (true, "getConstant");
522 if (prop.is_constant ()) 518 else
523 retval(0) = prop.get_value (); 519 error ("getConstant: property `%s' is not constant",
524 else 520 prop_name.c_str ());
525 error ("getConstant: property `%s' is not constant",
526 prop_name.c_str ());
527 }
528 else
529 gripe_property_access ("getConstant", prop);
530 } 521 }
531 else 522 else
532 error ("getConstant: property not found: %s", 523 error ("getConstant: property not found: %s",
533 prop_name.c_str ()); 524 prop_name.c_str ());
534 } 525 }
1002 // go with option 2) for the time being. 993 // go with option 2) for the time being.
1003 994
1004 cdef_method meth = cls.find_method (meth_name, false); 995 cdef_method meth = cls.find_method (meth_name, false);
1005 996
1006 if (meth.ok ()) 997 if (meth.ok ())
1007 { 998 retval = meth.execute (idx, nargout, true,
1008 if (meth.check_access ()) 999 meth_name);
1009 retval = meth.execute (idx, nargout);
1010 else
1011 gripe_method_access (meth_name, meth);
1012 }
1013 else 1000 else
1014 ::error ("no method `%s' found in superclass `%s'", 1001 ::error ("no method `%s' found in superclass `%s'",
1015 meth_name.c_str (), cls_name.c_str ()); 1002 meth_name.c_str (), cls_name.c_str ());
1016 } 1003 }
1017 else 1004 else
1091 1078
1092 cdef_method meth = cls.find_method (name); 1079 cdef_method meth = cls.find_method (name);
1093 1080
1094 if (meth.ok ()) 1081 if (meth.ok ())
1095 { 1082 {
1096 if (meth.check_access ()) 1083 int _nargout = (type.length () > 2 ? 1 : nargout);
1097 { 1084
1098 int _nargout = (type.length () > 2 ? 1 : nargout); 1085 octave_value_list args;
1099 1086
1100 octave_value_list args; 1087 skip = 1;
1101 1088
1102 skip = 1; 1089 if (type.length () > 1 && type[1] == '(')
1103 1090 {
1104 if (type.length () > 1 && type[1] == '(') 1091 std::list<octave_value_list>::const_iterator it = idx.begin ();
1105 { 1092
1106 std::list<octave_value_list>::const_iterator it = idx.begin (); 1093 args = *++it;
1107 1094
1108 args = *++it; 1095 skip++;
1109 1096 }
1110 skip++; 1097
1111 } 1098 if (meth.is_static ())
1112 1099 retval = meth.execute (args, _nargout, true, "subsref");
1113 if (meth.is_static ()) 1100 else
1114 retval = meth.execute (args, _nargout); 1101 {
1115 else 1102 refcount++;
1116 { 1103 retval = meth.execute (cdef_object (this), args, _nargout,
1117 refcount++; 1104 true, "subsref");
1118 retval = meth.execute (cdef_object (this), args, _nargout); 1105 }
1119 }
1120 }
1121 else
1122 gripe_method_access ("subsref", meth);
1123 } 1106 }
1124 1107
1125 if (skip == 0 && ! error_state) 1108 if (skip == 0 && ! error_state)
1126 { 1109 {
1127 cdef_property prop = cls.find_property (name); 1110 cdef_property prop = cls.find_property (name);
1128 1111
1129 if (prop.ok ()) 1112 if (prop.ok ())
1130 { 1113 {
1131 if (prop.check_get_access ()) 1114 if (prop.is_constant ())
1132 { 1115 retval(0) = prop.get_value (true, "subsref");
1133 if (prop.is_constant ()) 1116 else
1134 retval(0) = prop.get_value (); 1117 {
1135 else 1118 refcount++;
1136 { 1119 retval(0) = prop.get_value (cdef_object (this),
1137 refcount++; 1120 true, "subsref");
1138 retval(0) = prop.get_value (cdef_object (this)); 1121 }
1139 } 1122
1140 1123 skip = 1;
1141 skip = 1;
1142 }
1143 else
1144 gripe_property_access ("subsref", prop);
1145 } 1124 }
1146 else 1125 else
1147 error ("subsref: unknown method or property: %s", name.c_str ()); 1126 error ("subsref: unknown method or property: %s", name.c_str ());
1148 } 1127 }
1149 break; 1128 break;
1177 1156
1178 if (prop.ok ()) 1157 if (prop.ok ())
1179 { 1158 {
1180 if (type.length () == 1) 1159 if (type.length () == 1)
1181 { 1160 {
1182 if (prop.check_set_access ()) 1161 refcount++;
1183 { 1162
1184 refcount++; 1163 cdef_object obj (this);
1185 1164
1186 cdef_object obj (this); 1165 prop.set_value (obj, rhs, true, "subsasgn");
1187 1166
1188 prop.set_value (obj, rhs); 1167 if (! error_state)
1189 1168 retval = to_ov (obj);
1190 if (! error_state)
1191 retval = to_ov (obj);
1192 }
1193 else
1194 gripe_property_access ("subsasgn", prop, true);
1195 } 1169 }
1196 else 1170 else
1197 { 1171 {
1198 } 1172 }
1199 1173
1920 { 1894 {
1921 cdef_class cls = obj.get_class (); 1895 cdef_class cls = obj.get_class ();
1922 1896
1923 obj.set_class (wrap ()); 1897 obj.set_class (wrap ());
1924 1898
1925 it->second.execute (obj, octave_value_list (), 0); 1899 it->second.execute (obj, octave_value_list (), 0, false);
1926 1900
1927 obj.set_class (cls); 1901 obj.set_class (cls);
1928 } 1902 }
1929 1903
1930 // FIXME: should we destroy corresponding properties here? 1904 // FIXME: should we destroy corresponding properties here?
1972 1946
1973 if (meth.ok ()) 1947 if (meth.ok ())
1974 { 1948 {
1975 if (meth.is_static ()) 1949 if (meth.is_static ())
1976 { 1950 {
1977 if (meth.check_access ()) 1951 octave_value_list args;
1952
1953 if (type.length () > 1 && idx.size () > 1
1954 && type[1] == '(')
1978 { 1955 {
1979 octave_value_list args; 1956 args = *(++(idx.begin ()));
1980 1957 skip++;
1981 if (type.length () > 1 && idx.size () > 1
1982 && type[1] == '(')
1983 {
1984 args = *(++(idx.begin ()));
1985 skip++;
1986 }
1987
1988 retval = meth.execute (args, (type.length () > skip
1989 ? 1 : nargout));
1990 } 1958 }
1991 else 1959
1992 gripe_method_access ("meta.class", meth); 1960 retval = meth.execute (args, (type.length () > skip
1961 ? 1 : nargout), true,
1962 "meta.class");
1993 } 1963 }
1994 else 1964 else
1995 ::error ("method `%s' is not static", nm.c_str ()); 1965 ::error ("method `%s' is not static", nm.c_str ());
1996 } 1966 }
1997 else 1967 else
1999 cdef_property prop = find_property (nm); 1969 cdef_property prop = find_property (nm);
2000 1970
2001 if (prop.ok ()) 1971 if (prop.ok ())
2002 { 1972 {
2003 if (prop.is_constant ()) 1973 if (prop.is_constant ())
2004 { 1974 retval(0) = prop.get_value (true, "meta.class");
2005 if (prop.check_get_access ())
2006 retval(0) = prop.get_value ();
2007 else
2008 gripe_property_access ("meta.class", prop, false);
2009 }
2010 else 1975 else
2011 ::error ("property `%s' is not constant", 1976 ::error ("property `%s' is not constant",
2012 nm.c_str ()); 1977 nm.c_str ());
2013 } 1978 }
2014 else 1979 else
2097 2062
2098 cdef_method ctor = find_method (ctor_name); 2063 cdef_method ctor = find_method (ctor_name);
2099 2064
2100 if (ctor.ok ()) 2065 if (ctor.ok ())
2101 { 2066 {
2102 if (ctor.check_access ()) 2067 octave_value_list ctor_args (args);
2103 { 2068 octave_value_list ctor_retval;
2104 octave_value_list ctor_args (args); 2069
2105 octave_value_list ctor_retval; 2070 ctor_args.prepend (to_ov (obj));
2106 2071 ctor_retval = ctor.execute (ctor_args, 1, true, "constructor");
2107 ctor_args.prepend (to_ov (obj)); 2072
2108 ctor_retval = ctor.execute (ctor_args, 1); 2073 if (! error_state)
2109 2074 {
2110 if (! error_state) 2075 if (ctor_retval.length () == 1)
2076 obj = to_cdef (ctor_retval(0));
2077 else
2111 { 2078 {
2112 if (ctor_retval.length () == 1) 2079 ::error ("%s: invalid number of output arguments for classdef constructor",
2113 obj = to_cdef (ctor_retval(0)); 2080 ctor_name.c_str ());
2114 else 2081 return;
2115 {
2116 ::error ("%s: invalid number of output arguments for classdef constructor",
2117 ctor_name.c_str ());
2118 return;
2119 }
2120 } 2082 }
2121 } 2083 }
2122 else
2123 gripe_method_access ("constructor", ctor);
2124 } 2084 }
2125 2085
2126 obj.mark_as_constructed (wrap ()); 2086 obj.mark_as_constructed (wrap ());
2127 } 2087 }
2128 2088
2444 2404
2445 return p; 2405 return p;
2446 } 2406 }
2447 2407
2448 octave_value 2408 octave_value
2449 cdef_property::cdef_property_rep::get_value (const cdef_object& obj) 2409 cdef_property::cdef_property_rep::get_value (const cdef_object& obj,
2410 bool do_check_access,
2411 const std::string& who)
2450 { 2412 {
2451 octave_value retval; 2413 octave_value retval;
2414
2415 if (do_check_access && ! check_get_access ())
2416 {
2417 gripe_property_access (who, wrap (), false);
2418
2419 return retval;
2420 }
2452 2421
2453 if (! obj.is_constructed ()) 2422 if (! obj.is_constructed ())
2454 { 2423 {
2455 cdef_class cls (to_cdef (get ("DefiningClass"))); 2424 cdef_class cls (to_cdef (get ("DefiningClass")));
2456 2425
2481 } 2450 }
2482 2451
2483 return retval; 2452 return retval;
2484 } 2453 }
2485 2454
2455 octave_value
2456 cdef_property::cdef_property_rep::get_value (bool do_check_access,
2457 const std::string& who)
2458 {
2459 if (do_check_access && ! check_get_access ())
2460 {
2461 gripe_property_access (who, wrap (), false);
2462
2463 return octave_value ();
2464 }
2465
2466 return get ("DefaultValue");
2467 }
2468
2486 bool 2469 bool
2487 cdef_property::cdef_property_rep::is_recursive_set (const cdef_object& /* obj */) const 2470 cdef_property::cdef_property_rep::is_recursive_set (const cdef_object& /* obj */) const
2488 { 2471 {
2489 // FIXME: implement 2472 // FIXME: implement
2490 return false; 2473 return false;
2491 } 2474 }
2492 2475
2493 void 2476 void
2494 cdef_property::cdef_property_rep::set_value (cdef_object& obj, 2477 cdef_property::cdef_property_rep::set_value (cdef_object& obj,
2495 const octave_value& val) 2478 const octave_value& val,
2496 { 2479 bool do_check_access,
2480 const std::string& who)
2481 {
2482 if (do_check_access && ! check_set_access ())
2483 {
2484 gripe_property_access (who, wrap (), true);
2485
2486 return;
2487 }
2488
2497 if (! obj.is_constructed ()) 2489 if (! obj.is_constructed ())
2498 { 2490 {
2499 cdef_class cls (to_cdef (get ("DefiningClass"))); 2491 cdef_class cls (to_cdef (get ("DefiningClass")));
2500 2492
2501 if (! obj.is_partially_constructed_for (cls)) 2493 if (! obj.is_partially_constructed_for (cls))
2533 } 2525 }
2534 } 2526 }
2535 } 2527 }
2536 2528
2537 bool 2529 bool
2538 cdef_property::check_get_access (void) const 2530 cdef_property::cdef_property_rep::check_get_access (void) const
2539 { 2531 {
2540 cdef_class cls (to_cdef (get ("DefiningClass"))); 2532 cdef_class cls (to_cdef (get ("DefiningClass")));
2541 2533
2542 if (! error_state) 2534 if (! error_state)
2543 return ::check_access (cls, get ("GetAccess")); 2535 return ::check_access (cls, get ("GetAccess"));
2544 2536
2545 return false; 2537 return false;
2546 } 2538 }
2547 2539
2548 bool 2540 bool
2549 cdef_property::check_set_access (void) const 2541 cdef_property::cdef_property_rep::check_set_access (void) const
2550 { 2542 {
2551 cdef_class cls (to_cdef (get ("DefiningClass"))); 2543 cdef_class cls (to_cdef (get ("DefiningClass")));
2552 2544
2553 if (! error_state) 2545 if (! error_state)
2554 return ::check_access (cls, get ("SetAccess")); 2546 return ::check_access (cls, get ("SetAccess"));
2562 // FIXME: check whether re-load is needed 2554 // FIXME: check whether re-load is needed
2563 } 2555 }
2564 2556
2565 octave_value_list 2557 octave_value_list
2566 cdef_method::cdef_method_rep::execute (const octave_value_list& args, 2558 cdef_method::cdef_method_rep::execute (const octave_value_list& args,
2567 int nargout) 2559 int nargout, bool do_check_access,
2560 const std::string& who)
2568 { 2561 {
2569 octave_value_list retval; 2562 octave_value_list retval;
2563
2564 if (do_check_access && ! check_access ())
2565 {
2566 gripe_method_access (who, wrap ());
2567
2568 return retval;
2569 }
2570 2570
2571 if (! get ("Abstract").bool_value ()) 2571 if (! get ("Abstract").bool_value ())
2572 { 2572 {
2573 check_method (); 2573 check_method ();
2574 2574
2585 } 2585 }
2586 2586
2587 octave_value_list 2587 octave_value_list
2588 cdef_method::cdef_method_rep::execute (const cdef_object& obj, 2588 cdef_method::cdef_method_rep::execute (const cdef_object& obj,
2589 const octave_value_list& args, 2589 const octave_value_list& args,
2590 int nargout) 2590 int nargout, bool do_check_access,
2591 const std::string& who)
2591 { 2592 {
2592 octave_value_list retval; 2593 octave_value_list retval;
2594
2595 if (do_check_access && ! check_access ())
2596 {
2597 gripe_method_access (who, wrap ());
2598
2599 return retval;
2600 }
2593 2601
2594 if (! get ("Abstract").bool_value ()) 2602 if (! get ("Abstract").bool_value ())
2595 { 2603 {
2596 check_method (); 2604 check_method ();
2597 2605
2623 2631
2624 return false; 2632 return false;
2625 } 2633 }
2626 2634
2627 bool 2635 bool
2628 cdef_method::check_access (void) const 2636 cdef_method::cdef_method_rep::check_access (void) const
2629 { 2637 {
2630 cdef_class cls (to_cdef (get ("DefiningClass"))); 2638 cdef_class cls (to_cdef (get ("DefiningClass")));
2631 2639
2632 if (! error_state) 2640 if (! error_state)
2633 return ::check_access (cls, get ("Access")); 2641 return ::check_access (cls, get ("Access"));