Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[perl #39715] [TODO] IMCC errors should throw Parrot exceptions

4 views
Skip to first unread message

Audrey Tang

unread,
Jul 4, 2006, 10:32:25 PM7/4/06
to bugs-bi...@rt.perl.org
# New Ticket Created by Audrey Tang
# Please include the string: [perl #39715]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=39715 >


Currently, if you use IMCC inside embedded parrot (eg. when compiling
via PGE), when a syntax error occurs, imcc calls Parrot_exit (or
downright exit() -- see imclexer.c)), and it terminates the
interpreter right there without any chance of recover.

It should throw an exception using the standard Parrot exception
mechanism.
Note that doing this may depend on removing the global states, as to
make IMCC
reentrant.

PGP.sig

Vishal Soni via RT

unread,
Jul 13, 2006, 1:02:36 AM7/13/06
to perl6-i...@perl.org
Attached with this the patch for IMCC to handles errors gracefull
instead of exiting out. Currently when the parse fails IMCC shutsdown by
calling Parrot_exit().

With this patch, on IMCC failures, the control will be returned to the
calling program gracefully. The IMCC error message will be sent to the
calling program via a STRING*. For more examples look at
t/src/compiler.t after applying this patch.

This patch also introduces a Parrot API for the calling programs to
compile the code. Currently pugs uses immc_compile() call into IMCC.
Ideally Pugs should not be communicating with IMCC but with Parrot. This
new API will try to hide IMCC/PASM compile details from programming
languages

PARROT_API PMC *Parrot_compile_string(Parrot_Interp interpreter, STRING
*type, char *code, STRING **error);

PARROT_API void *Parrot_compile_file(Parrot_Interp interpreter,char
*fullname, String **error);

Along with this path there are some basic test for testing PIR
functionality via Parrot_compile_string(). I will be adding more tests
in comming days.

PATCH
-------
Index: src/inter_misc.c
===================================================================
--- src/inter_misc.c (revision 13269)
+++ src/inter_misc.c (working copy)
@@ -89,7 +89,47 @@
VTABLE_set_pointer_keyed_str(interpreter, nci, sc, (void*)func);
}

+/*
+=item C<PMC *
+Parrot_compile_string(Parrot_Interp interpreter, STRING *type,
+ STRING *code, String **error)

+Compile code string.
+
+*/
+PMC *
+Parrot_compile_string(Parrot_Interp interpreter, STRING *type,
+ char *code, STRING **error)
+{
+ if (!string_compare(interpreter, const_string(interpreter, "PIR"),
+ type)) {
+ return IMCC_compile_pir_s(interpreter, code, error);
+ }
+ else if (!string_compare(interpreter,const_string(interpreter,
+ "PASM"), type)) {
+ return IMCC_compile_pasm_s(interpreter, code, error);
+ }
+ else {
+ *error=const_string(interpreter, "Invalid interpreter type");
+ return NULL;
+ }
+}
+
+/*
+=item C<void
+Parrot_compile_file(Parrot_Interp interpreter, const char *fullname,
+ String **error)
+
+Compile code file.
+
+*/
+void *
+Parrot_compile_file(Parrot_Interp interpreter, char *fullname,
+ String **error)
+{
+ return IMCC_compile_file_s(interpreter, fullname, error);
+}
+
#ifdef GC_IS_MALLOC
# if 0
struct mallinfo {
Index: include/parrot/misc.h
===================================================================
--- include/parrot/misc.h (revision 13269)
+++ include/parrot/misc.h (working copy)
@@ -54,6 +54,17 @@
void *info);

/*
+ * IMCC API
+ */
+void *IMCC_compile_file_s(Parrot_Interp interp, const char *s,
+ STRING **error_message);
+void * IMCC_compile_file (Parrot_Interp interp, const char *s);
+PMC * IMCC_compile_pir_s(Parrot_Interp interp, const char *s,
+ STRING **error_message);
+PMC * IMCC_compile_pasm_s(Parrot_Interp interp, const char *s,
+ STRING **error_message);
+
+/*
* misc.c
*/

Index: include/parrot/interpreter.h
===================================================================
--- include/parrot/interpreter.h (revision 13269)
+++ include/parrot/interpreter.h (working copy)
@@ -484,6 +484,12 @@
const char * program );

PARROT_API void Parrot_compreg(Interp * interpreter, STRING *,
Parrot_compiler_func_t func);
+
+PARROT_API PMC *Parrot_compile_string(Parrot_Interp interpreter,
+ STRING *type, char *code, STRING **error);
+PARROT_API void *Parrot_compile_file(Parrot_Interp interpreter,
+ char *fullname, String **error);
+
INTVAL sysinfo_i(Interp * interpreter, INTVAL info_wanted);
STRING *sysinfo_s(Interp * interpreter, INTVAL info_wanted);
void exec_init_prederef(Interp *interpreter,
Index: compilers/imcc/debug.c
===================================================================
--- compilers/imcc/debug.c (revision 13269)
+++ compilers/imcc/debug.c (working copy)
@@ -11,11 +11,12 @@
IMCC_fatal(Interp *interp, int code, const char *fmt, ...)
{
va_list ap;
-
+ UNUSED(code);
+
va_start(ap, fmt);
- imcc_vfprintf(interp, stderr, fmt, ap);
+ IMCC_INFO(interp)->error_message = Parrot_vsprintf_c(interp, fmt, ap);
va_end(ap);
- Parrot_exit(code);
+ IMCC_THROW(IMCC_INFO(interp)->jump_buf,IMCC_FATAL_EXCEPTION);
}


@@ -23,14 +24,12 @@
IMCC_fataly(Interp *interp, int code, const char *fmt, ...)
{
va_list ap;
+ UNUSED(code);

va_start(ap, fmt);
- fprintf(stderr, "error:imcc:");
- imcc_vfprintf(interp, stderr, fmt, ap);
+ IMCC_INFO(interp)->error_message = Parrot_vsprintf_c(interp, fmt, ap);
va_end(ap);
- IMCC_print_inc(interp);
- /* TODO through compiler exception */
- Parrot_exit(code);
+ IMCC_THROW(IMCC_INFO(interp)->jump_buf,IMCC_FATALY_EXCEPTION);
}


Index: compilers/imcc/imc.h
===================================================================
--- compilers/imcc/imc.h (revision 13269)
+++ compilers/imcc/imc.h (working copy)
@@ -51,6 +51,15 @@
#include "unit.h"
#include "debug.h"

+#define IMCC_TRY(a,e) do{ e=0; switch(setjmp(a)){ case 0:
+#define IMCC_CATCH(x) break; case x:
+#define IMCC_END_TRY } }while(0)
+
+#define IMCC_THROW(a,x) longjmp(a,x)
+
+#define IMCC_FATAL_EXCEPTION 1
+#define IMCC_FATALY_EXCEPTION 2
+
/*
* imc.c
*/
@@ -98,9 +107,14 @@
*/
PMC *imcc_compile_pir(Parrot_Interp interp, const char *s);
PMC *imcc_compile_pasm(Parrot_Interp interp, const char *s);
-void *IMCC_compile_file (Parrot_Interp interp, const char *s);
+void *IMCC_compile_file(Parrot_Interp interp, const char *s);
+void *IMCC_compile_file_s(Parrot_Interp interp, const char *s,
+ STRING **error_message);
+PMC * IMCC_compile_pir_s(Parrot_Interp interp, const char *s,
+ STRING **error_message);
+PMC * IMCC_compile_pasm_s(Parrot_Interp interp, const char *s,
+ STRING **error_message);

-
/* Call convention independant API */

/*
@@ -190,9 +204,10 @@
SymHash ghash;
SymReg * cur_namespace;
struct nodeType_t *top_node;
-
struct parser_state_t *state;
-
+ jmp_buf jump_buf; //The jump for error handling
+ int error_code; //The Error code.
+ STRING * error_message; //The Error message
} imc_info_t;

#define IMCC_INFO(i) (((Parrot_Interp)(i))->imc_info)
Index: compilers/imcc/imcc.l
===================================================================
--- compilers/imcc/imcc.l (revision 13269)
+++ compilers/imcc/imcc.l (working copy)
@@ -658,8 +658,10 @@
/* FIXME if frame->s.file was allocated free it */

mem_sys_free(frame);
-
- yy_switch_to_buffer(buffer);
+
+ if (buffer != NULL) {
+ yy_switch_to_buffer(buffer);
+ }
}

static int
@@ -1040,10 +1042,22 @@
yy_switch_to_buffer(yy_create_buffer(file, YY_BUF_SIZE));

emit_open(interp, 1, NULL);
- yyparse((void *) interp);
- imc_compile_all_units(interp);

- yy_switch_to_buffer(buffer);
+ IMCC_TRY(IMCC_INFO(interp)->jump_buf, IMCC_INFO(interp)->error_code) {
+ yyparse((void *) interp);
+ imc_compile_all_units(interp);
+ }
+ IMCC_CATCH(IMCC_FATAL_EXCEPTION) {
+ IMCC_INFO(interp)->error_code=IMCC_FATAL_EXCEPTION;
+ }
+ IMCC_CATCH(IMCC_FATALY_EXCEPTION) {
+ IMCC_INFO(interp)->error_code=IMCC_FATALY_EXCEPTION;
+ }
+ IMCC_END_TRY;
+
+ if(buffer != NULL) {
+ yy_switch_to_buffer(buffer);
+ }
}

void
@@ -1056,9 +1070,22 @@

yy_scan_string(s);
emit_open(interp, 1, NULL);
- yyparse((void *) interp);
- imc_compile_all_units(interp);
- yy_switch_to_buffer(buffer);
+
+ IMCC_TRY(IMCC_INFO(interp)->jump_buf, IMCC_INFO(interp)->error_code) {
+ yyparse((void *) interp);
+ imc_compile_all_units(interp);
+ }
+ IMCC_CATCH(IMCC_FATAL_EXCEPTION) {
+ IMCC_INFO(interp)->error_code=IMCC_FATAL_EXCEPTION;
+ }
+ IMCC_CATCH(IMCC_FATALY_EXCEPTION) {
+ IMCC_INFO(interp)->error_code=IMCC_FATALY_EXCEPTION;
+ }
+ IMCC_END_TRY;
+
+ if(buffer != NULL) {
+ yy_switch_to_buffer(buffer);
+ }
}

void
Index: compilers/imcc/main.c
===================================================================
--- compilers/imcc/main.c (revision 13269)
+++ compilers/imcc/main.c (working copy)
@@ -607,13 +607,34 @@

if (ast_file) {
IMCC_ast_compile(interp, imc_yyin_get());
+ imc_compile_all_units(interp);
imc_compile_all_units_for_ast(interp);
}
else {
IMCC_INFO(interp)->state->pasm_file = pasm_file;
- yyparse((void *) interp);
+ IMCC_TRY(IMCC_INFO(interp)->jump_buf,
+ IMCC_INFO(interp)->error_code) {
+ yyparse((void *) interp);
+ imc_compile_all_units(interp);
+ }
+ IMCC_CATCH(IMCC_FATAL_EXCEPTION) {
+ IMCC_INFO(interp)->error_code=IMCC_FATAL_EXCEPTION;
+ fprintf(stderr,"Error occured in IMCC:\n%s",
+ string_to_cstring(interp,
+ IMCC_INFO(interp)->error_message));
+ IMCC_print_inc(interp);
+ Parrot_exit(IMCC_FATAL_EXCEPTION);
+ }
+ IMCC_CATCH(IMCC_FATALY_EXCEPTION) {
+ IMCC_INFO(interp)->error_code=IMCC_FATALY_EXCEPTION;
+ fprintf(stderr,"Error occured in IMCC:\n%s",
+ string_to_cstring(interp,
+ IMCC_INFO(interp)->error_message));
+ IMCC_print_inc(interp);
+ Parrot_exit(IMCC_FATALY_EXCEPTION);
+ }
+ IMCC_END_TRY;
}
- imc_compile_all_units(interp);

imc_cleanup(interp);

Index: compilers/imcc/parser_util.c
===================================================================
--- compilers/imcc/parser_util.c (revision 13269)
+++ compilers/imcc/parser_util.c (working copy)
@@ -23,9 +23,10 @@
#include "pbc.h"
#include "parser.h"

-static PMC * imcc_compile(Parrot_Interp interp, const char *s, int pasm);
-static const char * try_rev_cmp(Parrot_Interp, IMC_Unit * unit, char *name,
- SymReg ** r);
+PMC * imcc_compile(Parrot_Interp interp, const char *s, int pasm_file,
+ STRING **error_message);
+static const char *try_rev_cmp(Parrot_Interp, IMC_Unit *unit, char *name,
+ SymReg **r);

/*
* P = new type, [init]
@@ -569,14 +570,15 @@


PMC *
-imcc_compile(Parrot_Interp interp, const char *s, int pasm_file)
+imcc_compile(Parrot_Interp interp, const char *s, int pasm_file,
+ STRING **error_message)
{
/* imcc always compiles to interp->code
* save old cs, make new
*/
char name[64];
struct PackFile_ByteCode *old_cs, *new_cs;
- PMC *sub;
+ PMC *sub=NULL;
parrot_sub_t sub_data;
struct _imc_info_t *imc_info = NULL;
struct parser_state_t *next;
@@ -633,24 +635,29 @@
IMCC_INFO(interp)->state->next = next;
IMCC_pop_parser_state(interp);

- sub = pmc_new(interp, enum_class_Eval);
- PackFile_fixup_subs(interp, PBC_MAIN, sub);
- if (old_cs) {
- /* restore old byte_code, */
- (void)Parrot_switch_to_cs(interp, old_cs, 0);
+ if (!IMCC_INFO(interp)->error_code) {
+ sub = pmc_new(interp, enum_class_Eval);
+ PackFile_fixup_subs(interp, PBC_MAIN, sub);
+ if (old_cs) {
+ /* restore old byte_code, */
+ (void)Parrot_switch_to_cs(interp, old_cs, 0);
+ }
+
+ /*
+ * create sub PMC
+ *
+ * TODO if a sub was denoted :main return that instead
+ */
+ sub_data = PMC_sub(sub);
+ sub_data->seg = new_cs;
+ sub_data->start_offs = 0;
+ sub_data->end_offs = new_cs->base.size;
+ sub_data->name = string_from_cstring(interp, name, 0);
}
+ else {
+ *error_message = IMCC_INFO(interp)->error_message;
+ }

- /*
- * create sub PMC
- *
- * TODO if a sub was denoted :main return that instead
- */
- sub_data = PMC_sub(sub);
- sub_data->seg = new_cs;
- sub_data->start_offs = 0;
- sub_data->end_offs = new_cs->base.size;
- sub_data->name = string_from_cstring(interp, name, 0);
-
if (imc_info) {
IMCC_INFO(interp) = imc_info->prev;
mem_sys_free(imc_info);
@@ -664,26 +671,50 @@
return sub;
}

+/*
+ * Note: This function is provided for backward compatibility. This
+ * function can go away in future.
+ */
PMC *
imcc_compile_pasm(Parrot_Interp interp, const char *s)
{
- return imcc_compile(interp, s, 1);
+ STRING *error_message;
+ return imcc_compile(interp, s, 1, &error_message);
}

+/*
+ * Note: This function is provided for backward compatibility. This
+ * function can go away in future.
+ */
PMC *
imcc_compile_pir (Parrot_Interp interp, const char *s)
{
- return imcc_compile(interp, s, 0);
+ STRING *error_message;
+ return imcc_compile(interp, s, 0, &error_message);
}

+PMC *
+IMCC_compile_pir_s(Parrot_Interp interp, const char *s,
+ STRING **error_message)
+{
+ return imcc_compile(interp, s, 0, error_message);
+}

+PMC *
+IMCC_compile_pasm_s(Parrot_Interp interp, const char *s,
+ STRING **error_message)
+{
+ return imcc_compile(interp, s, 1, error_message);
+}
+
/*
* Compile a file by filename (can be either PASM or IMCC code)
*/
static void *
-imcc_compile_file (Parrot_Interp interp, const char *fullname)
+imcc_compile_file (Parrot_Interp interp, const char *fullname,
+ STRING **error_message)
{
- struct PackFile_ByteCode *cs_save = interp->code, *cs;
+ struct PackFile_ByteCode *cs_save = interp->code, *cs=NULL;
char *ext;
FILE *fp;
struct _imc_info_t *imc_info = NULL;
@@ -742,8 +773,14 @@

imc_cleanup(interp);
fclose(fp);
- cs = interp->code;

+ if (!IMCC_INFO(interp)->error_code) {
+ cs = interp->code;
+ }
+ else {
+ *error_message = IMCC_INFO(interp)->error_message;
+ }
+
if (cs_save)
(void)Parrot_switch_to_cs(interp, cs_save, 0);

@@ -754,12 +791,23 @@
return cs;
}

+/*
+ * Note: This function is provided for backward compatibility. This
+ * function can go away in future.
+ */
void *
-IMCC_compile_file (Parrot_Interp interp, const char *s)
+IMCC_compile_file(Parrot_Interp interp, const char *s)
{
- return imcc_compile_file(interp, s);
+ STRING *error_message;
+ return imcc_compile_file(interp, s, &error_message);
}

+void *
+IMCC_compile_file_s(Parrot_Interp interp, const char *s,
+ STRING **error_message)
+{
+ return imcc_compile_file(interp, s , error_message);
+}

/* Register additional compilers with the interpreter */
void
Index: t/src/compiler.t
===================================================================
--- t/src/compiler.t (revision 13269)
+++ t/src/compiler.t (working copy)
@@ -8,7 +8,7 @@
use Test::More;
use Parrot::Test;

-plan $^O =~ m/MSWin32/ ? (skip_all => 'broken on win32') : (tests => 1);
+plan $^O =~ m/MSWin32/ ? (skip_all => 'broken on win32') : (tests => 6);

=head1 NAME

@@ -34,13 +34,10 @@

extern void imcc_init(Parrot_Interp interp);

-static opcode_t*
+static opcode_t *
run(Parrot_Interp interpreter, int argc, char *argv[])
{
- const char *c_src =
- ".sub main :main\n"
- " print \"ok\\n\"\n"
- ".end\n";
+ const char *c_src = ".sub main :main\n" " print \"ok\\n\"\n"
".end\n";

STRING *src, *pir, *smain;
PMC *comp, *prog, *compreg, *entry;
@@ -49,12 +46,13 @@
* get PIR compiler - TODO API
*/
compreg = VTABLE_get_pmc_keyed_int(interpreter,
- interpreter->iglobals, IGLOBALS_COMPREG_HASH);
+ interpreter->iglobals,
+ IGLOBALS_COMPREG_HASH);
pir = const_string(interpreter, "PIR");
comp = VTABLE_get_pmc_keyed_str(interpreter, compreg, pir);
if (PMC_IS_NULL(comp) || !VTABLE_defined(interpreter, comp)) {
- PIO_eprintf(interpreter, "Pir compiler not loaded");
- exit(1);
+ PIO_eprintf(interpreter, "Pir compiler not loaded");
+ exit(1);
}
/*
* compile source
@@ -62,36 +60,38 @@
prog = imcc_compile_pir(interpreter, c_src);

if (PMC_IS_NULL(prog) || !VTABLE_defined(interpreter, prog)) {
- PIO_eprintf(interpreter, "Pir compiler returned no prog");
- exit(1);
+ PIO_eprintf(interpreter, "Pir compiler returned no prog");
+ exit(1);
}
/* keep eval PMC alive */
dod_register_pmc(interpreter, prog);
/* locate function to run */
- smain = const_string(interpreter, "main");
+ smain = const_string(interpreter, "main");
entry = Parrot_find_global_cur(interpreter, smain);
/* location of the entry */
- interpreter->current_cont = new_ret_continuation_pmc(interpreter,
NULL);
+ interpreter->current_cont = new_ret_continuation_pmc(interpreter,
NULL);
dest = VTABLE_invoke(interpreter, entry, NULL);
/* where to start */
- interpreter->resume_offset = dest - interpreter->code->base.data;
+ interpreter->resume_offset = dest -interpreter->code->base.data;
/* and go */
Parrot_runcode(interpreter, argc, argv);
return NULL;
}

-int main(int margc, char* margv[]) {
+int
+main(int margc, char *margv[])
+{
Parrot_Interp interpreter;
struct PackFile *pf;
int argc = 1;
- char *argv[] = {"test", NULL};
+ char *argv[] = { "test", NULL };

struct PackFile_Segment *seg;

/* Interpreter set-up */
interpreter = Parrot_new(NULL);
- if ( interpreter == NULL )
- return 1;
+ if (interpreter == NULL)
+ return 1;

/* this registers the PIR compiler */
imcc_init(interpreter);
@@ -109,3 +109,461 @@
CODE
ok
OUTPUT
+c_output_is(<<'CODE', <<'OUTPUT', "Parror Compile API Single call");
+
+#include <stdio.h>
+#include "parrot/parrot.h"
+#include "parrot/embed.h"
+
+extern void imcc_init(Parrot_Interp interp);
+
+static opcode_t *
+run(Parrot_Interp interpreter, int argc, char *argv[])
+{
+ const char *c_src = ".sub main :main\n" " print \"ok\\n\"\n"
".end\n";
+
+ STRING *src, *pir, *smain;
+ PMC *comp, *prog, *compreg, *entry;
+ opcode_t *dest;
+ STRING *error;
+ /*
+ * get PIR compiler - TODO API
+ */
+ compreg = VTABLE_get_pmc_keyed_int(interpreter,
+ interpreter->iglobals,
+ IGLOBALS_COMPREG_HASH);
+ pir = const_string(interpreter, "PIR");
+ comp = VTABLE_get_pmc_keyed_str(interpreter, compreg, pir);
+ if (PMC_IS_NULL(comp) || !VTABLE_defined(interpreter, comp)) {
+ PIO_eprintf(interpreter, "Pir compiler not loaded");
+ exit(1);
+ }
+
+ /*
+ * compile source
+ */
+ prog = Parrot_compile_string(interpreter, pir, c_src, &error);
+
+ if (PMC_IS_NULL(prog) || !VTABLE_defined(interpreter, prog)) {
+ PIO_eprintf(interpreter, "Pir compiler returned no prog");
+ exit(1);
+ }
+ /* keep eval PMC alive */
+ dod_register_pmc(interpreter, prog);
+ /* locate function to run */
+ smain = const_string(interpreter, "main");
+ entry = Parrot_find_global_cur(interpreter, smain);
+ /* location of the entry */
+ interpreter->current_cont = new_ret_continuation_pmc(interpreter,
NULL);
+ dest = VTABLE_invoke(interpreter, entry, NULL);
+ /* where to start */
+ interpreter->resume_offset = dest -interpreter->code->base.data;
+ /* and go */
+ Parrot_runcode(interpreter, argc, argv);
+ return NULL;
+}
+
+int
+main(int margc, char *margv[])
+{
+ Parrot_Interp interpreter;
+ struct PackFile *pf;
+ int argc = 1;
+ char *argv[] = { "test", NULL };
+
+ struct PackFile_Segment *seg;
+
+ /* Interpreter set-up */
+ interpreter = Parrot_new(NULL);
+ if (interpreter == NULL)
+ return 1;
+
+ /* this registers the PIR compiler */
+ imcc_init(interpreter);
+ /* dummy pf and segment to get things started */
+ pf = PackFile_new(interpreter, 0);
+ Parrot_loadbc(interpreter, pf);
+ pf->cur_cs = PF_create_default_segs(interpreter, "test_code", 1);
+ Parrot_loadbc(interpreter, pf);
+
+ /* Parrot_set_flag(interpreter, PARROT_TRACE_FLAG); */
+ run(interpreter, argc, argv);
+ Parrot_exit(0);
+ return 0;
+}
+CODE
+ok
+OUTPUT
+c_output_is(<<'CODE', <<'OUTPUT', "Parror Compile API Multiple Calls");
+
+#include <stdio.h>
+#include "parrot/parrot.h"
+#include "parrot/embed.h"
+
+extern void imcc_init(Parrot_Interp interp);
+
+static void
+compile_run(Parrot_Interp interpreter, const char *src, STRING *type,
int argc,
+ char *argv[])
+{
+ String *smain;
+ PMC *prog, *entry;
+ String *error;
+ opcode_t *dest;
+ prog = Parrot_compile_string(interpreter, type, src, &error);
+
+ if (PMC_IS_NULL(prog) || !VTABLE_defined(interpreter, prog)) {
+ PIO_eprintf(interpreter, "Pir compiler returned no prog");
+ exit(1);
+ }
+ /* keep eval PMC alive */
+ dod_register_pmc(interpreter, prog);
+ /* locate function to run */
+ smain = const_string(interpreter, "main");
+ entry = Parrot_find_global_cur(interpreter, smain);
+ /* location of the entry */
+ interpreter->current_cont = new_ret_continuation_pmc(interpreter,
NULL);
+ dest = VTABLE_invoke(interpreter, entry, NULL);
+ /* where to start */
+ interpreter->resume_offset = dest -interpreter->code->base.data;
+ /* and go */
+ Parrot_runcode(interpreter, argc, argv);
+ return NULL;
+}
+static opcode_t *
+run(Parrot_Interp interpreter, int argc, char *argv[])
+{
+ const char *c_src = ".sub main :main\n" " print \"ok\\n\"\n"
".end\n";
+
+ const char *c2_src =
+ ".sub main :main\n" " print \"hola\\n\"\n" ".end\n";
+
+ STRING *src, *pir, *smain;
+ PMC *comp, *compreg;
+ /*
+ * get PIR compiler - TODO API
+ */
+ compreg = VTABLE_get_pmc_keyed_int(interpreter,
+ interpreter->iglobals,
+ IGLOBALS_COMPREG_HASH);
+ pir = const_string(interpreter, "PIR");
+ comp = VTABLE_get_pmc_keyed_str(interpreter, compreg, pir);
+ if (PMC_IS_NULL(comp) || !VTABLE_defined(interpreter, comp)) {
+ PIO_eprintf(interpreter, "Pir compiler not loaded");
+ exit(1);
+ }
+ compile_run(interpreter, c_src, pir, argc, argv);
+ compile_run(interpreter, c2_src, pir, argc, argv);
+}
+
+int
+main(int margc, char *margv[])
+{
+ Parrot_Interp interpreter;
+ struct PackFile *pf;
+ int argc = 1;
+ char *argv[] = { "test", NULL };
+
+ struct PackFile_Segment *seg;
+
+ /* Interpreter set-up */
+ interpreter = Parrot_new(NULL);
+ if (interpreter == NULL)
+ return 1;
+
+ /* this registers the PIR compiler */
+ imcc_init(interpreter);
+ /* dummy pf and segment to get things started */
+ pf = PackFile_new(interpreter, 0);
+ Parrot_loadbc(interpreter, pf);
+ pf->cur_cs = PF_create_default_segs(interpreter, "test_code", 1);
+ Parrot_loadbc(interpreter, pf);
+
+ /* Parrot_set_flag(interpreter, PARROT_TRACE_FLAG); */
+ run(interpreter, argc, argv);
+ Parrot_exit(0);
+ return 0;
+}
+CODE
+ok
+hola
+OUTPUT
+c_output_is(<<'CODE', <<'OUTPUT', "Parror Compile API Multiple 1st bad
PIR");
+
+#include <stdio.h>
+#include "parrot/parrot.h"
+#include "parrot/embed.h"
+
+extern void imcc_init(Parrot_Interp interp);
+
+static void
+compile_run(Parrot_Interp interpreter, const char *src, STRING *type,
int argc,
+ char *argv[])
+{
+ STRING *smain;
+ PMC *prog, *entry;
+ STRING *error;
+ opcode_t *dest;
+ prog = Parrot_compile_string(interpreter, type, src, &error);
+
+ if (PMC_IS_NULL(prog) || !VTABLE_defined(interpreter, prog)) {
+ PIO_eprintf(interpreter, "Pir compiler returned no prog\n");
+ return;
+ }
+ /* keep eval PMC alive */
+ dod_register_pmc(interpreter, prog);
+ /* locate function to run */
+ smain = const_string(interpreter, "main");
+ entry = Parrot_find_global_cur(interpreter, smain);
+ /* location of the entry */
+ interpreter->current_cont = new_ret_continuation_pmc(interpreter,
NULL);
+ dest = VTABLE_invoke(interpreter, entry, NULL);
+ /* where to start */
+ interpreter->resume_offset = dest -interpreter->code->base.data;
+ /* and go */
+ Parrot_runcode(interpreter, argc, argv);
+}
+static opcode_t *
+run(Parrot_Interp interpreter, int argc, char *argv[])
+{
+ const char *c_src = ".sub main :main\n" " print ok\\n\"\n" ".end\n";
+
+ const char *c2_src =
+ ".sub main :main\n" " print \"hola\\n\"\n" ".end\n";
+
+ STRING *src, *pir, *smain;
+ PMC *comp, *compreg;
+ /*
+ * get PIR compiler - TODO API
+ */
+ compreg = VTABLE_get_pmc_keyed_int(interpreter,
+ interpreter->iglobals,
+ IGLOBALS_COMPREG_HASH);
+ pir = const_string(interpreter, "PIR");
+ comp = VTABLE_get_pmc_keyed_str(interpreter, compreg, pir);
+ if (PMC_IS_NULL(comp) || !VTABLE_defined(interpreter, comp)) {
+ PIO_eprintf(interpreter, "Pir compiler not loaded");
+ return NULL;
+ }
+ compile_run(interpreter, c_src, pir, argc, argv);
+ compile_run(interpreter, c2_src, pir, argc, argv);
+}
+
+int
+main(int margc, char *margv[])
+{
+ Parrot_Interp interpreter;
+ struct PackFile *pf;
+ int argc = 1;
+ char *argv[] = { "test", NULL };
+
+ struct PackFile_Segment *seg;
+
+ /* Interpreter set-up */
+ interpreter = Parrot_new(NULL);
+ if (interpreter == NULL)
+ return 1;
+
+ /* this registers the PIR compiler */
+ imcc_init(interpreter);
+ /* dummy pf and segment to get things started */
+ pf = PackFile_new(interpreter, 0);
+ Parrot_loadbc(interpreter, pf);
+ pf->cur_cs = PF_create_default_segs(interpreter, "test_code", 1);
+ Parrot_loadbc(interpreter, pf);
+
+ /* Parrot_set_flag(interpreter, PARROT_TRACE_FLAG); */
+ run(interpreter, argc, argv);
+ Parrot_exit(0);
+ return 0;
+}
+CODE
+Pir compiler returned no prog
+hola
+OUTPUT
+c_output_is(<<'CODE', <<'OUTPUT', "Parror Compile API Multiple 2nd bad
PIR");
+
+#include <stdio.h>
+#include "parrot/parrot.h"
+#include "parrot/embed.h"
+
+extern void imcc_init(Parrot_Interp interp);
+
+static void
+compile_run(Parrot_Interp interpreter, const char *src, STRING *type,
int argc,
+ char *argv[])
+{
+ STRING *smain;
+ PMC *prog, *entry;
+ STRING *error;
+ opcode_t *dest;
+ prog = Parrot_compile_string(interpreter, type, src, &error);
+
+ if (PMC_IS_NULL(prog) || !VTABLE_defined(interpreter, prog)) {
+ PIO_eprintf(interpreter, "Pir compiler returned no prog\n");
+ return;
+ }
+ /* keep eval PMC alive */
+ dod_register_pmc(interpreter, prog);
+ /* locate function to run */
+ smain = const_string(interpreter, "main");
+ entry = Parrot_find_global_cur(interpreter, smain);
+ /* location of the entry */
+ interpreter->current_cont = new_ret_continuation_pmc(interpreter,
NULL);
+ dest = VTABLE_invoke(interpreter, entry, NULL);
+ /* where to start */
+ interpreter->resume_offset = dest -interpreter->code->base.data;
+ /* and go */
+ Parrot_runcode(interpreter, argc, argv);
+}
+static opcode_t *
+run(Parrot_Interp interpreter, int argc, char *argv[])
+{
+ const char *c_src = ".sub main :main\n" " print ok\\n\"\n" ".end\n";
+
+ const char *c2_src =
+ ".sub main :main\n" " print \"hola\\n\"\n" ".end\n";
+
+ STRING *src, *pir, *smain;
+ PMC *comp, *compreg;
+ /*
+ * get PIR compiler - TODO API
+ */
+ compreg = VTABLE_get_pmc_keyed_int(interpreter,
+ interpreter->iglobals,
+ IGLOBALS_COMPREG_HASH);
+ pir = const_string(interpreter, "PIR");
+ comp = VTABLE_get_pmc_keyed_str(interpreter, compreg, pir);
+ if (PMC_IS_NULL(comp) || !VTABLE_defined(interpreter, comp)) {
+ PIO_eprintf(interpreter, "Pir compiler not loaded");
+ return NULL;
+ }
+ compile_run(interpreter, c2_src, pir, argc, argv);
+ compile_run(interpreter, c_src, pir, argc, argv);
+}
+
+int
+main(int margc, char *margv[])
+{
+ Parrot_Interp interpreter;
+ struct PackFile *pf;
+ int argc = 1;
+ char *argv[] = { "test", NULL };
+
+ struct PackFile_Segment *seg;
+
+ /* Interpreter set-up */
+ interpreter = Parrot_new(NULL);
+ if (interpreter == NULL)
+ return 1;
+
+ /* this registers the PIR compiler */
+ imcc_init(interpreter);
+ /* dummy pf and segment to get things started */
+ pf = PackFile_new(interpreter, 0);
+ Parrot_loadbc(interpreter, pf);
+ pf->cur_cs = PF_create_default_segs(interpreter, "test_code", 1);
+ Parrot_loadbc(interpreter, pf);
+
+ /* Parrot_set_flag(interpreter, PARROT_TRACE_FLAG); */
+ run(interpreter, argc, argv);
+ Parrot_exit(0);
+ return 0;
+}
+CODE
+hola
+Pir compiler returned no prog
+OUTPUT
+c_output_is(<<'CODE', <<'OUTPUT', "Parror Compile API Multiple bad PIR");
+
+#include <stdio.h>
+#include "parrot/parrot.h"
+#include "parrot/embed.h"
+
+extern void imcc_init(Parrot_Interp interp);
+
+static void
+compile_run(Parrot_Interp interpreter, const char *src, STRING *type,
int argc,
+ char *argv[])
+{
+ STRING *smain;
+ PMC *prog, *entry;
+ STRING *error;
+ opcode_t *dest;
+ prog = Parrot_compile_string(interpreter, type, src, &error);
+
+ if (PMC_IS_NULL(prog) || !VTABLE_defined(interpreter, prog)) {
+ PIO_eprintf(interpreter, "Pir compiler returned no prog\n");
+ return;
+ }
+ /* keep eval PMC alive */
+ dod_register_pmc(interpreter, prog);
+ /* locate function to run */
+ smain = const_string(interpreter, "main");
+ entry = Parrot_find_global_cur(interpreter, smain);
+ /* location of the entry */
+ interpreter->current_cont = new_ret_continuation_pmc(interpreter,
NULL);
+ dest = VTABLE_invoke(interpreter, entry, NULL);
+ /* where to start */
+ interpreter->resume_offset = dest -interpreter->code->base.data;
+ /* and go */
+ Parrot_runcode(interpreter, argc, argv);
+}
+static opcode_t *
+run(Parrot_Interp interpreter, int argc, char *argv[])
+{
+ const char *c_src = ".sub main :main\n" " print ok\\n\"\n" ".end\n";
+
+ const char *c2_src = ".sub main :main\n" " print hola\\n\"\n"
".end\n";
+
+ STRING *src, *pir, *smain;
+ PMC *comp, *compreg;
+ /*
+ * get PIR compiler - TODO API
+ */
+ compreg = VTABLE_get_pmc_keyed_int(interpreter,
+ interpreter->iglobals,
+ IGLOBALS_COMPREG_HASH);
+ pir = const_string(interpreter, "PIR");
+ comp = VTABLE_get_pmc_keyed_str(interpreter, compreg, pir);
+ if (PMC_IS_NULL(comp) || !VTABLE_defined(interpreter, comp)) {
+ PIO_eprintf(interpreter, "Pir compiler not loaded");
+ return NULL;
+ }
+ compile_run(interpreter, c_src, pir, argc, argv);
+ compile_run(interpreter, c2_src, pir, argc, argv);
+}
+
+int
+main(int margc, char *margv[])
+{
+ Parrot_Interp interpreter;
+ struct PackFile *pf;
+ int argc = 1;
+ char *argv[] = { "test", NULL };
+
+ struct PackFile_Segment *seg;
+
+ /* Interpreter set-up */
+ interpreter = Parrot_new(NULL);
+ if (interpreter == NULL)
+ return 1;
+
+ /* this registers the PIR compiler */
+ imcc_init(interpreter);
+ /* dummy pf and segment to get things started */
+ pf = PackFile_new(interpreter, 0);
+ Parrot_loadbc(interpreter, pf);
+ pf->cur_cs = PF_create_default_segs(interpreter, "test_code", 1);
+ Parrot_loadbc(interpreter, pf);
+
+ /* Parrot_set_flag(interpreter, PARROT_TRACE_FLAG); */
+ run(interpreter, argc, argv);
+ Parrot_exit(0);
+ return 0;
+}
+CODE
+Pir compiler returned no prog
+Pir compiler returned no prog
+OUTPUT
+

39715.patch

Vishal Soni

unread,
Jul 13, 2006, 1:33:40 AM7/13/06
to chromatic, perl6-i...@perl.org, bugs-par...@netlabs.develooper.com

> >
> > PARROT_API void *Parrot_compile_file(Parrot_Interp interpreter,char
> > *fullname, String **error);
>
> I like this interface, except for the return value from Parrot_compile_file.
> Are there other options, such as returning a Sub PMC?

Chip and I have had a chat about other possible API's which could be
added in future. Some e.g.

1. To throw Parrot exceptions instead of the String **error.
2. Possibly using Compiler PMC. (not sure on that yet)

Your suggestion is good and I will keep in mind.

These two functions are just a start for defining Compile API's.
Programming languages should not talk directly to IMCC or any other low
level compiler like IMCC and PASM.

Thanks for your suggestion.
Vishal

Chromatic

unread,
Jul 13, 2006, 1:20:07 AM7/13/06
to perl6-i...@perl.org, bugs-par...@netlabs.develooper.com
On Wednesday 12 July 2006 22:02, Vishal Soni via RT wrote:

> This patch also introduces a Parrot API for the calling programs to
> compile the code. Currently pugs uses immc_compile() call into IMCC.
> Ideally Pugs should not be communicating with IMCC but with Parrot. This
> new API will try to hide IMCC/PASM compile details from programming
> languages
>
> PARROT_API PMC *Parrot_compile_string(Parrot_Interp interpreter, STRING
> *type, char *code, STRING **error);
>
> PARROT_API void *Parrot_compile_file(Parrot_Interp interpreter,char
> *fullname, String **error);

I like this interface, except for the return value from Parrot_compile_file.

Are there other options, such as returning a Sub PMC?

-- c

Vishal Soni via RT

unread,
Jul 15, 2006, 12:30:12 PM7/15/06
to perl6-i...@perl.org
The previous patch broke some tests. I am re-issuing the whole patch again.

Patch
-----

Index: src/inter_misc.c
===================================================================
--- src/inter_misc.c (revision 13305)

--- include/parrot/misc.h (revision 13305)


+++ include/parrot/misc.h (working copy)
@@ -54,6 +54,17 @@
void *info);

/*
+ * IMCC API
+ */
+void *IMCC_compile_file_s(Parrot_Interp interp, const char *s,
+ STRING **error_message);
+void * IMCC_compile_file (Parrot_Interp interp, const char *s);
+PMC * IMCC_compile_pir_s(Parrot_Interp interp, const char *s,
+ STRING **error_message);
+PMC * IMCC_compile_pasm_s(Parrot_Interp interp, const char *s,
+ STRING **error_message);
+
+/*
* misc.c
*/

Index: include/parrot/interpreter.h
===================================================================

--- include/parrot/interpreter.h (revision 13305)


+++ include/parrot/interpreter.h (working copy)
@@ -484,6 +484,12 @@
const char * program );

PARROT_API void Parrot_compreg(Interp * interpreter, STRING *,
Parrot_compiler_func_t func);
+
+PARROT_API PMC *Parrot_compile_string(Parrot_Interp interpreter,
+ STRING *type, char *code, STRING **error);
+PARROT_API void *Parrot_compile_file(Parrot_Interp interpreter,
+ char *fullname, String **error);
+
INTVAL sysinfo_i(Interp * interpreter, INTVAL info_wanted);
STRING *sysinfo_s(Interp * interpreter, INTVAL info_wanted);
void exec_init_prederef(Interp *interpreter,
Index: compilers/imcc/debug.c
===================================================================

--- compilers/imcc/debug.c (revision 13305)

Index: compilers/imcc/imc.h
===================================================================
--- compilers/imcc/imc.h (revision 13305)

--- compilers/imcc/imcc.l (revision 13305)

--- compilers/imcc/main.c (revision 13305)


+++ compilers/imcc/main.c (working copy)
@@ -607,13 +607,34 @@

if (ast_file) {
IMCC_ast_compile(interp, imc_yyin_get());
+ imc_compile_all_units(interp);
imc_compile_all_units_for_ast(interp);
}
else {
IMCC_INFO(interp)->state->pasm_file = pasm_file;
- yyparse((void *) interp);
+ IMCC_TRY(IMCC_INFO(interp)->jump_buf,
+ IMCC_INFO(interp)->error_code) {
+ yyparse((void *) interp);
+ imc_compile_all_units(interp);
+ }
+ IMCC_CATCH(IMCC_FATAL_EXCEPTION) {
+ IMCC_INFO(interp)->error_code=IMCC_FATAL_EXCEPTION;

+ fprintf(stderr,"error:imcc:%s",


+ string_to_cstring(interp,
+ IMCC_INFO(interp)->error_message));
+ IMCC_print_inc(interp);
+ Parrot_exit(IMCC_FATAL_EXCEPTION);
+ }
+ IMCC_CATCH(IMCC_FATALY_EXCEPTION) {
+ IMCC_INFO(interp)->error_code=IMCC_FATALY_EXCEPTION;

+ fprintf(stderr,"error:imcc:%s",


+ string_to_cstring(interp,
+ IMCC_INFO(interp)->error_message));
+ IMCC_print_inc(interp);
+ Parrot_exit(IMCC_FATALY_EXCEPTION);
+ }
+ IMCC_END_TRY;
}
- imc_compile_all_units(interp);

imc_cleanup(interp);

Index: compilers/imcc/parser_util.c
===================================================================

--- compilers/imcc/parser_util.c (revision 13305)

--- t/src/compiler.t (revision 13305)

39715.patch

Leopold Toetsch via RT

unread,
Jul 15, 2006, 2:50:35 PM7/15/06
to perl6-i...@perl.org
Applied as r13307.

Still needs some tweaking, e.g. fix the failing past.t, but good enough
for now.

leo

0 new messages