diff --git a/.gitignore b/.gitignore index a903047..c845e37 100644 --- a/.gitignore +++ b/.gitignore @@ -1,55 +1,3 @@ -*.o -*.a -*.swp -*.swo -*.cmi -*.cmo -*.cmx -*.cma -*.cmxa -*.cmxs -*.byte -*.native -*.opt -.omakedb -.omakedb.lock -*.omc -src/compiler/capnpc-ocaml -src/tests/run-tests -src/tests/run-tests.opt -src/tests/run-tests.run -src/tests/test.mli -src/tests/test.ml -src/tests/.capnp-repo -src/tests/testLists.mli -src/tests/testLists.ml -src/tests/c2b2b.mli -src/tests/c2b2b.ml -src/tests/test_import.mli -src/tests/test_import.ml -src/tests/c2b2b_defun.ml -src/tests/testLists_defun.ml -src/tests/test_defun.ml -src/tests/test_import_defun.ml -src/benchmark/bench -src/benchmark/bench.opt -src/benchmark/bench.run -src/benchmark/.capnp-repo -src/benchmark/c2b2b.mli -src/benchmark/c2b2b.ml -src/benchmark/catrank.mli -src/benchmark/catrank.ml -src/benchmark/carsales.mli -src/benchmark/carsales.ml -src/benchmark/eval.mli -src/benchmark/eval.ml -src/benchmark/carsales -src/benchmark/catrank -src/benchmark/eval -src/compiler/includes.ml -src/benchmark/c2b2b_defun.ml -src/benchmark/carsales_defun.ml -src/benchmark/catrank_defun.ml -src/benchmark/eval_defun.ml -oUnit*.cache -oUnit*.log +_build +.merlin +capnp.install diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5491756 --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +all: + jbuilder build --dev + +test: + jbuilder runtest --dev + +clean: + rm -rf _build + +benchmark: + python src/benchmark/test.py diff --git a/OMakefile b/OMakefile deleted file mode 100644 index 728fe4a..0000000 --- a/OMakefile +++ /dev/null @@ -1,42 +0,0 @@ -USE_OCAMLFIND = true - -OCAMLOPTFLAGS += -inline 1000 -OCAMLFLAGS = -thread -short-paths - -if $(defined-env CAPNP_DEV) - OCAMLFLAGS += -safe-string -warn-error A - export - - -OCAMLPACKS[] = \ - core_kernel \ - extunix \ - uint \ - res \ - ocplib-endian - -NATIVE_ENABLED = true -BYTE_ENABLED = true - -PREFIX = $(getenv PREFIX,/usr/local) - -if $(defined-env DESTDIR) - DESTDIR = $(getenv DESTDIR)/ - export -else - DESTDIR = $(EMPTY) - export - -.SUBDIRS: src - -.PHONY: clean distclean install uninstall all-bench - -clean: runtime-clean compiler-clean - -distclean: clean src-distclean runtime-distclean compiler-distclean - rm -f *.omc .omakedb .omakedb.lock - -install: compiler-install runtime-install - -uninstall: compiler-uninstall runtime-uninstall - diff --git a/OMakeroot b/OMakeroot deleted file mode 100644 index a9d9497..0000000 --- a/OMakeroot +++ /dev/null @@ -1,4 +0,0 @@ -open build/OCaml -DefineCommandVars() -.SUBDIRS: . - diff --git a/README.adoc b/README.adoc index 87b948c..9922d10 100644 --- a/README.adoc +++ b/README.adoc @@ -421,15 +421,16 @@ subdirectories may be helpful to look at. Installation ------------ -capnp-ocaml requires OCaml >= 4.01. +capnp-ocaml requires OCaml >= 4.02. You should be able to install capnp-ocaml with http://opam.ocaml.org[OPAM] using using `opam install capnp`. -If you prefer to compile manually, you will need OMake, Findlib, and OCaml +If you prefer to compile manually, you will need jbuilder, Findlib, and OCaml packages `core_kernel`, `extunix`, `uint`, `ocplib-endian`, and `res`. -Run `omake` to build both the compiler and the runtime library, and then use -`omake install` to copy them into appropriate places within your filesystem. +Run `jbuilder build` to build both the compiler and the runtime library, +and then use `jbuilder install` to copy them into appropriate places within your +filesystem. Contact ------- @@ -460,3 +461,5 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +Some of the `.capnp` schema files are imported from the Cap'n Proto repository +and have their own license (at the top of each file). diff --git a/opam b/capnp.opam similarity index 57% rename from opam rename to capnp.opam index c24dd85..65158c0 100644 --- a/opam +++ b/capnp.opam @@ -6,23 +6,20 @@ bug-reports: "https://github.com/pelzlpj/capnp-ocaml/issues" dev-repo: "https://github.com/pelzlpj/capnp-ocaml.git" author: "Paul Pelzl " maintainer: "Paul Pelzl " -build: [["env" "PREFIX=%{prefix}%" "omake"]] -build-test: [ - ["env" "PREFIX=%{prefix}%" "omake" "src/tests/run-tests"] - [ocaml "./src/tests/run-tests.run"] -] -install: [["env" "PREFIX=%{prefix}%" "omake" "install"]] -remove: [["env" "PREFIX=%{prefix}%" "omake" "uninstall"]] + +build: ["jbuilder" "build" "-p" name "-j" jobs] +build-test: ["jbuilder" "build" "@runtest" "@src/benchmark/benchmarks"] + depends: [ - "omake" - "ocamlfind" {>= "1.5.1"} + "jbuilder" {build} "core_kernel" {>= "112.24.00"} "extunix" "ocplib-endian" {>= "0.7"} "res" "uint" + "core" {test} ] depexts: [ - [["debian"] ["capnproto"]] + [["debian"] ["capnproto" "libcapnp-dev"]] ] available: [ ocaml-version >= "4.02.0" ] diff --git a/jbuild-workspace.dev b/jbuild-workspace.dev new file mode 100644 index 0000000..e69de29 diff --git a/src/OMakefile b/src/OMakefile deleted file mode 100644 index 7ff60aa..0000000 --- a/src/OMakefile +++ /dev/null @@ -1,7 +0,0 @@ -.SUBDIRS: runtime compiler tests benchmark - -.PHONY: src-distclean - -src-distclean: - rm -f *.omc - diff --git a/src/benchmark/OMakefile b/src/benchmark/OMakefile deleted file mode 100644 index d9e2cd2..0000000 --- a/src/benchmark/OMakefile +++ /dev/null @@ -1,93 +0,0 @@ -OCAMLOPTFLAGS += -inlining-report -O3 -OCAMLINCLUDES += ../runtime -OCAML_LIBS += ../runtime/libcapnp -OCAML_CLIBS = libfastrand -OCAMLPACKS += core - -GENERATED = \ - c2b2b.mli \ - c2b2b.ml \ - catrank.mli \ - catrank.ml \ - carsales.mli \ - carsales.ml \ - eval.mli \ - eval.ml - -MODULES = \ - c2b2b \ - catrank \ - carsales \ - eval \ - methods \ - fastRand \ - testCaseSig \ - capnpCarsales \ - capnpCatrank \ - capnpEval \ - methods \ - main - - -PROGRAM = bench - -# We will check out a local copy of the capnproto repo in order to generate -# code based on the benchmark schema. -COMPILER = ../compiler/capnpc-ocaml -CAPNPROTO_REPO = https://github.com/kentonv/capnproto.git -CAPNPROTO_REVISION = f536c8cfbc749f98e43b679242b24afbab8e74b2 - -.capnp-repo: - bash -c 'REPO_DIR=`mktemp -d`/capnproto && git clone $(CAPNPROTO_REPO) $$REPO_DIR && \ - pushd $$REPO_DIR && git checkout $(CAPNPROTO_REVISION) && popd && \ - echo "$$REPO_DIR" > .capnp-repo' - -$(GENERATED): $(COMPILER) .capnp-repo - bash -c 'REPO_DIR=`cat .capnp-repo` && \ - capnp compile -o $(COMPILER) -I $$REPO_DIR/c++/src \ - $$REPO_DIR/c++/src/capnp/c++.capnp \ - $$REPO_DIR/c++/src/capnp/benchmark/catrank.capnp \ - $$REPO_DIR/c++/src/capnp/benchmark/carsales.capnp \ - $$REPO_DIR/c++/src/capnp/benchmark/eval.capnp' - - -open build/C -CFLAGS += -O3 -I$(shell $(OCAMLC) -where) - -StaticCLibrary(libfastrand, fast_rand) - - -OCAMLDEP_MODULES_ENABLED = false -LocalOCamlGeneratedFiles($(GENERATED)) -OCamlProgram($(PROGRAM), $(MODULES)) - - -# Some sort of a bug in omake, the OCamlProgram directive fails to build c2b2b.cmi -# as a dependency of the code which imports it. - -carsales: $(PROGRAM) - ln -f -s $(PROGRAM) carsales - -catrank: $(PROGRAM) - ln -f -s $(PROGRAM) catrank - -eval: $(PROGRAM) - ln -f -s $(PROGRAM) eval - -.PHONY: all-bench bench-clean bench-distclean - -all-bench: carsales catrank - -bench-clean: - rm -f $(PROGRAM)$(EXE) $(PROGRAM).opt $(PROGRAM).run \ - carsales catrank eval $(GENERATED) *.cmi *.cmo *.cmx *.cma *.cmxa *.cmxs \ - *.a *.o - -bench-distclean: bench-clean - rm -f *.omc - bash -c 'if [ -f .capnp-repo ]; then \ - cat .capnp-repo | xargs rm -rf --preserve-root; \ - rm .capnp-repo; \ - fi' - - diff --git a/src/benchmark/carsales.capnp b/src/benchmark/carsales.capnp new file mode 100644 index 0000000..075cae5 --- /dev/null +++ b/src/benchmark/carsales.capnp @@ -0,0 +1,80 @@ +# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +# Licensed under the MIT License: +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +using Cxx = import "/capnp/c++.capnp"; + +@0xff75ddc6a36723c9; +$Cxx.namespace("capnp::benchmark::capnp"); + +struct ParkingLot { + cars@0: List(Car); +} + +struct TotalValue { + amount@0: UInt64; +} + +struct Car { + make@0: Text; + model@1: Text; + color@2: Color; + seats@3: UInt8; + doors@4: UInt8; + wheels@5: List(Wheel); + length@6: UInt16; + width@7: UInt16; + height@8: UInt16; + weight@9: UInt32; + engine@10: Engine; + fuelCapacity@11: Float32; + fuelLevel@12: Float32; + hasPowerWindows@13: Bool; + hasPowerSteering@14: Bool; + hasCruiseControl@15: Bool; + cupHolders@16: UInt8; + hasNavSystem@17: Bool; +} + +enum Color { + black @0; + white @1; + red @2; + green @3; + blue @4; + cyan @5; + magenta @6; + yellow @7; + silver @8; +} + +struct Wheel { + diameter@0: UInt16; + airPressure@1: Float32; + snowTires@2: Bool; +} + +struct Engine { + horsepower@0: UInt16; + cylinders@1: UInt8; + cc@2: UInt32; + usesGas@3: Bool; + usesElectric@4: Bool; +} diff --git a/src/benchmark/catrank.capnp b/src/benchmark/catrank.capnp new file mode 100644 index 0000000..7ec754a --- /dev/null +++ b/src/benchmark/catrank.capnp @@ -0,0 +1,35 @@ +# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +# Licensed under the MIT License: +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +using Cxx = import "/capnp/c++.capnp"; + +@0x82beb8e37ff79aba; +$Cxx.namespace("capnp::benchmark::capnp"); + +struct SearchResultList { + results@0: List(SearchResult); +} + +struct SearchResult { + url@0: Text; + score@1: Float64; + snippet@2: Text; +} diff --git a/src/benchmark/eval.capnp b/src/benchmark/eval.capnp new file mode 100644 index 0000000..fe9a8d4 --- /dev/null +++ b/src/benchmark/eval.capnp @@ -0,0 +1,51 @@ +# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +# Licensed under the MIT License: +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +using Cxx = import "/capnp/c++.capnp"; + +@0xe12dc4c3e70e9eda; +$Cxx.namespace("capnp::benchmark::capnp"); + +enum Operation { + add @0; + subtract @1; + multiply @2; + divide @3; + modulus @4; +} + +struct Expression { + op@0: Operation; + + left :union { + value@1: Int32; + expression@2: Expression; + } + + right :union { + value@3: Int32; + expression@4: Expression; + } +} + +struct EvaluationResult { + value@0: Int32; +} diff --git a/src/benchmark/fastRand.ml b/src/benchmark/fastRand/fastRand.ml similarity index 100% rename from src/benchmark/fastRand.ml rename to src/benchmark/fastRand/fastRand.ml diff --git a/src/benchmark/fast_rand.c b/src/benchmark/fastRand/fast_rand.c similarity index 100% rename from src/benchmark/fast_rand.c rename to src/benchmark/fastRand/fast_rand.c diff --git a/src/benchmark/fastRand/jbuild b/src/benchmark/fastRand/jbuild new file mode 100644 index 0000000..25fa1c5 --- /dev/null +++ b/src/benchmark/fastRand/jbuild @@ -0,0 +1,9 @@ +(jbuild_version 1) + +(library + ((name fast_rand) + (wrapped false) + (c_names (fast_rand)) + (c_flags (:standard -O3)) + (flags (:standard -w -3)) +)) diff --git a/src/benchmark/jbuild b/src/benchmark/jbuild new file mode 100644 index 0000000..360d842 --- /dev/null +++ b/src/benchmark/jbuild @@ -0,0 +1,59 @@ +(* -*- tuareg -*- *) + +let config = {| + +(jbuild_version 1) + +(executable + ((name main) + (libraries (capnp fast_rand core)) + (flags (:standard -w -27-53-55-3-35)) + (ocamlopt_flags (:standard # -inline 2000)) +)) + +(rule + ((targets (carsales)) + (deps (main.exe)) + (action (run ln main.exe ${@})))) + +(rule + ((targets (catrank)) + (deps (main.exe)) + (action (run ln main.exe ${@})))) + +(rule + ((targets (eval)) + (deps (main.exe)) + (action (run ln main.exe ${@})))) + +(rule + ((targets (carsales.ml carsales.mli)) + (deps (carsales.capnp ../compiler/main.exe)) + (action (run capnpc -o ../compiler/main.exe ${<})))) + +(rule + ((targets (catrank.ml catrank.mli)) + (deps (catrank.capnp ../compiler/main.exe)) + (action (run capnpc -o ../compiler/main.exe ${<})))) + +(rule + ((targets (eval.ml eval.mli)) + (deps (eval.capnp ../compiler/main.exe)) + (action (run capnpc -o ../compiler/main.exe ${<})))) + +(alias + ((name benchmarks) + (deps (carsales catrank eval)) +)) + +|} + +let () = + let hash = String.index config '#' in + let opt = if Jbuild_plugin.V1.ocaml_version >= "4.03" then "-O3" else "" in + let config = + String.sub config 0 hash ^ + opt ^ + String.sub config (hash + 1) (String.length config - hash - 1) + in + Jbuild_plugin.V1.send config diff --git a/src/benchmark/test.py b/src/benchmark/test.py index 3de2da8..2ab3a44 100755 --- a/src/benchmark/test.py +++ b/src/benchmark/test.py @@ -1,8 +1,10 @@ #!/usr/bin/env python -import subprocess, os, csv, time +import subprocess, os, csv, time, sys +my_dir = os.path.abspath(os.path.dirname(sys.argv[0])) +os.chdir(my_dir) -#subprocess.check_call(["omake", "clean", "bench-clean"]) -subprocess.check_call(["omake", "carsales", "catrank", "eval"]) +subprocess.check_call(["jbuilder", "build", "--dev", "carsales", "catrank", "eval"]) +bin_dir = os.path.join(my_dir, '../../_build/default/src/benchmark') switch = subprocess.check_output(["opam", "sw", "show"]).strip() @@ -22,7 +24,7 @@ def run(cmd, base_iters, scale): iters = int(base_iters * scale) cmd = cmd + [str(iters)] t0 = time.time() - throughput = int(subprocess.check_output(cmd)) + throughput = int(subprocess.check_output(cmd, cwd = bin_dir)) t1 = time.time() t = t1 - t0 rate = throughput / t diff --git a/src/compiler/OMakefile b/src/compiler/OMakefile deleted file mode 100644 index 8763e0e..0000000 --- a/src/compiler/OMakefile +++ /dev/null @@ -1,46 +0,0 @@ -OCAMLINCLUDES += ../runtime -OCAML_LIBS += ../runtime/libcapnp - -COMP_MODULES = \ - c2b2b \ - defaults \ - genCommon \ - genModules \ - genSignatures \ - generate \ - main \ - pluginSchema \ - topsort - - -if $(defined-env OCAML_TOPLEVEL_PATH) - TOPLEVEL_INCLUDE = -I $(getenv OCAML_TOPLEVEL_PATH) - export -else - TOPLEVEL_INCLUDE = $(EMPTY) - export - - -PROGRAM = capnpc-ocaml - -OCAMLDEP_MODULES_ENABLED = false -OCamlProgram($(PROGRAM), $(COMP_MODULES)) - -.DEFAULT: $(PROGRAM)$(EXE) - -.PHONY: compiler-clean compiler-distclean compiler-install compiler-uninstall - -compiler-clean: - rm -f $(PROGRAM)$(EXE) $(PROGRAM).opt $(PROGRAM).byte \ - *.cmi *.cmo *.cmx *.cma *.cmxa *.cmxs *.a *.o - -compiler-distclean: compiler-clean - rm -f *.omc - -compiler-install: $(PROGRAM)$(EXE) - install -d $(DESTDIR)$(PREFIX)/bin - install $(PROGRAM)$(EXE) $(DESTDIR)$(PREFIX)/bin - -compiler-uninstall: - rm -f $(DESTDIR)$(PREFIX)/bin/$(PROGRAM)$(EXE) - diff --git a/src/compiler/c2b2b.ml b/src/compiler/c2b2b.ml index 7e99aee..9415677 100644 --- a/src/compiler/c2b2b.ml +++ b/src/compiler/c2b2b.ml @@ -1,3 +1,5 @@ +open Capnp + type ro = Capnp.Message.ro type rw = Capnp.Message.rw diff --git a/src/compiler/generate.ml b/src/compiler/generate.ml index 8a6871f..983e327 100644 --- a/src/compiler/generate.ml +++ b/src/compiler/generate.ml @@ -97,7 +97,7 @@ let mod_functor_header = [ let mod_header ~context = [ " let invalid_msg = Capnp.Message.invalid_msg"; ""; - " include CapnpRuntime.BuilderInc.Make[@inlined](MessageWrapper)"; + " include Capnp.Runtime.BuilderInc.Make[@inlined](MessageWrapper)"; ""; " type 'cap message_t = 'cap MessageWrapper.Message.t"; ""; ] @ (List.concat_map context.Context.imports ~f:(fun import -> [ diff --git a/src/compiler/jbuild b/src/compiler/jbuild new file mode 100644 index 0000000..ca61582 --- /dev/null +++ b/src/compiler/jbuild @@ -0,0 +1,8 @@ +(jbuild_version 1) + +(executable + ((name main) + (public_name capnpc-ocaml) + (libraries (capnp)) + (flags (:standard -w -39-27-33-32-60-37-6)) +)) diff --git a/src/compiler/pluginSchema.ml b/src/compiler/pluginSchema.ml index b8f12b0..f313d08 100644 --- a/src/compiler/pluginSchema.ml +++ b/src/compiler/pluginSchema.ml @@ -1008,6 +1008,7 @@ module Make (MessageWrapper : Capnp.MessageSig.S) = struct let invalid_msg = Capnp.Message.invalid_msg module RA_ = struct + open Capnp open Capnp.Runtime (****************************************************************************** * capnp-ocaml @@ -2696,6 +2697,7 @@ module Make (MessageWrapper : Capnp.MessageSig.S) = struct end module BA_ = struct + open Capnp open Capnp.Runtime module NM = MessageWrapper (****************************************************************************** diff --git a/src/runtime/META b/src/runtime/META deleted file mode 100644 index 7b54281..0000000 --- a/src/runtime/META +++ /dev/null @@ -1,8 +0,0 @@ -description = "Runtime support library for capnp-ocaml" -version = "2.1.1" -requires = "core_kernel unix extunix uint res ocplib-endian" -archive(byte) = "libcapnp.cma" -archive(byte, plugin) = "libcapnp.cma" -archive(native) = "libcapnp.cmxa" -archive(native, plugin) = "libcapnp.cmxs" -exists_if = "libcapnp.cma" diff --git a/src/runtime/OMakefile b/src/runtime/OMakefile deleted file mode 100644 index 462da3e..0000000 --- a/src/runtime/OMakefile +++ /dev/null @@ -1,65 +0,0 @@ -RUNTIME_MODULES = \ - commonInc \ - readerInc \ - builderInc \ - builderOps \ - bytesStorage \ - cArray \ - codecs \ - farPointer \ - fragmentBuffer \ - innerArray \ - iO \ - listPointer \ - listStorageType \ - message \ - messageSig \ - messageStorage \ - otherPointer \ - packing \ - pointer \ - structPointer \ - util - -INSTALL_FILES = \ - capnpRuntime.cmi \ - capnpRuntime.cmo \ - capnpRuntime.cmx \ - capnp.cmi \ - capnp.cmo \ - capnp.cmx \ - libcapnp.cma \ - libcapnp.cmxa \ - libcapnp.cmxs \ - libcapnp.a \ - capnp.ml \ - codecs.mli \ - cArray.mli \ - iO.mli \ - message.mli \ - messageSig.ml \ - messageStorage.ml \ - META - -libcapnp.cmxs: libcapnp.cmxa - ocamlfind ocamlopt -shared -linkall -o $@ $< - -OCamlLibrary(libcapnp, capnp capnpRuntime) - -OCamlPackage(capnpRuntime, $(RUNTIME_MODULES)) -OCAMLFLAGS += -for-pack CapnpRuntime - -.PHONY: runtime-clean runtime-distclean runtime-install runtime-uninstall - -runtime-clean: - rm -f *.cmi *.cmo *.cmx *.cma *.cmxa *.cmxs *.a *.o - -runtime-distclean: runtime-clean - rm -f *.omc - -runtime-install: $(INSTALL_FILES) - ocamlfind install capnp $(INSTALL_FILES) - -runtime-uninstall: - ocamlfind remove capnp - diff --git a/src/runtime/capnp.ml b/src/runtime/capnp.ml index ba1d881..007363c 100644 --- a/src/runtime/capnp.ml +++ b/src/runtime/capnp.ml @@ -27,12 +27,26 @@ * POSSIBILITY OF SUCH DAMAGE. ******************************************************************************) -module MessageSig = CapnpRuntime.MessageSig -module Message = CapnpRuntime.Message -module Array = CapnpRuntime.CArray -module BytesStorage = CapnpRuntime.BytesStorage -module BytesMessage = CapnpRuntime.Message.BytesMessage -module Codecs = CapnpRuntime.Codecs -module IO = CapnpRuntime.IO -module Runtime = CapnpRuntime - +module MessageSig = MessageSig +module Message = Message +module Array = CArray +module BytesStorage = BytesStorage +module BytesMessage = Message.BytesMessage +module Codecs = Codecs +module IO = IO +module Runtime = struct + module BuilderInc = BuilderInc + module BuilderOps = BuilderOps + module Codecs = Codecs + module FarPointer = FarPointer + module FragmentBuffer = FragmentBuffer + module InnerArray = InnerArray + module ListPointer = ListPointer + module ListStorageType = ListStorageType + module OtherPointer = OtherPointer + module Packing = Packing + module Pointer = Pointer + module ReaderInc = ReaderInc + module StructPointer = StructPointer + module Util = Util +end diff --git a/src/runtime/jbuild b/src/runtime/jbuild new file mode 100644 index 0000000..87f97be --- /dev/null +++ b/src/runtime/jbuild @@ -0,0 +1,26 @@ +(* -*- tuareg -*- *) + +let config = {| + +(jbuild_version 1) + +(library ( + (name capnp) + (public_name capnp) + (synopsis "Runtime support library for capnp-ocaml") + (libraries (core_kernel uint ocplib-endian res extunix)) + (flags (:standard -w -50-27-6-34-32-53-33)) + (ocamlopt_flags (:standard # -inline 1000)) +)) + +|} + +let () = + let hash = String.index config '#' in + let opt = if Jbuild_plugin.V1.ocaml_version >= "4.03" then "-O3" else "" in + let config = + String.sub config 0 hash ^ + opt ^ + String.sub config (hash + 1) (String.length config - hash - 1) + in + Jbuild_plugin.V1.send config diff --git a/src/tests/OMakefile b/src/tests/OMakefile deleted file mode 100644 index 0c0d493..0000000 --- a/src/tests/OMakefile +++ /dev/null @@ -1,67 +0,0 @@ -OCAMLINCLUDES += ../runtime -OCAML_LIBS += ../runtime/libcapnp -OCAMLPACKS += oUnit - -# It's OK if tests run slowly; if something goes wrong, we want the -# best possible backtrace support. -NATIVE_ENABLED = false - -GENERATED = \ - c2b2b.mli \ - c2b2b.ml \ - test.mli \ - test.ml \ - test_import.mli \ - test_import.ml \ - testLists.mli \ - testLists.ml - -TEST_MODULES = \ - c2b2b \ - test \ - test_import \ - testBytesStorage \ - testCodecs \ - testLists \ - testMisc \ - testEncoding - -PROGRAM = run-tests - -# We will check out a local copy of the capnproto repo in order to generate -# code based on the "test.capnp" schema. -COMPILER = ../compiler/capnpc-ocaml -CAPNPROTO_REPO = https://github.com/kentonv/capnproto.git -CAPNPROTO_REVISION = 25509cf4f1fe6b3f5a6faa2f42b865f7571db8c4 - -.capnp-repo: - bash -c 'REPO_DIR=`mktemp -d`/capnproto && git clone $(CAPNPROTO_REPO) $$REPO_DIR && \ - pushd $$REPO_DIR && git checkout $(CAPNPROTO_REVISION) && popd && \ - echo "$$REPO_DIR" > .capnp-repo' - -$(GENERATED): $(COMPILER) .capnp-repo - bash -c 'REPO_DIR=`cat .capnp-repo` && \ - capnp compile -o $(COMPILER) -I $$REPO_DIR/c++/src \ - $$REPO_DIR/c++/src/capnp/c++.capnp \ - $$REPO_DIR/c++/src/capnp/test.capnp \ - $$REPO_DIR/c++/src/capnp/test-import.capnp \ - testLists.capnp' - -OCAMLDEP_MODULES_ENABLED = false -LocalOCamlGeneratedFiles($(GENERATED)) -OCamlProgram($(PROGRAM), $(TEST_MODULES)) - -.PHONY: tests-clean tests-distclean - -tests-clean: - rm -f $(PROGRAM)$(EXE) $(PROGRAM).opt $(PROGRAM).run \ - *.cmi *.cmo *.cmx *.cma *.cmxa *.cmxs *.a *.o \ - test.mli test.ml - -tests-distclean: tests-clean - rm -f *.omc - bash -c 'if [ -f .capnp-repo ]; then \ - cat .capnp-repo | xargs rm -rf --preserve-root; \ - rm .capnp-repo; \ - fi' - diff --git a/src/tests/c++.capnp b/src/tests/c++.capnp new file mode 100644 index 0000000..4cbc704 --- /dev/null +++ b/src/tests/c++.capnp @@ -0,0 +1,28 @@ +# Copyright (c) 2013, Kenton Varda +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +@0xbdf87d7bb8304e81; +$namespace("capnp::annotations"); + +annotation namespace(file): Text; +annotation name(field, enumerant, struct, enum, interface, method, param, group, union): Text; diff --git a/src/tests/jbuild b/src/tests/jbuild new file mode 100644 index 0000000..ecc364b --- /dev/null +++ b/src/tests/jbuild @@ -0,0 +1,32 @@ +(jbuild_version 1) + +(executable + ((name run_tests) + (libraries (capnp oUnit)) + (flags (:standard -w -27-53)) +)) + +(rule + ((targets (test.ml test.mli)) + (deps (test.capnp ../compiler/main.exe)) + (action (run capnpc -o ../compiler/main.exe ${<})))) + +(rule + ((targets (test_import.ml test_import.mli)) + (deps (test-import.capnp ../compiler/main.exe)) + (action (run capnpc -o ../compiler/main.exe ${<})))) + +(rule + ((targets (c2b2b.ml c2b2b.mli)) + (deps (c++.capnp ../compiler/main.exe)) + (action (run capnpc -o ../compiler/main.exe ${<})))) + +(rule + ((targets (testLists.ml testLists.mli)) + (deps (testLists.capnp ../compiler/main.exe)) + (action (run capnpc -o ../compiler/main.exe ${<})))) + +(alias + ((name runtest) + (deps (run_tests.bc)) + (action (run ${<})))) diff --git a/src/tests/run_tests.ml b/src/tests/run_tests.ml new file mode 100644 index 0000000..73cf594 --- /dev/null +++ b/src/tests/run_tests.ml @@ -0,0 +1,19 @@ +open OUnit2 + +let () = run_test_tt_main TestEncoding.encoding_suite + +let () = run_test_tt_main TestBytesStorage.uint8_suite +let () = run_test_tt_main TestBytesStorage.uint16_suite +let () = run_test_tt_main TestBytesStorage.uint32_suite +let () = run_test_tt_main TestBytesStorage.uint64_suite +let () = run_test_tt_main TestBytesStorage.int8_suite +let () = run_test_tt_main TestBytesStorage.int16_suite +let () = run_test_tt_main TestBytesStorage.int32_suite +let () = run_test_tt_main TestBytesStorage.int64_suite + +let () = run_test_tt_main TestCodecs.packing_suite +let () = run_test_tt_main TestCodecs.random_packing_suite +let () = run_test_tt_main TestCodecs.random_serialize_suite + +let () = run_test_tt_main TestMisc.encode_signed_suite +let () = run_test_tt_main TestMisc.decode_signed_suite diff --git a/src/tests/test-import.capnp b/src/tests/test-import.capnp new file mode 100644 index 0000000..6e4363b --- /dev/null +++ b/src/tests/test-import.capnp @@ -0,0 +1,30 @@ +# Copyright (c) 2013, Kenton Varda +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +@0xf36d7b330303c66e; + +using Test = import "test.capnp"; + +struct TestImport { + field @0 :Test.TestAllTypes; +} diff --git a/src/tests/test.capnp b/src/tests/test.capnp new file mode 100644 index 0000000..4d5208e --- /dev/null +++ b/src/tests/test.capnp @@ -0,0 +1,728 @@ +# Copyright (c) 2013, Kenton Varda +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +@0xd508eebdc2dc42b8; + +using Cxx = import "c++.capnp"; + +# Use a namespace likely to cause trouble if the generated code doesn't use fully-qualified +# names for stuff in the capnproto namespace. +$Cxx.namespace("capnproto_test::capnp::test"); + +enum TestEnum { + foo @0; + bar @1; + baz @2; + qux @3; + quux @4; + corge @5; + grault @6; + garply @7; +} + +struct TestAllTypes { + voidField @0 : Void; + boolField @1 : Bool; + int8Field @2 : Int8; + int16Field @3 : Int16; + int32Field @4 : Int32; + int64Field @5 : Int64; + uInt8Field @6 : UInt8; + uInt16Field @7 : UInt16; + uInt32Field @8 : UInt32; + uInt64Field @9 : UInt64; + float32Field @10 : Float32; + float64Field @11 : Float64; + textField @12 : Text; + dataField @13 : Data; + structField @14 : TestAllTypes; + enumField @15 : TestEnum; + interfaceField @16 : Void; # TODO + + voidList @17 : List(Void); + boolList @18 : List(Bool); + int8List @19 : List(Int8); + int16List @20 : List(Int16); + int32List @21 : List(Int32); + int64List @22 : List(Int64); + uInt8List @23 : List(UInt8); + uInt16List @24 : List(UInt16); + uInt32List @25 : List(UInt32); + uInt64List @26 : List(UInt64); + float32List @27 : List(Float32); + float64List @28 : List(Float64); + textList @29 : List(Text); + dataList @30 : List(Data); + structList @31 : List(TestAllTypes); + enumList @32 : List(TestEnum); + interfaceList @33 : List(Void); # TODO +} + +struct TestDefaults { + voidField @0 : Void = void; + boolField @1 : Bool = true; + int8Field @2 : Int8 = -123; + int16Field @3 : Int16 = -12345; + int32Field @4 : Int32 = -12345678; + int64Field @5 : Int64 = -123456789012345; + uInt8Field @6 : UInt8 = 234; + uInt16Field @7 : UInt16 = 45678; + uInt32Field @8 : UInt32 = 3456789012; + uInt64Field @9 : UInt64 = 12345678901234567890; + float32Field @10 : Float32 = 1234.5; + float64Field @11 : Float64 = -123e45; + textField @12 : Text = "foo"; + dataField @13 : Data = "bar"; + structField @14 : TestAllTypes = ( + voidField = void, + boolField = true, + int8Field = -12, + int16Field = 3456, + int32Field = -78901234, + int64Field = 56789012345678, + uInt8Field = 90, + uInt16Field = 1234, + uInt32Field = 56789012, + uInt64Field = 345678901234567890, + float32Field = -1.25e-10, + float64Field = 345, + textField = "baz", + dataField = "qux", + structField = ( + textField = "nested", + structField = (textField = "really nested")), + enumField = baz, + # interfaceField can't have a default + + voidList = [void, void, void], + boolList = [false, true, false, true, true], + int8List = [12, -34, -0x80, 0x7f], + int16List = [1234, -5678, -0x8000, 0x7fff], + int32List = [12345678, -90123456, -0x80000000, 0x7fffffff], + int64List = [123456789012345, -678901234567890, -0x8000000000000000, 0x7fffffffffffffff], + uInt8List = [12, 34, 0, 0xff], + uInt16List = [1234, 5678, 0, 0xffff], + uInt32List = [12345678, 90123456, 0, 0xffffffff], + uInt64List = [123456789012345, 678901234567890, 0, 0xffffffffffffffff], + float32List = [0, 1234567, 1e37, -1e37, 1e-37, -1e-37], + float64List = [0, 123456789012345, 1e306, -1e306, 1e-306, -1e-306], + textList = ["quux", "corge", "grault"], + dataList = ["garply", "waldo", "fred"], + structList = [ + (textField = "x structlist 1"), + (textField = "x structlist 2"), + (textField = "x structlist 3")], + enumList = [qux, bar, grault] + # interfaceList can't have a default + ); + enumField @15 : TestEnum = corge; + interfaceField @16 : Void; # TODO + + voidList @17 : List(Void) = [void, void, void, void, void, void]; + boolList @18 : List(Bool) = [true, false, false, true]; + int8List @19 : List(Int8) = [111, -111]; + int16List @20 : List(Int16) = [11111, -11111]; + int32List @21 : List(Int32) = [111111111, -111111111]; + int64List @22 : List(Int64) = [1111111111111111111, -1111111111111111111]; + uInt8List @23 : List(UInt8) = [111, 222] ; + uInt16List @24 : List(UInt16) = [33333, 44444]; + uInt32List @25 : List(UInt32) = [3333333333]; + uInt64List @26 : List(UInt64) = [11111111111111111111]; + float32List @27 : List(Float32) = [5555.5, inf, -inf, nan]; + float64List @28 : List(Float64) = [7777.75, inf, -inf, nan]; + textList @29 : List(Text) = ["plugh", "xyzzy", "thud"]; + dataList @30 : List(Data) = ["oops", "exhausted", "rfc3092"]; + structList @31 : List(TestAllTypes) = [ + (textField = "structlist 1"), + (textField = "structlist 2"), + (textField = "structlist 3")]; + enumList @32 : List(TestEnum) = [foo, garply]; + interfaceList @33 : List(Void); # TODO +} + +struct TestAnyPointer { + anyPointerField @0 :AnyPointer; + + # Do not add any other fields here! Some tests rely on anyPointerField being the last pointer + # in the struct. +} + +struct TestOutOfOrder { + foo @3 :Text; + bar @2 :Text; + baz @8 :Text; + qux @0 :Text; + quux @6 :Text; + corge @4 :Text; + grault @1 :Text; + garply @7 :Text; + waldo @5 :Text; +} + +struct TestUnion { + union0 @0! :union { + # Pack union 0 under ideal conditions: there is no unused padding space prior to it. + u0f0s0 @4: Void; + u0f0s1 @5: Bool; + u0f0s8 @6: Int8; + u0f0s16 @7: Int16; + u0f0s32 @8: Int32; + u0f0s64 @9: Int64; + u0f0sp @10: Text; + + # Pack more stuff into union0 -- should go in same space. + u0f1s0 @11: Void; + u0f1s1 @12: Bool; + u0f1s8 @13: Int8; + u0f1s16 @14: Int16; + u0f1s32 @15: Int32; + u0f1s64 @16: Int64; + u0f1sp @17: Text; + } + + # Pack one bit in order to make pathological situation for union1. + bit0 @18: Bool; + + union1 @1! :union { + # Pack pathologically bad case. Each field takes up new space. + u1f0s0 @19: Void; + u1f0s1 @20: Bool; + u1f1s1 @21: Bool; + u1f0s8 @22: Int8; + u1f1s8 @23: Int8; + u1f0s16 @24: Int16; + u1f1s16 @25: Int16; + u1f0s32 @26: Int32; + u1f1s32 @27: Int32; + u1f0s64 @28: Int64; + u1f1s64 @29: Int64; + u1f0sp @30: Text; + u1f1sp @31: Text; + + # Pack more stuff into union1 -- each should go into the same space as corresponding u1f0s*. + u1f2s0 @32: Void; + u1f2s1 @33: Bool; + u1f2s8 @34: Int8; + u1f2s16 @35: Int16; + u1f2s32 @36: Int32; + u1f2s64 @37: Int64; + u1f2sp @38: Text; + } + + # Fill in the rest of that bitfield from earlier. + bit2 @39: Bool; + bit3 @40: Bool; + bit4 @41: Bool; + bit5 @42: Bool; + bit6 @43: Bool; + bit7 @44: Bool; + + # Interleave two unions to be really annoying. + # Also declare in reverse order to make sure union discriminant values are sorted by field number + # and not by declaration order. + union2 @2! :union { + u2f0s64 @54: Int64; + u2f0s32 @52: Int32; + u2f0s16 @50: Int16; + u2f0s8 @47: Int8; + u2f0s1 @45: Bool; + } + + union3 @3! :union { + u3f0s64 @55: Int64; + u3f0s32 @53: Int32; + u3f0s16 @51: Int16; + u3f0s8 @48: Int8; + u3f0s1 @46: Bool; + } + + byte0 @49: UInt8; +} + +struct TestUnnamedUnion { + before @0 :Text; + + union { + foo @1 :UInt16; + bar @3 :UInt32; + } + + middle @2 :UInt16; + + after @4 :Text; +} + +struct TestUnionInUnion { + # There is no reason to ever do this. + outer :union { + inner :union { + foo @0 :Int32; + bar @1 :Int32; + } + baz @2 :Int32; + } +} + +struct TestGroups { + groups :union { + foo :group { + corge @0 :Int32; + grault @2 :Int64; + garply @8 :Text; + } + bar :group { + corge @3 :Int32; + grault @4 :Text; + garply @5 :Int64; + } + baz :group { + corge @1 :Int32; + grault @6 :Text; + garply @7 :Text; + } + } +} + +struct TestInterleavedGroups { + group1 :group { + foo @0 :UInt32; + bar @2 :UInt64; + union { + qux @4 :UInt16; + corge :group { + grault @6 :UInt64; + garply @8 :UInt16; + plugh @14 :Text; + xyzzy @16 :Text; + } + + fred @12 :Text; + } + + waldo @10 :Text; + } + + group2 :group { + foo @1 :UInt32; + bar @3 :UInt64; + union { + qux @5 :UInt16; + corge :group { + grault @7 :UInt64; + garply @9 :UInt16; + plugh @15 :Text; + xyzzy @17 :Text; + } + + fred @13 :Text; + } + + waldo @11 :Text; + } +} + +struct TestUnionDefaults { + s16s8s64s8Set @0 :TestUnion = + (union0 = (u0f0s16 = 321), union1 = (u1f0s8 = 123), union2 = (u2f0s64 = 12345678901234567), + union3 = (u3f0s8 = 55)); + s0sps1s32Set @1 :TestUnion = + (union0 = (u0f1s0 = void), union1 = (u1f0sp = "foo"), union2 = (u2f0s1 = true), + union3 = (u3f0s32 = 12345678)); + + unnamed1 @2 :TestUnnamedUnion = (foo = 123); + unnamed2 @3 :TestUnnamedUnion = (bar = 321, before = "foo", after = "bar"); +} + +struct TestNestedTypes { + enum NestedEnum { + foo @0; + bar @1; + } + + struct NestedStruct { + enum NestedEnum { + baz @0; + qux @1; + quux @2; + } + + outerNestedEnum @0 :TestNestedTypes.NestedEnum = bar; + innerNestedEnum @1 :NestedEnum = quux; + } + + nestedStruct @0 :NestedStruct; + + outerNestedEnum @1 :NestedEnum = bar; + innerNestedEnum @2 :NestedStruct.NestedEnum = quux; +} + +struct TestUsing { + using OuterNestedEnum = TestNestedTypes.NestedEnum; + using TestNestedTypes.NestedStruct.NestedEnum; + + outerNestedEnum @1 :OuterNestedEnum = bar; + innerNestedEnum @0 :NestedEnum = quux; +} + +struct TestLists { + # Small structs, when encoded as list, will be encoded as primitive lists rather than struct + # lists, to save space. + struct Struct0 { f @0 :Void; } + struct Struct1 { f @0 :Bool; } + struct Struct8 { f @0 :UInt8; } + struct Struct16 { f @0 :UInt16; } + struct Struct32 { f @0 :UInt32; } + struct Struct64 { f @0 :UInt64; } + struct StructP { f @0 :Text; } + + # Versions of the above which cannot be encoded as primitive lists. + struct Struct0c { f @0 :Void; pad @1 :Text; } + struct Struct1c { f @0 :Bool; pad @1 :Text; } + struct Struct8c { f @0 :UInt8; pad @1 :Text; } + struct Struct16c { f @0 :UInt16; pad @1 :Text; } + struct Struct32c { f @0 :UInt32; pad @1 :Text; } + struct Struct64c { f @0 :UInt64; pad @1 :Text; } + struct StructPc { f @0 :Text; pad @1 :UInt64; } + + list0 @0 :List(Struct0); + list1 @1 :List(Struct1); + list8 @2 :List(Struct8); + list16 @3 :List(Struct16); + list32 @4 :List(Struct32); + list64 @5 :List(Struct64); + listP @6 :List(StructP); + + int32ListList @7 :List(List(Int32)); + textListList @8 :List(List(Text)); + structListList @9 :List(List(TestAllTypes)); +} + +struct TestFieldZeroIsBit { + bit @0 :Bool; + secondBit @1 :Bool = true; + thirdField @2 :UInt8 = 123; +} + +struct TestListDefaults { + lists @0 :TestLists = ( + list0 = [(f = void), (f = void)], + list1 = [(f = true), (f = false), (f = true), (f = true)], + list8 = [(f = 123), (f = 45)], + list16 = [(f = 12345), (f = 6789)], + list32 = [(f = 123456789), (f = 234567890)], + list64 = [(f = 1234567890123456), (f = 2345678901234567)], + listP = [(f = "foo"), (f = "bar")], + int32ListList = [[1, 2, 3], [4, 5], [12341234]], + textListList = [["foo", "bar"], ["baz"], ["qux", "corge"]], + structListList = [[(int32Field = 123), (int32Field = 456)], [(int32Field = 789)]]); +} + +struct TestLateUnion { + # Test what happens if the unions are not the first ordinals in the struct. At one point this + # was broken for the dynamic API. + + foo @0 :Int32; + bar @1 :Text; + baz @2 :Int16; + + theUnion @3! :union { + qux @4 :Text; + corge @5 :List(Int32); + grault @6 :Float32; + } + + anotherUnion @7! :union { + qux @8 :Text; + corge @9 :List(Int32); + grault @10 :Float32; + } +} + +struct TestOldVersion { + # A subset of TestNewVersion. + old1 @0 :Int64; + old2 @1 :Text; + old3 @2 :TestOldVersion; +} + +struct TestNewVersion { + # A superset of TestOldVersion. + old1 @0 :Int64; + old2 @1 :Text; + old3 @2 :TestNewVersion; + new1 @3 :Int64 = 987; + new2 @4 :Text = "baz"; +} + +struct TestStructUnion { + un @0! :union { + struct @1 :SomeStruct; + object @2 :TestAnyPointer; + } + + struct SomeStruct { + someText @0 :Text; + moreText @1 :Text; + } +} + +struct TestPrintInlineStructs { + someText @0 :Text; + + structList @1 :List(InlineStruct); + struct InlineStruct { + int32Field @0 :Int32; + textField @1 :Text; + } +} + +struct TestEmptyStruct {} + +struct TestConstants { + const voidConst :Void = void; + const boolConst :Bool = true; + const int8Const :Int8 = -123; + const int16Const :Int16 = -12345; + const int32Const :Int32 = -12345678; + const int64Const :Int64 = -123456789012345; + const uint8Const :UInt8 = 234; + const uint16Const :UInt16 = 45678; + const uint32Const :UInt32 = 3456789012; + const uint64Const :UInt64 = 12345678901234567890; + const float32Const :Float32 = 1234.5; + const float64Const :Float64 = -123e45; + const textConst :Text = "foo"; + const dataConst :Data = "bar"; + const structConst :TestAllTypes = ( + voidField = void, + boolField = true, + int8Field = -12, + int16Field = 3456, + int32Field = -78901234, + int64Field = 56789012345678, + uInt8Field = 90, + uInt16Field = 1234, + uInt32Field = 56789012, + uInt64Field = 345678901234567890, + float32Field = -1.25e-10, + float64Field = 345, + textField = "baz", + dataField = "qux", + structField = ( + textField = "nested", + structField = (textField = "really nested")), + enumField = baz, + # interfaceField can't have a default + + voidList = [void, void, void], + boolList = [false, true, false, true, true], + int8List = [12, -34, -0x80, 0x7f], + int16List = [1234, -5678, -0x8000, 0x7fff], + int32List = [12345678, -90123456, -0x80000000, 0x7fffffff], + int64List = [123456789012345, -678901234567890, -0x8000000000000000, 0x7fffffffffffffff], + uInt8List = [12, 34, 0, 0xff], + uInt16List = [1234, 5678, 0, 0xffff], + uInt32List = [12345678, 90123456, 0, 0xffffffff], + uInt64List = [123456789012345, 678901234567890, 0, 0xffffffffffffffff], + float32List = [0, 1234567, 1e37, -1e37, 1e-37, -1e-37], + float64List = [0, 123456789012345, 1e306, -1e306, 1e-306, -1e-306], + textList = ["quux", "corge", "grault"], + dataList = ["garply", "waldo", "fred"], + structList = [ + (textField = "x structlist 1"), + (textField = "x structlist 2"), + (textField = "x structlist 3")], + enumList = [qux, bar, grault] + # interfaceList can't have a default + ); + const enumConst :TestEnum = corge; + + const voidListConst :List(Void) = [void, void, void, void, void, void]; + const boolListConst :List(Bool) = [true, false, false, true]; + const int8ListConst :List(Int8) = [111, -111]; + const int16ListConst :List(Int16) = [11111, -11111]; + const int32ListConst :List(Int32) = [111111111, -111111111]; + const int64ListConst :List(Int64) = [1111111111111111111, -1111111111111111111]; + const uint8ListConst :List(UInt8) = [111, 222] ; + const uint16ListConst :List(UInt16) = [33333, 44444]; + const uint32ListConst :List(UInt32) = [3333333333]; + const uint64ListConst :List(UInt64) = [11111111111111111111]; + const float32ListConst :List(Float32) = [5555.5, inf, -inf, nan]; + const float64ListConst :List(Float64) = [7777.75, inf, -inf, nan]; + const textListConst :List(Text) = ["plugh", "xyzzy", "thud"]; + const dataListConst :List(Data) = ["oops", "exhausted", "rfc3092"]; + const structListConst :List(TestAllTypes) = [ + (textField = "structlist 1"), + (textField = "structlist 2"), + (textField = "structlist 3")]; + const enumListConst :List(TestEnum) = [foo, garply]; +} + +const globalInt :UInt32 = 12345; +const globalText :Text = "foobar"; +const globalStruct :TestAllTypes = (int32Field = 54321); +const globalPrintableStruct :TestPrintInlineStructs = (someText = "foo"); +const derivedConstant :TestAllTypes = ( + uInt32Field = .globalInt, + textField = TestConstants.textConst, + structField = TestConstants.structConst, + int16List = TestConstants.int16ListConst, + structList = TestConstants.structListConst); + +interface TestInterface { + foo @0 (i :UInt32, j :Bool) -> (x :Text); + bar @1 () -> (); + baz @2 (s: TestAllTypes); +} + +interface TestExtends extends(TestInterface) { + qux @0 (); + corge @1 TestAllTypes -> (); + grault @2 () -> TestAllTypes; +} + +interface TestPipeline { + getCap @0 (n: UInt32, inCap :TestInterface) -> (s: Text, outBox :Box); + testPointers @1 (cap :TestInterface, obj :AnyPointer, list :List(TestInterface)) -> (); + + struct Box { + cap @0 :TestInterface; + } +} + +interface TestCallOrder { + getCallSequence @0 (expected: UInt32) -> (n: UInt32); + # First call returns 0, next returns 1, ... + # + # The input `expected` is ignored but useful for disambiguating debug logs. +} + +interface TestTailCallee { + struct TailResult { + i @0 :UInt32; + t @1 :Text; + c @2 :TestCallOrder; + } + + foo @0 (i :Int32, t :Text) -> TailResult; +} + +interface TestTailCaller { + foo @0 (i :Int32, callee :TestTailCallee) -> TestTailCallee.TailResult; +} + +interface TestMoreStuff extends(TestCallOrder) { + # Catch-all type that contains lots of testing methods. + + callFoo @0 (cap :TestInterface) -> (s: Text); + # Call `cap.foo()`, check the result, and return "bar". + + callFooWhenResolved @1 (cap :TestInterface) -> (s: Text); + # Like callFoo but waits for `cap` to resolve first. + + neverReturn @2 (cap :TestInterface) -> (capCopy :TestInterface); + # Doesn't return. You should cancel it. + + hold @3 (cap :TestInterface) -> (); + # Returns immediately but holds on to the capability. + + callHeld @4 () -> (s: Text); + # Calls the capability previously held using `hold` (and keeps holding it). + + getHeld @5 () -> (cap :TestInterface); + # Returns the capability previously held using `hold` (and keeps holding it). + + echo @6 (cap :TestCallOrder) -> (cap :TestCallOrder); + # Just returns the input cap. + + expectCancel @7 (cap :TestInterface) -> (); + # evalLater()-loops forever, holding `cap`. Must be canceled. + + methodWithDefaults @8 (a :Text, b :UInt32 = 123, c :Text = "foo") -> (d :Text, e :Text = "bar"); +} + +interface TestKeywordMethods { + delete @0 (); + class @1 (); + void @2 (); + return @3 (); +} + +struct TestSturdyRefHostId { + host @0 :Text; +} + +struct TestSturdyRefObjectId { + tag @0 :Tag; + enum Tag { + testInterface @0; + testExtends @1; + testPipeline @2; + testTailCallee @3; + testTailCaller @4; + testMoreStuff @5; + } +} + +struct TestProvisionId {} +struct TestRecipientId {} +struct TestThirdPartyCapId {} +struct TestJoinResult {} + +struct TestNameAnnotation $Cxx.name("RenamedStruct") { + union { + badFieldName @0 :Bool $Cxx.name("goodFieldName"); + bar @1 :Int8; + } + + enum BadlyNamedEnum $Cxx.name("RenamedEnum") { + foo @0; + bar @1; + baz @2 $Cxx.name("qux"); + } + + anotherBadFieldName @2 :BadlyNamedEnum $Cxx.name("anotherGoodFieldName"); + + struct NestedStruct $Cxx.name("RenamedNestedStruct") { + badNestedFieldName @0 :Bool $Cxx.name("goodNestedFieldName"); + anotherBadNestedFieldName @1 :NestedStruct $Cxx.name("anotherGoodNestedFieldName"); + + enum DeeplyNestedEnum $Cxx.name("RenamedDeeplyNestedEnum") { + quux @0; + corge @1; + grault @2 $Cxx.name("garply"); + } + } + + badlyNamedUnion :union $Cxx.name("renamedUnion") { + badlyNamedGroup :group $Cxx.name("renamedGroup") { + foo @3 :Void; + bar @4 :Void; + } + baz @5 :NestedStruct $Cxx.name("qux"); + } +} + +interface TestNameAnnotationInterface $Cxx.name("RenamedInterface") { + badlyNamedMethod @0 (badlyNamedParam :UInt8 $Cxx.name("renamedParam")) $Cxx.name("renamedMethod"); +} diff --git a/src/tests/testBytesStorage.ml b/src/tests/testBytesStorage.ml index 0fa2e7b..a418a9b 100644 --- a/src/tests/testBytesStorage.ml +++ b/src/tests/testBytesStorage.ml @@ -496,13 +496,3 @@ let int64_suite = -let () = run_test_tt_main uint8_suite -let () = run_test_tt_main uint16_suite -let () = run_test_tt_main uint32_suite -let () = run_test_tt_main uint64_suite -let () = run_test_tt_main int8_suite -let () = run_test_tt_main int16_suite -let () = run_test_tt_main int32_suite -let () = run_test_tt_main int64_suite - - diff --git a/src/tests/testCodecs.ml b/src/tests/testCodecs.ml index b74dabd..dc6792b 100644 --- a/src/tests/testCodecs.ml +++ b/src/tests/testCodecs.ml @@ -198,8 +198,8 @@ let test_random_serialize_deserialize ctx = | Result.Ok decoded_message -> let () = assert (Codecs.FramedStream.bytes_available ser_fragments = (String.length trailing_data)) in - (Message.BytesMessage.Message.to_storage m) = - (Message.BytesMessage.Message.to_storage decoded_message) + (Capnp.Message.BytesMessage.Message.to_storage m) = + (Capnp.Message.BytesMessage.Message.to_storage decoded_message) | Result.Error _ -> assert false) @@ -213,8 +213,8 @@ let test_random_serialize_deserialize_packed ctx = let () = fragment packed (Codecs.FramedStream.add_fragment pack_fragments) in match Codecs.FramedStream.get_next_frame pack_fragments with | Result.Ok decoded_message -> - (Message.BytesMessage.Message.to_storage m) = - (Message.BytesMessage.Message.to_storage decoded_message) + (Capnp.Message.BytesMessage.Message.to_storage m) = + (Capnp.Message.BytesMessage.Message.to_storage decoded_message) | Result.Error _ -> assert false) @@ -225,8 +225,3 @@ let random_serialize_suite = "serialize_deserialize_packed_message" >:: test_random_serialize_deserialize_packed; ] - -let () = run_test_tt_main packing_suite -let () = run_test_tt_main random_packing_suite -let () = run_test_tt_main random_serialize_suite - diff --git a/src/tests/testEncoding.ml b/src/tests/testEncoding.ml index fc5461a..48a25c1 100644 --- a/src/tests/testEncoding.ml +++ b/src/tests/testEncoding.ml @@ -1667,5 +1667,3 @@ let encoding_suite = "test any pointers" >:: test_any_pointers; ] -let () = run_test_tt_main encoding_suite - diff --git a/src/tests/testLists.capnp b/src/tests/testLists.capnp index 1c420a0..d09b1a5 100644 --- a/src/tests/testLists.capnp +++ b/src/tests/testLists.capnp @@ -27,7 +27,7 @@ @0xfc014463ebb6551b; -using Test = import "/capnp/test.capnp"; +using Test = import "test.capnp"; struct VoidList { a @0 : List(Void); diff --git a/src/tests/testMisc.ml b/src/tests/testMisc.ml index db77903..c1ab260 100644 --- a/src/tests/testMisc.ml +++ b/src/tests/testMisc.ml @@ -59,7 +59,4 @@ let decode_signed_suite = "random negative" >:: t4; ] -let () = run_test_tt_main encode_signed_suite -let () = run_test_tt_main decode_signed_suite -