Permalink
Browse files

Merge branch 'whiteknight/imcc_tag'

  • Loading branch information...
2 parents 61b84be + a5fc564 commit f957d202193c67b760671f309d58dd30e3d7907d @Whiteknight Whiteknight committed Aug 13, 2011
View
1 compilers/imcc/imcc.l
@@ -308,6 +308,7 @@ SP [ ]
<emit,INITIAL>":init" return INIT;
<emit,INITIAL>":immediate" return IMMEDIATE;
<emit,INITIAL>":postcomp" return POSTCOMP;
+<emit,INITIAL>":tag" return SUBTAG;
<emit,INITIAL>":anon" return ANON;
<emit,INITIAL>":outer" return OUTER;
<emit,INITIAL>":lex" return NEED_LEX;
View
139 compilers/imcc/imcc.y
@@ -1054,7 +1054,7 @@ do_loadlib(ARGMOD(imc_info_t *imcc), ARGIN(const char *lib))
%token <t> PCC_BEGIN PCC_END PCC_CALL PCC_SUB PCC_BEGIN_RETURN PCC_END_RETURN
%token <t> PCC_BEGIN_YIELD PCC_END_YIELD INVOCANT
%token <t> MAIN LOAD INIT IMMEDIATE POSTCOMP METHOD ANON OUTER NEED_LEX
-%token <t> MULTI VTABLE_METHOD LOADLIB SUB_INSTANCE_OF SUBID
+%token <t> MULTI SUBTAG VTABLE_METHOD LOADLIB SUB_INSTANCE_OF SUBID
%token <t> NS_ENTRY
%token <s> LABEL
%token <t> EMIT EOM
@@ -1073,7 +1073,7 @@ do_loadlib(ARGMOD(imc_info_t *imcc), ARGIN(const char *lib))
%type <sr> pcc_returns pcc_yields pcc_return pcc_call arg arglist the_sub multi_type
%type <t> argtype_list argtype paramtype_list paramtype
%type <t> pcc_return_many
-%type <t> proto sub_proto sub_proto_list multi multi_types outer
+%type <t> proto sub_proto sub_proto_list multi subtag multi_types subtags outer
%type <t> vtable instanceof subid
%type <t> method ns_entry_name
%type <i> instruction assignment conditional_statement labeled_inst opt_label op_assign
@@ -1407,6 +1407,75 @@ multi:
MULTI '(' multi_types ')' { $$ = 0; }
;
+multi_types:
+ /* empty */
+ {
+ add_pcc_multi(imcc, imcc->cur_call, NULL);
+ }
+ | multi_types COMMA multi_type
+ {
+ $$ = 0;
+ add_pcc_multi(imcc, imcc->cur_call, $3);
+ }
+ | multi_type
+ {
+ $$ = 0;
+ add_pcc_multi(imcc, imcc->cur_call, $1);
+ }
+ ;
+
+multi_type:
+ INTV { $$ = mk_const(imcc, "INTVAL", 'S'); }
+ | FLOATV { $$ = mk_const(imcc, "FLOATVAL", 'S'); }
+ | PMCV { $$ = mk_const(imcc, "PMC", 'S'); }
+ | STRINGV { $$ = mk_const(imcc, "STRING", 'S'); }
+ | IDENTIFIER
+ {
+ SymReg *r;
+ if (strcmp($1, "_") != 0)
+ r = mk_const(imcc, $1, 'S');
+ else {
+ r = mk_const(imcc, "PMC", 'S');
+ }
+ mem_sys_free($1);
+ $$ = r;
+ }
+ | STRINGC
+ {
+ SymReg *r;
+ if (strcmp($1, "\"_\"") == 0 || strcmp($1, "'_'") == 0)
+ r = mk_const(imcc, "PMC", 'S');
+ else {
+ r = mk_const(imcc, $1, 'S');
+ }
+ mem_sys_free($1);
+ $$ = r;
+ }
+ | '[' keylist ']' { $$ = $2; }
+ ;
+
+
+subtag:
+ SUBTAG '(' subtags ')' { $$ = 0; }
+
+subtags:
+ subtags COMMA STRINGC
+ {
+ SymReg * const r = mk_const(imcc, $3, 'S');
+ add_pcc_flag_str(imcc, imcc->cur_call, r);
+ mem_sys_free($3);
+ $$ = r;
+ }
+ | STRINGC
+ {
+ SymReg * const r = mk_const(imcc, $1, 'S');
+ add_pcc_flag_str(imcc, imcc->cur_call, r);
+ mem_sys_free($1);
+ $$ = r;
+ }
+ ;
+
+
outer:
OUTER '(' STRINGC ')'
{
@@ -1491,53 +1560,6 @@ subid:
}
;
-multi_types:
- /* empty */
- {
- add_pcc_multi(imcc, imcc->cur_call, NULL);
- }
- | multi_types COMMA multi_type
- {
- $$ = 0;
- add_pcc_multi(imcc, imcc->cur_call, $3);
- }
- | multi_type
- {
- $$ = 0;
- add_pcc_multi(imcc, imcc->cur_call, $1);
- }
- ;
-
-multi_type:
- INTV { $$ = mk_const(imcc, "INTVAL", 'S'); }
- | FLOATV { $$ = mk_const(imcc, "FLOATVAL", 'S'); }
- | PMCV { $$ = mk_const(imcc, "PMC", 'S'); }
- | STRINGV { $$ = mk_const(imcc, "STRING", 'S'); }
- | IDENTIFIER
- {
- SymReg *r;
- if (strcmp($1, "_") != 0)
- r = mk_const(imcc, $1, 'S');
- else {
- r = mk_const(imcc, "PMC", 'S');
- }
- mem_sys_free($1);
- $$ = r;
- }
- | STRINGC
- {
- SymReg *r;
- if (strcmp($1, "\"_\"") == 0 || strcmp($1, "'_'") == 0)
- r = mk_const(imcc, "PMC", 'S');
- else {
- r = mk_const(imcc, $1, 'S');
- }
- mem_sys_free($1);
- $$ = r;
- }
- | '[' keylist ']' { $$ = $2; }
- ;
-
sub_body:
/* empty */
| statements
@@ -1590,14 +1612,29 @@ sub_proto_list:
;
proto:
- LOAD { $$ = P_LOAD; }
- | INIT { $$ = P_INIT; }
+ LOAD {
+ $$ = P_LOAD;
+ /*
+ SymReg * const r = mk_const(imcc, "load", 'S');
+ add_pcc_flag_str(imcc, imcc->cur_call, r);
+ $$ = r;
+ */
+ }
+ | INIT {
+ $$ = P_INIT;
+ /*
+ SymReg * const r = mk_const(imcc, "load", 'S');
+ add_pcc_flag_str(imcc, imcc->cur_call, r);
+ $$ = r;
+ */
+ }
| MAIN { $$ = P_MAIN; }
| IMMEDIATE { $$ = P_IMMEDIATE; }
| POSTCOMP { $$ = P_POSTCOMP; }
| ANON { $$ = P_ANON; }
| NEED_LEX { $$ = P_NEED_LEX; }
| multi
+ | subtag
| outer
| vtable
| method
View
3,309 compilers/imcc/imclexer.c
1,658 additions, 1,651 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
2,293 compilers/imcc/imcparser.c
1,173 additions, 1,120 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
108 compilers/imcc/imcparser.h
@@ -138,32 +138,33 @@
OUTER = 343,
NEED_LEX = 344,
MULTI = 345,
- VTABLE_METHOD = 346,
- LOADLIB = 347,
- SUB_INSTANCE_OF = 348,
- SUBID = 349,
- NS_ENTRY = 350,
- LABEL = 351,
- EMIT = 352,
- EOM = 353,
- IREG = 354,
- NREG = 355,
- SREG = 356,
- PREG = 357,
- IDENTIFIER = 358,
- REG = 359,
- MACRO = 360,
- ENDM = 361,
- STRINGC = 362,
- INTC = 363,
- FLOATC = 364,
- USTRINGC = 365,
- PARROT_OP = 366,
- VAR = 367,
- LINECOMMENT = 368,
- FILECOMMENT = 369,
- DOT = 370,
- CONCAT = 371
+ SUBTAG = 346,
+ VTABLE_METHOD = 347,
+ LOADLIB = 348,
+ SUB_INSTANCE_OF = 349,
+ SUBID = 350,
+ NS_ENTRY = 351,
+ LABEL = 352,
+ EMIT = 353,
+ EOM = 354,
+ IREG = 355,
+ NREG = 356,
+ SREG = 357,
+ PREG = 358,
+ IDENTIFIER = 359,
+ REG = 360,
+ MACRO = 361,
+ ENDM = 362,
+ STRINGC = 363,
+ INTC = 364,
+ FLOATC = 365,
+ USTRINGC = 366,
+ PARROT_OP = 367,
+ VAR = 368,
+ LINECOMMENT = 369,
+ FILECOMMENT = 370,
+ DOT = 371,
+ CONCAT = 372
};
#endif
/* Tokens. */
@@ -255,32 +256,33 @@
#define OUTER 343
#define NEED_LEX 344
#define MULTI 345
-#define VTABLE_METHOD 346
-#define LOADLIB 347
-#define SUB_INSTANCE_OF 348
-#define SUBID 349
-#define NS_ENTRY 350
-#define LABEL 351
-#define EMIT 352
-#define EOM 353
-#define IREG 354
-#define NREG 355
-#define SREG 356
-#define PREG 357
-#define IDENTIFIER 358
-#define REG 359
-#define MACRO 360
-#define ENDM 361
-#define STRINGC 362
-#define INTC 363
-#define FLOATC 364
-#define USTRINGC 365
-#define PARROT_OP 366
-#define VAR 367
-#define LINECOMMENT 368
-#define FILECOMMENT 369
-#define DOT 370
-#define CONCAT 371
+#define SUBTAG 346
+#define VTABLE_METHOD 347
+#define LOADLIB 348
+#define SUB_INSTANCE_OF 349
+#define SUBID 350
+#define NS_ENTRY 351
+#define LABEL 352
+#define EMIT 353
+#define EOM 354
+#define IREG 355
+#define NREG 356
+#define SREG 357
+#define PREG 358
+#define IDENTIFIER 359
+#define REG 360
+#define MACRO 361
+#define ENDM 362
+#define STRINGC 363
+#define INTC 364
+#define FLOATC 365
+#define USTRINGC 366
+#define PARROT_OP 367
+#define VAR 368
+#define LINECOMMENT 369
+#define FILECOMMENT 370
+#define DOT 371
+#define CONCAT 372
@@ -301,7 +303,7 @@ typedef union YYSTYPE
/* Line 1676 of yacc.c */
-#line 294 "compilers/imcc/imcparser.h"
+#line 296 "compilers/imcc/imcparser.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
View
8 compilers/imcc/main.c
@@ -553,7 +553,8 @@ imcc_run_compilation_internal(ARGMOD(imc_info_t *imcc), ARGIN(STRING *source),
ASSERT_ARGS(imcc_run_compilation_internal)
yyscan_t yyscanner = imcc_get_scanner(imcc);
PackFile * const pf_raw = PackFile_new(imcc->interp, 0);
- PMC * const packfilepmc = Parrot_pf_get_packfile_pmc(imcc->interp, pf_raw);
+ PMC * const old_packfilepmc = Parrot_pf_get_current_packfile(imcc->interp);
+ PMC * const packfilepmc = Parrot_pf_get_packfile_pmc(imcc->interp, pf_raw);
INTVAL success = 0;
/* TODO: Don't set current packfile in the interpreter. Leave the
@@ -578,7 +579,8 @@ imcc_run_compilation_internal(ARGMOD(imc_info_t *imcc), ARGIN(STRING *source),
/* XXX Parrot_pf_get_packfile_pmc registers PMC */
Parrot_pmc_gc_unregister(imcc->interp, packfilepmc);
-
+ if (!PMC_IS_NULL(old_packfilepmc))
+ Parrot_pf_set_current_packfile(imcc->interp, old_packfilepmc);
return PMCNULL;
}
@@ -592,6 +594,8 @@ imcc_run_compilation_internal(ARGMOD(imc_info_t *imcc), ARGIN(STRING *source),
PackFile_fixup_subs(imcc->interp, PBC_IMMEDIATE, packfilepmc);
PackFile_fixup_subs(imcc->interp, PBC_POSTCOMP, packfilepmc);
+ if (!PMC_IS_NULL(old_packfilepmc))
+ Parrot_pf_set_current_packfile(imcc->interp, old_packfilepmc);
return packfilepmc;
}
View
48 compilers/imcc/pbc.c
@@ -260,6 +260,17 @@ static void store_sub_size(
__attribute__nonnull__(1)
FUNC_MODIFIES(* imcc);
+static void store_sub_tags(
+ ARGMOD(imc_info_t * imcc),
+ ARGIN(pcc_sub_t * sub),
+ const int sub_idx,
+ ARGMOD(PackFile_ConstTable * ct))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ __attribute__nonnull__(4)
+ FUNC_MODIFIES(* imcc)
+ FUNC_MODIFIES(* ct);
+
static void verify_signature(
ARGMOD(imc_info_t * imcc),
ARGIN(const Instruction *ins),
@@ -350,6 +361,10 @@ static void verify_signature(
, PARROT_ASSERT_ARG(str))
#define ASSERT_ARGS_store_sub_size __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc))
+#define ASSERT_ARGS_store_sub_tags __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(imcc) \
+ , PARROT_ASSERT_ARG(sub) \
+ , PARROT_ASSERT_ARG(ct))
#define ASSERT_ARGS_verify_signature __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(ins) \
@@ -1423,8 +1438,8 @@ add_const_pmc_sub(ARGMOD(imc_info_t * imcc), ARGMOD(SymReg *r), size_t offs,
PMC *ns_pmc;
PMC *sub_pmc;
Parrot_Sub_attributes *sub;
- PackFile_ByteCode * const interp_code = Parrot_pf_get_current_code_segment(imcc->interp);
- PackFile_ConstTable * const ct = interp_code->const_table;
+ PackFile_ByteCode * const interp_code = Parrot_pf_get_current_code_segment(imcc->interp);
+ PackFile_ConstTable * const ct = interp_code->const_table;
IMC_Unit * const unit = imcc->globals->cs->subs->unit;
int i;
@@ -1646,13 +1661,42 @@ add_const_pmc_sub(ARGMOD(imc_info_t * imcc), ARGMOD(SymReg *r), size_t offs,
}
}
+ store_sub_tags(imcc, r->pcc_sub, k, ct);
+
return k;
}
}
/*
+=item C<static void store_sub_tags(imc_info_t * imcc, pcc_sub_t * sub, const int
+sub_idx, PackFile_ConstTable * ct)>
+
+Store the tags associated with a sub in the provided constant table.
+
+=cut
+
+*/
+
+static void
+store_sub_tags(ARGMOD(imc_info_t * imcc), ARGIN(pcc_sub_t * sub), const int sub_idx,
+ ARGMOD(PackFile_ConstTable * ct))
+{
+ ASSERT_ARGS(store_sub_tags)
+ opcode_t i;
+ for (i = 0; i < sub->nflags; i++) {
+ SymReg * const flag = sub->flags[i];
+
+ STRING * const tag = Parrot_str_new(imcc->interp, flag->name + 1,
+ strlen(flag->name) - 2);
+ const int tag_idx = add_const_str(imcc, tag, ct->code);
+ Parrot_pf_tag_constant(imcc->interp, ct, tag_idx, sub_idx);
+ }
+}
+
+/*
+
=item C<static opcode_t build_key(imc_info_t * imcc, SymReg *key_reg,
PackFile_ByteCode * bc)>
View
21 compilers/imcc/symreg.c
@@ -486,6 +486,27 @@ add_pcc_multi(ARGMOD(imc_info_t * imcc), ARGMOD(SymReg *r), ARGIN_NULLOK(SymReg
/*
+=item C<void add_pcc_flag_str(imc_info_t * imcc, SymReg * r, SymReg * arg)>
+
+Associate a tag with a sub.
+
+=cut
+
+*/
+
+void
+add_pcc_flag_str(ARGMOD(imc_info_t * imcc), ARGMOD(SymReg * r), ARGIN(SymReg * arg))
+{
+ ASSERT_ARGS(add_pcc_flag_str)
+ pcc_sub_t * const sub = r->pcc_sub;
+ const int n = sub->nflags;
+ sub->flags = mem_gc_realloc_n_typed(imcc->interp, sub->flags, n + 1, SymReg*);
+ sub->flags[n] = arg;
+ sub->nflags++;
+}
+
+/*
+
=item C<void add_pcc_sub(SymReg *r, SymReg *arg)>
Sets the current sub in the given SymReg to the second SymReg.
View
16 compilers/imcc/symreg.h
@@ -104,11 +104,13 @@ typedef struct pcc_sub_t {
SymReg **multi;
SymReg **ret;
SymReg *object;
+ SymReg **flags; /* "load", "init", etc */
int *arg_flags; /* :slurpy, :optional, ... */
int *ret_flags; /* :slurpy, :optional, ... */
int nargs;
int nret;
int nmulti;
+ int nflags;
int yield;
int tailcall;
int label;
@@ -204,6 +206,16 @@ void add_pcc_cc(ARGMOD(SymReg *r), ARGIN(SymReg *arg))
__attribute__nonnull__(2)
FUNC_MODIFIES(*r);
+void add_pcc_flag_str(
+ ARGMOD(imc_info_t * imcc),
+ ARGMOD(SymReg * r),
+ ARGIN(SymReg * arg))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ __attribute__nonnull__(3)
+ FUNC_MODIFIES(* imcc)
+ FUNC_MODIFIES(* r);
+
void add_pcc_multi(
ARGMOD(imc_info_t * imcc),
ARGMOD(SymReg *r),
@@ -425,6 +437,10 @@ char * symreg_to_str(ARGIN(const SymReg *s))
#define ASSERT_ARGS_add_pcc_cc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(r) \
, PARROT_ASSERT_ARG(arg))
+#define ASSERT_ARGS_add_pcc_flag_str __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(imcc) \
+ , PARROT_ASSERT_ARG(r) \
+ , PARROT_ASSERT_ARG(arg))
#define ASSERT_ARGS_add_pcc_multi __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(r))
View
17 include/parrot/packfile.h
@@ -168,6 +168,11 @@ typedef struct PackFile_Segment {
typedef INTVAL (*PackFile_map_segments_func_t)(PARROT_INTERP, ARGMOD(PackFile_Segment *seg), ARGIN_NULLOK(void *user_data));
+typedef struct PackFile_ConstTagPair {
+ opcode_t tag_idx;
+ opcode_t const_idx;
+} PackFile_ConstTagPair;
+
typedef struct PackFile_ConstTable {
PackFile_Segment base;
struct {
@@ -182,9 +187,11 @@ typedef struct PackFile_ConstTable {
opcode_t const_count;
PMC **constants;
} pmc;
- PackFile_ByteCode *code; /* where this segment belongs to */
- Hash *string_hash; /* Hash for lookup of string indices */
- Hash *pmc_hash; /* Hash for lookup of pmc indices */
+ PackFile_ByteCode *code; /* where this segment belongs to */
+ Hash *string_hash; /* Hash for lookup of string indices */
+ Hash *pmc_hash; /* Hash for lookup of pmc indices */
+ PackFile_ConstTagPair *tag_map; /* n-m Mapping pmc constants to string tags */
+ opcode_t ntags; /* Number of tags */
} PackFile_ConstTable;
typedef struct PackFile_ByteCode_OpMappingEntry {
@@ -711,7 +718,7 @@ void Parrot_pf_set_current_packfile(PARROT_INTERP, ARGIN(PMC *pbc))
PARROT_EXPORT
PARROT_CANNOT_RETURN_NULL
-PMC * Parrot_pf_subs_by_flag(PARROT_INTERP,
+PMC * Parrot_pf_subs_by_tag(PARROT_INTERP,
ARGIN(PMC * pfpmc),
ARGIN(STRING * flag))
__attribute__nonnull__(1)
@@ -864,7 +871,7 @@ void Parrot_pf_mark_packfile(PARROT_INTERP, ARGMOD_NULLOK(PackFile * pf))
__attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(pbc))
-#define ASSERT_ARGS_Parrot_pf_subs_by_flag __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+#define ASSERT_ARGS_Parrot_pf_subs_by_tag __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(pfpmc) \
, PARROT_ASSERT_ARG(flag))
View
119 src/packfile/api.c
@@ -358,26 +358,69 @@ Parrot_pf_deserialize(PARROT_INTERP, ARGIN(STRING *str))
return pf;
}
+
+void
+Parrot_pf_tag_constant(PARROT_INTERP, ARGIN(PackFile_ConstTable *ct), const int tag_idx,
+ const int const_idx) {
+ int lo, hi, cur;
+ const STRING *tag = ct->str.constants[tag_idx];
+
+ /* allocate space */
+ if (ct->tag_map == NULL) {
+ ct->tag_map = mem_gc_allocate_n_zeroed_typed(interp, 1, PackFile_ConstTagPair);
+ ct->ntags = 1;
+ }
+ else {
+ ct->tag_map = mem_gc_realloc_n_typed_zeroed(interp, ct->tag_map, ct->ntags + 1, ct->ntags,
+ PackFile_ConstTagPair);
+ ct->ntags++;
+ }
+
+ /* find the slot to insert into */
+ lo = 0;
+ cur = 0;
+ hi = ct->ntags - 1;
+ while (lo < hi) {
+ cur = (lo + hi)/2;
+
+ switch (STRING_compare(interp, tag, ct->str.constants[ct->tag_map[cur].tag_idx])) {
+ case -1:
+ lo = ++cur;
+ break;
+ case 0:
+ lo = hi = cur;
+ break;
+ case 1:
+ hi = cur;
+ break;
+ }
+ }
+
+ mem_sys_memmove(&ct->tag_map[cur + 1], &ct->tag_map[cur],
+ ((ct->ntags - 1) - cur) * sizeof (PackFile_ConstTagPair));
+ ct->tag_map[cur].tag_idx = tag_idx;
+ ct->tag_map[cur].const_idx = const_idx;
+}
+
/*
-=item C<PMC * Parrot_pf_subs_by_flag(PARROT_INTERP, PMC * pfpmc, STRING * flag)>
+=item C<PMC * Parrot_pf_subs_by_tag(PARROT_INTERP, PMC * pfpmc, STRING * flag)>
Get an array of Subs in the packfile by named flag.
-Currently accepted values are "load" and "init".
-
=cut
*/
PARROT_EXPORT
PARROT_CANNOT_RETURN_NULL
PMC *
-Parrot_pf_subs_by_flag(PARROT_INTERP, ARGIN(PMC * pfpmc), ARGIN(STRING * flag))
+Parrot_pf_subs_by_tag(PARROT_INTERP, ARGIN(PMC * pfpmc), ARGIN(STRING * flag))
{
- ASSERT_ARGS(Parrot_pf_subs_by_flag)
+ ASSERT_ARGS(Parrot_pf_subs_by_tag)
PackFile * const pf = (PackFile*)VTABLE_get_pointer(interp, pfpmc);
int mode = 0;
+ PMC * const subs = Parrot_pmc_new(interp, enum_class_ResizablePMCArray);
if (!pf || !pf->cur_cs || !pf->cur_cs->const_table)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_UNEXPECTED_NULL,
"NULL or invalid packfile");
@@ -386,12 +429,66 @@ Parrot_pf_subs_by_flag(PARROT_INTERP, ARGIN(PMC * pfpmc), ARGIN(STRING * flag))
mode = 1;
else if (STRING_equal(interp, flag, CONST_STRING(interp, "init")))
mode = 2;
- else
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
- "%S is not a valid packfile trigger", flag);
-
{
- PMC * const subs = Parrot_pmc_new(interp, enum_class_ResizablePMCArray);
+ PackFile_ConstTable * const ct = pf->cur_cs->const_table;
+ opcode_t flag_idx = -1;
+
+ int bottom_lo, bottom_hi, top_lo, top_hi, cur;
+ int i;
+
+ bottom_lo = top_lo = cur = 0;
+ bottom_hi = top_hi = ct->ntags;
+
+ /* find the first match (if any) */
+ while (flag_idx < 0) {
+ if (bottom_lo == top_hi) {
+ /* tag not present */
+ goto done_find_bounds;
+ }
+
+ cur = (bottom_lo + top_hi)/2;
+
+ switch (STRING_compare(interp, flag, ct->str.constants[ct->tag_map[cur].tag_idx])) {
+ case -1:
+ bottom_lo = cur + 1;
+ break;
+ case 0:
+ flag_idx = ct->tag_map[cur].tag_idx;
+ bottom_hi = cur;
+ top_lo = cur + 1;
+ break;
+ case 1:
+ top_hi = cur;
+ break;
+ }
+ }
+
+ /* find the bottom of the map's range with this tag */
+ while (bottom_lo < bottom_hi) {
+ cur = (bottom_lo + bottom_hi)/2;
+ if (ct->tag_map[cur].tag_idx == flag_idx)
+ bottom_hi = cur;
+ else
+ bottom_lo = cur + 1;
+ }
+
+ /* find the top */
+ while (top_lo < top_hi) {
+ cur = (top_lo + top_hi)/2;
+ if (ct->tag_map[cur].tag_idx == flag_idx)
+ top_lo = cur + 1;
+ else
+ top_hi = cur;
+ }
+
+ done_find_bounds:
+ for (i = bottom_lo; i < top_hi; i++)
+ VTABLE_push_pmc(interp, subs, ct->pmc.constants[ct->tag_map[i].const_idx]);
+ }
+
+ /* Backwards compatibility. :load is equivalent to "load" tag. :init is
+ equivalent to "init" tag */
+ if (mode == 1 || mode == 2) {
PackFile_ByteCode * const self = pf->cur_cs;
PackFile_ConstTable * const ct = self->const_table;
STRING * const SUB = CONST_STRING(interp, "Sub");
@@ -412,8 +509,8 @@ Parrot_pf_subs_by_flag(PARROT_INTERP, ARGIN(PMC * pfpmc), ARGIN(STRING * flag))
else if (mode == 2 && Sub_comp_INIT_TEST(sub))
VTABLE_push_pmc(interp, subs, sub_pmc);
}
- return subs;
}
+ return subs;
}
/*
View
7 src/packfile/output.c
@@ -225,6 +225,7 @@ PackFile_ConstTable_pack_size(PARROT_INTERP, ARGMOD(PackFile_Segment *seg))
}
Parrot_hash_destroy(interp, self->pmc_hash);
self->pmc_hash = NULL;
+ size += 1 + (self->ntags * 2);
return size;
}
@@ -277,6 +278,12 @@ PackFile_ConstTable_pack(PARROT_INTERP,
Parrot_hash_destroy(interp, self->pmc_hash);
self->pmc_hash = NULL;
+ *cursor++ = self->ntags;
+ for (i = 0; i < self->ntags; i++) {
+ *cursor++ = self->tag_map[i].tag_idx;
+ *cursor++ = self->tag_map[i].const_idx;
+ }
+
return cursor;
}
View
12 src/packfile/segments.c
@@ -339,6 +339,11 @@ PackFile_ConstTable_clear(PARROT_INTERP, ARGMOD(PackFile_ConstTable *self))
self->string_hash = NULL;
}
+ if (self->tag_map) {
+ mem_gc_free(interp, self->tag_map);
+ self->ntags = 0;
+ }
+
return;
}
@@ -420,6 +425,13 @@ PackFile_ConstTable_unpack(PARROT_INTERP, ARGMOD(PackFile_Segment *seg),
Parrot_ns_store_sub(interp, pmc);
}
+ self->ntags = PF_fetch_opcode(pf, &cursor);
+ self->tag_map = mem_gc_allocate_n_zeroed_typed(interp, self->ntags, PackFile_ConstTagPair);
+ for (i = 0; i < self->ntags; i++) {
+ self->tag_map[i].tag_idx = PF_fetch_opcode(pf, &cursor);
+ self->tag_map[i].const_idx = PF_fetch_opcode(pf, &cursor);
+ }
+
return cursor;
err:
View
92 src/pmc/imccompiler.pmc
@@ -30,21 +30,37 @@ static PMC * get_packfile_eval_pmc(PARROT_INTERP,
__attribute__nonnull__(1)
__attribute__nonnull__(2);
-PARROT_CANNOT_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-static PMC * get_packfile_pmc(PARROT_INTERP, ARGIN(PMC *pf_ptr_pmc))
- __attribute__nonnull__(1)
- __attribute__nonnull__(2);
-
#define ASSERT_ARGS_get_packfile_eval_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(pf_pmc))
-#define ASSERT_ARGS_get_packfile_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp) \
- , PARROT_ASSERT_ARG(pf_ptr_pmc))
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
/* HEADERIZER END: static */
+#define BEGIN_IMCC_COMPILE(i) \
+ do { \
+ UINTVAL __regs_used[4] = {3, 3, 3, 3}; \
+ PMC * const __newcontext = Parrot_push_context((i), __regs_used); \
+ PackFile_ByteCode * const __old_bc = (i)->code; \
+ PMC * const __old_cur_pf = (i)->current_pf; \
+ Parrot_block_GC_mark((i)); \
+ Parrot_pcc_set_HLL((i), __newcontext, 0); \
+ Parrot_pcc_set_sub((i), __newcontext, 0); \
+
+#define END_IMCC_COMPILE(i) \
+ Parrot_pop_context((i)); \
+ Parrot_unblock_GC_mark((i)); \
+ (i)->code = __old_bc; \
+ if (!PMC_IS_NULL(__old_cur_pf)) \
+ Parrot_pf_set_current_packfile((i), __old_cur_pf); \
+ } while (0)
+
+#define ERROR_IMCC_COMPILE(i) \
+ Parrot_pop_context((i)); \
+ Parrot_unblock_GC_mark((i)); \
+ (i)->code = __old_bc; \
+ if (!PMC_IS_NULL(__old_cur_pf)) \
+ Parrot_pf_set_current_packfile((i), __old_cur_pf); \
+
/*
=over 4
@@ -78,31 +94,6 @@ get_packfile_eval_pmc(PARROT_INTERP, ARGIN(PMC *pf_pmc), INTVAL current_eval)
return eval_pmc;
}
-/*
-
-=item C<static PMC * get_packfile_pmc(PARROT_INTERP, PMC *pf_ptr_pmc)>
-
-Get a PMC pointer to a passed packfile pointer
-
-=back
-
-=cut
-
-*/
-
-PARROT_CANNOT_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-static PMC *
-get_packfile_pmc(PARROT_INTERP, ARGIN(PMC *pf_ptr_pmc))
-{
- ASSERT_ARGS(get_packfile_pmc)
-
- PackFile * const pf = (PackFile*)VTABLE_get_pointer(interp, pf_ptr_pmc);
- PMC * const pf_pmc = Parrot_pmc_new(interp, enum_class_PackfileView);
- VTABLE_set_pointer(interp, pf_pmc, pf);
- return pf_pmc;
-}
-
/* HEADERIZER HFILE: none */
pmclass IMCCompiler auto_attrs provides HLLCompiler provide invokable {
@@ -131,6 +122,7 @@ pmclass IMCCompiler auto_attrs provides HLLCompiler provide invokable {
}
/* provided to emulate the current NCI compreg */
+ /* DEPRECATED. See TT #1967 */
VTABLE opcode_t* invoke(void* next) {
Parrot_IMCCompiler_attributes * const attrs = PARROT_IMCCOMPILER(SELF);
imc_info_t * const imcc = (imc_info_t*) attrs->imcc_info;
@@ -204,34 +196,26 @@ pmclass IMCCompiler auto_attrs provides HLLCompiler provide invokable {
{
Parrot_IMCCompiler_attributes * const attrs = PARROT_IMCCOMPILER(SELF);
PMC * pf;
- PMC * eval_pmc = PMCNULL;
imc_info_t * const imcc = (imc_info_t*)attrs->imcc_info;
- UINTVAL regs_used[4] = {3, 3, 3, 3};
- PMC * const newcontext = Parrot_push_context(interp, regs_used);
- PackFile_ByteCode * const old_bc = interp->code;
if (has_target)
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
"IMCCompiler: compiler does not support the target option");
- Parrot_block_GC_mark(interp);
- Parrot_pcc_set_HLL(interp, newcontext, 0);
- Parrot_pcc_set_sub(interp, newcontext, 0);
+ BEGIN_IMCC_COMPILE(interp);
/* TODO: Handle outer_ctx */
pf = imcc_compile_string(imcc, source, attrs->is_pasm);
if (PMC_IS_NULL(pf)) {
STRING * const msg = imcc_last_error_message(imcc);
INTVAL code = imcc_last_error_code(imcc);
+ ERROR_IMCC_COMPILE(interp);
Parrot_ex_throw_from_c_args(INTERP, NULL, code, "%Ss", msg);
}
- eval_pmc = get_packfile_pmc(INTERP, pf);
- Parrot_pop_context(interp);
- Parrot_unblock_GC_mark(interp);
- interp->code = old_bc;
+ END_IMCC_COMPILE(interp);
- RETURN(PMC *eval_pmc);
+ RETURN(PMC *pf);
}
METHOD compile_file(STRING *filename,
@@ -241,33 +225,23 @@ pmclass IMCCompiler auto_attrs provides HLLCompiler provide invokable {
Parrot_IMCCompiler_attributes * const attrs = PARROT_IMCCOMPILER(SELF);
PMC * pf = PMCNULL;
imc_info_t * const imcc = (imc_info_t*)attrs->imcc_info;
- UINTVAL regs_used[4] = {3, 3, 3, 3};
- PMC * const newcontext = Parrot_push_context(interp, regs_used);
- PMC * const old_pf = Parrot_pf_get_current_packfile(interp);
- PMC * pf_pmc;
if (has_target)
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
"IMCCompiler: compiler does not support the target option");
- Parrot_block_GC_mark(interp);
- Parrot_pcc_set_HLL(interp, newcontext, 0);
- Parrot_pcc_set_sub(interp, newcontext, 0);
+ BEGIN_IMCC_COMPILE(interp);
/* TODO: Handle outer_ctx */
pf = imcc_compile_file(imcc, filename, attrs->is_pasm);
if (PMC_IS_NULL(pf)) {
STRING * const msg = imcc_last_error_message(imcc);
const INTVAL code = imcc_last_error_code(imcc);
+ ERROR_IMCC_COMPILE(interp);
Parrot_ex_throw_from_c_args(INTERP, NULL, code, "%Ss", msg);
}
- /* This causes errors during the build */
- /*pf_pmc = get_packfile_pmc(INTERP, pf);*/
- Parrot_pop_context(interp);
- Parrot_unblock_GC_mark(interp);
- if (!PMC_IS_NULL(old_pf))
- Parrot_pf_set_current_packfile(interp, old_pf);
+ END_IMCC_COMPILE(interp);
RETURN(PMC *pf);
}
View
32 src/pmc/packfileconstanttable.pmc
@@ -32,6 +32,7 @@ pmclass PackfileConstantTable auto_attrs extends PackfileSegment {
ATTR PMC *num_constants;
ATTR PMC *str_constants;
ATTR PMC *pmc_constants;
+ ATTR PMC *tag_map;
/*
@@ -50,6 +51,7 @@ Create empty PackfileConstantTable.
attrs->num_constants = Parrot_pmc_new(INTERP, enum_class_ResizableFloatArray);
attrs->str_constants = Parrot_pmc_new(INTERP, enum_class_ResizableStringArray);
attrs->pmc_constants = Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
+ attrs->tag_map = Parrot_pmc_new(INTERP, enum_class_ResizableIntegerArray);
PObj_custom_mark_SET(SELF);
PMC_data(SELF) = attrs;
@@ -72,6 +74,7 @@ Marks the object as live.
Parrot_gc_mark_PMC_alive(INTERP, attrs->num_constants);
Parrot_gc_mark_PMC_alive(INTERP, attrs->str_constants);
Parrot_gc_mark_PMC_alive(INTERP, attrs->pmc_constants);
+ Parrot_gc_mark_PMC_alive(INTERP, attrs->tag_map);
SUPER();
}
@@ -98,6 +101,7 @@ Set pointer to underlying PackFile_ConstTable
VTABLE_set_integer_native(INTERP, attrs->num_constants, table->num.const_count);
VTABLE_set_integer_native(INTERP, attrs->str_constants, table->str.const_count);
VTABLE_set_integer_native(INTERP, attrs->pmc_constants, table->pmc.const_count);
+ VTABLE_set_integer_native(INTERP, attrs->tag_map, table->ntags * 2);
for (i = 0; i < table->num.const_count; i++)
SELF.set_number_keyed_int(i, table->num.constants[i]);
@@ -107,6 +111,12 @@ Set pointer to underlying PackFile_ConstTable
for (i = 0; i < table->pmc.const_count; i++)
SELF.set_pmc_keyed_int(i, table->pmc.constants[i]);
+
+ for (i = 0; i < table->ntags; i++) {
+ const INTVAL ptr = i * 2;
+ VTABLE_set_integer_keyed_int(INTERP, attrs->tag_map, ptr, table->tag_map[i].tag_idx);
+ VTABLE_set_integer_keyed_int(INTERP, attrs->tag_map, ptr, table->tag_map[i].const_idx);
+ }
}
/*
@@ -121,6 +131,7 @@ Set pointer to underlying PackFile_ConstTable
PackFile_ConstTable * const pftable =
mem_gc_allocate_zeroed_typed(INTERP, PackFile_ConstTable);
opcode_t i;
+ const int tag_elts = VTABLE_elements(INTERP, attrs->tag_map);
pftable->base.type = PF_CONST_SEG;
@@ -148,6 +159,12 @@ Set pointer to underlying PackFile_ConstTable
pftable->pmc.constants[i] =
VTABLE_get_pmc_keyed_int(INTERP, attrs->pmc_constants, i);
+ for (i = 0; i < tag_elts; i += 2) {
+ Parrot_pf_tag_constant(interp, pftable,
+ VTABLE_get_integer_keyed_int(INTERP, attrs->tag_map, i),
+ VTABLE_get_integer_keyed_int(INTERP, attrs->tag_map, i + 1));
+ }
+
return pftable;
}
@@ -399,6 +416,21 @@ Set segment type.
RETURN(INTVAL PF_CONST_SEG);
}
+/*
+
+=item C<METHOD add_tag_mapping(INTVAL pmc_idx, INTVAL str_idx)>
+
+Add a string->pmc tag mapping
+
+*/
+
+ METHOD add_tag_mapping(INTVAL pmc_idx, INTVAL str_idx) {
+ Parrot_PackfileConstantTable_attributes * const attrs =
+ PARROT_PACKFILECONSTANTTABLE(SELF);
+ INTVAL idx = VTABLE_elements(INTERP, attrs->tag_map);
+ VTABLE_set_integer_keyed_int(INTERP, attrs->tag_map, idx, pmc_idx);
+ VTABLE_set_integer_keyed_int(INTERP, attrs->tag_map, idx, str_idx);
+ }
}
/*
View
27 src/pmc/packfileview.pmc
@@ -34,7 +34,7 @@ static void add_called_tag(PARROT_INTERP,
static INTVAL find_called_tag(PARROT_INTERP,
ARGIN(PMC * self),
- ARGIN(STRING *tag))
+ ARGIN(STRING * tag))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
__attribute__nonnull__(3);
@@ -88,16 +88,21 @@ get_const_table(PARROT_INTERP, ARGIN(PMC * self))
/*
-=item C<static INTVAL find_called_tag(PARROT_INTERP, PMC * self, STRING *tag)>
+=item C<static INTVAL find_called_tag(PARROT_INTERP, PMC * self, STRING * tag)>
+
+Find a called tag in the cache. Return 1 if it exists, 0 otherwise.
-TK
+=item C<static void add_called_tag(PARROT_INTERP, PMC * self, STRING * tag)>
+
+Add a called tag to the cache, if it doesn't exist already. Do nothing
+otherwise.
=cut
*/
static INTVAL
-find_called_tag(PARROT_INTERP, ARGIN(PMC * self), ARGIN(STRING *tag))
+find_called_tag(PARROT_INTERP, ARGIN(PMC * self), ARGIN(STRING * tag))
{
ASSERT_ARGS(find_called_tag)
Parrot_PackfileView_attributes * const attrs = PARROT_PACKFILEVIEW(self);
@@ -114,16 +119,6 @@ find_called_tag(PARROT_INTERP, ARGIN(PMC * self), ARGIN(STRING *tag))
return 0;
}
-/*
-
-=item C<static void add_called_tag(PARROT_INTERP, PMC * self, STRING * tag)>
-
-TK
-
-=cut
-
-*/
-
static void
add_called_tag(PARROT_INTERP, ARGMOD(PMC * self), ARGIN(STRING * tag))
{
@@ -370,8 +365,8 @@ Return a ResizablePMCArray with all Sub constants from the constant table.
}
}
- METHOD subs_by_flag(STRING *flag) {
- PMC * const subs = Parrot_pf_subs_by_flag(INTERP, SELF, flag);
+ METHOD subs_by_tag(STRING *flag) {
+ PMC * const subs = Parrot_pf_subs_by_tag(INTERP, SELF, flag);
RETURN(PMC *subs);
}
View
92 t/pmc/packfileview.t
@@ -4,16 +4,18 @@
.sub 'main' :main
.include 'test_more.pir'
- plan(15)
+ plan(20)
test_create()
+ test_interp_same_after_compile()
test_vtable_get_bool()
test_vtable_get_pmc_keyed_int()
test_vtable_get_string_keyed_int()
test_vtable_get_number_keyed_int()
test_method_constant_counts()
test_method_main_sub()
- test_method_subs_by_flag()
+ test_method_subs_by_tag()
+ test_method_subs_by_tag_tag_syntax()
test_method_serialized_size()
test_method_serialize()
test_method_all_subs()
@@ -26,6 +28,15 @@
$P0 = new ['PackfileView']
.end
+.sub 'test_interp_same_after_compile'
+ $P0 = getinterp
+ $P2 = compreg "PIR"
+ $S0 = ".sub __init :anon :init\nok(1, 'init function executed on demand')\n.end"
+ $P5 = $P2.'compile'($S0)
+ $P1 = getinterp
+ is_same($P0, $P1, "interp['packfile'] does not change over IMCC invocation")
+.end
+
.sub 'test_vtable_get_bool'
$P0 = new ['PackfileView']
if $P0 goto fail_first
@@ -76,30 +87,69 @@
.end
# We are executing this file as a program, so :load functions shouldn't be
-# triggered automatically. In the 'test_method_subs_by_flag' test, we do it
+# triggered automatically. In the 'test_method_subs_by_tag' test, we do it
# manually.
.sub '__onload' :load
ok(1, "can manually trigger :load")
.end
-.sub 'test_method_subs_by_flag'
+.sub 'test_method_subs_by_tag'
$P0 = getinterp
$P1 = $P0["packfile"]
- $P3 = $P1.'subs_by_flag'("load")
+ $P3 = $P1.'subs_by_tag'("load")
$I0 = elements $P3
is($I0, 1)
$P4 = $P3[0]
$P4()
$P2 = compreg "PIR"
- $S0 = ".sub __init :init\nok(1, 'init function executed on demand')\n.end"
- $P1 = $P2.'compile'($S0)
- $P3 = $P1.'subs_by_flag'("init")
+ $S0 = ".sub __init :anon :init\nok(1, 'init function executed on demand')\n.end"
+ $P5 = $P2.'compile'($S0)
+ $P3 = $P5.'subs_by_tag'("init")
$I0 = elements $P3
is($I0, 1)
$P4 = $P3[0]
$P4()
.end
+.sub 'test_method_subs_by_tag_tag_syntax'
+ $P0 = getinterp
+ $P1 = $P0["packfile"]
+
+ $P2 = $P1.'subs_by_tag'("tag-a")
+ $I0 = elements $P2
+ is($I0, 1, "Can get subs marked 'tag-a'")
+
+ $P2 = $P1.'subs_by_tag'("tag-b")
+ $I0 = elements $P2
+ is($I0, 2, "Can get subs marked 'tag-b'")
+
+ $P2 = $P1.'subs_by_tag'("tag-c")
+ $I0 = elements $P2
+ is($I0, 2, "Can get subs marked 'tag-c'")
+
+ # For upgrade, verify that :init is the same as :tag("init")
+ $P2 = compreg "PIR"
+ $S0 = <<'__EOCODE__'
+
+.sub __init_old :init
+ .return("init_old")
+.end
+
+.sub __init_tag :tag("init")
+ .return("init_tag")
+.end
+
+.sub __not_init :tag("something-else")
+ .return("not_init")
+.end
+__EOCODE__
+
+ $P1 = $P2.'compile'($S0)
+ $P3 = $P1.'subs_by_tag'("init")
+ $I0 = elements $P3
+ is($I0, 2)
+.end
+
.sub 'test_method_serialized_size'
$P0 = new ['PackfileView']
$I0 = $P0.'serialized_size'()
@@ -147,6 +197,32 @@
# TODO: Would really like temporary files for this. TT #955
.end
+# Subs with :tag syntax
+.sub 'tag1' :tag("tag-a")
+ .return('tag1')
+.end
+
+.sub 'tag2' :tag("tag-b")
+ .return('tag2')
+.end
+
+.sub 'tag3' :tag("tag-c")
+ .return('tag3')
+.end
+
+.sub 'tag4' :tag("tag-c", "tag-b")
+ .return('tag4')
+.end
+
+# Helper method
+.sub 'is_same'
+ .param pmc x
+ .param pmc y
+ .param string msg
+ $I0 = issame x, y
+ 'ok'($I0, msg)
+.end
+
# Local Variables:
# mode: pir
# fill-column: 100

0 comments on commit f957d20

Please sign in to comment.