mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-26 05:32:25 +00:00
[OCaml] Implement Llvm_linker, bindings for the IR linker
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193951 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1185582dfd
commit
9d33bf70c2
@ -8,7 +8,7 @@
|
|||||||
##===----------------------------------------------------------------------===##
|
##===----------------------------------------------------------------------===##
|
||||||
|
|
||||||
LEVEL := ../..
|
LEVEL := ../..
|
||||||
DIRS = llvm bitreader bitwriter analysis target executionengine transforms
|
DIRS = llvm bitreader bitwriter analysis target executionengine transforms linker
|
||||||
ExtraMakefiles = $(PROJ_OBJ_DIR)/Makefile.ocaml
|
ExtraMakefiles = $(PROJ_OBJ_DIR)/Makefile.ocaml
|
||||||
|
|
||||||
ocamldoc:
|
ocamldoc:
|
||||||
|
19
bindings/ocaml/linker/Makefile
Normal file
19
bindings/ocaml/linker/Makefile
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
##===- bindings/ocaml/linker/Makefile ----------------------*- Makefile -*-===##
|
||||||
|
#
|
||||||
|
# The LLVM Compiler Infrastructure
|
||||||
|
#
|
||||||
|
# This file is distributed under the University of Illinois Open Source
|
||||||
|
# License. See LICENSE.TXT for details.
|
||||||
|
#
|
||||||
|
##===----------------------------------------------------------------------===##
|
||||||
|
#
|
||||||
|
# This is the makefile for the Objective Caml Llvm_target interface.
|
||||||
|
#
|
||||||
|
##===----------------------------------------------------------------------===##
|
||||||
|
|
||||||
|
LEVEL := ../../..
|
||||||
|
LIBRARYNAME := llvm_linker
|
||||||
|
UsedComponents := linker
|
||||||
|
UsedOcamlInterfaces := llvm
|
||||||
|
|
||||||
|
include ../Makefile.ocaml
|
54
bindings/ocaml/linker/linker_ocaml.c
Normal file
54
bindings/ocaml/linker/linker_ocaml.c
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*===-- linker_ocaml.c - LLVM Ocaml Glue ------------------------*- C++ -*-===*\
|
||||||
|
|* *|
|
||||||
|
|* The LLVM Compiler Infrastructure *|
|
||||||
|
|* *|
|
||||||
|
|* This file is distributed under the University of Illinois Open Source *|
|
||||||
|
|* License. See LICENSE.TXT for details. *|
|
||||||
|
|* *|
|
||||||
|
|*===----------------------------------------------------------------------===*|
|
||||||
|
|* *|
|
||||||
|
|* This file glues LLVM's OCaml interface to its C interface. These functions *|
|
||||||
|
|* are by and large transparent wrappers to the corresponding C functions. *|
|
||||||
|
|* *|
|
||||||
|
|* Note that these functions intentionally take liberties with the CAMLparamX *|
|
||||||
|
|* macros, since most of the parameters are not GC heap objects. *|
|
||||||
|
|* *|
|
||||||
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
#include "llvm-c/Linker.h"
|
||||||
|
#include "caml/alloc.h"
|
||||||
|
#include "caml/memory.h"
|
||||||
|
#include "caml/fail.h"
|
||||||
|
|
||||||
|
static value llvm_linker_error_exn;
|
||||||
|
|
||||||
|
CAMLprim value llvm_register_linker_exns(value Error) {
|
||||||
|
llvm_linker_error_exn = Field(Error, 0);
|
||||||
|
register_global_root(&llvm_linker_error_exn);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void llvm_raise(value Prototype, char *Message) {
|
||||||
|
CAMLparam1(Prototype);
|
||||||
|
CAMLlocal1(CamlMessage);
|
||||||
|
|
||||||
|
CamlMessage = copy_string(Message);
|
||||||
|
LLVMDisposeMessage(Message);
|
||||||
|
|
||||||
|
raise_with_arg(Prototype, CamlMessage);
|
||||||
|
abort(); /* NOTREACHED */
|
||||||
|
#ifdef CAMLnoreturn
|
||||||
|
CAMLnoreturn; /* Silences warnings, but is missing in some versions. */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* llmodule -> llmodule -> Mode.t -> unit
|
||||||
|
raises Error msg on error */
|
||||||
|
CAMLprim value llvm_link_modules(LLVMModuleRef Dst, LLVMModuleRef Src, value Mode) {
|
||||||
|
char* Message;
|
||||||
|
|
||||||
|
if (LLVMLinkModules(Dst, Src, Int_val(Mode), &Message))
|
||||||
|
llvm_raise(llvm_linker_error_exn, Message);
|
||||||
|
|
||||||
|
return Val_unit;
|
||||||
|
}
|
22
bindings/ocaml/linker/llvm_linker.ml
Normal file
22
bindings/ocaml/linker/llvm_linker.ml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
(*===-- llvm_linker.ml - LLVM OCaml Interface ------------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* The LLVM Compiler Infrastructure
|
||||||
|
*
|
||||||
|
* This file is distributed under the University of Illinois Open Source
|
||||||
|
* License. See LICENSE.TXT for details.
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
exception Error of string
|
||||||
|
|
||||||
|
external register_exns : exn -> unit = "llvm_register_linker_exns"
|
||||||
|
let _ = register_exns (Error "")
|
||||||
|
|
||||||
|
module Mode = struct
|
||||||
|
type t =
|
||||||
|
| DestroySource
|
||||||
|
| PreserveSource
|
||||||
|
end
|
||||||
|
|
||||||
|
external link_modules : Llvm.llmodule -> Llvm.llmodule -> Mode.t -> unit
|
||||||
|
= "llvm_link_modules"
|
27
bindings/ocaml/linker/llvm_linker.mli
Normal file
27
bindings/ocaml/linker/llvm_linker.mli
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
(*===-- llvm_linker.mli - LLVM OCaml Interface -----------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* The LLVM Compiler Infrastructure
|
||||||
|
*
|
||||||
|
* This file is distributed under the University of Illinois Open Source
|
||||||
|
* License. See LICENSE.TXT for details.
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
(** Linker.
|
||||||
|
|
||||||
|
This interface provides an OCaml API for LLVM bitcode linker,
|
||||||
|
the classes in the Linker library. *)
|
||||||
|
|
||||||
|
exception Error of string
|
||||||
|
|
||||||
|
(** Linking mode. *)
|
||||||
|
module Mode : sig
|
||||||
|
type t =
|
||||||
|
| DestroySource
|
||||||
|
| PreserveSource
|
||||||
|
end
|
||||||
|
|
||||||
|
(** [link_modules dst src mode] links [src] into [dst], raising [Error]
|
||||||
|
if the linking fails. *)
|
||||||
|
external link_modules : Llvm.llmodule -> Llvm.llmodule -> Mode.t -> unit
|
||||||
|
= "llvm_link_modules"
|
@ -69,3 +69,11 @@ package "target" (
|
|||||||
archive(byte) = "llvm_target.cma"
|
archive(byte) = "llvm_target.cma"
|
||||||
archive(native) = "llvm_target.cmxa"
|
archive(native) = "llvm_target.cmxa"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
package "linker" (
|
||||||
|
requires = "llvm"
|
||||||
|
version = "@PACKAGE_VERSION@"
|
||||||
|
description = "Intermediate Representation Linker for LLVM"
|
||||||
|
archive(byte) = "llvm_linker.cma"
|
||||||
|
archive(native) = "llvm_linker.cmxa"
|
||||||
|
)
|
||||||
|
63
test/Bindings/Ocaml/linker.ml
Normal file
63
test/Bindings/Ocaml/linker.ml
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
(* RUN: rm -rf %t.builddir
|
||||||
|
* RUN: mkdir -p %t.builddir
|
||||||
|
* RUN: cp %s %t.builddir
|
||||||
|
* RUN: %ocamlopt -warn-error A llvm.cmxa llvm_linker.cmxa %t.builddir/linker.ml -o %t
|
||||||
|
* RUN: %t
|
||||||
|
* XFAIL: vg_leak
|
||||||
|
*)
|
||||||
|
|
||||||
|
(* Note: It takes several seconds for ocamlopt to link an executable with
|
||||||
|
libLLVMCore.a, so it's better to write a big test than a bunch of
|
||||||
|
little ones. *)
|
||||||
|
|
||||||
|
open Llvm
|
||||||
|
open Llvm_linker
|
||||||
|
|
||||||
|
let context = global_context ()
|
||||||
|
let void_type = Llvm.void_type context
|
||||||
|
|
||||||
|
(* Tiny unit test framework - really just to help find which line is busted *)
|
||||||
|
let print_checkpoints = false
|
||||||
|
|
||||||
|
let suite name f =
|
||||||
|
if print_checkpoints then
|
||||||
|
prerr_endline (name ^ ":");
|
||||||
|
f ()
|
||||||
|
|
||||||
|
|
||||||
|
(*===-- Linker -----------------------------------------------------------===*)
|
||||||
|
|
||||||
|
let test_linker () =
|
||||||
|
let fty = function_type void_type [| |] in
|
||||||
|
|
||||||
|
let make_module name =
|
||||||
|
let m = create_module context name in
|
||||||
|
let fn = define_function ("fn_" ^ name) fty m in
|
||||||
|
ignore (build_ret_void (builder_at_end context (entry_block fn)));
|
||||||
|
m
|
||||||
|
in
|
||||||
|
|
||||||
|
let m1 = make_module "one"
|
||||||
|
and m2 = make_module "two" in
|
||||||
|
link_modules m1 m2 Mode.PreserveSource;
|
||||||
|
dispose_module m1;
|
||||||
|
dispose_module m2;
|
||||||
|
|
||||||
|
let m1 = make_module "one"
|
||||||
|
and m2 = make_module "two" in
|
||||||
|
link_modules m1 m2 Mode.DestroySource;
|
||||||
|
dispose_module m1;
|
||||||
|
|
||||||
|
let m1 = make_module "one"
|
||||||
|
and m2 = make_module "one" in
|
||||||
|
try
|
||||||
|
link_modules m1 m2 Mode.PreserveSource;
|
||||||
|
failwith "must raise"
|
||||||
|
with Error _ ->
|
||||||
|
dispose_module m1;
|
||||||
|
dispose_module m2
|
||||||
|
|
||||||
|
(*===-- Driver ------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
let _ =
|
||||||
|
suite "linker" test_linker
|
Loading…
Reference in New Issue
Block a user