/* Copyright (C) 2005-2007, The Perl Foundation. $Id: luauserdata.pmc 21554 2007-09-25 13:55:52Z paultcochrane $ =head1 NAME pmc/luauserdata.pmc - Lua Userdata =head1 DESCRIPTION C extends C to provide a class with the behaviour of the Lua C type. =head2 Overloaded Methods =over 4 =cut */ #include "lua_private.h" pmclass LuaUserdata extends LuaAny does scalar dynpmc need_ext group lua_group hll Lua { /* =item C Initializes the userdata. =cut */ void init() { PMC_pmc_val(SELF) = NULL; PMC_metadata(SELF) = NULL; PObj_custom_mark_destroy_SETALL(SELF); } /* =item C Marks the userdata as live. =cut */ void mark() { if (PMC_pmc_val(SELF)) pobject_lives(INTERP, (PObj *)PMC_pmc_val(SELF)); if (PMC_metadata(SELF)) pobject_lives(INTERP, (PObj *)PMC_metadata(SELF)); } /* =item C Call finalizer and free the userdata. =cut */ void destroy() { PMC* meth = find_meth(INTERP, SELF, "__gc"); if (meth != NULL) { (void)Parrot_runops_fromc_args(INTERP, meth, "vP", SELF); } if (PMC_pmc_val(SELF)) { PMC_pmc_val(SELF) = NULL; } } /* =item C =cut */ STRING* get_string() { return Parrot_sprintf_c(INTERP, "userdata: %08X", SELF); } /* =item C Return the string "userdata". =cut */ STRING* name() { return const_string(INTERP, "userdata"); } /* =item C =cut */ PMC* clone() { return SELF; } /* =item C =cut */ void set_pmc(PMC *value) { PMC_struct_val(SELF) = PMC_struct_val(value); PMC_metadata(SELF) = PMC_metadata(value); } /* =item C =cut */ PMC* get_attr_str(STRING* key) { return PMC_pmc_val(SELF); } /* =item C =cut */ void set_attr_str(STRING* key, PMC* value) { PMC_pmc_val(SELF) = value; } /* =back =head2 non-Vtable Methods =over 4 =item C The C<==> operation. Compares reference (not in depth). =cut */ INTVAL is_equal(PMC* value) { MMD_LuaUserdata: { PMC *meth = find_meth(INTERP, SELF, "__eq"); if (meth != NULL) { PMC *retval = Parrot_runops_fromc_args(INTERP, meth, "PPP", SELF, value); if (PMC_IS_NULL(retval)) { return (INTVAL)0; } return VTABLE_get_bool(INTERP, retval); } if (SELF == value) return (INTVAL)1; else return (INTVAL)0; } MMD_DEFAULT: { return (INTVAL)0; } } /* =item C =cut */ INTVAL cmp(PMC* value) { MMD_LuaUserdata: { real_exception(INTERP, NULL, ILL_INHERIT, "attempt to compare two userdata values"); return (INTVAL)0; } MMD_DEFAULT: { real_exception(INTERP, NULL, ILL_INHERIT, "attempt to compare userdata with %s", string_to_cstring(INTERP, VTABLE_name(INTERP, value))); return (INTVAL)0; } } /* =back =head2 Specific Methods =over 4 =item C =cut */ METHOD PMC* get_metatable() { PMC *retval = PMC_metadata(SELF); if (NULL == retval) retval = pmc_new(INTERP, dynpmc_LuaNil); return retval; } /* =item C =cut */ METHOD PMC* rawequal(PMC* value) { PMC* retval = pmc_new(INTERP, dynpmc_LuaBoolean); if (PMC_type(SELF) == PMC_type(value) && SELF == value) PMC_int_val(retval) = 1; else PMC_int_val(retval) = 0; return retval; } /* =item C =cut */ METHOD void set_metatable(PMC *meta) { if (dynpmc_LuaNil == PMC_type(meta)) { PMC_metadata(SELF) = NULL; } else { PMC_metadata(SELF) = meta; } } } /* =back =head1 AUTHORS Francois Perrad. =cut */ /* * Local variables: * c-file-style: "parrot" * End: * vim: expandtab shiftwidth=4: */