mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-26 05:32:25 +00:00
[OCaml] Impement Llvm_irreader, bindings to LLVM assembly parser
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194138 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c6099db476
commit
ec7270c966
@ -8,7 +8,8 @@
|
|||||||
##===----------------------------------------------------------------------===##
|
##===----------------------------------------------------------------------===##
|
||||||
|
|
||||||
LEVEL := ../..
|
LEVEL := ../..
|
||||||
DIRS = llvm bitreader bitwriter analysis target executionengine transforms linker
|
DIRS = llvm bitreader bitwriter irreader analysis target executionengine \
|
||||||
|
transforms linker
|
||||||
ExtraMakefiles = $(PROJ_OBJ_DIR)/Makefile.ocaml
|
ExtraMakefiles = $(PROJ_OBJ_DIR)/Makefile.ocaml
|
||||||
|
|
||||||
ocamldoc:
|
ocamldoc:
|
||||||
|
19
bindings/ocaml/irreader/Makefile
Normal file
19
bindings/ocaml/irreader/Makefile
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
##===- bindings/ocaml/irreader/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_irreader interface.
|
||||||
|
#
|
||||||
|
##===----------------------------------------------------------------------===##
|
||||||
|
|
||||||
|
LEVEL := ../../..
|
||||||
|
LIBRARYNAME := llvm_irreader
|
||||||
|
UsedComponents := irreader
|
||||||
|
UsedOcamlInterfaces := llvm
|
||||||
|
|
||||||
|
include ../Makefile.ocaml
|
59
bindings/ocaml/irreader/irreader_ocaml.c
Normal file
59
bindings/ocaml/irreader/irreader_ocaml.c
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*===-- irreader_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. *|
|
||||||
|
|* *|
|
||||||
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
#include "llvm-c/IRReader.h"
|
||||||
|
#include "caml/alloc.h"
|
||||||
|
#include "caml/fail.h"
|
||||||
|
#include "caml/memory.h"
|
||||||
|
|
||||||
|
/* Can't use the recommended caml_named_value mechanism for backwards
|
||||||
|
compatibility reasons. This is largely equivalent. */
|
||||||
|
static value llvm_irreader_error_exn;
|
||||||
|
|
||||||
|
CAMLprim value llvm_register_irreader_exns(value Error) {
|
||||||
|
llvm_irreader_error_exn = Field(Error, 0);
|
||||||
|
register_global_root(&llvm_irreader_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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===-- Modules -----------------------------------------------------------===*/
|
||||||
|
|
||||||
|
/* Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule */
|
||||||
|
CAMLprim value llvm_parse_ir(LLVMContextRef C,
|
||||||
|
LLVMMemoryBufferRef MemBuf) {
|
||||||
|
CAMLparam0();
|
||||||
|
CAMLlocal2(Variant, MessageVal);
|
||||||
|
LLVMModuleRef M;
|
||||||
|
char *Message;
|
||||||
|
|
||||||
|
if (LLVMParseIRInContext(C, MemBuf, &M, &Message))
|
||||||
|
llvm_raise(llvm_irreader_error_exn, Message);
|
||||||
|
|
||||||
|
CAMLreturn((value) M);
|
||||||
|
}
|
17
bindings/ocaml/irreader/llvm_irreader.ml
Normal file
17
bindings/ocaml/irreader/llvm_irreader.ml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
(*===-- llvm_irreader.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_irreader_exns"
|
||||||
|
let _ = register_exns (Error "")
|
||||||
|
|
||||||
|
external parse_ir : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
|
||||||
|
= "llvm_parse_ir"
|
21
bindings/ocaml/irreader/llvm_irreader.mli
Normal file
21
bindings/ocaml/irreader/llvm_irreader.mli
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
(*===-- llvm_irreader.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.
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
(** IR reader.
|
||||||
|
|
||||||
|
This interface provides an OCaml API for the LLVM assembly reader, the
|
||||||
|
classes in the IRReader library. *)
|
||||||
|
|
||||||
|
exception Error of string
|
||||||
|
|
||||||
|
(** [parse_ir context mb] parses the IR for a new module [m] from the
|
||||||
|
memory buffer [mb] in the context [context]. Returns [m] if successful, or
|
||||||
|
raises [Error msg] otherwise, where [msg] is a description of the error
|
||||||
|
encountered. See the function [llvm::ParseIR]. *)
|
||||||
|
val parse_ir : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
|
@ -46,6 +46,14 @@ package "ipo" (
|
|||||||
archive(native) = "llvm_ipo.cmxa"
|
archive(native) = "llvm_ipo.cmxa"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
package "irreader" (
|
||||||
|
requires = "llvm"
|
||||||
|
version = "@PACKAGE_VERSION@"
|
||||||
|
description = "IR assembly reader for LLVM"
|
||||||
|
archive(byte) = "llvm_irreader.cma"
|
||||||
|
archive(native) = "llvm_irreader.cmxa"
|
||||||
|
)
|
||||||
|
|
||||||
package "scalar_opts" (
|
package "scalar_opts" (
|
||||||
requires = "llvm"
|
requires = "llvm"
|
||||||
version = "@PACKAGE_VERSION@"
|
version = "@PACKAGE_VERSION@"
|
||||||
|
59
test/Bindings/Ocaml/irreader.ml
Normal file
59
test/Bindings/Ocaml/irreader.ml
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
(* RUN: rm -rf %t.builddir
|
||||||
|
* RUN: mkdir -p %t.builddir
|
||||||
|
* RUN: cp %s %t.builddir
|
||||||
|
* RUN: %ocamlopt -g -warn-error A llvm.cmxa llvm_irreader.cmxa %t.builddir/irreader.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_irreader
|
||||||
|
|
||||||
|
let context = global_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 ()
|
||||||
|
|
||||||
|
let _ =
|
||||||
|
Printexc.record_backtrace true
|
||||||
|
|
||||||
|
let insist cond =
|
||||||
|
if not cond then failwith "insist"
|
||||||
|
|
||||||
|
|
||||||
|
(*===-- IR Reader ---------------------------------------------------------===*)
|
||||||
|
|
||||||
|
let test_irreader () =
|
||||||
|
begin
|
||||||
|
let buf = MemoryBuffer.of_string "@foo = global i32 42" in
|
||||||
|
let m = parse_ir context buf in
|
||||||
|
match lookup_global "foo" m with
|
||||||
|
| Some foo ->
|
||||||
|
insist ((global_initializer foo) = (const_int (i32_type context) 42))
|
||||||
|
| None ->
|
||||||
|
failwith "global"
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
let buf = MemoryBuffer.of_string "@foo = global garble" in
|
||||||
|
try
|
||||||
|
ignore (parse_ir context buf);
|
||||||
|
failwith "parsed"
|
||||||
|
with Llvm_irreader.Error _ ->
|
||||||
|
()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
(*===-- Driver ------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
let _ =
|
||||||
|
suite "irreader" test_irreader
|
Loading…
Reference in New Issue
Block a user