# New Ticket Created by Leopold Toetsch # Please include the string: [perl #20315] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=20315 >
Attached is a first try towards eval. - interpreter has a new data member Parrot_compreg_hash - parrot registers the PASM1 type i.e. what PDB_eval can parse - the new B<compile> opcode (ab)uses nci to build a function for calling PDB_eval - nci is extended (jit/i386 only), to understand an 'I' param as interpreter - the string is evaled immediately, we don't have multiple byte code segments yet No registers, which nci uses, are preserved, no error checking and so on, but works ;-) Some questions arise here: - Should the B<compreg> opcode also have a form with a label to build PASM compilers, ook? - is using the NCI interface ok for evals purpose? - how should a byte code segment (PMC) look like? Comment welcome leo -- attachment 1 ------------------------------------------------------ url: http://rt.perl.org/rt2/attach/48556/37739/ade5a5/eval.patch
--- parrot/classes/csub.pmc Fri Jan 10 18:05:02 2003 +++ parrot-leo/classes/csub.pmc Tue Jan 14 19:06:24 2003 @@ -49,7 +49,7 @@ return SELF->cache.struct_val != NULL; } - void * invoke (void * next) { + void* invoke (void * next) { Parrot_csub_t func = (Parrot_csub_t)SELF->cache.struct_val; func(INTERP, SELF); return next; --- parrot/core.ops Tue Jan 14 09:09:55 2003 +++ parrot-leo/core.ops Tue Jan 14 19:25:19 2003 @@ -4485,6 +4485,10 @@ Call the subroutine in P0, as described in PDD03. +=item B<compile>(out PMC, in STR, in STR) + +Compile source code $2 of a registered source type $3 into PMC $1. + =cut inline op loadext(in STR, in STR) { @@ -4547,6 +4551,19 @@ goto ADDRESS(dest); } + +inline op compile(OUT PMC, in STR, in STR) { + opcode_t *dest; + PMC *key = key_new_string(interpreter, $3); + PMC *func = interpreter->Parrot_compreg_hash->vtable->get_pmc_keyed( + interpreter, interpreter->Parrot_compreg_hash, key); + /* XXX undef */ + interpreter->ctx.string_reg.registers[5] = $2; /* XXX */ + dest = (opcode_t *)func->vtable->invoke(interpreter, func, expr NEXT()); + /* XXX retval */ + goto ADDRESS(dest); +} + =item B<find_method>(out PMC, in PMC, in STR) --- parrot/dod.c Tue Jan 14 09:09:55 2003 +++ parrot-leo/dod.c Tue Jan 14 18:51:15 2003 @@ -104,6 +104,8 @@ /* mark it as used */ pobject_lives(interpreter, (PObj *)current); + if (interpreter->Parrot_compreg_hash) + pobject_lives(interpreter, (PObj *)interpreter->Parrot_compreg_hash); /* Now, go run through the PMC registers and mark them as live */ /* First mark the current set. */ for (i = 0; i < NUM_REGISTERS; i++) { --- parrot/include/parrot/interpreter.h Sat Jan 4 12:35:22 2003 +++ parrot-leo/include/parrot/interpreter.h Tue Jan 14 18:13:08 2003 @@ -169,6 +169,7 @@ INTVAL world_inited; /* Parrot_init is done */ PMC *mark_ptr; /* last PMC marked used in DOD runs */ PMC *Parrot_base_classname_hash; /* hash containing name->base_type */ + PMC *Parrot_compreg_hash; /* hash containing assembler/compilers */ } Interp; #define PCONST(i) PF_CONST(interpreter->code, (i)) @@ -189,6 +190,7 @@ VAR_SCOPE opcode_t *(*run_native)(struct Parrot_Interp * interpreter, opcode_t * cur_opcode, opcode_t * start_code); +void Parrot_compreg(Parrot_Interp interpreter, STRING *type, PMC *func); #endif /* Parrot core */ --- parrot/interpreter.c Sat Jan 11 09:39:08 2003 +++ parrot-leo/interpreter.c Tue Jan 14 19:21:00 2003 @@ -21,11 +21,13 @@ #ifdef HAVE_COMPUTED_GOTO # include "parrot/oplib/core_ops_cg.h" #endif +#include "parrot/method_util.h" #define ATEXIT_DESTROY extern op_lib_t *PARROT_CORE_PREDEREF_OPLIB_INIT(void); +static void setup_default_compreg(Parrot_Interp interpreter); /*=for api interpreter runops_generic * TODO: Not really part of the API, but here's the docs. @@ -512,6 +514,10 @@ SET_NULL_P(interpreter->prederef_code, void **); SET_NULL(interpreter->jit_info); + SET_NULL_P(interpreter->Parrot_compreg_hash, PMC *); + /* register assembler/compilers */ + setup_default_compreg(interpreter); + /* Done. Return and be done with it */ /* Okay, we've finished doing anything that might trigger GC. @@ -686,6 +692,42 @@ } return ret; } + +/*=for api interpreter Parrot_compreg + * register a parser/compiler function + */ + +void Parrot_compreg(Parrot_Interp interpreter, STRING *type, PMC *func) +{ + PMC* key, *hash; + if (!interpreter->Parrot_compreg_hash) { + hash = interpreter->Parrot_compreg_hash = + pmc_new_noinit(interpreter, enum_class_PerlHash); + hash->vtable->init(interpreter, hash); + } + key = key_new_string(interpreter, type); + hash->vtable->set_pmc_keyed(interpreter, hash, key, func, NULL); +} + +void PDB_eval_wrapper(Parrot_Interp interpreter, STRING *code); +void PDB_eval_wrapper(Parrot_Interp interpreter, STRING *code) +{ + char *s = string_to_cstring(interpreter, code); + PDB_eval(interpreter, s); + free(s); +} + +static void setup_default_compreg(Parrot_Interp interpreter) +{ + STRING *pasm1 = string_make(interpreter, "PASM1", 5, NULL,0,NULL); + PMC * func; + Parrot_csub_t p = (Parrot_csub_t) F2DPTR(PDB_eval); + func = Parrot_new_nci(interpreter, p, + string_make(interpreter, "pIt", 3, NULL,0,NULL)); + Parrot_compreg(interpreter, pasm1, func); +} + + /* * Local variables: * c-indentation-style: bsd --- parrot/jit/i386/jit_emit.h Tue Jan 14 10:34:02 2003 +++ parrot-leo/jit/i386/jit_emit.h Tue Jan 14 21:10:53 2003 @@ -2137,6 +2137,9 @@ emitm_addb_i_r(pc, 8, emit_ESP); emitm_pushl_r(pc, emit_EAX); break; + case 'I': + emitm_pushl_i(pc, interpreter); + break; default: internal_exception(1, "Parrot_jit_build_call_func: unimp argument\n"); --- /dev/null Tue Oct 10 22:47:19 2000 +++ parrot-leo/eval.pasm Tue Jan 14 19:33:57 2003 @@ -0,0 +1,4 @@ + compile P1, "set_s_sc S1, '42\n'", "PASM1" + compile P1, "print_s S1", "PASM1" + print "\n" + end