Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

343 lines (272 sloc) 10.274 kb
#include "pmc_nqplexinfo.h"
/* Locates the register number for getting the specified name
* and type of lexical. */
static INTVAL register_number_for_get(PARROT_INTERP, Hash *hash,
STRING *name, INTVAL reg_type) {
HashBucket *b = Parrot_hash_get_bucket(interp, hash, name);
if (!b)
return -1;
if (((INTVAL)b->value & 3) != reg_type)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LEX_NOT_FOUND,
"Lexical '%Ss' is of wrong register type in lexical lookup", name);
return ((INTVAL)b->value) >> 2;
}
/* Locates the register number for setting the specified name
* and type of lexical. */
static INTVAL register_number_for_set(PARROT_INTERP, Hash *hash,
STRING *name, INTVAL reg_type) {
HashBucket *b = Parrot_hash_get_bucket(interp, hash, name);
if (!b)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LEX_NOT_FOUND,
"Lexical '%Ss' not found", name);
if (((INTVAL)b->value & 3) != reg_type)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LEX_NOT_FOUND,
"Lexical '%Ss' is of wrong register type in lexical lookup", name);
return ((INTVAL)b->value) >> 2;
}
pmclass NQPLexPad
provides hash
auto_attrs
dynpmc group nqp
hll nqp
maps LexPad
{
ATTR PMC *lexinfo;
ATTR PMC *ctx;
/* Cache of the hash from the static lex info, so we needn't look it up
* every time. */
ATTR Hash *lexinfo_hash;
VTABLE void init() {
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
"Cannot create a NQPLexPad PMC without an initializer");
}
/*
=item C<init_pmc(PMC *lexinfo)>
Initialize the LexPad PMC and remember the associate
lexinfo.
=item C<void set_pointer(void *)>
Associate the context, and set into it any static entries.
=item C<INTVAL elements()>
Returns the number of elements in the hash.
=item C<INTVAL exists_keyed(PMC *name)>
=item C<INTVAL exists_keyed_str(STRING *name)>
Returns whether a lexical C<name> exists in the hash.
=item C<PMC *get_pmc_keyed_str(STRING *name)>
=item C<PMC *get_pmc_keyed(PMC *name)>
Return the lexical with the given name, or NULL (not PMCNULL), if the
lexical doesn't exist.
=item C<void set_pmc_keyed(PMC *name, PMC *value)>
=item C<void set_pmc_keyed_str(STRING *name, PMC *value)>
Set the lexical with the given name to value. If the lexical name
doesn't exist, it is created.
=item C<PMC *get_lexinfo()>
Return the LexInfo PMC, if any or a Null PMC.
=cut
*/
VTABLE void init_pmc(PMC *lexinfo) {
SET_ATTR_lexinfo(INTERP, SELF, lexinfo);
PObj_custom_mark_SET(SELF);
}
VTABLE void mark() {
PMC *lexinfo, *ctx;
GET_ATTR_lexinfo(INTERP, SELF, lexinfo);
GET_ATTR_ctx(INTERP, SELF, ctx);
Parrot_gc_mark_PMC_alive(INTERP, lexinfo);
Parrot_gc_mark_PMC_alive(INTERP, ctx);
}
VTABLE void set_pointer(void *ctx) {
/* Check if we need to put any static values in place. */
PMC *info;
Hash *hash;
GET_ATTR_lexinfo(INTERP, SELF, info);
if (info->vtable->base_type != enum_class_LexInfo
#ifdef enum_class_Proxy
&& info->vtable->base_type != enum_class_Proxy
#endif
) {
PMC *name_map;
GETATTR_NQPLexInfo_name_to_register_map(INTERP, info, name_map);
hash = (Hash *)VTABLE_get_pointer(INTERP, name_map);
}
else {
hash = (Hash *)VTABLE_get_pointer(INTERP, info);
}
SET_ATTR_lexinfo_hash(INTERP, SELF, hash);
if (info->vtable->base_type != enum_class_LexInfo) {
PMC *static_slots_cache;
GETATTR_NQPLexInfo_static_slots_cache(INTERP, info, static_slots_cache);
if (!PMC_IS_NULL(static_slots_cache)) {
/* Yes, we have some. Grab values too, then iterate. */
PMC *static_values_cache;
INTVAL num_statics = VTABLE_elements(interp, static_slots_cache);
INTVAL i;
GETATTR_NQPLexInfo_static_values_cache(INTERP, info, static_values_cache);
for (i = 0; i < num_statics; i++) {
INTVAL slot = VTABLE_get_integer_keyed_int(interp, static_slots_cache, i);
PMC *value = VTABLE_get_pmc_keyed_int(interp, static_values_cache, i);
CTX_REG_PMC(interp, (PMC *)ctx, slot) = value;
}
PARROT_GC_WRITE_BARRIER(INTERP, (PMC *)ctx);
}
}
/* Stash the context pointer. */
SET_ATTR_ctx(INTERP, SELF, (PMC *)ctx);
}
VTABLE INTVAL elements() {
PMC *info;
GET_ATTR_lexinfo(INTERP, SELF, info);
return VTABLE_elements(interp, info);
}
VTABLE INTVAL exists_keyed_str(STRING *name) {
PMC *info, *name_map;
const Hash *hash;
GET_ATTR_lexinfo(INTERP, SELF, info);
if (info->vtable->base_type != enum_class_LexInfo) {
GETATTR_NQPLexInfo_name_to_register_map(INTERP, info, name_map);
hash = (const Hash *)VTABLE_get_pointer(INTERP, name_map);
}
else {
hash = (const Hash *)VTABLE_get_pointer(INTERP, info);
}
return hash->entries
? (Parrot_hash_get_bucket(INTERP, hash, name) != 0)
: 0;
}
VTABLE INTVAL exists_keyed(PMC *name) {
STRING * const s = VTABLE_get_string(INTERP, name);
return SELF.exists_keyed_str(s);
}
VTABLE PMC *get_pmc_keyed_str(STRING *name) {
Hash *hash;
INTVAL reg;
PMC *ctx;
GET_ATTR_lexinfo_hash(INTERP, SELF, hash);
reg = register_number_for_get(INTERP, hash, name, REGNO_PMC);
if (reg < 0)
return PMCNULL;
GET_ATTR_ctx(INTERP, SELF, ctx);
return CTX_REG_PMC(interp, ctx, reg);
}
VTABLE INTVAL get_integer_keyed_str(STRING *name) {
Hash *hash;
INTVAL reg;
PMC *ctx;
GET_ATTR_lexinfo_hash(INTERP, SELF, hash);
reg = register_number_for_get(INTERP, hash, name, REGNO_INT);
if (reg < 0)
return 0;
GET_ATTR_ctx(INTERP, SELF, ctx);
return CTX_REG_INT(interp, ctx, reg);
}
VTABLE FLOATVAL get_number_keyed_str(STRING *name) {
Hash *hash;
INTVAL reg;
PMC *ctx;
GET_ATTR_lexinfo_hash(INTERP, SELF, hash);
reg = register_number_for_get(INTERP, hash, name, REGNO_NUM);
if (reg < 0)
return 0.0;
GET_ATTR_ctx(INTERP, SELF, ctx);
return CTX_REG_NUM(interp, ctx, reg);
}
VTABLE STRING *get_string_keyed_str(STRING *name) {
Hash *hash;
INTVAL reg;
PMC *ctx;
GET_ATTR_lexinfo_hash(INTERP, SELF, hash);
reg = register_number_for_get(INTERP, hash, name, REGNO_STR);
if (reg < 0)
return STRINGNULL;
GET_ATTR_ctx(INTERP, SELF, ctx);
return CTX_REG_STR(interp, ctx, reg);
}
VTABLE PMC *get_pmc_keyed(PMC *name) {
STRING * const s = VTABLE_get_string(INTERP, name);
return SELF.get_pmc_keyed_str(s);
}
VTABLE INTVAL get_integer_keyed(PMC *name) {
STRING * const s = VTABLE_get_string(INTERP, name);
return SELF.get_integer_keyed_str(s);
}
VTABLE FLOATVAL get_number_keyed(PMC *name) {
STRING * const s = VTABLE_get_string(INTERP, name);
return SELF.get_number_keyed_str(s);
}
VTABLE STRING *get_string_keyed(PMC *name) {
STRING * const s = VTABLE_get_string(INTERP, name);
return SELF.get_string_keyed_str(s);
}
VTABLE void set_pmc_keyed_str(STRING *name, PMC *value) {
Hash *hash;
INTVAL reg;
PMC *ctx;
GET_ATTR_lexinfo_hash(INTERP, SELF, hash);
reg = register_number_for_set(INTERP, hash, name, REGNO_PMC);
GET_ATTR_ctx(INTERP, SELF, ctx);
CTX_REG_PMC(interp, ctx, reg) = value;
PARROT_GC_WRITE_BARRIER(INTERP, ctx);
}
VTABLE void set_integer_keyed_str(STRING *name, INTVAL value) {
Hash *hash;
INTVAL reg;
PMC *ctx;
GET_ATTR_lexinfo_hash(INTERP, SELF, hash);
reg = register_number_for_set(INTERP, hash, name, REGNO_INT);
GET_ATTR_ctx(INTERP, SELF, ctx);
CTX_REG_INT(interp, ctx, reg) = value;
}
VTABLE void set_number_keyed_str(STRING *name, FLOATVAL value) {
Hash *hash;
INTVAL reg;
PMC *ctx;
GET_ATTR_lexinfo_hash(INTERP, SELF, hash);
reg = register_number_for_set(INTERP, hash, name, REGNO_NUM);
GET_ATTR_ctx(INTERP, SELF, ctx);
CTX_REG_NUM(interp, ctx, reg) = value;
}
VTABLE void set_string_keyed_str(STRING *name, STRING *value) {
Hash *hash;
INTVAL reg;
PMC *ctx;
GET_ATTR_lexinfo_hash(INTERP, SELF, hash);
reg = register_number_for_set(INTERP, hash, name, REGNO_STR);
GET_ATTR_ctx(INTERP, SELF, ctx);
CTX_REG_STR(interp, ctx, reg) = value;
PARROT_GC_WRITE_BARRIER(INTERP, ctx);
}
VTABLE void set_pmc_keyed(PMC *name, PMC *value) {
STRING * const s = VTABLE_get_string(INTERP, name);
SELF.set_pmc_keyed_str(s, value);
}
VTABLE void set_integer_keyed(PMC *name, INTVAL value) {
STRING * const s = VTABLE_get_string(INTERP, name);
SELF.set_integer_keyed_str(s, value);
}
VTABLE void set_number_keyed(PMC *name, FLOATVAL value) {
STRING * const s = VTABLE_get_string(INTERP, name);
SELF.set_number_keyed_str(s, value);
}
VTABLE void set_string_keyed(PMC *name, STRING *value) {
STRING * const s = VTABLE_get_string(INTERP, name);
SELF.set_string_keyed_str(s, value);
}
METHOD get_lexinfo() {
PMC *lexinfo;
GET_ATTR_lexinfo(INTERP, SELF, lexinfo);
RETURN(PMC *lexinfo);
}
/*
=item C<PMC *get_iter()>
Get iterator for declared lexicals.
=cut
*/
VTABLE PMC *get_iter() {
PMC *lexinfo;
GET_ATTR_lexinfo(INTERP, SELF, lexinfo);
return VTABLE_get_iter(INTERP, lexinfo);
}
}
/*
=back
=cut
*/
Jump to Line
Something went wrong with that request. Please try again.