2 Copyright (C) 2001-2008, The Perl Foundation.
7 src/pmc/default.pmc - Abstract root class
11 These are the vtable functions for the default PMC class.
13 All methods which are not defined here get a default implementation
14 generated from F<src/vtable.tbl> by F<tools/build/pmc2c.pl>.
24 #include "parrot/parrot.h"
26 #define INT2KEY(i, k) key_new_integer((i), (k))
28 /* undef 'interface' to keep MSVC happy */
33 =item C<static const char *caller(PARROT_INTERP, PMC *pmc)>
35 Returns a C string for the name of C<*pmc>.
42 caller(PARROT_INTERP, PMC *pmc /*NULLOK*/)
44 return pmc && pmc->vtable && pmc->vtable->whoami ?
45 VTABLE_name(interp, pmc)->strstart : "(null)";
50 =item C<static void cant_do_method(PARROT_INTERP, PMC *pmc,
51 const char *methname)>
53 Throws an exception "$methname() not implemented in class '$class'", used by
54 all unimplemented messages.
61 cant_do_method(PARROT_INTERP, PMC *pmc /*NULLOK*/, const char *methname)
63 real_exception(interp, NULL, ILL_INHERIT,
64 "%s() not implemented in class '%s'", methname,
71 check_set_std_props(PARROT_INTERP, PMC *pmc, STRING *key, PMC *value)>
73 Called from C<setprop()>.
75 Returns a true value if C<setprop()> can avoid actually setting a property
76 in the prophash. If it returns true, the property setting will be reflected
77 in a future call to C<propagate_std_props()>
84 check_set_std_props(PARROT_INTERP, PMC *pmc, STRING *key, PMC *value)
86 /* the quick hack below cannot be used because the string could
87 be constructed in an interpreter that is later destroyed */
90 * a quick hack, to prevent freeing that string during DOD
91 * triggered in t/pmc/pmc_62.t when configured with --gc=libc
95 ro = string_make(interp, "_ro", 3, "ascii",
96 PObj_constant_FLAG|PObj_external_FLAG);
97 if (!string_compare(interp, key, ro)) {
101 * s2 in string_compare is freed here
103 if (!string_compare(interp, key, CONST_STRING(interp, "_ro"))) {
105 /* pmc should set/clear readonly */
106 const INTVAL on = VTABLE_get_bool(interp, value);
108 /* morph to Const/normal class or readonly class */
109 /* RT #46661 warn when this fails? */
110 if (on && (pmc->vtable->flags & VTABLE_HAS_CONST_TOO))
111 pmc->vtable = interp->vtables[pmc->vtable->base_type + 1];
112 else if (!on && (pmc->vtable->flags & (VTABLE_IS_CONST_FLAG)))
113 VTABLE_morph(interp, pmc, pmc->vtable->base_type - 1);
114 else if (on && (pmc->vtable->flags & VTABLE_HAS_READONLY_FLAG))
115 pmc->vtable = pmc->vtable->ro_variant_vtable;
116 else if (!on && (pmc->vtable->flags & VTABLE_IS_READONLY_FLAG)
117 && pmc->vtable->ro_variant_vtable)
118 pmc->vtable = pmc->vtable->ro_variant_vtable;
131 propagate_std_props(PARROT_INTERP, PMC *self, PMC *prop_hash)>
133 Set pending standard properties in C<prop_hash>.
140 propagate_std_props(PARROT_INTERP, PMC *self, PMC *prop_hash) {
141 if (self->vtable->flags & (VTABLE_IS_CONST_FLAG | VTABLE_IS_READONLY_FLAG)){
142 PMC * const pmc_true = pmc_new(interp, enum_class_Integer);
143 PMC_int_val(pmc_true) = 1;
144 VTABLE_set_pmc_keyed_str(interp, prop_hash, CONST_STRING(interp, "_ro"), pmc_true);
150 =item C<static INTVAL
151 has_pending_std_props(PMC *self)>
153 Returns true if propagate_std_props() would create a non-empty prophash.
160 has_pending_std_props(PMC *self) {
161 if (self->vtable->flags & (VTABLE_IS_CONST_FLAG | VTABLE_IS_READONLY_FLAG))
171 check_get_std_props(PARROT_INTERPeter, PMC *self, STRING *key)>
173 Checks if we can infer the value of C<key> property from C<self> without
174 looking at its prophash. Returns C<PMCNULL> if not, returns the value otherwise.
180 check_get_std_props(PARROT_INTERP, PMC *self, STRING *key) {
181 if ((self->vtable->flags & (VTABLE_IS_CONST_FLAG | VTABLE_IS_READONLY_FLAG))
182 &&!string_compare(interp, key, CONST_STRING(interp, "_ro"))) {
183 PMC * const ret_val = pmc_new(interp, enum_class_Integer);
184 PMC_int_val(ret_val) = 1;
194 make_prop_hash(PARROT_INTERP, PMC *self)>
196 Create a property hash for C<self>. Returns the created hash. Inferred
197 properties will be added to the hash and it will be set as
198 C<PMC_metadata(self)>.
205 make_prop_hash(PARROT_INTERP, PMC *self) {
209 add_pmc_ext(interp, self);
211 PMC_metadata(self) = prop = pmc_new_noinit(interp, enum_class_Hash);
212 GC_WRITE_BARRIER(interp, self, NULL, prop);
213 VTABLE_init(interp, prop);
214 propagate_std_props(interp, self, prop);
220 =item C<static INTVAL
221 does_isa(PARROT_INTERP, STRING *method, STRING *what)>
223 Compares C<*method> and C<*what>.
224 Returns true (1) if B<method> is found in B<what>, false (0) otherwise.
231 does_isa(PARROT_INTERP, const STRING *method, const STRING *what)
238 pos = string_str_index(interp, what, method, pos);
243 if (pos >= (INTVAL)string_length(interp, what))
246 len = string_length(interp, method);
248 if (pos && string_index(interp, what, pos - 1) != 32) {
253 if (pos+len < (INTVAL)string_length(interp, what) &&
254 string_index(interp, what, pos + len) != 32) {
263 pmclass default abstract no_init {
286 =item C<void init_pmc(PMC *initializer)>
288 With a null C<initializer>, calls C<init()>, else throws an exception.
294 VTABLE void init_pmc(PMC *initializer) {
295 if (PMC_IS_NULL(initializer))
298 real_exception(interp, NULL, ILL_INHERIT,
299 "init_pmc() not implemented in class '%s'",
300 caller(interp, pmc));
305 =item C<PMC *instantiate(PMC *init)>
307 Default fallback. Creates a new PMC of the type of the class SELF and
314 VTABLE PMC *instantiate(PMC *init) {
315 const INTVAL type = VTABLE_type(INTERP, SELF);
317 /* Ensure no looping, as pmc_new calls the instantiate vtable entry for
319 if (PObj_is_class_TEST(SELF))
320 real_exception(interp, NULL, 1,
321 "All high-level classes should override instantiate");
323 if (!PMC_IS_NULL(init))
324 return pmc_new_init(INTERP, type, init);
326 return pmc_new(INTERP, type);
333 Panics with a "no custom mark routine defined" error message.
340 PANIC(INTERP, "custom_mark flag set but no custom mark routine defined");
345 =item C<PMC *getprop(STRING *key)>
347 Returns the property for C<*key>. If no property is defined then the
348 NULL PMC is returned.
354 VTABLE PMC *getprop(STRING *key) {
355 if (SELF->pmc_ext && PMC_metadata(SELF))
356 return VTABLE_get_pmc_keyed_str(INTERP, PMC_metadata(SELF), key);
358 return check_get_std_props(interp, SELF, key);
363 =item C<void setprop(STRING *key, PMC *value)>
365 Sets the property for C<*key> to C<*value>.
371 VTABLE void setprop(STRING *key, PMC *value) {
372 if (check_set_std_props(INTERP, SELF, key, value))
375 if (SELF->pmc_ext && PMC_metadata(SELF)) {
376 VTABLE_set_pmc_keyed_str(INTERP,
377 PMC_metadata(SELF), key, value);
380 PMC * const prop = make_prop_hash(INTERP, SELF);
382 /* RT #46663 is this too late for --gc-debug? */
383 VTABLE_set_pmc_keyed_str(INTERP, prop, key, value);
389 =item C<void delprop(STRING *key)>
391 Deletes the property for C<*key>.
397 VTABLE void delprop(STRING *key) {
398 if (SELF->pmc_ext && PMC_metadata(SELF))
399 VTABLE_delete_keyed_str(INTERP, PMC_metadata(SELF), key);
404 =item C<PMC *getprops()>
406 Returns the PMC's properties or the NULL PMC if no properties exist.
412 VTABLE PMC *getprops() {
414 add_pmc_ext(INTERP, SELF);
416 if (!PMC_metadata(SELF)) {
417 if (has_pending_std_props(SELF))
418 return make_prop_hash(INTERP, SELF);
423 return PMC_metadata(SELF);
428 =item C<INTVAL type()>
430 Returns the PMC's type.
436 VTABLE INTVAL type() {
437 return SELF->vtable->base_type;
442 =item C<INTVAL type_keyed_int(INTVAL key)>
444 Converts C<key> to a PMC key and returns the result of calling
445 C<type_keyed()> with it.
451 VTABLE INTVAL type_keyed_int(INTVAL key) {
452 PMC *const r_key = INT2KEY(INTERP, key);
453 return SELF.type_keyed(r_key);
458 =item C<STRING *name()>
460 Returns the name of the PMC.
466 VTABLE STRING *name() {
467 return SELF->vtable->whoami;
473 =item C<PMC *get_namespace>
475 Return the namespace for this PMC.
477 =item C<PMC *find_method(STRING *method_name)>
479 Looks up the method for C<*method_name> and returns it. If no method is
480 found then C<NULL> is returned.
482 =item C<void add_method(STRING *method_name, PMC *sub)>
484 Store the method as a global in the namespace of this class.
490 VTABLE PMC *get_namespace() {
491 return SELF->vtable->_namespace;
495 VTABLE PMC *find_method(STRING *method_name) {
496 return Parrot_find_method_with_cache(INTERP, SELF, method_name);
499 VTABLE void add_method(STRING *method_name, PMC *sub_pmc) {
500 VTABLE_set_pmc_keyed_str(INTERP, SELF->vtable->_namespace,
501 method_name, sub_pmc);
505 =item C<INTVAL get_integer_keyed_int(INTVAL key)>
507 Converts C<key> to a PMC key and returns the result of calling
508 C<get_integer_keyed()> with it.
514 VTABLE INTVAL get_integer_keyed_int(INTVAL key) {
515 PMC *const r_key = INT2KEY(INTERP, key);
516 return SELF.get_integer_keyed(r_key);
521 =item C<FLOATVAL get_number_keyed_int(INTVAL key)>
523 Converts C<key> to a PMC key and returns the result of calling
524 C<get_number_keyed()> with it.
530 VTABLE FLOATVAL get_number_keyed_int(INTVAL key) {
531 PMC *const r_key = INT2KEY(INTERP, key);
532 return SELF.get_number_keyed(r_key);
538 =item C<STRING *get_string_keyed_int(INTVAL key)>
540 Converts C<key> to a PMC key and returns the result of calling
541 C<get_string_keyed()> with it.
547 VTABLE STRING *get_string_keyed_int(INTVAL key) {
548 PMC *const r_key = INT2KEY(INTERP, key);
549 return SELF.get_string_keyed(r_key);
554 =item C<INTVAL elements_keyed_int(INTVAL key)>
556 Converts C<key> to a PMC key and returns the result of calling
557 C<elements_keyed()> with it.
563 INTVAL elements_keyed_int(INTVAL key) {
564 PMC *const r_key = INT2KEY(INTERP, key);
565 return SELF.elements_keyed(r_key);
571 =item C<PMC *get_pmc_keyed_int(INTVAL key)>
573 Converts C<key> to a PMC key and returns the result of calling
574 C<get_pmc_keyed()> with it.
580 VTABLE PMC *get_pmc_keyed_int(INTVAL key) {
581 PMC *const r_key = INT2KEY(INTERP, key);
582 return SELF.get_pmc_keyed(r_key);
587 =item C<void *get_pointer()>
589 Returns the address of the PMC.
595 VTABLE void *get_pointer() {
601 =item C<INTVAL is_same(PMC *value)>
603 Returns whether the PMC is numerically equal to C<value>.
609 VTABLE INTVAL is_same(PMC *value) {
610 return SELF == value;
615 =item C<void assign_pmc(PMC *value)>
617 =item C<void assign_string_native(PMC *value)>
619 Defaults fall back to C<set_pmc> and C<set_string_native>.
625 VTABLE void assign_pmc(PMC *value) {
626 STRING * const undef = CONST_STRING(INTERP, "Undef");
628 if (VTABLE_isa(INTERP, value, undef))
629 pmc_reuse(INTERP, SELF, value->vtable->base_type, 0);
634 VTABLE void assign_string_native(STRING *value) {
635 SELF.set_string_native(value);
640 =item C<void morph(INTVAL type)>
642 Changes the PMC to a PMC of a new type
648 VTABLE void morph(INTVAL type) {
649 pmc_reuse(INTERP, SELF, type, 0);
654 =item C<void set_integer_keyed_int(INTVAL key, INTVAL value)>
656 Converts C<key> to a PMC key and calls C<set_integer_keyed()> with it
663 VTABLE void set_integer_keyed_int(INTVAL key, INTVAL value) {
664 PMC *const r_key = INT2KEY(INTERP, key);
665 SELF.set_integer_keyed(r_key, value);
670 =item C<void set_number_keyed_int(INTVAL key, FLOATVAL value)>
672 Converts C<key> to a PMC key and calls C<set_number_keyed()> with it
679 VTABLE void set_number_keyed_int(INTVAL key, FLOATVAL value) {
680 PMC *const r_key = INT2KEY(INTERP, key);
681 SELF.set_number_keyed(r_key, value);
686 =item C<void set_string_keyed_int(INTVAL key, STRING *string)>
688 Converts C<key> to a PMC key and calls C<set_string_keyed()> with it
695 VTABLE void set_string_keyed_int(INTVAL key, STRING *string) {
696 PMC *const r_key = INT2KEY(INTERP, key);
697 SELF.set_string_keyed(r_key, string);
702 =item C<void set_bool_keyed_int(INTVAL key, INTVAL value)>
704 Converts C<key> to a PMC key and calls C<set_bool_keyed()> with it
711 void set_bool_keyed_int(INTVAL key, INTVAL value) {
712 PMC *const r_key = INT2KEY(INTERP, key);
713 SELF.set_bool_keyed(r_key, value);
718 =item C<void set_pmc_keyed_int(INTVAL key, PMC *value)>
720 Converts C<key> to a PMC key and calls C<set_pmc_keyed()> with it
727 VTABLE void set_pmc_keyed_int(INTVAL key, PMC *value) {
728 PMC *const r_key = INT2KEY(INTERP, key);
729 SELF.set_pmc_keyed(r_key, value);
734 =item C<INTVAL is_equal(PMC *value)>
736 Returns whether the PMC is equal to C<*value>.
742 VTABLE INTVAL is_equal(PMC *value) {
743 return (SELF->vtable == value->vtable
744 && PMC_struct_val(SELF) == PMC_struct_val(value)
745 && PMC_data(SELF) == PMC_data(value));
750 =item C<INTVAL is_equal_num(PMC *value)>
752 Returns whether the PMC is numerically equal to C<*value>.
758 VTABLE INTVAL is_equal_num(PMC *value) {
759 return (VTABLE_get_number(INTERP, SELF) ==
760 VTABLE_get_number(INTERP, value));
765 =item C<INTVAL is_equal_str(PMC *value)>
767 Returns whether the PMC is numerically equal to C<*value>.
773 VTABLE INTVAL is_equal_str(PMC *value) {
774 return (0 == string_equal(INTERP, VTABLE_get_string(INTERP, SELF),
775 VTABLE_get_string(INTERP, value)));
782 =item C<INTVAL exists_keyed_int(INTVAL key)>
784 Converts C<key> to a PMC key and returns the result of calling
785 C<exists_keyed()> with it.
791 VTABLE INTVAL exists_keyed_int(INTVAL key) {
792 PMC *const r_key = INT2KEY(INTERP, key);
793 return SELF.exists_keyed(r_key);
798 =item C<INTVAL defined()>
806 VTABLE INTVAL defined() {
812 =item C<INTVAL defined_keyed_int(INTVAL key)>
814 Converts C<key> to a PMC key and returns the result of calling
815 C<defined_keyed()> with it.
821 VTABLE INTVAL defined_keyed_int(INTVAL key) {
822 PMC *const r_key = INT2KEY(INTERP, key);
823 return SELF.defined_keyed(r_key);
828 =item C<void delete_keyed_int(INTVAL key)>
830 Converts C<key> to a PMC key and calls C<delete_keyed()> with it.
836 VTABLE void delete_keyed_int(INTVAL key) {
837 PMC *const r_key = INT2KEY(INTERP, key);
838 SELF.delete_keyed(r_key);
843 =item C<PMC *nextkey_keyed_int(INTVAL key, INTVAL w)>
845 Converts C<key> to a PMC key and returns the result of calling
846 C<nextkey_keyed()> with it.
852 VTABLE PMC *nextkey_keyed_int(INTVAL key, INTVAL w) {
853 PMC *const r_key = INT2KEY(INTERP, key);
854 return SELF.nextkey_keyed(r_key, w);
859 =item C<INTVAL can(STRING *method)>
861 Reports whether the PMC "can" perform C<method>.
862 If the PMC implements the vtable function C<method>,
863 true (1) is returned; otherwise, false (0) is returned.
869 VTABLE INTVAL can(STRING *method) {
870 return !PMC_IS_NULL(VTABLE_find_method(INTERP, SELF, method));
875 =item C<INTVAL does(STRING *interface)>
877 Reports whether the PMC "does" perform C<interface>.
878 If the interface C<interface> is found in the PMC's interface list,
879 true (1) is returned; otherwise, false (0) is returned.
885 VTABLE INTVAL does(STRING *_interface) {
886 return does_isa(INTERP, _interface, SELF->vtable->provides_str);
891 =item C<INTVAL does_pmc(PMC *role)>
893 Reports whether the PMC "does" the C<role>.
899 INTVAL does_pmc(PMC *role) {
900 /* No C-level roles yet. */
906 =item C<INTVAL isa_pmc(PMC *_class)>
908 Reports whether the PMC "isa" C<_class>.
909 If the class C<_class> is found in the PMC's class hierarchy,
910 true (1) is returned; otherwise, false (0) is returned.
916 VTABLE INTVAL isa_pmc(PMC *lookup) {
917 /* RT #46665 - walk mro */
918 return parrot_hash_exists(INTERP, SELF->vtable->isa_hash,
919 (void *)VTABLE_get_string(interp, lookup));
924 =item C<INTVAL isa(STRING *_class)>
926 Reports whether the PMC "isa" C<_class>.
927 If the class C<_class> is found in the PMC's class hierarchy,
928 true (1) is returned; otherwise, false (0) is returned.
934 VTABLE INTVAL isa(STRING *_class) {
935 /* RT #46665 - walk mro */
936 return parrot_hash_exists(INTERP, SELF->vtable->isa_hash,
942 =item C<PMC *inspect_str(STRING *what)>
944 Provides introspection of a specific piece of information about the PMC.
950 PMC *inspect_str(STRING *name) {
952 if (string_equal(interp, name, CONST_STRING(interp, "flags")) == 0) {
953 found = pmc_new(interp, enum_class_Integer);
954 VTABLE_set_integer_native(interp, found, PObj_get_FLAGS(SELF));
957 real_exception(interp, NULL, INVALID_OPERATION,
958 "Unknown introspection value '%S'", name);
965 =item C<PMC *inspect()>
967 Returns a Hash describing the class, with key/value pairs as described in
974 PMC *metadata = pmc_new(interp, enum_class_Hash);
975 STRING * const flags_str = CONST_STRING(interp, "flags");
977 VTABLE_set_pmc_keyed_str(interp, metadata, flags_str,
978 VTABLE_inspect_str(interp, SELF, flags_str));
985 =item C<PMC *get_class()>
987 Returns SELF. A PMC is its own class.
989 =item C<PMC *get_attr_str(STRING *attr)>
991 Look for NCI methods and properties.
996 VTABLE PMC *get_class() {
997 PMC *ns = VTABLE_get_namespace(interp, SELF);
998 PMC *_class = PMCNULL;
1000 if (!PMC_IS_NULL(ns))
1001 _class = VTABLE_get_class(interp, ns);
1003 if (PMC_IS_NULL(_class)) {
1004 INTVAL type = VTABLE_type(interp, SELF);
1005 PMC *type_num = pmc_new(interp, enum_class_Integer);
1006 VTABLE_set_integer_native(interp, type_num, type);
1007 return pmc_new_init(interp, enum_class_PMCProxy, type_num);
1014 VTABLE PMC *get_attr_str(STRING *name) {
1017 /* let's look for props first
1018 * RT #46667 do we need that in the default object system?
1020 if (SELF->pmc_ext && PMC_metadata(SELF)) {
1021 const HashBucket * const b =
1022 parrot_hash_get_bucket(INTERP, (Hash *)PMC_metadata(SELF), name);
1025 p = (PMC *)b->value;
1030 p = VTABLE_find_method(INTERP, SELF, name);
1035 if (VTABLE_isa(INTERP, p, CONST_STRING(INTERP, "NCI"))) {
1036 PMC * const bound_meth = VTABLE_clone(INTERP, p);
1037 bound_meth->vtable = interp->vtables[enum_class_Bound_NCI];
1038 VTABLE_set_pmc(INTERP, bound_meth, SELF);
1042 else if (p->vtable->base_type == enum_class_MultiSub) {
1043 PMC * const bound_meth = pmc_new(INTERP, enum_class_Bound_NCI);
1044 VTABLE_set_pmc(INTERP, bound_meth, SELF);
1045 PMC_struct_val(bound_meth) = p;
1046 PObj_get_FLAGS(bound_meth) |= PObj_private0_FLAG;
1051 /* RT #46671 bound user functions */
1057 =item C<PMC *get_attr_keyed(PMC *key, STRING *name)>
1059 Default version of keyed attribute lookups. Discards the key and does a lookup
1060 by the string name passed in.
1062 =item C<void set_attr_keyed(PMC *key, STRING *name, PMC *value)>
1064 Default version of keyed attribute set. Discards the key and does a set by
1065 the string name passed in.
1070 VTABLE PMC *get_attr_keyed(PMC *key, STRING *name) {
1071 return VTABLE_get_attr_str(INTERP, SELF, name);
1074 VTABLE void set_attr_keyed(PMC *key, STRING *name, PMC *value) {
1075 VTABLE_set_attr_str(INTERP, SELF, name, value);
1080 =item C<void add_parent(PMC *parent)>
1082 Add class C<parent> to the list of our parents.
1088 VTABLE void add_parent(PMC *parent) {
1089 if (!PObj_is_class_TEST(SELF))
1090 real_exception(interp, NULL, 1, "Only classes can be subclassed");
1092 real_exception(interp, NULL, 1, "All classes should override add_parent");
1097 =item C<void visit(visit_info *info)>
1099 Used by DOD to mark the PMC.
1105 VTABLE void visit(visit_info *info) {
1106 /* default - mark prop hash */
1107 if (SELF->pmc_ext && PMC_metadata(SELF) &&
1108 info->extra_flags != EXTRA_IS_PROP_HASH) {
1109 info->extra_flags = EXTRA_IS_PROP_HASH;
1110 info->extra = PMC_metadata(SELF);
1112 /* place escape mark */
1113 (info->visit_pmc_now)(INTERP, SELF, info);
1115 /* place and the prop hash */
1116 (info->visit_pmc_now)(INTERP, PMC_metadata(SELF), info);
1122 =item C<PMC* clone()>
1124 Clones this PMC. By default, this just does a freeze and thaw.
1130 VTABLE PMC* clone() {
1131 return Parrot_thaw(interp, Parrot_freeze(interp, SELF));
1136 =item C<void freeze(visit_info *info)>
1144 VTABLE void freeze(visit_info *info) {
1145 /* default - no action */
1150 =item C<void thaw(visit_info *info)>
1152 Initializes the PMC during unarchiving.
1158 VTABLE void thaw(visit_info *info) {
1159 /* default - initialize the PMC */
1160 if (info->extra_flags == EXTRA_IS_PROP_HASH) {
1162 add_pmc_ext(INTERP, SELF);
1164 info->thaw_ptr = &PMC_metadata(SELF);
1165 info->container = SELF;
1167 (info->visit_pmc_now)(INTERP, PMC_metadata(SELF), info);
1175 =item C<void thawfinish(visit_info *info)>
1183 void thawfinish(visit_info *info) {
1184 /* default - no action */
1199 * c-file-style: "parrot"
1201 * vim: expandtab shiftwidth=4: