Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Stub in NQPLexInfo and NQPLexPad, which will eventually give static l…
…expad support.
- Loading branch information
Showing
3 changed files
with
281 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
| /* This implements a container of static lexical information for | ||
| * NQP (will also be used by Rakudo). It differs from Parrot's | ||
| * LexInfo in that it provides support for static lexical values | ||
| * that get set into each created lexpad by default. It will also | ||
| * enable indexed lookups and, some day, may also allow for native | ||
| * values to be stored too. */ | ||
| pmclass NQPLexInfo provides hash auto_attrs dynpmc group nqp { | ||
| /* Hash mapping a name to the register that always holds its | ||
| * value. */ | ||
| ATTR PMC *name_to_register_map; | ||
|
|
||
| /* Hash mapping names to static values. This is the authoritative | ||
| * source of these, but we always build a more quickly usable | ||
| * cache in the next two attributes. */ | ||
| ATTR PMC *static_values; | ||
|
|
||
| /* Integer array of slots that we always want to pre-initialize | ||
| * with static values; built from the static_values hash. */ | ||
| ATTR PMC *static_slots_cache; | ||
|
|
||
| /* Matching PMC array of the values to pre-init with; built from | ||
| * the static_values hash. */ | ||
| ATTR PMC *static_values_cache; | ||
|
|
||
| void class_init() { | ||
| INTERP->vtables[entry]->flags |= VTABLE_IS_CONST_PMC_FLAG; | ||
| } | ||
|
|
||
| VTABLE void init() { | ||
| SELF.init_pmc(PMCNULL); | ||
| } | ||
|
|
||
| VTABLE void init_pmc(PMC *sub) { | ||
| /* Set up the lex info storage. */ | ||
| PMC *name_to_register_map = pmc_new(interp, enum_class_Hash); | ||
| VTABLE_init_int(interp, name_to_register_map, (INTVAL)enum_type_INTVAL); | ||
| SET_ATTR_name_to_register_map(INTERP, SELF, name_to_register_map); | ||
|
|
||
| /* Ensure we're constant. */ | ||
| PARROT_ASSERT(PObj_constant_TEST(SELF)); | ||
|
|
||
| /* Need custom mark. */ | ||
| PObj_custom_mark_SET(SELF); | ||
| } | ||
|
|
||
| VTABLE INTVAL get_integer_keyed_str(STRING *key) { | ||
| PMC *name_to_register_map; | ||
| GET_ATTR_name_to_register_map(INTERP, SELF, name_to_register_map); | ||
| return VTABLE_get_integer_keyed_str(interp, name_to_register_map, key); | ||
| } | ||
|
|
||
| VTABLE INTVAL exists_keyed_str(STRING *key) { | ||
| PMC *name_to_register_map; | ||
| GET_ATTR_name_to_register_map(INTERP, SELF, name_to_register_map); | ||
| return VTABLE_exists_keyed_str(interp, name_to_register_map, key); | ||
| } | ||
|
|
||
| VTABLE void set_integer_keyed_str(STRING *key, INTVAL value) { | ||
| PMC *name_to_register_map; | ||
| GET_ATTR_name_to_register_map(INTERP, SELF, name_to_register_map); | ||
| VTABLE_set_integer_keyed_str(interp, name_to_register_map, key, value); | ||
| } | ||
|
|
||
| /* | ||
|
|
||
| =item C<void declare_lex_preg(STRING *name, INTVAL preg)> | ||
|
|
||
| Declare a lexical variable that is an alias for a PMC register. The PIR | ||
| compiler calls this method in response to a ".lex STRING, PREG" directive. | ||
|
|
||
| =cut | ||
|
|
||
| */ | ||
|
|
||
| METHOD declare_lex_preg(STRING *name, INTVAL preg) { | ||
| PMC *name_to_register_map; | ||
| GET_ATTR_name_to_register_map(INTERP, SELF, name_to_register_map); | ||
| VTABLE_set_integer_keyed_str(INTERP, name_to_register_map, name, preg); | ||
| } | ||
|
|
||
| /* | ||
|
|
||
| =item C<PMC *inspect_str(STRING *what)> | ||
|
|
||
| Introspects this LexInfo structure. The only valid introspection key is | ||
| C<symbols>, which gets an array of the names of the symbols in this lexpad. | ||
|
|
||
| =cut | ||
|
|
||
| */ | ||
|
|
||
| VTABLE PMC *inspect_str(STRING *what) { | ||
| if (STRING_equal(INTERP, what, CONST_STRING(INTERP, "symbols"))) { | ||
| PMC * const result = Parrot_pmc_new(INTERP, enum_class_ResizableStringArray); | ||
| PMC *name_to_register_map; | ||
| Hash *hash; | ||
|
|
||
| GET_ATTR_name_to_register_map(INTERP, SELF, name_to_register_map); | ||
| hash = (Hash *)VTABLE_get_pointer(interp, name_to_register_map); | ||
|
|
||
| parrot_hash_iterate(hash, | ||
| PARROT_ASSERT(_bucket->key); | ||
| VTABLE_push_string(INTERP, result, (STRING *)_bucket->key);); | ||
|
|
||
| return result; | ||
| } | ||
| else | ||
| Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION, | ||
| "Unknown introspection value '%S'", what); | ||
| } | ||
| } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,168 @@ | ||
| #include "pmc_nqplexinfo.h" | ||
|
|
||
| pmclass NQPLexPad provides hash no_ro auto_attrs dynpmc group nqp { | ||
| ATTR PMC *lexinfo; | ||
| ATTR PMC *ctx; | ||
|
|
||
| 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); | ||
| } | ||
|
|
||
| VTABLE void set_pointer(void *ctx) { | ||
| SET_ATTR_ctx(INTERP, SELF, (PMC *)ctx); | ||
| } | ||
|
|
||
| VTABLE INTVAL elements() { | ||
| PMC *info, *name_map; | ||
| GET_ATTR_lexinfo(INTERP, SELF, info); | ||
| GETATTR_NQPLexInfo_name_to_register_map(INTERP, info, name_map); | ||
| return Parrot_hash_size(INTERP, | ||
| (Hash *)VTABLE_get_pointer(INTERP, name_map)); | ||
| } | ||
|
|
||
| VTABLE INTVAL exists_keyed_str(STRING *name) { | ||
| PMC *info, *name_map; | ||
| const Hash *hash; | ||
| GET_ATTR_lexinfo(INTERP, SELF, info); | ||
| GETATTR_NQPLexInfo_name_to_register_map(INTERP, info, name_map); | ||
| hash = (const Hash *)VTABLE_get_pointer(INTERP, name_map); | ||
|
|
||
| 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) { | ||
| PMC *info, *name_map; | ||
| const Hash *hash; | ||
| PMC *ctx; | ||
| HashBucket *b; | ||
|
|
||
| GET_ATTR_lexinfo(INTERP, SELF, info); | ||
| GETATTR_NQPLexInfo_name_to_register_map(INTERP, info, name_map); | ||
| hash = (const Hash *)VTABLE_get_pointer(INTERP, name_map); | ||
|
|
||
| if (!hash->entries) | ||
| return PMCNULL; | ||
|
|
||
| b = Parrot_hash_get_bucket(INTERP, hash, name); | ||
|
|
||
| if (!b) | ||
| return PMCNULL; | ||
|
|
||
| GET_ATTR_ctx(INTERP, SELF, ctx); | ||
| return CTX_REG_PMC(ctx, (INTVAL)b->value); | ||
| } | ||
|
|
||
| VTABLE PMC *get_pmc_keyed(PMC *name) { | ||
| STRING * const s = VTABLE_get_string(INTERP, name); | ||
| return SELF.get_pmc_keyed_str(s); | ||
| } | ||
|
|
||
| VTABLE void set_pmc_keyed_str(STRING *name, PMC *value) { | ||
| PMC *info, *name_map; | ||
| const Hash *hash; | ||
| PMC * ctx; | ||
| HashBucket * b; | ||
|
|
||
| GET_ATTR_lexinfo(INTERP, SELF, info); | ||
| GETATTR_NQPLexInfo_name_to_register_map(INTERP, info, name_map); | ||
| hash = (const Hash *)VTABLE_get_pointer(INTERP, name_map); | ||
| 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); | ||
|
|
||
| GET_ATTR_ctx(INTERP, SELF, ctx); | ||
| CTX_REG_PMC(ctx, (INTVAL)b->value) = 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); | ||
| } | ||
|
|
||
| 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 | ||
|
|
||
| */ |