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 */
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
76 # include "parrot/exec.h"
77 # endif /* EXEC_CAPABLE */
82 PARROT_CANNOT_RETURN_NULL
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.
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:
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.
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
);
145 case PARROT_BOUNDS_FLAG
:
146 case PARROT_PROFILE_FLAG
:
147 Interp_core_SET(interp
, PARROT_SLOW_CORE
);
157 =item C<void Parrot_set_debug>
159 Set a debug flag: C<PARROT_DEBUG_FLAG>.
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
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
,
197 =item C<void Parrot_set_trace>
199 Set a trace flag: C<PARROT_TRACE_FLAG>
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.
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.
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.
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>.
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>.
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>.
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.
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.
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.
370 PARROT_CAN_RETURN_NULL
372 Parrot_readbc(PARROT_INTERP
, ARGIN_NULLOK(const char *fullname
))
375 INTVAL is_mapped
= 0;
380 #ifdef PARROT_HAS_HEADER_SYSMMAN
384 if (fullname
== NULL
|| STREQ(fullname
, "-")) {
385 /* read from STDIN */
388 /* read 1k at a time */
392 STRING
* const fs
= string_make(interp
, fullname
, strlen(fullname
),
394 if (!Parrot_stat_info_intval(interp
, fs
, STAT_EXISTS
)) {
395 PIO_eprintf(interp
, "Parrot VM: Can't stat %s, code %i.\n",
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");
408 PIO_eprintf(interp
, "Parrot VM: Can't open %s, code %i.\n",
412 #endif /* PARROT_HAS_HEADER_SYSMMAN */
415 #ifdef PARROT_HAS_HEADER_SYSMMAN
418 /* if we've opened a file (or stdin) with PIO, read it in */
420 size_t chunk_size
= program_size
> 0 ? program_size
: 1024;
421 INTVAL wanted
= program_size
;
425 program_code
= (char *)mem_sys_allocate(chunk_size
);
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
)
435 (char *)mem_sys_realloc(program_code
, program_size
+ chunk_size
);
439 "Parrot VM: Could not reallocate buffer "
440 "while reading packfile from PIO.\n");
444 cursor
= (char *)program_code
+ program_size
;
448 PIO_eprintf(interp
, "Parrot VM: Problem reading packfile from PIO: code %d.\n",
455 /* if we've gotten here, we opted not to use PIO to read the file.
458 #ifdef PARROT_HAS_HEADER_SYSMMAN
460 /* check that fullname isn't NULL, just in case */
462 real_exception(interp
, NULL
, 1, "Trying to open a NULL filename");
464 fd
= open(fullname
, O_RDONLY
| O_BINARY
);
467 PIO_eprintf(interp
, "Parrot VM: Can't open %s, code %i.\n",
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",
480 /* try again, now with IO reading the file */
481 io
= fopen(fullname
, "rb");
483 PIO_eprintf(interp
, "Parrot VM: Can't open %s, code %i.\n",
491 #else /* PARROT_HAS_HEADER_SYSMMAN */
493 PIO_eprintf(interp
, "Parrot VM: uncaught error occurred reading "
494 "file or mmap not available.\n");
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",
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 */
522 /* RT #46155 Parrot_exec uses this
523 mem_sys_free(program_code); */
532 =item C<void Parrot_loadbc>
534 Loads the C<PackFile> returned by C<Parrot_readbc()>.
542 Parrot_loadbc(PARROT_INTERP
, NOTNULL(PackFile
*pf
))
545 PIO_eprintf(interp
, "Invalid packfile\n");
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.
564 PARROT_CANNOT_RETURN_NULL
566 setup_argv(PARROT_INTERP
, int argc
, ARGIN(char **argv
))
571 if (Interp_debug_TEST(interp
, PARROT_START_DEBUG_FLAG
)) {
573 "*** Parrot VM: Setting up ARGV array. Current argc: %d ***\n",
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. */
588 string_make(interp
, argv
[i
], strlen(argv
[i
]), NULL
,
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
);
603 =item C<static int prof_sort_f>
605 Sort function for profile data. Sorts by time.
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
;
629 =item C<static const char * op_name>
631 Returns the name of the opcode.
637 PARROT_CANNOT_RETURN_NULL
639 op_name(PARROT_INTERP
, int 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";
652 case PARROT_PROF_EXCEPTION
:
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>.
674 calibrate(PARROT_INTERP
)
676 size_t count
= 1000000;
678 opcode_t code
[] = { 1 }; /* noop */
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 */
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.
704 print_profile(PARROT_INTERP
, SHIM(int status
), SHIM(void *p
))
706 RunProfile
* const profile
= interp
->profile
;
711 UINTVAL op_count
= 0;
712 UINTVAL call_count
= 0;
713 FLOATVAL sum_time
= 0.0;
714 const FLOATVAL empty
= calibrate(interp
);
717 "Calibration: overhead = %.6f ms/op\n", 1000.0 * empty
);
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
;
743 const FLOATVAL t
= profile
->data
[j
].time
;
749 k
= profile
->data
[j
].op
;
752 if (k
>= PARROT_PROF_EXTRA
&&
753 op_jit
[k
- PARROT_PROF_EXTRA
].extcall
!= 1)
756 PIO_printf(interp
, " %4d %c %-25s %8vu %10vf %10.6vf\n",
757 k
- PARROT_PROF_EXTRA
,
762 (FLOATVAL
)(t
* 1000.0 / (FLOATVAL
)n
));
766 PIO_printf(interp
, " %4vu - %-25s %8vu %10vf %10.6vf\n",
771 (FLOATVAL
)(sum_time
* 1000.0 / (FLOATVAL
)call_count
));
778 =item C<static void print_debug>
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");
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
812 PARROT_CANNOT_RETURN_NULL
814 set_current_sub(PARROT_INTERP
)
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
;
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
;
860 =item C<void Parrot_runcode>
862 Sets up C<ARGV> and runs the ops.
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
))
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
)) {
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");
894 case PARROT_FAST_CORE
:
895 PIO_eprintf(interp
, "Fast core");
897 case PARROT_SWITCH_CORE
:
898 case PARROT_SWITCH_JIT_CORE
:
899 PIO_eprintf(interp
, "Switch core");
901 case PARROT_CGP_CORE
:
902 case PARROT_CGP_JIT_CORE
:
903 PIO_eprintf(interp
, "CGP core");
905 case PARROT_CGOTO_CORE
:
906 PIO_eprintf(interp
, "CGoto core");
908 case PARROT_JIT_CORE
:
909 PIO_eprintf(interp
, "JIT core");
911 case PARROT_EXEC_CORE
:
912 PIO_eprintf(interp
, "EXEC core");
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
);
926 /* s. runops_exec interpreter.c */
927 if (Interp_core_TEST(interp
, PARROT_EXEC_CORE
))
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 */
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.
965 PARROT_CAN_RETURN_NULL
967 Parrot_debug(NOTNULL(Parrot_Interp debugger
), opcode_t
* pc
)
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
;
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
);
996 =item C<void Parrot_disassemble>
998 Disassembles and prints out the interpreter's bytecode.
1000 This is used by the Parrot disassembler.
1008 Parrot_disassemble(PARROT_INTERP
)
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;
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");
1028 PIO_printf(interp
, " %6s:\n", "SrcLn#");
1029 num_mappings
= interp
->code
->debugs
->num_mappings
;
1032 PIO_printf(interp
, "\n");
1035 while (line
->next
) {
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
);
1052 PIO_printf(interp
, "%012i-%012i", op_code_seq_num
, line
->opcode
- interp
->code
->base
.data
);
1055 PIO_printf(interp
, " %06i: ", interp
->code
->debugs
->base
.data
[op_code_seq_num
]);
1057 /* If it has a label print it */
1059 PIO_printf(interp
, "L%li:\t", line
->label
->number
);
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");
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
1085 This function is used in some of the source tests in F<t/src> which use
1086 the interpreter outside a runloop.
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
);
1111 if (interp
->code
&& interp
->code
->const_table
)
1112 CONTEXT(interp
)->constants
= interp
->code
->const_table
->constants
;
1114 runops(interp
, interp
->resume_offset
);
1123 F<include/parrot/embed.h> and F<docs/embed.pod>.
1127 Initial version by Brent Dax on 2002.1.28.
1135 * c-file-style: "parrot"
1137 * vim: expandtab shiftwidth=4: