[svn:parrot] r36614 - in branches/load_language: compilers/imcc include/parrot src src/ops

allison at svn.parrot.org allison at svn.parrot.org
Thu Feb 12 01:01:14 UTC 2009


Author: allison
Date: Thu Feb 12 01:01:11 2009
New Revision: 36614
URL: https://trac.parrot.org/parrot/changeset/36614

Log:
[load_language] Adding the load_language opcode, with supporting library changes.

Modified:
   branches/load_language/compilers/imcc/main.c
   branches/load_language/include/parrot/call.h
   branches/load_language/include/parrot/library.h
   branches/load_language/include/parrot/packfile.h
   branches/load_language/include/parrot/thread.h
   branches/load_language/src/library.c
   branches/load_language/src/ops/core.ops
   branches/load_language/src/ops/ops.num
   branches/load_language/src/packfile.c

Modified: branches/load_language/compilers/imcc/main.c
==============================================================================
--- branches/load_language/compilers/imcc/main.c	Thu Feb 12 00:38:13 2009	(r36613)
+++ branches/load_language/compilers/imcc/main.c	Thu Feb 12 01:01:11 2009	(r36614)
@@ -556,11 +556,11 @@
                 SET_FLAG(PARROT_DESTROY_FLAG);
                 break;
             case 'I':
-                Parrot_add_library_path(interp, opt.opt_arg,
+                Parrot_add_library_path_from_cstring(interp, opt.opt_arg,
                     PARROT_LIB_PATH_INCLUDE);
                 break;
             case 'L':
-                Parrot_add_library_path(interp, opt.opt_arg,
+                Parrot_add_library_path_from_cstring(interp, opt.opt_arg,
                     PARROT_LIB_PATH_LIBRARY);
                 break;
             default:

Modified: branches/load_language/include/parrot/call.h
==============================================================================
--- branches/load_language/include/parrot/call.h	Thu Feb 12 00:38:13 2009	(r36613)
+++ branches/load_language/include/parrot/call.h	Thu Feb 12 01:01:11 2009	(r36614)
@@ -92,16 +92,6 @@
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
 PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-PMC* Parrot_pcc_build_sig_object_from_varargs(PARROT_INTERP,
-    ARGIN_NULLOK(PMC* obj),
-    ARGIN(const char *sig),
-    va_list args)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(3);
-
-PARROT_EXPORT
 void Parrot_convert_arg(PARROT_INTERP, ARGMOD(call_state *st))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -185,6 +175,16 @@
         FUNC_MODIFIES(*dest_indexes);
 
 PARROT_EXPORT
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+PMC* Parrot_pcc_build_sig_object_from_varargs(PARROT_INTERP,
+    ARGIN_NULLOK(PMC* obj),
+    ARGIN(const char *sig),
+    va_list args)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(3);
+
+PARROT_EXPORT
 void Parrot_pcc_invoke_from_sig_object(PARROT_INTERP,
     ARGIN(PMC *sub_obj),
     ARGIN(PMC *sig_obj))
@@ -278,10 +278,6 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(3);
 
-#define ASSERT_ARGS_Parrot_pcc_build_sig_object_from_varargs \
-     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(sig)
 #define ASSERT_ARGS_Parrot_convert_arg __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(st)
@@ -317,6 +313,10 @@
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(src_ctx) \
     || PARROT_ASSERT_ARG(dest_ctx)
+#define ASSERT_ARGS_Parrot_pcc_build_sig_object_from_varargs \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(sig)
 #define ASSERT_ARGS_Parrot_pcc_invoke_from_sig_object \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \

Modified: branches/load_language/include/parrot/library.h
==============================================================================
--- branches/load_language/include/parrot/library.h	Thu Feb 12 00:38:13 2009	(r36613)
+++ branches/load_language/include/parrot/library.h	Thu Feb 12 01:01:11 2009	(r36614)
@@ -17,7 +17,8 @@
     PARROT_RUNTIME_FT_LIBRARY = 0x0001,
     PARROT_RUNTIME_FT_INCLUDE = 0x0002,
     PARROT_RUNTIME_FT_DYNEXT  = 0x0004,
-    PARROT_RUNTIME_FT_PBC     = 0x0010,
+    PARROT_RUNTIME_FT_LANG    = 0x0010,
+    PARROT_RUNTIME_FT_PBC     = 0x0020,
     PARROT_RUNTIME_FT_PASM    = 0x0100,
     PARROT_RUNTIME_FT_PIR     = 0x0200,
     PARROT_RUNTIME_FT_PAST    = 0x0400,
@@ -28,6 +29,7 @@
     PARROT_LIB_PATH_INCLUDE,            /* .include "foo" */
     PARROT_LIB_PATH_LIBRARY,            /* load_bytecode "bar" */
     PARROT_LIB_PATH_DYNEXT,             /* loadlib "baz" */
+    PARROT_LIB_PATH_LANG,               /* load_language "buz" */
     PARROT_LIB_DYN_EXTS,                /* ".so", ".dylib" .. */
     /* must be last: */
     PARROT_LIB_PATH_SIZE
@@ -38,6 +40,13 @@
 
 PARROT_EXPORT
 void Parrot_add_library_path(PARROT_INTERP,
+    ARGIN(STRING *path),
+    enum_lib_paths which)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_add_library_path_from_cstring(PARROT_INTERP,
     ARGIN(const char *path),
     enum_lib_paths which)
         __attribute__nonnull__(1)
@@ -94,6 +103,10 @@
 #define ASSERT_ARGS_Parrot_add_library_path __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(path)
+#define ASSERT_ARGS_Parrot_add_library_path_from_cstring \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(path)
 #define ASSERT_ARGS_Parrot_get_runtime_path __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_get_runtime_prefix __attribute__unused__ int _ASSERT_ARGS_CHECK = \

Modified: branches/load_language/include/parrot/packfile.h
==============================================================================
--- branches/load_language/include/parrot/packfile.h	Thu Feb 12 00:38:13 2009	(r36613)
+++ branches/load_language/include/parrot/packfile.h	Thu Feb 12 01:01:11 2009	(r36614)
@@ -676,6 +676,10 @@
         __attribute__nonnull__(1);
 
 PARROT_EXPORT
+void Parrot_load_language(PARROT_INTERP, ARGIN_NULLOK(STRING *lang_name))
+        __attribute__nonnull__(1);
+
+PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 PackFile_Debug * Parrot_new_debug_seg(PARROT_INTERP,
@@ -866,6 +870,8 @@
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_load_bytecode __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_load_language __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_new_debug_seg __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(cs)

Modified: branches/load_language/include/parrot/thread.h
==============================================================================
--- branches/load_language/include/parrot/thread.h	Thu Feb 12 00:38:13 2009	(r36613)
+++ branches/load_language/include/parrot/thread.h	Thu Feb 12 01:01:11 2009	(r36614)
@@ -175,6 +175,9 @@
 
 void pt_clone_code(Parrot_Interp d, Parrot_Interp s);
 void pt_clone_globals(Parrot_Interp d, Parrot_Interp s);
+void pt_free_pool(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
 void pt_gc_mark_root_finished(PARROT_INTERP)
         __attribute__nonnull__(1);
 
@@ -184,9 +187,6 @@
 void pt_gc_stop_mark(PARROT_INTERP)
         __attribute__nonnull__(1);
 
-void pt_free_pool(PARROT_INTERP)
-        __attribute__nonnull__(1);
-
 void pt_join_threads(PARROT_INTERP)
         __attribute__nonnull__(1);
 
@@ -269,14 +269,14 @@
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_pt_clone_code __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
 #define ASSERT_ARGS_pt_clone_globals __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
+#define ASSERT_ARGS_pt_free_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_pt_gc_mark_root_finished __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_pt_gc_start_mark __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_pt_gc_stop_mark __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_pt_free_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_pt_join_threads __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_pt_shared_fixup __attribute__unused__ int _ASSERT_ARGS_CHECK = \

Modified: branches/load_language/src/library.c
==============================================================================
--- branches/load_language/src/library.c	Thu Feb 12 00:38:13 2009	(r36613)
+++ branches/load_language/src/library.c	Thu Feb 12 01:01:11 2009	(r36614)
@@ -136,6 +136,7 @@
     [ "runtime/parrot/include", ... ],   # paths for .include 'file'
     [ "runtime/parrot/library", ... ],   # paths for load_bytecode
     [ "runtime/parrot/dynext", ... ],    # paths for loadlib
+    [ "languages", ... ],                # paths for languages
     [ ".so", ... ]                       # list of shared extensions
   ]
 
@@ -143,7 +144,7 @@
 
   #define PARROT_PLATFORM_LIB_PATH_INIT_HOOK the_init_hook
 
-if will be called as a function with this prototype:
+it will be called as a function with this prototype:
 
   void the_init_hook(PARROT_INTERP, PMC *lib_paths);
 
@@ -212,6 +213,17 @@
     entry = CONST_STRING(interp, "lib/parrot/");
     VTABLE_push_string(interp, paths, entry);
 
+    /* define languages paths */
+    paths = pmc_new(interp, enum_class_ResizableStringArray);
+    VTABLE_set_pmc_keyed_int(interp, lib_paths,
+            PARROT_LIB_PATH_LANG, paths);
+    entry = CONST_STRING(interp, "languages/");
+    VTABLE_push_string(interp, paths, entry);
+    entry = CONST_STRING(interp, "lib/parrot/languages/");
+    VTABLE_push_string(interp, paths, entry);
+    entry = CONST_STRING(interp, "./");
+    VTABLE_push_string(interp, paths, entry);
+
     /* define dynext paths */
     paths = pmc_new(interp, enum_class_ResizableStringArray);
     VTABLE_set_pmc_keyed_int(interp, lib_paths,
@@ -253,6 +265,7 @@
     [ "runtime/parrot/include", ... ],   # paths for .include 'file'
     [ "runtime/parrot/library", ... ],   # paths for load_bytecode
     [ "runtime/parrot/dynext", ... ],    # paths for loadlib
+    [ "languages", ... ],                # paths for languages
     [ ".so", ... ]                       # list of shared extensions
   ]
 
@@ -581,9 +594,6 @@
 
 Add a path to the library searchpath of the given type.
 
-TODO:
-  - allow path to be a list of paths.
-
 =cut
 
 */
@@ -591,7 +601,7 @@
 PARROT_EXPORT
 void
 Parrot_add_library_path(PARROT_INTERP,
-        ARGIN(const char *path),
+        ARGIN(STRING *path),
         enum_lib_paths which)
 {
     ASSERT_ARGS(Parrot_add_library_path)
@@ -599,8 +609,31 @@
     PMC * const lib_paths = VTABLE_get_pmc_keyed_int(interp, iglobals,
         IGLOBALS_LIB_PATHS);
     PMC * const paths = VTABLE_get_pmc_keyed_int(interp, lib_paths, which);
+    VTABLE_push_string(interp, paths, path);
+}
+
+/*
+
+=item C<void Parrot_add_library_path_from_cstring>
+
+Add a path to the library searchpath of the given type (passing in a C string).
+
+This function is just an interface to C<Parrot_add_library_path> for low-level
+code.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_add_library_path_from_cstring(PARROT_INTERP,
+        ARGIN(const char *path),
+        enum_lib_paths which)
+{
+    ASSERT_ARGS(Parrot_add_library_path)
     STRING * const path_str = Parrot_str_new(interp, path, 0);
-    VTABLE_push_string(interp, paths, path_str);
+    Parrot_add_library_path(interp, path_str, which);
 }
 
 /*
@@ -613,10 +646,15 @@
 
 =item C<STRING* Parrot_locate_runtime_file_str>
 
-Like above but use and return STRINGs. If successful, the returned STRING
-is 0-terminated so that C<result-E<gt>strstart> is usable as B<const char*>
-c-string for C library functions like fopen(3).
-This is the preferred API function.
+Like above but use and return STRINGs. 
+
+Locate the full path for C<file_name> and the given file type(s). If
+successful, returns a C-string allocated with C<Parrot_str_to_cstring> or
+NULL otherwise.
+
+If successful, the returned STRING is 0-terminated so that
+C<result-E<gt>strstart> is usable as B<const char*> c-string for C library
+functions like fopen(3).  This is the preferred API function.
 
 The C<enum_runtime_ft type> is one or more of the types defined in
 F<include/parrot/library.h>.
@@ -642,7 +680,9 @@
     if (is_abs_path(file))
         return file;
 
-    if (type & PARROT_RUNTIME_FT_DYNEXT)
+    if (type & PARROT_RUNTIME_FT_LANG)
+        paths = get_search_paths(interp, PARROT_LIB_PATH_LANG);
+    else if (type & PARROT_RUNTIME_FT_DYNEXT)
         paths = get_search_paths(interp, PARROT_LIB_PATH_DYNEXT);
     else if (type & (PARROT_RUNTIME_FT_PBC | PARROT_RUNTIME_FT_SOURCE))
         paths = get_search_paths(interp, PARROT_LIB_PATH_LIBRARY);

Modified: branches/load_language/src/ops/core.ops
==============================================================================
--- branches/load_language/src/ops/core.ops	Thu Feb 12 00:38:13 2009	(r36613)
+++ branches/load_language/src/ops/core.ops	Thu Feb 12 01:01:11 2009	(r36614)
@@ -163,6 +163,18 @@
     Parrot_load_bytecode(interp, $1);
 }
 
+=item B<load_language>(in STR)
+
+Load the compiler libraries for a language $1. Search the library path to
+locate the main compiler file in the standard locations.
+
+inline op load_language(in STR) :load_file {
+    Parrot_load_language(interp, $1);
+}
+
+
+=cut
+
 =back
 
 =cut

Modified: branches/load_language/src/ops/ops.num
==============================================================================
--- branches/load_language/src/ops/ops.num	Thu Feb 12 00:38:13 2009	(r36613)
+++ branches/load_language/src/ops/ops.num	Thu Feb 12 01:01:11 2009	(r36614)
@@ -1257,3 +1257,5 @@
 set_root_global_pc_sc_p        1227
 find_name_p_s                  1228
 find_name_p_sc                 1229
+load_language_s                1230
+load_language_sc               1231

Modified: branches/load_language/src/packfile.c
==============================================================================
--- branches/load_language/src/packfile.c	Thu Feb 12 00:38:13 2009	(r36613)
+++ branches/load_language/src/packfile.c	Thu Feb 12 01:01:11 2009	(r36614)
@@ -54,6 +54,12 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
+static void compile_or_load_file(PARROT_INTERP,
+    ARGIN(STRING *path),
+    enum_runtime_ft file_type)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
 static void const_destroy(PARROT_INTERP, ARGMOD(PackFile_Segment *self))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -331,6 +337,9 @@
 #define ASSERT_ARGS_clone_constant __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(old_const)
+#define ASSERT_ARGS_compile_or_load_file __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(path)
 #define ASSERT_ARGS_const_destroy __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(self)
@@ -4458,9 +4467,49 @@
 
 /*
 
+=item C<static void compile_or_load_file>
+
+Either load a bytecode file and append it to the current packfile directory, or
+compile a PIR or PASM file from source.
+
+=cut
+
+*/
+
+static void
+compile_or_load_file(PARROT_INTERP, ARGIN(STRING *path),
+		enum_runtime_ft file_type)
+{
+    char *filename = Parrot_str_to_cstring(interp, path);
+
+    if (file_type == PARROT_RUNTIME_FT_PBC) {
+        PackFile *pf = PackFile_append_pbc(interp, filename);
+        Parrot_str_free_cstring(filename);
+
+        if (!pf)
+            Parrot_ex_throw_from_c_args(interp, NULL, 1,
+                "Unable to append PBC to the current directory");
+    }
+    else {
+        STRING *err;
+        PackFile_ByteCode * const cs =
+            (PackFile_ByteCode *)IMCC_compile_file_s(interp,
+                filename, &err);
+        Parrot_str_free_cstring(filename);
+
+        if (cs)
+            do_sub_pragmas(interp, cs, PBC_LOADED, NULL);
+        else
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
+                "compiler returned NULL ByteCode '%Ss' - %Ss", path, err);
+    }
+}
+
+/*
+
 =item C<void Parrot_load_bytecode>
 
-Load and append a bytecode, IMC or PASM file into interpreter.
+Load and append a bytecode, PIR or PASM file into interpreter.
 
 Load some bytecode (PASM, PIR, PBC ...) and append it to the current
 directory.
@@ -4508,6 +4557,10 @@
     VTABLE_set_string_keyed_str(interp, is_loaded_hash,
             wo_ext, path);
     filename = Parrot_str_to_cstring(interp, path);
+
+
+    /* Check if the found file was actually bytecode (.pbc extension), or a
+     * source file (.pir or .pasm extension). */
     if (file_type == PARROT_RUNTIME_FT_PBC) {
         PackFile *pf = PackFile_append_pbc(interp, filename);
         Parrot_str_free_cstring(filename);
@@ -4531,6 +4584,78 @@
     }
 }
 
+
+/*
+
+=item C<void Parrot_load_language>
+
+Load the compiler libraries for a given high-level language into the
+interpreter.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_load_language(PARROT_INTERP, ARGIN_NULLOK(STRING *lang_name))
+{
+    ASSERT_ARGS(Parrot_load_language)
+    STRING *wo_ext, *file_str, *path, *pbc;
+    STRING *found_path, *found_ext;
+    INTVAL name_length;
+    enum_runtime_ft file_type;
+    PMC *is_loaded_hash;
+
+    if (STRING_IS_NULL(lang_name))
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
+            "\"load_language\" no language name");
+
+    /* Full path to language library is "abc/abc.pbc". */
+    pbc = CONST_STRING(interp, "pbc");
+    wo_ext   = Parrot_str_concat(interp, lang_name, CONST_STRING(interp, "/"), 0);
+    wo_ext   = Parrot_str_append(interp, wo_ext, lang_name);
+    file_str = Parrot_str_concat(interp, wo_ext, CONST_STRING(interp, "."), 0);
+    file_str = Parrot_str_append(interp, file_str, pbc);
+
+    /* Check if the language is already loaded */
+    is_loaded_hash = VTABLE_get_pmc_keyed_int(interp,
+        interp->iglobals, IGLOBALS_PBC_LIBS);
+    if (VTABLE_exists_keyed_str(interp, is_loaded_hash, wo_ext))
+        return;
+
+    file_type = PARROT_RUNTIME_FT_LANG;
+
+    path = Parrot_locate_runtime_file_str(interp, file_str, file_type);
+    if (!path)
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
+            "\"load_language\" couldn't find a compiler module for the language '%Ss'", lang_name);
+
+    /* remember wo_ext => full_path mapping */
+    VTABLE_set_string_keyed_str(interp, is_loaded_hash,
+            wo_ext, path);
+
+    /* Add the include and dynext paths to the global search */
+    parrot_split_path_ext(interp, path, &found_path, &found_ext);
+    name_length = Parrot_str_length(interp, lang_name);
+    found_path = Parrot_str_substr(interp, found_path, -name_length, name_length, NULL, 0);
+    Parrot_add_library_path(interp, Parrot_str_append(interp, found_path, CONST_STRING(interp, "include/")),
+		    PARROT_LIB_PATH_INCLUDE);
+    Parrot_add_library_path(interp, Parrot_str_append(interp, found_path, CONST_STRING(interp, "dynext/")),
+		    PARROT_LIB_PATH_DYNEXT);
+
+
+    /* Check if the file found was actually a bytecode file (.pbc extension) or
+     * a source file (.pir or .pasm extension. */
+
+    if (Parrot_str_equal(interp, found_ext, pbc))
+        file_type = PARROT_RUNTIME_FT_PBC;
+    else
+        file_type = PARROT_RUNTIME_FT_SOURCE;
+
+    compile_or_load_file(interp, path, file_type);
+}
+
 /*
 
 =item C<void PackFile_fixup_subs>


More information about the parrot-commits mailing list