Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

219 lines (142 sloc) 4.433 kb
/*
Copyright (C) 2010-2014, Parrot Foundation.
=head1 NAME
src/pmc/nativepccmethod.pmc - NativePCCMethod PMC
=head1 DESCRIPTION
Container for native functions that handle PCC, the Parrot Calling Convention,
on their own.
=head2 Methods
=over 4
=cut
*/
/* HEADERIZER HFILE: none */
pmclass NativePCCMethod auto_attrs provides invokable {
ATTR STRING *signature;
ATTR void *func;
/* MMD fields */
ATTR STRING *mmd_long_signature;
ATTR PMC *mmd_multi_sig;
/*
=item C<void init()>
Initializes the PMC with a C<NULL> function pointer.
=cut
*/
VTABLE void init() {
Parrot_NativePCCMethod_attributes * const attrs = PARROT_NATIVEPCCMETHOD(SELF);
attrs->func = NULL;
attrs->signature = STRINGNULL;
attrs->mmd_long_signature = STRINGNULL;
attrs->mmd_multi_sig = PMCNULL;
PObj_custom_mark_SET(SELF);
}
/*
=item C<void *get_pointer()>
Get the pointer to the native function.
=item C<void set_pointer_keyed_str(STRING *sig, void *func)>
Set the pointer to the native function and the PCC signature.
=cut
*/
VTABLE void *get_pointer() :no_wb {
UNUSED(INTERP)
return PARROT_NATIVEPCCMETHOD(SELF)->func;
}
VTABLE void set_pointer_keyed_str(STRING *sig, void *func) {
PARROT_NATIVEPCCMETHOD(SELF)->signature = sig;
PARROT_NATIVEPCCMETHOD(SELF)->func = func;
}
/*
=item C<INTVAL defined()>
=item C<INTVAL get_bool()>
NULLness check.
=cut
*/
VTABLE INTVAL defined() :no_wb {
UNUSED(INTERP)
return !! PARROT_NATIVEPCCMETHOD(SELF)->func;
}
VTABLE INTVAL get_bool() :no_wb {
return STATICSELF.defined();
}
/*
=item C<opcode_t *invoke(void *next)>
Call the function pointer.
=cut
*/
VTABLE opcode_t *invoke(void *next) :no_wb {
void *func;
native_pcc_method_t fptr;
GET_ATTR_func(INTERP, SELF, func);
if (!func)
Parrot_ex_throw_from_c_noargs(INTERP,
EXCEPTION_INVALID_OPERATION,
"attempt to call NULL native function");
fptr = (native_pcc_method_t)D2FPTR(func);
fptr(INTERP, SELF);
/*
* If this function was tailcalled, the return result
* is already passed back to the caller of this frame.
* We therefore invoke the return continuation here,
* which gets rid of this frame and returns the real
* return address.
*/
{
PMC *cont = INTERP->current_cont;
if (!PMC_IS_NULL(cont)
&& (PObj_get_FLAGS(cont) & SUB_FLAG_TAILCALL)) {
cont = Parrot_pcc_get_continuation(interp, CURRENT_CONTEXT(interp));
next = VTABLE_invoke(INTERP, cont, next);
}
}
return (opcode_t *)next;
}
/*
=item C<void mark()>
Mark contained elements for GC.
=cut
*/
VTABLE void mark() :no_wb {
const Parrot_NativePCCMethod_attributes * const attrs = PARROT_NATIVEPCCMETHOD(SELF);
Parrot_gc_mark_STRING_alive(INTERP, attrs->signature);
Parrot_gc_mark_STRING_alive(INTERP, attrs->mmd_long_signature);
Parrot_gc_mark_PMC_alive(INTERP, attrs->mmd_multi_sig);
}
/*
=item C<PMC *clone()>
Create a clone of this PMC.
=cut
*/
VTABLE PMC *clone() :no_wb {
PMC * const ret = Parrot_pmc_new(INTERP, SELF->vtable->base_type);
const Parrot_NativePCCMethod_attributes * const self_attrs = PARROT_NATIVEPCCMETHOD(SELF);
Parrot_NativePCCMethod_attributes * const ret_attrs = PARROT_NATIVEPCCMETHOD(ret);
ret_attrs->func = self_attrs->func;
ret_attrs->signature = self_attrs->signature;
ret_attrs->mmd_long_signature = self_attrs->mmd_long_signature;
ret_attrs->mmd_multi_sig = self_attrs->mmd_multi_sig;
return ret;
}
/*
=item C<METHOD get_multisig()>
Return the MMD signature PMC, if any or C<PMCNULL>.
=cut
*/
METHOD get_multisig() :no_wb {
PMC *sig;
GET_ATTR_mmd_multi_sig(INTERP, SELF, sig);
if (PMC_IS_NULL(sig))
sig = PMCNULL;
RETURN(PMC *sig);
}
}
/*
=back
=head1 SEE ALSO
F<docs/pdds/pdd03_calling_conventions.pod>.
=cut
*/
/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
*/
Jump to Line
Something went wrong with that request. Please try again.