tagged release 0.6.4
[parrot.git] / src / embed.c
blob51c811b1a7809728cc2840a3f6b4abe8af0afd2a
1 /*
2 Copyright (C) 2001-2008, The Perl Foundation.
3 $Id$
5 =head1 NAME
7 src/embed.c - The Parrot embedding interface
9 =head1 DESCRIPTION
11 This file implements the Parrot embedding interface.
13 =head2 Functions
15 =over 4
17 =cut
21 #include "parrot/parrot.h"
22 #include "parrot/embed.h"
23 #include "parrot/oplib/ops.h"
25 /* HEADERIZER HFILE: none */ /* The visible types are different than what we use in here */
27 /* HEADERIZER BEGIN: static */
28 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
30 static FLOATVAL calibrate(PARROT_INTERP)
31 __attribute__nonnull__(1);
33 PARROT_CANNOT_RETURN_NULL
34 static const char * op_name(PARROT_INTERP, int k)
35 __attribute__nonnull__(1);
37 static void print_debug(PARROT_INTERP, SHIM(int status), SHIM(void *p))
38 __attribute__nonnull__(1);
40 static void print_profile(PARROT_INTERP, SHIM(int status), SHIM(void *p))
41 __attribute__nonnull__(1);
43 static int prof_sort_f(ARGIN(const void *a), ARGIN(const void *b))
44 __attribute__nonnull__(1)
45 __attribute__nonnull__(2);
47 PARROT_CANNOT_RETURN_NULL
48 static PMC* set_current_sub(PARROT_INTERP)
49 __attribute__nonnull__(1);
51 PARROT_CANNOT_RETURN_NULL
52 static PMC* setup_argv(PARROT_INTERP, int argc, ARGIN(char **argv))
53 __attribute__nonnull__(1)
54 __attribute__nonnull__(3);
56 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
57 /* HEADERIZER END: static */
59 extern int Parrot_exec_run;
63 =item C<Parrot_Interp Parrot_new>
65 Returns a new Parrot interpreter.
67 The first created interpreter (C<parent> is C<NULL>) is the last one
68 to get destroyed.
70 =cut
74 #ifdef JIT_CAPABLE
75 # if EXEC_CAPABLE
76 # include "parrot/exec.h"
77 # endif /* EXEC_CAPABLE */
78 # include "jit.h"
79 #endif
81 PARROT_API
82 PARROT_CANNOT_RETURN_NULL
83 Parrot_Interp
84 Parrot_new(ARGIN_NULLOK(Parrot_Interp parent))
86 /* inter_create.c:make_interpreter builds a new Parrot_Interp. */
87 return make_interpreter(parent, PARROT_NO_FLAGS);
90 extern void Parrot_initialize_core_pmcs(PARROT_INTERP);
95 =item C<void Parrot_init_stacktop>
97 Initializes the new interpreter when it hasn't been initialized before.
99 Additionally sets the stack top, so that Parrot objects created
100 in inner stack frames will be visible during DODs stack walking code.
101 B<stack_top> should be the address of an automatic variable in the caller's
102 stack frame. All unanchored Parrot objects (PMCs) must live in inner stack
103 frames so that they are not destroyed during DOD runs.
105 Use this function when you call into Parrot before entering a run loop.
107 =cut
111 PARROT_API
112 void
113 Parrot_init_stacktop(PARROT_INTERP, void *stack_top)
115 interp->lo_var_ptr = stack_top;
116 init_world_once(interp);
122 =item C<void Parrot_set_flag>
124 Sets on any of the following flags, specified by C<flag>, in the interpreter:
126 Flag Effect
127 C<PARROT_BOUNDS_FLAG> enable bounds checking
128 C<PARROT_PROFILE_FLAG> enable profiling,
129 C<PARROT_THR_TYPE_1> disable variable sharing and thread communication
130 C<PARROT_THR_TYPE_2> disable variable sharing but enable thread communication
131 C<PARROT_THR_TYPE_3> enable variable sharing.
133 =cut
137 PARROT_API
138 void
139 Parrot_set_flag(PARROT_INTERP, INTVAL flag)
141 /* These two macros (from interpreter.h) do exactly what they look like. */
143 Interp_flags_SET(interp, flag);
144 switch (flag) {
145 case PARROT_BOUNDS_FLAG:
146 case PARROT_PROFILE_FLAG:
147 Interp_core_SET(interp, PARROT_SLOW_CORE);
148 break;
149 default:
150 break;
157 =item C<void Parrot_set_debug>
159 Set a debug flag: C<PARROT_DEBUG_FLAG>.
161 =cut
165 PARROT_API
166 void
167 Parrot_set_debug(PARROT_INTERP, UINTVAL flag)
169 interp->debug_flags |= flag;
175 =item C<void Parrot_set_executable_name>
177 Sets the name of the executable launching Parrot (see C<pbc_to_exe> and the
178 C<parrot> binary).
180 =cut
184 PARROT_API
185 void
186 Parrot_set_executable_name(PARROT_INTERP, Parrot_Pointer name)
188 PMC * const name_pmc = pmc_new(interp, enum_class_String);
189 VTABLE_set_string_native(interp, name_pmc, (STRING *)name);
190 VTABLE_set_pmc_keyed_int(interp, interp->iglobals, IGLOBALS_EXECUTABLE,
191 name_pmc);
197 =item C<void Parrot_set_trace>
199 Set a trace flag: C<PARROT_TRACE_FLAG>
201 =cut
205 PARROT_API
206 void
207 Parrot_set_trace(PARROT_INTERP, UINTVAL flag)
209 CONTEXT(interp)->trace_flags |= flag;
210 Interp_core_SET(interp, PARROT_SLOW_CORE);
216 =item C<void Parrot_clear_flag>
218 Clears a flag in the interpreter.
220 =cut
224 PARROT_API
225 void
226 Parrot_clear_flag(PARROT_INTERP, INTVAL flag)
228 Interp_flags_CLEAR(interp, flag);
234 =item C<void Parrot_clear_debug>
236 Clears a flag in the interpreter.
238 =cut
242 PARROT_API
243 void
244 Parrot_clear_debug(PARROT_INTERP, UINTVAL flag)
246 interp->debug_flags &= ~flag;
252 =item C<void Parrot_clear_trace>
254 Clears a flag in the interpreter.
256 =cut
260 PARROT_API
261 void
262 Parrot_clear_trace(PARROT_INTERP, UINTVAL flag)
264 CONTEXT(interp)->trace_flags &= ~flag;
270 =item C<Parrot_Int Parrot_test_flag>
272 Test the interpreter flags specified in C<flag>.
274 =cut
278 PARROT_API
279 Parrot_Int
280 Parrot_test_flag(PARROT_INTERP, INTVAL flag)
282 return Interp_flags_TEST(interp, flag);
288 =item C<UINTVAL Parrot_test_debug>
290 Test the interpreter flags specified in C<flag>.
292 =cut
296 PARROT_API
297 UINTVAL
298 Parrot_test_debug(PARROT_INTERP, UINTVAL flag)
300 return interp->debug_flags & flag;
306 =item C<UINTVAL Parrot_test_trace>
308 Test the interpreter flags specified in C<flag>.
310 =cut
314 PARROT_API
315 UINTVAL
316 Parrot_test_trace(PARROT_INTERP, UINTVAL flag)
318 return CONTEXT(interp)->trace_flags & flag;
324 =item C<void Parrot_set_run_core>
326 Sets the specified run core.
328 =cut
332 PARROT_API
333 void
334 Parrot_set_run_core(PARROT_INTERP, Parrot_Run_core_t core)
336 Interp_core_SET(interp, core);
342 =item C<void Parrot_setwarnings>
344 Activates the given warnings.
346 =cut
350 PARROT_API
351 void
352 Parrot_setwarnings(PARROT_INTERP, Parrot_warnclass wc)
354 /* Activates the given warnings. (Macro from warnings.h.) */
355 PARROT_WARNINGS_on(interp, wc);
361 =item C<PackFile * Parrot_readbc>
363 Read in a bytecode, unpack it into a C<PackFile> structure, and do fixups.
365 =cut
369 PARROT_API
370 PARROT_CAN_RETURN_NULL
371 PackFile *
372 Parrot_readbc(PARROT_INTERP, ARGIN_NULLOK(const char *fullname))
374 FILE *io = NULL;
375 INTVAL is_mapped = 0;
376 char *program_code;
377 PackFile *pf;
378 INTVAL program_size;
380 #ifdef PARROT_HAS_HEADER_SYSMMAN
381 int fd = -1;
382 #endif
384 if (fullname == NULL || STREQ(fullname, "-")) {
385 /* read from STDIN */
386 io = stdin;
388 /* read 1k at a time */
389 program_size = 0;
391 else {
392 STRING * const fs = string_make(interp, fullname, strlen(fullname),
393 NULL, 0);
394 if (!Parrot_stat_info_intval(interp, fs, STAT_EXISTS)) {
395 PIO_eprintf(interp, "Parrot VM: Can't stat %s, code %i.\n",
396 fullname, errno);
397 return NULL;
400 /* RT #46153 check for regular file */
402 program_size = Parrot_stat_info_intval(interp, fs, STAT_FILESIZE);
404 #ifndef PARROT_HAS_HEADER_SYSMMAN
405 io = fopen(fullname, "rb");
407 if (!io) {
408 PIO_eprintf(interp, "Parrot VM: Can't open %s, code %i.\n",
409 fullname, errno);
410 return NULL;
412 #endif /* PARROT_HAS_HEADER_SYSMMAN */
415 #ifdef PARROT_HAS_HEADER_SYSMMAN
416 again:
417 #endif
418 /* if we've opened a file (or stdin) with PIO, read it in */
419 if (io) {
420 size_t chunk_size = program_size > 0 ? program_size : 1024;
421 INTVAL wanted = program_size;
422 char *cursor;
423 size_t read_result;
425 program_code = (char *)mem_sys_allocate(chunk_size);
426 program_size = 0;
427 cursor = (char *)program_code;
429 while ((read_result = fread(cursor, 1, chunk_size, io)) > 0) {
430 program_size += read_result;
431 if (program_size == wanted)
432 break;
433 chunk_size = 1024;
434 program_code =
435 (char *)mem_sys_realloc(program_code, program_size + chunk_size);
437 if (!program_code) {
438 PIO_eprintf(interp,
439 "Parrot VM: Could not reallocate buffer "
440 "while reading packfile from PIO.\n");
441 return NULL;
444 cursor = (char *)program_code + program_size;
447 if (ferror(io)) {
448 PIO_eprintf(interp, "Parrot VM: Problem reading packfile from PIO: code %d.\n",
449 ferror(io));
450 return NULL;
452 fclose(io);
454 else {
455 /* if we've gotten here, we opted not to use PIO to read the file.
456 * use mmap */
458 #ifdef PARROT_HAS_HEADER_SYSMMAN
460 /* check that fullname isn't NULL, just in case */
461 if (!fullname)
462 real_exception(interp, NULL, 1, "Trying to open a NULL filename");
464 fd = open(fullname, O_RDONLY | O_BINARY);
466 if (!fd) {
467 PIO_eprintf(interp, "Parrot VM: Can't open %s, code %i.\n",
468 fullname, errno);
469 return NULL;
472 program_code =
473 (char *)mmap(0, program_size, PROT_READ, MAP_SHARED, fd, (off_t)0);
475 if (program_code == (void *)MAP_FAILED) {
476 Parrot_warn(interp, PARROT_WARNINGS_IO_FLAG,
477 "Parrot VM: Can't mmap file %s, code %i.\n",
478 fullname, errno);
480 /* try again, now with IO reading the file */
481 io = fopen(fullname, "rb");
482 if (!io) {
483 PIO_eprintf(interp, "Parrot VM: Can't open %s, code %i.\n",
484 fullname, errno);
485 return NULL;
487 goto again;
489 is_mapped = 1;
491 #else /* PARROT_HAS_HEADER_SYSMMAN */
493 PIO_eprintf(interp, "Parrot VM: uncaught error occurred reading "
494 "file or mmap not available.\n");
495 return NULL;
497 #endif /* PARROT_HAS_HEADER_SYSMMAN */
501 /* Now that we have the bytecode, let's unpack it. */
503 pf = PackFile_new(interp, is_mapped);
505 if (!PackFile_unpack(interp, pf, (opcode_t *)program_code, program_size)) {
506 PIO_eprintf(interp, "Parrot VM: Can't unpack packfile %s.\n",
507 fullname);
508 return NULL;
511 /* Set :main routine */
512 do_sub_pragmas(interp, pf->cur_cs, PBC_PBC, NULL);
514 /* JITting and/or prederefing the sub/the bytecode is done
515 * in switch_to_cs before actual usage of the segment */
517 #ifdef PARROT_HAS_HEADER_SYSMMAN
518 /* the man page states that it's ok to close a mmaped file */
519 if (fd >= 0)
520 close(fd);
521 #else
522 /* RT #46155 Parrot_exec uses this
523 mem_sys_free(program_code); */
524 #endif
526 return pf;
532 =item C<void Parrot_loadbc>
534 Loads the C<PackFile> returned by C<Parrot_readbc()>.
536 =cut
540 PARROT_API
541 void
542 Parrot_loadbc(PARROT_INTERP, NOTNULL(PackFile *pf))
544 if (pf == NULL) {
545 PIO_eprintf(interp, "Invalid packfile\n");
546 return;
549 interp->initial_pf = pf;
550 interp->code = pf->cur_cs;
556 =item C<static PMC* setup_argv>
558 Creates and returns C<ARGS> array PMC.
560 =cut
564 PARROT_CANNOT_RETURN_NULL
565 static PMC*
566 setup_argv(PARROT_INTERP, int argc, ARGIN(char **argv))
568 INTVAL i;
569 PMC *userargv;
571 if (Interp_debug_TEST(interp, PARROT_START_DEBUG_FLAG)) {
572 PIO_eprintf(interp,
573 "*** Parrot VM: Setting up ARGV array. Current argc: %d ***\n",
574 argc);
577 userargv = pmc_new_noinit(interp, enum_class_ResizableStringArray);
579 /* immediately anchor pmc to root set */
580 VTABLE_set_pmc_keyed_int(interp, interp->iglobals,
581 (INTVAL)IGLOBALS_ARGV_LIST, userargv);
583 VTABLE_init(interp, userargv);
585 for (i = 0; i < argc; i++) {
586 /* Run through argv, adding everything to @ARGS. */
587 STRING * const arg =
588 string_make(interp, argv[i], strlen(argv[i]), NULL,
589 PObj_external_FLAG);
591 if (Interp_debug_TEST(interp, PARROT_START_DEBUG_FLAG))
592 PIO_eprintf(interp, "\t%vd: %s\n", i, argv[i]);
594 VTABLE_push_string(interp, userargv, arg);
597 return userargv;
603 =item C<static int prof_sort_f>
605 Sort function for profile data. Sorts by time.
607 =cut
611 static int
612 prof_sort_f(ARGIN(const void *a), ARGIN(const void *b))
614 const FLOATVAL timea = ((const ProfData *)a)->time;
615 const FLOATVAL timeb = ((const ProfData *)b)->time;
617 if (timea < timeb)
618 return 1;
620 if (timea > timeb)
621 return -1;
623 return 0;
629 =item C<static const char * op_name>
631 Returns the name of the opcode.
633 =cut
637 PARROT_CANNOT_RETURN_NULL
638 static const char *
639 op_name(PARROT_INTERP, int k)
641 switch (k) {
642 case PARROT_PROF_DOD_p1:
643 return "DOD_mark_root";
644 case PARROT_PROF_DOD_p2:
645 return "DOD_mark_next";
646 case PARROT_PROF_DOD_cp:
647 return "DOD_collect_PMC";
648 case PARROT_PROF_DOD_cb:
649 return "DOD_collect_buffers";
650 case PARROT_PROF_GC:
651 return "GC";
652 case PARROT_PROF_EXCEPTION:
653 return "EXCEPTION";
654 default:
655 break;
658 return interp->op_info_table[k - PARROT_PROF_EXTRA].full_name;
664 =item C<static FLOATVAL calibrate>
666 With this calibration, reported times of C<parrot -p> almost match those
667 measured with time C<parrot -b>.
669 =cut
673 static FLOATVAL
674 calibrate(PARROT_INTERP)
676 size_t count = 1000000;
677 size_t n = count;
678 opcode_t code[] = { 1 }; /* noop */
679 opcode_t *pc = code;
680 FLOATVAL start = Parrot_floatval_time();
681 FLOATVAL now = start;
683 /* op timing isn't free; it requires at least one time fetch per op */
684 for (; n; --n) {
685 pc = (interp->op_func_table[*code])(pc, interp);
686 now = Parrot_floatval_time();
689 return (now - start) / (FLOATVAL) count;
695 =item C<static void print_profile>
697 Prints out a profile listing.
699 =cut
703 static void
704 print_profile(PARROT_INTERP, SHIM(int status), SHIM(void *p))
706 RunProfile * const profile = interp->profile;
708 if (profile) {
709 UINTVAL j;
710 int k, jit;
711 UINTVAL op_count = 0;
712 UINTVAL call_count = 0;
713 FLOATVAL sum_time = 0.0;
714 const FLOATVAL empty = calibrate(interp);
716 PIO_printf(interp,
717 "Calibration: overhead = %.6f ms/op\n", 1000.0 * empty);
719 PIO_printf(interp,
720 " Code J Name "
721 "Calls Total/s Avg/ms\n");
723 for (j = 0; j < interp->op_count + PARROT_PROF_EXTRA; j++) {
724 const UINTVAL n = profile->data[j].numcalls;
725 profile->data[j].op = j;
727 if (j >= PARROT_PROF_EXTRA) {
728 profile->data[j].time -= empty * n;
730 /* faster than noop */
731 if (profile->data[j].time < 0.0)
732 profile->data[j].time = 0.0;
736 qsort(profile->data, interp->op_count + PARROT_PROF_EXTRA,
737 sizeof (ProfData), prof_sort_f);
739 for (j = 0; j < interp->op_count + PARROT_PROF_EXTRA; j++) {
740 const UINTVAL n = profile->data[j].numcalls;
742 if (n > 0) {
743 const FLOATVAL t = profile->data[j].time;
745 op_count++;
746 call_count += n;
747 sum_time += t;
749 k = profile->data[j].op;
750 jit = '-';
751 #if JIT_CAPABLE
752 if (k >= PARROT_PROF_EXTRA &&
753 op_jit[k - PARROT_PROF_EXTRA].extcall != 1)
754 jit = 'j';
755 #endif
756 PIO_printf(interp, " %4d %c %-25s %8vu %10vf %10.6vf\n",
757 k - PARROT_PROF_EXTRA,
758 jit,
759 op_name(interp, k),
762 (FLOATVAL)(t * 1000.0 / (FLOATVAL)n));
766 PIO_printf(interp, " %4vu - %-25s %8vu %10vf %10.6vf\n",
767 op_count,
768 "-",
769 call_count,
770 sum_time,
771 (FLOATVAL)(sum_time * 1000.0 / (FLOATVAL)call_count));
778 =item C<static void print_debug>
780 Prints GC info.
782 =cut
786 static void
787 print_debug(PARROT_INTERP, SHIM(int status), SHIM(void *p))
789 if (Interp_debug_TEST(interp, PARROT_MEM_STAT_DEBUG_FLAG)) {
790 /* Give souls brave enough to activate debugging an earful about GC. */
792 PIO_eprintf(interp, "*** Parrot VM: Dumping GC info ***\n");
793 PDB_info(interp);
800 =item C<static PMC* set_current_sub>
802 Search the fixup table for a PMC matching the argument. On a match,
803 set up the appropriate context.
805 If no match, set up a dummy PMC entry. In either case, return a
806 pointer to the PMC.
808 =cut
812 PARROT_CANNOT_RETURN_NULL
813 static PMC*
814 set_current_sub(PARROT_INTERP)
816 opcode_t i;
817 PMC *sub_pmc;
819 PackFile_ByteCode * const cur_cs = interp->code;
820 PackFile_FixupTable * const ft = cur_cs->fixups;
821 PackFile_ConstTable * const ct = cur_cs->const_table;
824 * Walk the fixup table. The first Sub-like entry should be our
825 * entry point with the address at our resume_offset.
828 for (i = 0; i < ft->fixup_count; i++) {
829 if (ft->fixups[i]->type == enum_fixup_sub) {
830 const opcode_t ci = ft->fixups[i]->offset;
831 PMC *sub_pmc = ct->constants[ci]->u.key;
832 Parrot_sub *sub = PMC_sub(sub_pmc);
834 if (sub->seg == cur_cs) {
835 const size_t offs = sub->start_offs;
837 if (offs == interp->resume_offset) {
838 CONTEXT(interp)->current_sub = sub_pmc;
839 CONTEXT(interp)->current_HLL = sub->HLL_id;
840 return sub_pmc;
843 break;
848 /* if we didn't find anything put a dummy PMC into current_sub */
850 sub_pmc = pmc_new(interp, enum_class_Sub);
851 PMC_sub(sub_pmc)->start_offs = 0;
852 CONTEXT(interp)->current_sub = sub_pmc;
854 return sub_pmc;
860 =item C<void Parrot_runcode>
862 Sets up C<ARGV> and runs the ops.
864 =cut
868 PARROT_API
869 void
870 Parrot_runcode(PARROT_INTERP, int argc, ARGIN(char **argv))
872 PMC *userargv, *main_sub;
874 if (Interp_debug_TEST(interp, PARROT_START_DEBUG_FLAG))
875 PIO_eprintf(interp,
876 "*** Parrot VM: Setting stack top. ***\n");
878 /* Debugging mode nonsense. */
879 if (Interp_debug_TEST(interp, PARROT_START_DEBUG_FLAG)) {
880 if (Interp_flags_TEST(interp, PARROT_BOUNDS_FLAG)) {
881 PIO_eprintf(interp,
882 "*** Parrot VM: Bounds checking enabled. ***\n");
885 if (Interp_trace_TEST(interp, PARROT_TRACE_OPS_FLAG))
886 PIO_eprintf(interp, "*** Parrot VM: Tracing enabled. ***\n");
888 PIO_eprintf(interp, "*** Parrot VM: ");
890 switch (interp->run_core) {
891 case PARROT_SLOW_CORE:
892 PIO_eprintf(interp, "Slow core");
893 break;
894 case PARROT_FAST_CORE:
895 PIO_eprintf(interp, "Fast core");
896 break;
897 case PARROT_SWITCH_CORE:
898 case PARROT_SWITCH_JIT_CORE:
899 PIO_eprintf(interp, "Switch core");
900 break;
901 case PARROT_CGP_CORE:
902 case PARROT_CGP_JIT_CORE:
903 PIO_eprintf(interp, "CGP core");
904 break;
905 case PARROT_CGOTO_CORE:
906 PIO_eprintf(interp, "CGoto core");
907 break;
908 case PARROT_JIT_CORE:
909 PIO_eprintf(interp, "JIT core");
910 break;
911 case PARROT_EXEC_CORE:
912 PIO_eprintf(interp, "EXEC core");
913 break;
914 default:
915 real_exception(interp, NULL, 1, "Unknown run core");
918 PIO_eprintf(interp, " ***\n");
921 /* Set up @ARGS (or whatever this language calls it) in userargv. */
922 userargv = setup_argv(interp, argc, argv);
924 #if EXEC_CAPABLE
926 /* s. runops_exec interpreter.c */
927 if (Interp_core_TEST(interp, PARROT_EXEC_CORE))
928 Parrot_exec_run = 1;
930 #endif
933 * If any profile information was gathered, print it out
934 * before exiting, then print debug infos if turned on.
936 Parrot_on_exit(interp, print_debug, NULL);
937 Parrot_on_exit(interp, print_profile, NULL);
939 /* Let's kick the tires and light the fires--call interpreter.c:runops. */
940 main_sub = CONTEXT(interp)->current_sub;
942 /* if no sub was marked being :main, we create a dummy sub with offset 0 */
944 if (!main_sub)
945 main_sub = set_current_sub(interp);
947 CONTEXT(interp)->current_sub = NULL;
948 CONTEXT(interp)->constants = interp->code->const_table->constants;
950 Parrot_runops_fromc_args(interp, main_sub, "vP", userargv);
956 =item C<opcode_t * Parrot_debug>
958 Runs the interpreter's bytecode in debugging mode.
960 =cut
964 PARROT_API
965 PARROT_CAN_RETURN_NULL
966 opcode_t *
967 Parrot_debug(NOTNULL(Parrot_Interp debugger), opcode_t * pc)
969 const char *command;
970 Interp *interp;
971 PDB_t * const pdb = debugger->pdb;
973 pdb->cur_opcode = pc;
975 PDB_init(debugger, NULL);
977 /* disassemble needs this for now */
978 interp = pdb->debugee;
979 interp->pdb = pdb;
980 debugger->lo_var_ptr = interp->lo_var_ptr;
982 PDB_disassemble(interp, NULL);
984 while (!(pdb->state & PDB_EXIT)) {
985 PDB_get_command(debugger);
986 command = pdb->cur_command;
987 PDB_run_command(debugger, command);
990 return NULL;
996 =item C<void Parrot_disassemble>
998 Disassembles and prints out the interpreter's bytecode.
1000 This is used by the Parrot disassembler.
1002 =cut
1006 PARROT_API
1007 void
1008 Parrot_disassemble(PARROT_INTERP)
1010 PDB_line_t *line;
1011 PDB_t *pdb = mem_allocate_zeroed_typed(PDB_t);
1012 int num_mappings = 0;
1013 int curr_mapping = 0;
1014 int op_code_seq_num = 0;
1015 int debugs;
1017 interp->pdb = pdb;
1018 pdb->cur_opcode = interp->code->base.data;
1020 PDB_disassemble(interp, NULL);
1022 line = pdb->file->line;
1023 debugs = (interp->code->debugs != NULL);
1025 PIO_printf(interp, "%12s-%12s", "Seq_Op_Num", "Relative-PC");
1027 if (debugs) {
1028 PIO_printf(interp, " %6s:\n", "SrcLn#");
1029 num_mappings = interp->code->debugs->num_mappings;
1031 else {
1032 PIO_printf(interp, "\n");
1035 while (line->next) {
1036 const char *c;
1038 /* PIO_printf(interp, "%i < %i %i == %i \n", curr_mapping,
1039 * num_mappings, op_code_seq_num,
1040 * interp->code->debugs->mappings[curr_mapping]->offset); */
1042 if (debugs && curr_mapping < num_mappings) {
1043 if (op_code_seq_num == interp->code->debugs->mappings[curr_mapping]->offset) {
1044 const int filename_const_offset =
1045 interp->code->debugs->mappings[curr_mapping]->u.filename;
1046 PIO_printf(interp, "Current Source Filename %Ss\n",
1047 interp->code->const_table->constants[filename_const_offset]->u.string);
1048 curr_mapping++;
1052 PIO_printf(interp, "%012i-%012i", op_code_seq_num, line->opcode - interp->code->base.data);
1054 if (debugs)
1055 PIO_printf(interp, " %06i: ", interp->code->debugs->base.data[op_code_seq_num]);
1057 /* If it has a label print it */
1058 if (line->label)
1059 PIO_printf(interp, "L%li:\t", line->label->number);
1060 else
1061 PIO_printf(interp, "\t");
1063 c = pdb->file->source + line->source_offset;
1065 while (c && *c != '\n')
1066 PIO_printf(interp, "%c", *(c++));
1068 PIO_printf(interp, "\n");
1069 line = line->next;
1070 op_code_seq_num++;
1073 return;
1079 =item C<void Parrot_run_native>
1081 Run the C function C<func> through the program C<[enternative, end]>.
1082 This ensures that the function is run with the same setup as in other
1083 run loops.
1085 This function is used in some of the source tests in F<t/src> which use
1086 the interpreter outside a runloop.
1088 =cut
1092 PARROT_API
1093 void
1094 Parrot_run_native(PARROT_INTERP, native_func_t func)
1096 PackFile *pf = PackFile_new(interp, 0);
1097 static opcode_t program_code[2];
1099 program_code[0] = interp->op_lib->op_code("enternative", 0);
1100 program_code[1] = 0; /* end */
1102 pf->cur_cs = (PackFile_ByteCode *)
1103 (pf->PackFuncs[PF_BYTEC_SEG].new_seg)(interp, pf, "code", 1);
1104 pf->cur_cs->base.data = program_code;
1105 pf->cur_cs->base.size = 2;
1107 Parrot_loadbc(interp, pf);
1109 run_native = func;
1111 if (interp->code && interp->code->const_table)
1112 CONTEXT(interp)->constants = interp->code->const_table->constants;
1114 runops(interp, interp->resume_offset);
1119 =back
1121 =head1 SEE ALSO
1123 F<include/parrot/embed.h> and F<docs/embed.pod>.
1125 =head1 HISTORY
1127 Initial version by Brent Dax on 2002.1.28.
1129 =cut
1134 * Local variables:
1135 * c-file-style: "parrot"
1136 * End:
1137 * vim: expandtab shiftwidth=4: