2 Copyright (C) 2001-2008, The Perl Foundation.
7 src/embed.c - The Parrot embedding interface
11 This file implements the Parrot embedding interface.
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 */
29 static FLOATVAL
calibrate(PARROT_INTERP
)
30 __attribute__nonnull__(1);
32 PARROT_CANNOT_RETURN_NULL
33 static const char * op_name(PARROT_INTERP
, int k
)
34 __attribute__nonnull__(1);
36 static void print_debug(PARROT_INTERP
, SHIM(int status
), SHIM(void *p
))
37 __attribute__nonnull__(1);
39 static void print_profile(PARROT_INTERP
, SHIM(int status
), SHIM(void *p
))
40 __attribute__nonnull__(1);
42 static int prof_sort_f(ARGIN(const void *a
), ARGIN(const void *b
))
43 __attribute__nonnull__(1)
44 __attribute__nonnull__(2);
46 PARROT_CANNOT_RETURN_NULL
47 static PMC
* set_current_sub(PARROT_INTERP
)
48 __attribute__nonnull__(1);
50 PARROT_CANNOT_RETURN_NULL
51 static PMC
* setup_argv(PARROT_INTERP
, int argc
, ARGIN(const char **argv
))
52 __attribute__nonnull__(1)
53 __attribute__nonnull__(3);
55 /* HEADERIZER END: static */
57 extern int Parrot_exec_run
;
61 =item C<Parrot_Interp Parrot_new>
63 Returns a new Parrot interpreter.
65 The first created interpreter (C<parent> is C<NULL>) is the last one
74 # include "parrot/exec.h"
75 # endif /* EXEC_CAPABLE */
80 PARROT_CANNOT_RETURN_NULL
82 Parrot_new(ARGIN_NULLOK(Parrot_Interp parent
))
84 /* inter_create.c:make_interpreter builds a new Parrot_Interp. */
85 return make_interpreter(parent
, PARROT_NO_FLAGS
);
88 extern void Parrot_initialize_core_pmcs(PARROT_INTERP
);
92 =item C<void Parrot_init_stacktop>
94 Initializes the new interpreter when it hasn't been initialized before.
96 Additionally sets the stack top, so that Parrot objects created
97 in inner stack frames will be visible during DODs stack walking code.
98 B<stack_top> should be the address of an automatic variable in the caller's
99 stack frame. All unanchored Parrot objects (PMCs) must live in inner stack
100 frames so that they are not destroyed during DOD runs.
102 Use this function when you call into Parrot before entering a run loop.
110 Parrot_init_stacktop(PARROT_INTERP
, void *stack_top
)
112 interp
->lo_var_ptr
= stack_top
;
113 init_world_once(interp
);
118 =item C<void Parrot_set_flag>
120 Sets on any of the following flags, specified by C<flag>, in the interpreter:
123 C<PARROT_BOUNDS_FLAG> enable bounds checking
124 C<PARROT_PROFILE_FLAG> enable profiling,
125 C<PARROT_THR_TYPE_1> disable variable sharing and thread communication
126 C<PARROT_THR_TYPE_2> disable variable sharing but enable thread communication
127 C<PARROT_THR_TYPE_3> enable variable sharing.
135 Parrot_set_flag(PARROT_INTERP
, INTVAL flag
)
137 /* These two macros (from interpreter.h) do exactly what they look like. */
139 Interp_flags_SET(interp
, flag
);
141 case PARROT_BOUNDS_FLAG
:
142 case PARROT_PROFILE_FLAG
:
143 Interp_core_SET(interp
, PARROT_SLOW_CORE
);
152 =item C<void Parrot_set_debug>
154 Set a debug flag: C<PARROT_DEBUG_FLAG>.
162 Parrot_set_debug(PARROT_INTERP
, UINTVAL flag
)
164 interp
->debug_flags
|= flag
;
169 =item C<void Parrot_set_executable_name>
171 Sets the name of the executable launching Parrot (see C<pbc_to_exe> and the
180 Parrot_set_executable_name(PARROT_INTERP
, Parrot_Pointer name
)
182 PMC
* const name_pmc
= pmc_new(interp
, enum_class_String
);
183 VTABLE_set_string_native(interp
, name_pmc
, (STRING
*)name
);
184 VTABLE_set_pmc_keyed_int(interp
, interp
->iglobals
, IGLOBALS_EXECUTABLE
,
190 =item C<void Parrot_set_trace>
192 Set a trace flag: C<PARROT_TRACE_FLAG>
200 Parrot_set_trace(PARROT_INTERP
, UINTVAL flag
)
202 CONTEXT(interp
->ctx
)->trace_flags
|= flag
;
203 Interp_core_SET(interp
, PARROT_SLOW_CORE
);
208 =item C<void Parrot_clear_flag>
210 Clears a flag in the interpreter.
218 Parrot_clear_flag(PARROT_INTERP
, INTVAL flag
)
220 Interp_flags_CLEAR(interp
, flag
);
225 =item C<void Parrot_clear_debug>
227 Clears a flag in the interpreter.
235 Parrot_clear_debug(PARROT_INTERP
, UINTVAL flag
)
237 interp
->debug_flags
&= ~flag
;
242 =item C<void Parrot_clear_trace>
244 Clears a flag in the interpreter.
252 Parrot_clear_trace(PARROT_INTERP
, UINTVAL flag
)
254 CONTEXT(interp
->ctx
)->trace_flags
&= ~flag
;
259 =item C<Parrot_Int Parrot_test_flag>
261 Test the interpreter flags specified in C<flag>.
269 Parrot_test_flag(PARROT_INTERP
, INTVAL flag
)
271 return Interp_flags_TEST(interp
, flag
);
276 =item C<UINTVAL Parrot_test_debug>
278 Test the interpreter flags specified in C<flag>.
286 Parrot_test_debug(PARROT_INTERP
, UINTVAL flag
)
288 return interp
->debug_flags
& flag
;
293 =item C<UINTVAL Parrot_test_trace>
295 Test the interpreter flags specified in C<flag>.
303 Parrot_test_trace(PARROT_INTERP
, UINTVAL flag
)
305 return CONTEXT(interp
->ctx
)->trace_flags
& flag
;
310 =item C<void Parrot_set_run_core>
312 Sets the specified run core.
320 Parrot_set_run_core(PARROT_INTERP
, Parrot_Run_core_t core
)
322 Interp_core_SET(interp
, core
);
327 =item C<void Parrot_setwarnings>
329 Activates the given warnings.
337 Parrot_setwarnings(PARROT_INTERP
, Parrot_warnclass wc
)
339 /* Activates the given warnings. (Macro from warnings.h.) */
340 PARROT_WARNINGS_on(interp
, wc
);
345 =item C<PackFile * Parrot_readbc>
347 Read in a bytecode, unpack it into a C<PackFile> structure, and do fixups.
354 PARROT_CAN_RETURN_NULL
356 Parrot_readbc(PARROT_INTERP
, ARGIN_NULLOK(const char *fullname
))
362 INTVAL is_mapped
= 0;
363 #ifdef PARROT_HAS_HEADER_SYSMMAN
367 if (fullname
== NULL
|| STREQ(fullname
, "-")) {
368 /* read from STDIN */
370 /* read 1k at a time */
374 STRING
* const fs
= string_make(interp
, fullname
,
375 strlen(fullname
), NULL
, 0);
376 if (!Parrot_stat_info_intval(interp
, fs
, STAT_EXISTS
)) {
377 PIO_eprintf(interp
, "Parrot VM: Can't stat %s, code %i.\n",
382 * RT#46153 check for regular file
385 program_size
= Parrot_stat_info_intval(interp
, fs
, STAT_FILESIZE
);
387 #ifndef PARROT_HAS_HEADER_SYSMMAN
388 io
= fopen(fullname
, "rb");
390 PIO_eprintf(interp
, "Parrot VM: Can't open %s, code %i.\n",
394 #endif /* PARROT_HAS_HEADER_SYSMMAN */
397 #ifdef PARROT_HAS_HEADER_SYSMMAN
400 /* if we've opened a file (or stdin) with PIO, read it in */
407 chunk_size
= program_size
> 0 ? program_size
: 1024;
408 program_code
= (char *)mem_sys_allocate(chunk_size
);
409 wanted
= program_size
;
411 cursor
= (char *)program_code
;
413 while ((read_result
= fread(cursor
, 1, chunk_size
, io
)) > 0) {
414 program_size
+= read_result
;
415 if (program_size
== wanted
)
419 (char *)mem_sys_realloc(program_code
, program_size
+ chunk_size
);
423 "Parrot VM: Could not reallocate buffer "
424 "while reading packfile from PIO.\n");
428 cursor
= (char *)program_code
+ program_size
;
431 if (read_result
< 0) {
433 "Parrot VM: Problem reading packfile from PIO.\n");
439 /* if we've gotten here, we opted not to use PIO to read the file.
442 #ifdef PARROT_HAS_HEADER_SYSMMAN
444 /* check that fullname isn't NULL, just in case */
446 real_exception(interp
, NULL
, 1,
447 "About to try and open a NULL filename");
450 fd
= open(fullname
, O_RDONLY
| O_BINARY
);
452 PIO_eprintf(interp
, "Parrot VM: Can't open %s, code %i.\n",
458 (char *)mmap(0, program_size
, PROT_READ
, MAP_SHARED
, fd
, (off_t
)0);
460 if (program_code
== (void *)MAP_FAILED
) {
461 Parrot_warn(interp
, PARROT_WARNINGS_IO_FLAG
,
462 "Parrot VM: Can't mmap file %s, code %i.\n",
464 /* try again, now with IO reading the file */
465 io
= fopen(fullname
, "rb");
468 "Parrot VM: Can't open %s, code %i.\n",
476 #else /* PARROT_HAS_HEADER_SYSMMAN */
478 PIO_eprintf(interp
, "Parrot VM: uncaught error occurred reading "
479 "file or mmap not available.\n");
482 #endif /* PARROT_HAS_HEADER_SYSMMAN */
486 /* Now that we have the bytecode, let's unpack it. */
488 pf
= PackFile_new(interp
, is_mapped
);
490 if (!PackFile_unpack(interp
, pf
, (opcode_t
*)program_code
, program_size
)) {
491 PIO_eprintf(interp
, "Parrot VM: Can't unpack packfile %s.\n",
499 do_sub_pragmas(interp
, pf
->cur_cs
, PBC_PBC
, NULL
);
501 * JITting and/or prederefing the sub/the bytecode is done
502 * in switch_to_cs before actual usage of the segment
505 #ifdef PARROT_HAS_HEADER_SYSMMAN
507 close(fd
); /* the man page states, it's ok to close a mmaped file */
510 /* RT#46155 Parrot_exec uses this
511 mem_sys_free(program_code); */
519 =item C<void Parrot_loadbc>
521 Loads the C<PackFile> returned by C<Parrot_readbc()>.
529 Parrot_loadbc(PARROT_INTERP
, NOTNULL(PackFile
*pf
))
532 PIO_eprintf(interp
, "Invalid packfile\n");
535 interp
->initial_pf
= pf
;
536 interp
->code
= pf
->cur_cs
;
541 =item C<static PMC* setup_argv>
543 Creates and returns C<ARGS> array PMC.
549 PARROT_CANNOT_RETURN_NULL
551 setup_argv(PARROT_INTERP
, int argc
, ARGIN(const char **argv
))
556 if (Interp_debug_TEST(interp
, PARROT_START_DEBUG_FLAG
)) {
558 "*** Parrot VM: Setting up ARGV array."
559 " Current argc: %d ***\n",
563 userargv
= pmc_new_noinit(interp
, enum_class_ResizableStringArray
);
564 /* immediately anchor pmc to root set */
565 VTABLE_set_pmc_keyed_int(interp
, interp
->iglobals
,
566 (INTVAL
)IGLOBALS_ARGV_LIST
, userargv
);
567 VTABLE_init(interp
, userargv
);
569 for (i
= 0; i
< argc
; i
++) {
570 /* Run through argv, adding everything to @ARGS. */
572 string_make(interp
, argv
[i
], strlen(argv
[i
]), NULL
, PObj_external_FLAG
);
574 if (Interp_debug_TEST(interp
, PARROT_START_DEBUG_FLAG
)) {
575 PIO_eprintf(interp
, "\t%vd: %s\n", i
, argv
[i
]);
578 VTABLE_push_string(interp
, userargv
, arg
);
585 =item C<static int prof_sort_f>
587 Sort function for profile data. Sorts by time.
594 prof_sort_f(ARGIN(const void *a
), ARGIN(const void *b
))
596 const FLOATVAL timea
= ((const ProfData
*)a
)->time
;
597 const FLOATVAL timeb
= ((const ProfData
*)b
)->time
;
608 =item C<static const char * op_name>
610 Returns the name of the opcode.
616 PARROT_CANNOT_RETURN_NULL
618 op_name(PARROT_INTERP
, int k
)
621 case PARROT_PROF_DOD_p1
:
622 return "DOD_mark_root";
623 case PARROT_PROF_DOD_p2
:
624 return "DOD_mark_next";
625 case PARROT_PROF_DOD_cp
:
626 return "DOD_collect_PMC";
627 case PARROT_PROF_DOD_cb
:
628 return "DOD_collect_buffers";
631 case PARROT_PROF_EXCEPTION
:
636 return interp
->op_info_table
[k
- PARROT_PROF_EXTRA
].full_name
;
641 =item C<static FLOATVAL calibrate>
643 With this calibration, reported times of C<parrot -p> almost match those
644 measured with time C<parrot -b>.
651 calibrate(PARROT_INTERP
)
653 size_t n
= interp
->op_count
;
655 FLOATVAL start
, empty
;
656 opcode_t code
[] = { 1 }; /* noop */
659 if (n
< 1000000) /* minimum opcode count for calibration */
661 start
= Parrot_floatval_time();
662 for (empty
= 0.0, i
= 0; i
< n
; i
++)
663 pc
= (interp
->op_func_table
[*code
])(pc
, interp
);
664 empty
+= Parrot_floatval_time() - start
;
665 return empty
/ (FLOATVAL
)n
;
670 =item C<static void print_profile>
672 Prints out a profile listing.
679 print_profile(PARROT_INTERP
, SHIM(int status
), SHIM(void *p
))
681 RunProfile
* const profile
= interp
->profile
;
687 UINTVAL op_count
= 0;
688 UINTVAL call_count
= 0;
689 FLOATVAL sum_time
= 0.0;
690 const FLOATVAL empty
= calibrate(interp
);
694 "Calls Total/s Avg/ms\n");
695 for (j
= 0; j
< interp
->op_count
+ PARROT_PROF_EXTRA
; j
++) {
696 const UINTVAL n
= profile
->data
[j
].numcalls
;
697 profile
->data
[j
].op
= j
;
698 if (j
>= PARROT_PROF_EXTRA
) {
699 profile
->data
[j
].time
-= empty
* n
;
700 if (profile
->data
[j
].time
< 0.0) /* faster than noop */
701 profile
->data
[j
].time
= 0.0;
704 qsort(profile
->data
, interp
->op_count
+
706 sizeof (ProfData
), prof_sort_f
);
707 for (j
= 0; j
< interp
->op_count
+ PARROT_PROF_EXTRA
; j
++) {
708 const UINTVAL n
= profile
->data
[j
].numcalls
;
711 const FLOATVAL t
= profile
->data
[j
].time
;
717 k
= profile
->data
[j
].op
;
720 if (k
>= PARROT_PROF_EXTRA
&&
721 op_jit
[k
- PARROT_PROF_EXTRA
].extcall
!= 1)
724 PIO_printf(interp
, " %4d %c %-25s %8vu %10vf %10.6vf\n",
725 k
- PARROT_PROF_EXTRA
,
730 (FLOATVAL
)(t
* 1000.0 / (FLOATVAL
)n
));
734 PIO_printf(interp
, " %4vu - %-25s %8vu %10vf %10.6vf\n",
739 (FLOATVAL
)(sum_time
* 1000.0 / (FLOATVAL
)call_count
));
745 =item C<static void print_debug>
754 print_debug(PARROT_INTERP
, SHIM(int status
), SHIM(void *p
))
756 if (Interp_debug_TEST(interp
, PARROT_MEM_STAT_DEBUG_FLAG
)) {
757 /* Give the souls brave enough to activate debugging an earful
760 PIO_eprintf(interp
, "*** Parrot VM: Dumping GC info ***\n");
767 =item C<static PMC* set_current_sub>
769 Search the fixup table for a PMC matching the argument. On a match,
770 set up the appropriate context.
772 If no match, set up a dummy PMC entry. In either case, return a
779 PARROT_CANNOT_RETURN_NULL
781 set_current_sub(PARROT_INTERP
)
786 PackFile_ByteCode
* const cur_cs
= interp
->code
;
787 PackFile_FixupTable
* const ft
= cur_cs
->fixups
;
788 PackFile_ConstTable
* const ct
= cur_cs
->const_table
;
791 * Walk the fixup table. The first Sub-like entry should be our
792 * entry point with the address at our resume_offset.
795 for (i
= 0; i
< ft
->fixup_count
; i
++) {
796 if (ft
->fixups
[i
]->type
== enum_fixup_sub
) {
797 const opcode_t ci
= ft
->fixups
[i
]->offset
;
800 sub_pmc
= ct
->constants
[ci
]->u
.key
;
801 sub
= PMC_sub(sub_pmc
);
802 if (sub
->seg
== cur_cs
) {
803 const size_t offs
= sub
->start_offs
;
804 if (offs
== interp
->resume_offset
) {
805 CONTEXT(interp
->ctx
)->current_sub
= sub_pmc
;
806 CONTEXT(interp
->ctx
)->current_HLL
= sub
->HLL_id
;
814 * if we didn't find anything put a dummy PMC into current_sub
816 sub_pmc
= pmc_new(interp
, enum_class_Sub
);
817 PMC_sub(sub_pmc
)->start_offs
= 0;
818 CONTEXT(interp
->ctx
)->current_sub
= sub_pmc
;
824 =item C<void Parrot_runcode>
826 Sets up C<ARGV> and runs the ops.
834 Parrot_runcode(PARROT_INTERP
, int argc
, ARGIN(const char **argv
))
836 PMC
*userargv
, *main_sub
;
838 if (Interp_debug_TEST(interp
, PARROT_START_DEBUG_FLAG
)) {
840 "*** Parrot VM: Setting stack top. ***\n");
842 /* Debugging mode nonsense. */
843 if (Interp_debug_TEST(interp
, PARROT_START_DEBUG_FLAG
)) {
844 if (Interp_flags_TEST(interp
, PARROT_BOUNDS_FLAG
)) {
846 "*** Parrot VM: Bounds checking enabled. ***\n");
848 if (Interp_trace_TEST(interp
, PARROT_TRACE_OPS_FLAG
)) {
849 PIO_eprintf(interp
, "*** Parrot VM: Tracing enabled. ***\n");
851 PIO_eprintf(interp
, "*** Parrot VM: ");
852 switch (interp
->run_core
) {
853 case PARROT_SLOW_CORE
:
854 PIO_eprintf(interp
, "Slow core");
856 case PARROT_FAST_CORE
:
857 PIO_eprintf(interp
, "Fast core");
859 case PARROT_SWITCH_CORE
:
860 case PARROT_SWITCH_JIT_CORE
:
861 PIO_eprintf(interp
, "Switch core");
863 case PARROT_CGP_CORE
:
864 case PARROT_CGP_JIT_CORE
:
865 PIO_eprintf(interp
, "CGP core");
867 case PARROT_CGOTO_CORE
:
868 PIO_eprintf(interp
, "CGoto core");
870 case PARROT_JIT_CORE
:
871 PIO_eprintf(interp
, "JIT core");
873 case PARROT_EXEC_CORE
:
874 PIO_eprintf(interp
, "EXEC core");
877 real_exception(interp
, NULL
, 1, "Unknown run core");
879 PIO_eprintf(interp
, " ***\n");
882 /* Set up @ARGS (or whatever this language calls it) in userargv. */
883 userargv
= setup_argv(interp
, argc
, argv
);
887 /* s. runops_exec interpreter.c */
888 if (Interp_core_TEST(interp
, PARROT_EXEC_CORE
)) {
895 * If any profile information was gathered, print it out
896 * before exiting, then print debug infos if turned on.
898 Parrot_on_exit(interp
, print_debug
, NULL
);
899 Parrot_on_exit(interp
, print_profile
, NULL
);
901 /* Let's kick the tires and light the fires--call interpreter.c:runops. */
902 main_sub
= CONTEXT(interp
->ctx
)->current_sub
;
904 * if no sub was marked being :main, we create a dummy sub with offset 0
907 main_sub
= set_current_sub(interp
);
909 CONTEXT(interp
->ctx
)->current_sub
= NULL
;
910 CONTEXT(interp
->ctx
)->constants
=
911 interp
->code
->const_table
->constants
;
912 Parrot_runops_fromc_args(interp
, main_sub
, "vP", userargv
);
918 =item C<opcode_t * Parrot_debug>
920 Runs the interpreter's bytecode in debugging mode.
927 PARROT_CAN_RETURN_NULL
929 Parrot_debug(NOTNULL(Parrot_Interp debugger
), opcode_t
* pc
)
934 PDB_t
* const pdb
= debugger
->pdb
;
936 pdb
->cur_opcode
= pc
;
938 PDB_init(debugger
, NULL
);
939 /* disassemble needs this for now */
940 interp
= pdb
->debugee
;
942 debugger
->lo_var_ptr
= interp
->lo_var_ptr
;
944 PDB_disassemble(interp
, NULL
);
946 while (!(pdb
->state
& PDB_EXIT
)) {
947 PDB_get_command(debugger
);
948 command
= pdb
->cur_command
;
949 PDB_run_command(debugger
, command
);
956 =item C<void Parrot_disassemble>
958 Disassembles and prints out the interpreter's bytecode.
960 This is used by the Parrot disassembler.
968 Parrot_disassemble(PARROT_INTERP
)
970 PDB_t
*pdb
= mem_allocate_zeroed_typed(PDB_t
);
973 int num_mappings
= 0;
974 int curr_mapping
= 0;
975 int op_code_seq_num
= 0;
978 pdb
->cur_opcode
= interp
->code
->base
.data
;
980 PDB_disassemble(interp
, NULL
);
982 line
= pdb
->file
->line
;
983 debugs
= (interp
->code
->debugs
!= NULL
);
985 PIO_printf(interp
, "%12s-%12s", "Seq_Op_Num", "Relative-PC");
988 PIO_printf(interp
, " %6s:\n", "SrcLn#");
989 num_mappings
= interp
->code
->debugs
->num_mappings
;
992 PIO_printf(interp
, "\n");
998 /* PIO_printf(interp, "%i < %i %i == %i \n", curr_mapping,
999 * num_mappings, op_code_seq_num,
1000 * interp->code->debugs->mappings[curr_mapping]->offset); */
1002 if (debugs
&& curr_mapping
< num_mappings
) {
1003 if (op_code_seq_num
== interp
->code
->debugs
->mappings
[curr_mapping
]->offset
) {
1004 const int filename_const_offset
=
1005 interp
->code
->debugs
->mappings
[curr_mapping
]->u
.filename
;
1006 PIO_printf(interp
, "Current Source Filename %Ss\n",
1007 interp
->code
->const_table
->constants
[filename_const_offset
]->u
.string
);
1012 PIO_printf(interp
, "%012i-%012i", op_code_seq_num
, line
->opcode
- interp
->code
->base
.data
);
1015 PIO_printf(interp
, " %06i: ", interp
->code
->debugs
->base
.data
[op_code_seq_num
]);
1017 /* If it has a label print it */
1019 PIO_printf(interp
, "L%li:\t", line
->label
->number
);
1021 PIO_printf(interp
, "\t");
1023 c
= pdb
->file
->source
+ line
->source_offset
;
1025 while (c
&& *c
!= '\n')
1026 PIO_printf(interp
, "%c", *(c
++));
1028 PIO_printf(interp
, "\n");
1038 =item C<void Parrot_run_native>
1040 Run the C function C<func> through the program C<[enternative, end]>.
1041 This ensures that the function is run with the same setup as in other
1044 This function is used in some of the source tests in F<t/src> which use
1045 the interpreter outside a runloop.
1053 Parrot_run_native(PARROT_INTERP
, native_func_t func
)
1055 static opcode_t program_code
[2];
1058 program_code
[0] = interp
->op_lib
->op_code("enternative", 0);
1059 program_code
[1] = 0; /* end */
1060 pf
= PackFile_new(interp
, 0);
1061 pf
->cur_cs
= (PackFile_ByteCode
*)
1062 (pf
->PackFuncs
[PF_BYTEC_SEG
].new_seg
)(interp
, pf
, "code", 1);
1063 pf
->cur_cs
->base
.data
= program_code
;
1064 pf
->cur_cs
->base
.size
= 2;
1065 Parrot_loadbc(interp
, pf
);
1067 if (interp
->code
&& interp
->code
->const_table
) {
1068 CONTEXT(interp
->ctx
)->constants
=
1069 interp
->code
->const_table
->constants
;
1071 runops(interp
, interp
->resume_offset
);
1080 F<include/parrot/embed.h> and F<docs/embed.pod>.
1084 Initial version by Brent Dax on 2002.1.28.
1093 * c-file-style: "parrot"
1095 * vim: expandtab shiftwidth=4: