2
0
Эх сурвалжийг харах

Merge branch 'development' into null_uint_test

Simon Krajewski 1 жил өмнө
parent
commit
5d5053ff3f
100 өөрчлөгдсөн 5081 нэмэгдсэн , 9631 устгасан
  1. 24 0
      .devcontainer/devcontainer.json
  2. 28 0
      .devcontainer/docker-compose.yml
  3. 454 0
      .devcontainer/library-scripts/common-debian.sh
  4. 309 0
      .devcontainer/library-scripts/docker-debian.sh
  5. 6 0
      .earthlyignore
  6. 0 2
      .gitattributes
  7. 14 0
      .github/workflows/cancel.yml
  8. 828 0
      .github/workflows/main.yml
  9. 4 0
      .gitignore
  10. 8 0
      .vscode/schemas/define.schema.json
  11. 1 2
      .vscode/schemas/meta.schema.json
  12. 3 53
      CONTRIBUTING.md
  13. 411 0
      Earthfile
  14. 18 10
      Makefile
  15. 7 4
      Makefile.win
  16. 1 3
      README.md
  17. 0 315
      azure-pipelines.yml
  18. 2 1
      dune
  19. 2 2
      dune-project
  20. 3 3
      extra/BUILDING.md
  21. 556 4
      extra/CHANGES.txt
  22. 1 1
      extra/EnvVarUpdate.nsh
  23. 38 41
      extra/ImportAll.hx
  24. 1 11
      extra/all.hxml
  25. 0 61
      extra/azure-pipelines/build-linux.yml
  26. 0 46
      extra/azure-pipelines/build-mac.yml
  27. 0 72
      extra/azure-pipelines/build-windows.yml
  28. 0 33
      extra/azure-pipelines/install-neko-snapshot.yaml
  29. 0 87
      extra/azure-pipelines/test-windows.yml
  30. 3 3
      extra/choco/haxe.nuspec
  31. 2 7
      extra/doc.hxml
  32. 47 0
      extra/github-actions/Main.hx
  33. 62 0
      extra/github-actions/build-mac.yml
  34. 40 0
      extra/github-actions/build-windows.yml
  35. 2 0
      extra/github-actions/build.hxml
  36. 16 0
      extra/github-actions/install-neko-unix.yml
  37. 11 0
      extra/github-actions/install-neko-windows.yml
  38. 14 0
      extra/github-actions/install-nsis.yml
  39. 6 0
      extra/github-actions/install-ocaml-libs-windows.yml
  40. 39 0
      extra/github-actions/install-ocaml-windows.yml
  41. 20 0
      extra/github-actions/install-ocaml-windows64.yml
  42. 32 0
      extra/github-actions/test-mac.yml
  43. 59 0
      extra/github-actions/test-windows.yml
  44. 492 0
      extra/github-actions/workflows/main.yml
  45. 1 1
      extra/haxelib_src
  46. BIN
      extra/images/Readme.png
  47. 1 1
      extra/installer.nsi
  48. 2 2
      extra/mac-installer/scripts/neko-postinstall.sh
  49. 22 11
      extra/release-checklist.txt
  50. 15 12
      haxe.opam
  51. 2 3
      libs/Makefile
  52. 0 5
      libs/README.md
  53. 7 3
      libs/extc/dune
  54. 3 3
      libs/extc/extc.ml
  55. 21 21
      libs/extc/extc_stubs.c
  56. 46 52
      libs/extc/process_stubs.c
  57. 130 0
      libs/extlib-leftovers/base64.ml
  58. 65 0
      libs/extlib-leftovers/base64.mli
  59. 8 2
      libs/extlib-leftovers/dune
  60. 5 5
      libs/extlib-leftovers/multiArray.ml
  61. 1 1
      libs/extlib-leftovers/uTF8.ml
  62. 0 26
      libs/ilib/Makefile
  63. 0 38
      libs/ilib/dump.ml
  64. 0 9
      libs/ilib/dune
  65. 0 115
      libs/ilib/ilData.mli
  66. 0 1204
      libs/ilib/ilMeta.mli
  67. 0 24
      libs/ilib/ilMetaDebug.ml
  68. 0 2403
      libs/ilib/ilMetaReader.ml
  69. 0 472
      libs/ilib/ilMetaTools.ml
  70. 0 78
      libs/ilib/ilMetaWriter.ml
  71. 0 546
      libs/ilib/peData.ml
  72. 0 184
      libs/ilib/peDataDebug.ml
  73. 0 493
      libs/ilib/peReader.ml
  74. 0 158
      libs/ilib/peWriter.ml
  75. 0 22
      libs/javalib/Makefile
  76. 0 7
      libs/javalib/dune
  77. 0 250
      libs/javalib/jData.ml
  78. 0 597
      libs/javalib/jReader.ml
  79. 0 289
      libs/javalib/jWriter.ml
  80. 4 4
      libs/mbedtls/dune
  81. 7 1
      libs/neko/dune
  82. 2 2
      libs/neko/ncompile.ml
  83. 0 0
      libs/objsize/alloc.h
  84. 1 1
      libs/objsize/bitarray.h
  85. 28 5
      libs/objsize/c_objsize.c
  86. 3 4
      libs/objsize/dune
  87. 0 66
      libs/ocamake/ocamake.dsp
  88. 0 29
      libs/ocamake/ocamake.dsw
  89. 0 94
      libs/ocamake/ocamake.html
  90. 0 661
      libs/ocamake/ocamake.ml
  91. 0 28
      libs/pcre/Makefile
  92. 0 7
      libs/pcre/dune
  93. 0 737
      libs/pcre/pcre_stubs.c
  94. 28 0
      libs/pcre2/Makefile
  95. 9 0
      libs/pcre2/dune
  96. 309 194
      libs/pcre2/pcre2.ml
  97. 794 0
      libs/pcre2/pcre2_stubs.c
  98. 1 0
      libs/swflib/as3.mli
  99. 1 0
      libs/swflib/as3code.ml
  100. 1 0
      libs/swflib/as3hl.mli

+ 24 - 0
.devcontainer/devcontainer.json

@@ -0,0 +1,24 @@
+// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
+// https://github.com/microsoft/vscode-dev-containers/tree/v0.202.5/containers/docker-from-docker-compose
+{
+	"name": "haxe",
+	"dockerComposeFile": "docker-compose.yml",
+	"service": "workspace",
+	"workspaceFolder": "/workspace",
+
+	// Use this environment variable if you need to bind mount your local source code into a new container.
+	"remoteEnv": {
+		"LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}"
+	},
+	
+	// Set *default* container specific settings.json values on container create.
+	"settings": {},
+
+	"extensions": [
+		"nadako.vshaxe",
+		"ms-azuretools.vscode-docker",
+		"earthly.earthfile-syntax-highlighting",
+	],
+
+	"remoteUser": "vscode"
+}

+ 28 - 0
.devcontainer/docker-compose.yml

@@ -0,0 +1,28 @@
+version: '3'
+services:
+  workspace:
+    image: ghcr.io/haxefoundation/haxe_devcontainer:development
+    init: true
+    volumes:
+      - /var/run/docker.sock:/var/run/docker-host.sock
+      - ..:/workspace:cached
+    environment:
+      - EARTHLY_BUILDKIT_HOST=tcp://earthly:8372
+      - EARTHLY_USE_INLINE_CACHE=true
+      - EARTHLY_SAVE_INLINE_CACHE=true
+    user: vscode
+    entrypoint: /usr/local/share/docker-init.sh
+    command: sleep infinity
+  earthly:
+    image: earthly/buildkitd:v0.6.13
+    privileged: true
+    environment:
+      - BUILDKIT_TCP_TRANSPORT_ENABLED=true
+    expose:
+      - 8372
+    volumes:
+      # https://docs.earthly.dev/docs/guides/using-the-earthly-docker-images/buildkit-standalone#earthly_tmp_dir
+      - earthly-tmp:/tmp/earthly:rw
+
+volumes:
+  earthly-tmp:

+ 454 - 0
.devcontainer/library-scripts/common-debian.sh

@@ -0,0 +1,454 @@
+#!/usr/bin/env bash
+#-------------------------------------------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
+#-------------------------------------------------------------------------------------------------------------
+#
+# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/common.md
+# Maintainer: The VS Code and Codespaces Teams
+#
+# Syntax: ./common-debian.sh [install zsh flag] [username] [user UID] [user GID] [upgrade packages flag] [install Oh My Zsh! flag] [Add non-free packages]
+
+set -e
+
+INSTALL_ZSH=${1:-"true"}
+USERNAME=${2:-"automatic"}
+USER_UID=${3:-"automatic"}
+USER_GID=${4:-"automatic"}
+UPGRADE_PACKAGES=${5:-"true"}
+INSTALL_OH_MYS=${6:-"true"}
+ADD_NON_FREE_PACKAGES=${7:-"false"}
+SCRIPT_DIR="$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)"
+MARKER_FILE="/usr/local/etc/vscode-dev-containers/common"
+
+if [ "$(id -u)" -ne 0 ]; then
+    echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
+    exit 1
+fi
+
+# Ensure that login shells get the correct path if the user updated the PATH using ENV.
+rm -f /etc/profile.d/00-restore-env.sh
+echo "export PATH=${PATH//$(sh -lc 'echo $PATH')/\$PATH}" > /etc/profile.d/00-restore-env.sh
+chmod +x /etc/profile.d/00-restore-env.sh
+
+# If in automatic mode, determine if a user already exists, if not use vscode
+if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
+    USERNAME=""
+    POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)")
+    for CURRENT_USER in ${POSSIBLE_USERS[@]}; do
+        if id -u ${CURRENT_USER} > /dev/null 2>&1; then
+            USERNAME=${CURRENT_USER}
+            break
+        fi
+    done
+    if [ "${USERNAME}" = "" ]; then
+        USERNAME=vscode
+    fi
+elif [ "${USERNAME}" = "none" ]; then
+    USERNAME=root
+    USER_UID=0
+    USER_GID=0
+fi
+
+# Load markers to see which steps have already run
+if [ -f "${MARKER_FILE}" ]; then
+    echo "Marker file found:"
+    cat "${MARKER_FILE}"
+    source "${MARKER_FILE}"
+fi
+
+# Ensure apt is in non-interactive to avoid prompts
+export DEBIAN_FRONTEND=noninteractive
+
+# Function to call apt-get if needed
+apt_get_update_if_needed()
+{
+    if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
+        echo "Running apt-get update..."
+        apt-get update
+    else
+        echo "Skipping apt-get update."
+    fi
+}
+
+# Run install apt-utils to avoid debconf warning then verify presence of other common developer tools and dependencies
+if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then
+
+    package_list="apt-utils \
+        openssh-client \
+        gnupg2 \
+        dirmngr \
+        iproute2 \
+        procps \
+        lsof \
+        htop \
+        net-tools \
+        psmisc \
+        curl \
+        wget \
+        rsync \
+        ca-certificates \
+        unzip \
+        zip \
+        nano \
+        vim-tiny \
+        less \
+        jq \
+        lsb-release \
+        apt-transport-https \
+        dialog \
+        libc6 \
+        libgcc1 \
+        libkrb5-3 \
+        libgssapi-krb5-2 \
+        libicu[0-9][0-9] \
+        liblttng-ust0 \
+        libstdc++6 \
+        zlib1g \
+        locales \
+        sudo \
+        ncdu \
+        man-db \
+        strace \
+        manpages \
+        manpages-dev \
+        init-system-helpers"
+        
+    # Needed for adding manpages-posix and manpages-posix-dev which are non-free packages in Debian
+    if [ "${ADD_NON_FREE_PACKAGES}" = "true" ]; then
+        # Bring in variables from /etc/os-release like VERSION_CODENAME
+        . /etc/os-release
+        sed -i -E "s/deb http:\/\/(deb|httpredir)\.debian\.org\/debian ${VERSION_CODENAME} main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME} main contrib non-free/" /etc/apt/sources.list
+        sed -i -E "s/deb-src http:\/\/(deb|httredir)\.debian\.org\/debian ${VERSION_CODENAME} main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME} main contrib non-free/" /etc/apt/sources.list
+        sed -i -E "s/deb http:\/\/(deb|httpredir)\.debian\.org\/debian ${VERSION_CODENAME}-updates main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME}-updates main contrib non-free/" /etc/apt/sources.list
+        sed -i -E "s/deb-src http:\/\/(deb|httpredir)\.debian\.org\/debian ${VERSION_CODENAME}-updates main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME}-updates main contrib non-free/" /etc/apt/sources.list
+        sed -i "s/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main contrib non-free/" /etc/apt/sources.list
+        sed -i "s/deb-src http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main contrib non-free/" /etc/apt/sources.list
+        sed -i "s/deb http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main/deb http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main contrib non-free/" /etc/apt/sources.list 
+        sed -i "s/deb-src http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main/deb http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main contrib non-free/" /etc/apt/sources.list
+        # Handle bullseye location for security https://www.debian.org/releases/bullseye/amd64/release-notes/ch-information.en.html
+        sed -i "s/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}-security main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}-security main contrib non-free/" /etc/apt/sources.list
+        sed -i "s/deb-src http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}-security main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}-security main contrib non-free/" /etc/apt/sources.list
+        echo "Running apt-get update..."
+        apt-get update
+        package_list="${package_list} manpages-posix manpages-posix-dev"
+    else
+        apt_get_update_if_needed
+    fi
+
+    # Install libssl1.1 if available
+    if [[ ! -z $(apt-cache --names-only search ^libssl1.1$) ]]; then
+        package_list="${package_list}       libssl1.1"
+    fi
+    
+    # Install appropriate version of libssl1.0.x if available
+    libssl_package=$(dpkg-query -f '${db:Status-Abbrev}\t${binary:Package}\n' -W 'libssl1\.0\.?' 2>&1 || echo '')
+    if [ "$(echo "$LIlibssl_packageBSSL" | grep -o 'libssl1\.0\.[0-9]:' | uniq | sort | wc -l)" -eq 0 ]; then
+        if [[ ! -z $(apt-cache --names-only search ^libssl1.0.2$) ]]; then
+            # Debian 9
+            package_list="${package_list}       libssl1.0.2"
+        elif [[ ! -z $(apt-cache --names-only search ^libssl1.0.0$) ]]; then
+            # Ubuntu 18.04, 16.04, earlier
+            package_list="${package_list}       libssl1.0.0"
+        fi
+    fi
+
+    echo "Packages to verify are installed: ${package_list}"
+    apt-get -y install --no-install-recommends ${package_list} 2> >( grep -v 'debconf: delaying package configuration, since apt-utils is not installed' >&2 )
+        
+    # Install git if not already installed (may be more recent than distro version)
+    if ! type git > /dev/null 2>&1; then
+        apt-get -y install --no-install-recommends git
+    fi
+
+    PACKAGES_ALREADY_INSTALLED="true"
+fi
+
+# Get to latest versions of all packages
+if [ "${UPGRADE_PACKAGES}" = "true" ]; then
+    apt_get_update_if_needed
+    apt-get -y upgrade --no-install-recommends
+    apt-get autoremove -y
+fi
+
+# Ensure at least the en_US.UTF-8 UTF-8 locale is available.
+# Common need for both applications and things like the agnoster ZSH theme.
+if [ "${LOCALE_ALREADY_SET}" != "true" ] && ! grep -o -E '^\s*en_US.UTF-8\s+UTF-8' /etc/locale.gen > /dev/null; then
+    echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen 
+    locale-gen
+    LOCALE_ALREADY_SET="true"
+fi
+
+# Create or update a non-root user to match UID/GID.
+group_name="${USERNAME}"
+if id -u ${USERNAME} > /dev/null 2>&1; then
+    # User exists, update if needed
+    if [ "${USER_GID}" != "automatic" ] && [ "$USER_GID" != "$(id -g $USERNAME)" ]; then 
+        group_name="$(id -gn $USERNAME)"
+        groupmod --gid $USER_GID ${group_name}
+        usermod --gid $USER_GID $USERNAME
+    fi
+    if [ "${USER_UID}" != "automatic" ] && [ "$USER_UID" != "$(id -u $USERNAME)" ]; then 
+        usermod --uid $USER_UID $USERNAME
+    fi
+else
+    # Create user
+    if [ "${USER_GID}" = "automatic" ]; then
+        groupadd $USERNAME
+    else
+        groupadd --gid $USER_GID $USERNAME
+    fi
+    if [ "${USER_UID}" = "automatic" ]; then 
+        useradd -s /bin/bash --gid $USERNAME -m $USERNAME
+    else
+        useradd -s /bin/bash --uid $USER_UID --gid $USERNAME -m $USERNAME
+    fi
+fi
+
+# Add add sudo support for non-root user
+if [ "${USERNAME}" != "root" ] && [ "${EXISTING_NON_ROOT_USER}" != "${USERNAME}" ]; then
+    echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME
+    chmod 0440 /etc/sudoers.d/$USERNAME
+    EXISTING_NON_ROOT_USER="${USERNAME}"
+fi
+
+# ** Shell customization section **
+if [ "${USERNAME}" = "root" ]; then 
+    user_rc_path="/root"
+else
+    user_rc_path="/home/${USERNAME}"
+fi
+
+# Restore user .bashrc defaults from skeleton file if it doesn't exist or is empty
+if [ ! -f "${user_rc_path}/.bashrc" ] || [ ! -s "${user_rc_path}/.bashrc" ] ; then
+    cp  /etc/skel/.bashrc "${user_rc_path}/.bashrc"
+fi
+
+# Restore user .profile defaults from skeleton file if it doesn't exist or is empty
+if  [ ! -f "${user_rc_path}/.profile" ] || [ ! -s "${user_rc_path}/.profile" ] ; then
+    cp  /etc/skel/.profile "${user_rc_path}/.profile"
+fi
+
+# .bashrc/.zshrc snippet
+rc_snippet="$(cat << 'EOF'
+
+if [ -z "${USER}" ]; then export USER=$(whoami); fi
+if [[ "${PATH}" != *"$HOME/.local/bin"* ]]; then export PATH="${PATH}:$HOME/.local/bin"; fi
+
+# Display optional first run image specific notice if configured and terminal is interactive
+if [ -t 1 ] && [[ "${TERM_PROGRAM}" = "vscode" || "${TERM_PROGRAM}" = "codespaces" ]] && [ ! -f "$HOME/.config/vscode-dev-containers/first-run-notice-already-displayed" ]; then
+    if [ -f "/usr/local/etc/vscode-dev-containers/first-run-notice.txt" ]; then
+        cat "/usr/local/etc/vscode-dev-containers/first-run-notice.txt"
+    elif [ -f "/workspaces/.codespaces/shared/first-run-notice.txt" ]; then
+        cat "/workspaces/.codespaces/shared/first-run-notice.txt"
+    fi
+    mkdir -p "$HOME/.config/vscode-dev-containers"
+    # Mark first run notice as displayed after 10s to avoid problems with fast terminal refreshes hiding it
+    ((sleep 10s; touch "$HOME/.config/vscode-dev-containers/first-run-notice-already-displayed") &)
+fi
+
+# Set the default git editor if not already set
+if [ -z "$(git config --get core.editor)" ] && [ -z "${GIT_EDITOR}" ]; then
+    if  [ "${TERM_PROGRAM}" = "vscode" ]; then
+        if [[ -n $(command -v code-insiders) &&  -z $(command -v code) ]]; then 
+            export GIT_EDITOR="code-insiders --wait"
+        else 
+            export GIT_EDITOR="code --wait"
+        fi
+    fi
+fi
+
+EOF
+)"
+
+# code shim, it fallbacks to code-insiders if code is not available
+cat << 'EOF' > /usr/local/bin/code
+#!/bin/sh
+
+get_in_path_except_current() {
+    which -a "$1" | grep -A1 "$0" | grep -v "$0"
+}
+
+code="$(get_in_path_except_current code)"
+
+if [ -n "$code" ]; then
+    exec "$code" "$@"
+elif [ "$(command -v code-insiders)" ]; then
+    exec code-insiders "$@"
+else
+    echo "code or code-insiders is not installed" >&2
+    exit 127
+fi
+EOF
+chmod +x /usr/local/bin/code
+
+# systemctl shim - tells people to use 'service' if systemd is not running
+cat << 'EOF' > /usr/local/bin/systemctl
+#!/bin/sh
+set -e
+if [ -d "/run/systemd/system" ]; then
+    exec /bin/systemctl/systemctl "$@"
+else
+    echo '\n"systemd" is not running in this container due to its overhead.\nUse the "service" command to start services intead. e.g.: \n\nservice --status-all'
+fi
+EOF
+chmod +x /usr/local/bin/systemctl
+
+# Codespaces bash and OMZ themes - partly inspired by https://github.com/ohmyzsh/ohmyzsh/blob/master/themes/robbyrussell.zsh-theme
+codespaces_bash="$(cat \
+<<'EOF'
+
+# Codespaces bash prompt theme
+__bash_prompt() {
+    local userpart='`export XIT=$? \
+        && [ ! -z "${GITHUB_USER}" ] && echo -n "\[\033[0;32m\]@${GITHUB_USER} " || echo -n "\[\033[0;32m\]\u " \
+        && [ "$XIT" -ne "0" ] && echo -n "\[\033[1;31m\]➜" || echo -n "\[\033[0m\]➜"`'
+    local gitbranch='`\
+        if [ "$(git config --get codespaces-theme.hide-status 2>/dev/null)" != 1 ]; then \
+            export BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null || git rev-parse --short HEAD 2>/dev/null); \
+            if [ "${BRANCH}" != "" ]; then \
+                echo -n "\[\033[0;36m\](\[\033[1;31m\]${BRANCH}" \
+                && if git ls-files --error-unmatch -m --directory --no-empty-directory -o --exclude-standard ":/*" > /dev/null 2>&1; then \
+                        echo -n " \[\033[1;33m\]✗"; \
+                fi \
+                && echo -n "\[\033[0;36m\]) "; \
+            fi; \
+        fi`'
+    local lightblue='\[\033[1;34m\]'
+    local removecolor='\[\033[0m\]'
+    PS1="${userpart} ${lightblue}\w ${gitbranch}${removecolor}\$ "
+    unset -f __bash_prompt
+}
+__bash_prompt
+
+EOF
+)"
+
+codespaces_zsh="$(cat \
+<<'EOF'
+# Codespaces zsh prompt theme
+__zsh_prompt() {
+    local prompt_username
+    if [ ! -z "${GITHUB_USER}" ]; then 
+        prompt_username="@${GITHUB_USER}"
+    else
+        prompt_username="%n"
+    fi
+    PROMPT="%{$fg[green]%}${prompt_username} %(?:%{$reset_color%}➜ :%{$fg_bold[red]%}➜ )" # User/exit code arrow
+    PROMPT+='%{$fg_bold[blue]%}%(5~|%-1~/…/%3~|%4~)%{$reset_color%} ' # cwd
+    PROMPT+='$([ "$(git config --get codespaces-theme.hide-status 2>/dev/null)" != 1 ] && git_prompt_info)' # Git status
+    PROMPT+='%{$fg[white]%}$ %{$reset_color%}'
+    unset -f __zsh_prompt
+}
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[cyan]%}(%{$fg_bold[red]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
+ZSH_THEME_GIT_PROMPT_DIRTY=" %{$fg_bold[yellow]%}✗%{$fg_bold[cyan]%})"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg_bold[cyan]%})"
+__zsh_prompt
+
+EOF
+)"
+
+# Add RC snippet and custom bash prompt
+if [ "${RC_SNIPPET_ALREADY_ADDED}" != "true" ]; then
+    echo "${rc_snippet}" >> /etc/bash.bashrc
+    echo "${codespaces_bash}" >> "${user_rc_path}/.bashrc"
+    echo 'export PROMPT_DIRTRIM=4' >> "${user_rc_path}/.bashrc"
+    if [ "${USERNAME}" != "root" ]; then
+        echo "${codespaces_bash}" >> "/root/.bashrc"
+        echo 'export PROMPT_DIRTRIM=4' >> "/root/.bashrc"
+    fi
+    chown ${USERNAME}:${group_name} "${user_rc_path}/.bashrc"
+    RC_SNIPPET_ALREADY_ADDED="true"
+fi
+
+# Optionally install and configure zsh and Oh My Zsh!
+if [ "${INSTALL_ZSH}" = "true" ]; then
+    if ! type zsh > /dev/null 2>&1; then
+        apt_get_update_if_needed
+        apt-get install -y zsh
+    fi
+    if [ "${ZSH_ALREADY_INSTALLED}" != "true" ]; then
+        echo "${rc_snippet}" >> /etc/zsh/zshrc
+        ZSH_ALREADY_INSTALLED="true"
+    fi
+
+    # Adapted, simplified inline Oh My Zsh! install steps that adds, defaults to a codespaces theme.
+    # See https://github.com/ohmyzsh/ohmyzsh/blob/master/tools/install.sh for official script.
+    oh_my_install_dir="${user_rc_path}/.oh-my-zsh"
+    if [ ! -d "${oh_my_install_dir}" ] && [ "${INSTALL_OH_MYS}" = "true" ]; then
+        template_path="${oh_my_install_dir}/templates/zshrc.zsh-template"
+        user_rc_file="${user_rc_path}/.zshrc"
+        umask g-w,o-w
+        mkdir -p ${oh_my_install_dir}
+        git clone --depth=1 \
+            -c core.eol=lf \
+            -c core.autocrlf=false \
+            -c fsck.zeroPaddedFilemode=ignore \
+            -c fetch.fsck.zeroPaddedFilemode=ignore \
+            -c receive.fsck.zeroPaddedFilemode=ignore \
+            "https://github.com/ohmyzsh/ohmyzsh" "${oh_my_install_dir}" 2>&1
+        echo -e "$(cat "${template_path}")\nDISABLE_AUTO_UPDATE=true\nDISABLE_UPDATE_PROMPT=true" > ${user_rc_file}
+        sed -i -e 's/ZSH_THEME=.*/ZSH_THEME="codespaces"/g' ${user_rc_file}
+
+        mkdir -p ${oh_my_install_dir}/custom/themes
+        echo "${codespaces_zsh}" > "${oh_my_install_dir}/custom/themes/codespaces.zsh-theme"
+        # Shrink git while still enabling updates
+        cd "${oh_my_install_dir}"
+        git repack -a -d -f --depth=1 --window=1
+        # Copy to non-root user if one is specified
+        if [ "${USERNAME}" != "root" ]; then
+            cp -rf "${user_rc_file}" "${oh_my_install_dir}" /root
+            chown -R ${USERNAME}:${group_name} "${user_rc_path}"
+        fi
+    fi
+fi
+
+# Persist image metadata info, script if meta.env found in same directory
+meta_info_script="$(cat << 'EOF'
+#!/bin/sh
+. /usr/local/etc/vscode-dev-containers/meta.env
+
+# Minimal output
+if [ "$1" = "version" ] || [ "$1" = "image-version" ]; then
+    echo "${VERSION}"
+    exit 0
+elif [ "$1" = "release" ]; then
+    echo "${GIT_REPOSITORY_RELEASE}"
+    exit 0
+elif [ "$1" = "content" ] || [ "$1" = "content-url" ] || [ "$1" = "contents" ] || [ "$1" = "contents-url" ]; then
+    echo "${CONTENTS_URL}"
+    exit 0
+fi
+
+#Full output
+echo
+echo "Development container image information"
+echo
+if [ ! -z "${VERSION}" ]; then echo "- Image version: ${VERSION}"; fi
+if [ ! -z "${DEFINITION_ID}" ]; then echo "- Definition ID: ${DEFINITION_ID}"; fi
+if [ ! -z "${VARIANT}" ]; then echo "- Variant: ${VARIANT}"; fi
+if [ ! -z "${GIT_REPOSITORY}" ]; then echo "- Source code repository: ${GIT_REPOSITORY}"; fi
+if [ ! -z "${GIT_REPOSITORY_RELEASE}" ]; then echo "- Source code release/branch: ${GIT_REPOSITORY_RELEASE}"; fi
+if [ ! -z "${BUILD_TIMESTAMP}" ]; then echo "- Timestamp: ${BUILD_TIMESTAMP}"; fi
+if [ ! -z "${CONTENTS_URL}" ]; then echo && echo "More info: ${CONTENTS_URL}"; fi
+echo
+EOF
+)"
+if [ -f "${SCRIPT_DIR}/meta.env" ]; then
+    mkdir -p /usr/local/etc/vscode-dev-containers/
+    cp -f "${SCRIPT_DIR}/meta.env" /usr/local/etc/vscode-dev-containers/meta.env
+    echo "${meta_info_script}" > /usr/local/bin/devcontainer-info
+    chmod +x /usr/local/bin/devcontainer-info
+fi
+
+# Write marker file
+mkdir -p "$(dirname "${MARKER_FILE}")"
+echo -e "\
+    PACKAGES_ALREADY_INSTALLED=${PACKAGES_ALREADY_INSTALLED}\n\
+    LOCALE_ALREADY_SET=${LOCALE_ALREADY_SET}\n\
+    EXISTING_NON_ROOT_USER=${EXISTING_NON_ROOT_USER}\n\
+    RC_SNIPPET_ALREADY_ADDED=${RC_SNIPPET_ALREADY_ADDED}\n\
+    ZSH_ALREADY_INSTALLED=${ZSH_ALREADY_INSTALLED}" > "${MARKER_FILE}"
+
+echo "Done!"

+ 309 - 0
.devcontainer/library-scripts/docker-debian.sh

@@ -0,0 +1,309 @@
+#!/usr/bin/env bash
+#-------------------------------------------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
+#-------------------------------------------------------------------------------------------------------------
+#
+# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/docker.md
+# Maintainer: The VS Code and Codespaces Teams
+#
+# Syntax: ./docker-debian.sh [enable non-root docker socket access flag] [source socket] [target socket] [non-root user] [use moby] [CLI version]
+
+ENABLE_NONROOT_DOCKER=${1:-"true"}
+SOURCE_SOCKET=${2:-"/var/run/docker-host.sock"}
+TARGET_SOCKET=${3:-"/var/run/docker.sock"}
+USERNAME=${4:-"automatic"}
+USE_MOBY=${5:-"true"}
+DOCKER_VERSION=${6:-"latest"}
+MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc"
+DOCKER_DASH_COMPOSE_VERSION="1"
+
+set -e
+
+if [ "$(id -u)" -ne 0 ]; then
+    echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
+    exit 1
+fi
+
+# Determine the appropriate non-root user
+if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
+    USERNAME=""
+    POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)")
+    for CURRENT_USER in ${POSSIBLE_USERS[@]}; do
+        if id -u ${CURRENT_USER} > /dev/null 2>&1; then
+            USERNAME=${CURRENT_USER}
+            break
+        fi
+    done
+    if [ "${USERNAME}" = "" ]; then
+        USERNAME=root
+    fi
+elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then
+    USERNAME=root
+fi
+
+# Get central common setting
+get_common_setting() {
+    if [ "${common_settings_file_loaded}" != "true" ]; then
+        curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping."
+        common_settings_file_loaded=true
+    fi
+    if [ -f "/tmp/vsdc-settings.env" ]; then
+        local multi_line=""
+        if [ "$2" = "true" ]; then multi_line="-z"; fi
+        local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')"
+        if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi
+    fi
+    echo "$1=${!1}"
+}
+
+# Function to run apt-get if needed
+apt_get_update_if_needed()
+{
+    if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
+        echo "Running apt-get update..."
+        apt-get update
+    else
+        echo "Skipping apt-get update."
+    fi
+}
+
+# Checks if packages are installed and installs them if not
+check_packages() {
+    if ! dpkg -s "$@" > /dev/null 2>&1; then
+        apt_get_update_if_needed
+        apt-get -y install --no-install-recommends "$@"
+    fi
+}
+
+# Figure out correct version of a three part version number is not passed
+find_version_from_git_tags() {
+    local variable_name=$1
+    local requested_version=${!variable_name}
+    if [ "${requested_version}" = "none" ]; then return; fi
+    local repository=$2
+    local prefix=${3:-"tags/v"}
+    local separator=${4:-"."}
+    local last_part_optional=${5:-"false"}    
+    if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then
+        local escaped_separator=${separator//./\\.}
+        local last_part
+        if [ "${last_part_optional}" = "true" ]; then
+            last_part="(${escaped_separator}[0-9]+)?"
+        else
+            last_part="${escaped_separator}[0-9]+"
+        fi
+        local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$"
+        local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)"
+        if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then
+            declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)"
+        else
+            set +e
+            declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")"
+            set -e
+        fi
+    fi
+    if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then
+        echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2
+        exit 1
+    fi
+    echo "${variable_name}=${!variable_name}"
+}
+
+# Ensure apt is in non-interactive to avoid prompts
+export DEBIAN_FRONTEND=noninteractive
+
+# Install dependencies
+check_packages apt-transport-https curl ca-certificates gnupg2 dirmngr
+if ! type git > /dev/null 2>&1; then
+    apt_get_update_if_needed
+    apt-get -y install git
+fi
+
+# Source /etc/os-release to get OS info
+. /etc/os-release
+# Fetch host/container arch.
+architecture="$(dpkg --print-architecture)"
+
+# Set up the necessary apt repos (either Microsoft's or Docker's)
+if [ "${USE_MOBY}" = "true" ]; then
+
+    cli_package_name="moby-cli"
+
+    # Import key safely and import Microsoft apt repo
+    get_common_setting MICROSOFT_GPG_KEYS_URI
+    curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg
+    echo "deb [arch=${architecture} signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/microsoft-${ID}-${VERSION_CODENAME}-prod ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/microsoft.list
+else
+    # Name of proprietary engine package
+    cli_package_name="docker-ce-cli"
+
+    # Import key safely and import Docker apt repo
+    curl -fsSL https://download.docker.com/linux/${ID}/gpg | gpg --dearmor > /usr/share/keyrings/docker-archive-keyring.gpg
+    echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/${ID} ${VERSION_CODENAME} stable" > /etc/apt/sources.list.d/docker.list
+fi
+
+# Refresh apt lists
+apt-get update
+
+# Soft version matching for CLI
+if [ "${DOCKER_VERSION}" = "latest" ] || [ "${DOCKER_VERSION}" = "lts" ] || [ "${DOCKER_VERSION}" = "stable" ]; then
+    # Empty, meaning grab whatever "latest" is in apt repo
+    cli_version_suffix=""
+else    
+    # Fetch a valid version from the apt-cache (eg: the Microsoft repo appends +azure, breakfix, etc...)
+    docker_version_dot_escaped="${DOCKER_VERSION//./\\.}"
+    docker_version_dot_plus_escaped="${docker_version_dot_escaped//+/\\+}"
+    # Regex needs to handle debian package version number format: https://www.systutorials.com/docs/linux/man/5-deb-version/
+    docker_version_regex="^(.+:)?${docker_version_dot_plus_escaped}([\\.\\+ ~:-]|$)"
+    set +e # Don't exit if finding version fails - will handle gracefully
+    cli_version_suffix="=$(apt-cache madison ${cli_package_name} | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${docker_version_regex}")"
+    set -e
+    if [ -z "${cli_version_suffix}" ] || [ "${cli_version_suffix}" = "=" ]; then
+        echo "(!) No full or partial Docker / Moby version match found for \"${DOCKER_VERSION}\" on OS ${ID} ${VERSION_CODENAME} (${architecture}). Available versions:"
+        apt-cache madison ${cli_package_name} | awk -F"|" '{print $2}' | grep -oP '^(.+:)?\K.+'
+        exit 1
+    fi
+    echo "cli_version_suffix ${cli_version_suffix}"
+fi
+
+# Install Docker / Moby CLI if not already installed
+if type docker > /dev/null 2>&1; then
+    echo "Docker / Moby CLI already installed."
+else
+    if [ "${USE_MOBY}" = "true" ]; then
+        apt-get -y install --no-install-recommends moby-cli${cli_version_suffix} moby-buildx
+        apt-get -y install --no-install-recommends moby-compose || echo "(*) Package moby-compose (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping."
+    else
+        apt-get -y install --no-install-recommends docker-ce-cli${cli_version_suffix}
+    fi
+fi
+
+# Install Docker Compose if not already installed  and is on a supported architecture
+if type docker-compose > /dev/null 2>&1; then
+    echo "Docker Compose already installed."
+else
+    TARGET_COMPOSE_ARCH="$(uname -m)"
+    if [ "${TARGET_COMPOSE_ARCH}" = "amd64" ]; then
+        TARGET_COMPOSE_ARCH="x86_64"
+    fi
+    if [ "${TARGET_COMPOSE_ARCH}" != "x86_64" ]; then
+        # Use pip to get a version that runns on this architecture
+        if ! dpkg -s python3-minimal python3-pip libffi-dev python3-venv > /dev/null 2>&1; then
+            apt_get_update_if_needed
+            apt-get -y install python3-minimal python3-pip libffi-dev python3-venv
+        fi
+        export PIPX_HOME=/usr/local/pipx
+        mkdir -p ${PIPX_HOME}
+        export PIPX_BIN_DIR=/usr/local/bin
+        export PYTHONUSERBASE=/tmp/pip-tmp
+        export PIP_CACHE_DIR=/tmp/pip-tmp/cache
+        pipx_bin=pipx
+        if ! type pipx > /dev/null 2>&1; then
+            pip3 install --disable-pip-version-check --no-cache-dir --user pipx
+            pipx_bin=/tmp/pip-tmp/bin/pipx
+        fi
+        ${pipx_bin} install --pip-args '--no-cache-dir --force-reinstall' docker-compose
+        rm -rf /tmp/pip-tmp
+    else 
+        find_version_from_git_tags DOCKER_DASH_COMPOSE_VERSION "https://github.com/docker/compose" "tags/"
+        echo "(*) Installing docker-compose ${DOCKER_DASH_COMPOSE_VERSION}..."
+        curl -fsSL "https://github.com/docker/compose/releases/download/${DOCKER_DASH_COMPOSE_VERSION}/docker-compose-Linux-x86_64" -o /usr/local/bin/docker-compose
+        chmod +x /usr/local/bin/docker-compose
+    fi
+fi
+
+# If init file already exists, exit
+if [ -f "/usr/local/share/docker-init.sh" ]; then
+    exit 0
+fi
+echo "docker-init doesnt exist, adding..."
+
+# By default, make the source and target sockets the same
+if [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ]; then
+    touch "${SOURCE_SOCKET}"
+    ln -s "${SOURCE_SOCKET}" "${TARGET_SOCKET}"
+fi
+
+# Add a stub if not adding non-root user access, user is root
+if [ "${ENABLE_NONROOT_DOCKER}" = "false" ] || [ "${USERNAME}" = "root" ]; then
+    echo '/usr/bin/env bash -c "\$@"' > /usr/local/share/docker-init.sh
+    chmod +x /usr/local/share/docker-init.sh
+    exit 0
+fi
+
+# If enabling non-root access and specified user is found, setup socat and add script
+chown -h "${USERNAME}":root "${TARGET_SOCKET}"        
+if ! dpkg -s socat > /dev/null 2>&1; then
+    apt_get_update_if_needed
+    apt-get -y install socat
+fi
+tee /usr/local/share/docker-init.sh > /dev/null \
+<< EOF 
+#!/usr/bin/env bash
+#-------------------------------------------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
+#-------------------------------------------------------------------------------------------------------------
+
+set -e
+
+SOCAT_PATH_BASE=/tmp/vscr-docker-from-docker
+SOCAT_LOG=\${SOCAT_PATH_BASE}.log
+SOCAT_PID=\${SOCAT_PATH_BASE}.pid
+
+# Wrapper function to only use sudo if not already root
+sudoIf()
+{
+    if [ "\$(id -u)" -ne 0 ]; then
+        sudo "\$@"
+    else
+        "\$@"
+    fi
+}
+
+# Log messages
+log()
+{
+    echo -e "[\$(date)] \$@" | sudoIf tee -a \${SOCAT_LOG} > /dev/null
+}
+
+echo -e "\n** \$(date) **" | sudoIf tee -a \${SOCAT_LOG} > /dev/null
+log "Ensuring ${USERNAME} has access to ${SOURCE_SOCKET} via ${TARGET_SOCKET}"
+
+# If enabled, try to add a docker group with the right GID. If the group is root, 
+# fall back on using socat to forward the docker socket to another unix socket so 
+# that we can set permissions on it without affecting the host.
+if [ "${ENABLE_NONROOT_DOCKER}" = "true" ] && [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ] && [ "${USERNAME}" != "root" ] && [ "${USERNAME}" != "0" ]; then
+    SOCKET_GID=\$(stat -c '%g' ${SOURCE_SOCKET})
+    if [ "\${SOCKET_GID}" != "0" ]; then
+        log "Adding user to group with GID \${SOCKET_GID}."
+        if [ "\$(cat /etc/group | grep :\${SOCKET_GID}:)" = "" ]; then
+            sudoIf groupadd --gid \${SOCKET_GID} docker-host
+        fi
+        # Add user to group if not already in it
+        if [ "\$(id ${USERNAME} | grep -E "groups.*(=|,)\${SOCKET_GID}\(")" = "" ]; then
+            sudoIf usermod -aG \${SOCKET_GID} ${USERNAME}
+        fi
+    else
+        # Enable proxy if not already running
+        if [ ! -f "\${SOCAT_PID}" ] || ! ps -p \$(cat \${SOCAT_PID}) > /dev/null; then
+            log "Enabling socket proxy."
+            log "Proxying ${SOURCE_SOCKET} to ${TARGET_SOCKET} for vscode"
+            sudoIf rm -rf ${TARGET_SOCKET}
+            (sudoIf socat UNIX-LISTEN:${TARGET_SOCKET},fork,mode=660,user=${USERNAME} UNIX-CONNECT:${SOURCE_SOCKET} 2>&1 | sudoIf tee -a \${SOCAT_LOG} > /dev/null & echo "\$!" | sudoIf tee \${SOCAT_PID} > /dev/null)
+        else
+            log "Socket proxy already running."
+        fi
+    fi
+    log "Success"
+fi
+
+# Execute whatever commands were passed in (if any). This allows us 
+# to set this script to ENTRYPOINT while still executing the default CMD.
+set +e
+exec "\$@"
+EOF
+chmod +x /usr/local/share/docker-init.sh
+chown ${USERNAME}:root /usr/local/share/docker-init.sh
+echo "Done!"

+ 6 - 0
.earthlyignore

@@ -0,0 +1,6 @@
+.github
+.vscode
+Earthfile
+extra/doc
+bin
+out

+ 0 - 2
.gitattributes

@@ -3,6 +3,4 @@
 
 .gitattributes export-ignore
 .gitignore export-ignore
-.travis.yml export-ignore
-appveyor.yml export-ignore
 *.sh		eol=lf

+ 14 - 0
.github/workflows/cancel.yml

@@ -0,0 +1,14 @@
+name: Cancel previous jobs
+on:
+  workflow_run:
+    workflows: ["CI"]
+    types:
+      - requested
+jobs:
+  cancel:
+    runs-on: ubuntu-latest
+    steps:
+    - name: Cancel previous runs
+      uses: styfle/[email protected]
+      with:
+        workflow_id: ${{ github.event.workflow.id }}

+ 828 - 0
.github/workflows/main.yml

@@ -0,0 +1,828 @@
+# DO NOT EDIT. Generated from /extra/github-actions
+# TODO: support skip ci (https://github.community/t/github-actions-does-not-respect-skip-ci/17325/8)
+
+name: CI
+on: [push, pull_request]
+
+jobs:
+  windows64-build:
+    runs-on: windows-latest
+    env:
+      ACTIONS_ALLOW_UNSECURE_COMMANDS: true
+      PLATFORM: windows64
+      ARCH: 64
+      MINGW_ARCH: x86_64
+      CYG_ROOT: D:\cygwin
+    steps:
+      - uses: actions/checkout@main
+        with:
+          submodules: recursive
+
+      - name: Use GNU Tar from msys
+        run: |
+          echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
+          rm C:\msys64\usr\bin\bash.exe
+
+      - name: choco install nsis
+        uses: nick-invision/retry@v2
+        with:
+          timeout_minutes: 10
+          max_attempts: 10
+          command: choco install --no-progress nsis.portable --version 3.09 -y
+
+      - name: choco install things
+        shell: pwsh
+        run: choco install --no-progress curl wget 7zip.portable -y
+
+      - name: Prepend Chocolatey path
+        shell: pwsh
+        run: Write-Host "::add-path::C:\ProgramData\chocolatey\bin"
+
+      - name: Install Neko from S3
+        shell: pwsh
+        run: |
+          Invoke-WebRequest https://build.haxe.org/builds/neko/$env:PLATFORM/neko_latest.zip -OutFile $env:RUNNER_TEMP/neko_latest.zip
+          Expand-Archive $env:RUNNER_TEMP/neko_latest.zip -DestinationPath $env:RUNNER_TEMP
+          $NEKOPATH = Get-ChildItem $env:RUNNER_TEMP/neko-*-*
+          echo "$NEKOPATH" >> $env:GITHUB_PATH
+          echo "NEKOPATH=$NEKOPATH" >> $env:GITHUB_ENV
+
+      - name: Print Neko version
+        run: neko -version 2>&1
+
+      - name: Setup ocaml
+        uses: ocaml/setup-ocaml@v2
+        with:
+          ocaml-compiler: 4.08.1
+          opam-repositories: |
+            opam-repository-mingw: https://github.com/ocaml-opam/opam-repository-mingw.git#sunset
+            default: https://github.com/ocaml/opam-repository.git
+          opam-local-packages: |
+            haxe.opam
+
+      - name: Install dependencies
+        shell: pwsh
+        run: |
+          Set-PSDebug -Trace 1
+          curl.exe -fsSL -o "libmbedtls.tar.xz" --retry 3 https://github.com/Simn/mingw64-mbedtls/releases/download/2.16.3/mingw64-$($env:MINGW_ARCH)-mbedtls-2.16.3-1.tar.xz
+          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'curl -L https://cpanmin.us | perl - App::cpanminus')
+          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm IPC::System::Simple module')
+          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm String::ShellQuote')
+          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'echo "$OLDPWD"')
+          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && tar -C / -xvf libmbedtls.tar.xz')
+
+      - name: Install OCaml libraries
+        shell: pwsh
+        run: |
+          Set-PSDebug -Trace 1
+          opam install haxe --deps-only
+          opam list
+
+      - name: Expose mingw dll files
+        shell: pwsh
+        run: Write-Host "::add-path::${env:CYG_ROOT}/usr/$($env:MINGW_ARCH)-w64-mingw32/sys-root/mingw/bin"
+
+      # required to be able to retrieve the revision
+      - name: Mark directory as safe
+        shell: pwsh
+        run: |
+          Set-PSDebug -Trace 1
+          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'git config --global --add safe.directory "$OLDPWD"')
+
+      - name: Set ADD_REVISION=1 for non-release
+        if: ${{ !startsWith(github.ref, 'refs/tags/') }}
+        shell: pwsh
+        run: echo "ADD_REVISION=1" >> $Env:GITHUB_ENV
+
+      - name: Build Haxe
+        shell: pwsh
+        run: |
+          Set-PSDebug -Trace 1
+          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && opam config exec -- make -s -f Makefile.win -j`nproc` haxe 2>&1')
+          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && opam config exec -- make -s -f Makefile.win haxelib 2>&1')
+          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && opam config exec -- make -f Makefile.win echo_package_files package_bin package_installer_win package_choco 2>&1')
+          dir out
+          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && cygcheck ./haxe.exe')
+          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && cygcheck ./haxelib.exe')
+          & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && ls ./out')
+
+      - name: Check artifact
+        shell: bash
+        run: |
+          ls out
+          # Output should contain binaries zip, installer zip and nupkg
+          [ $(ls -1 out | wc -l) -eq "3" ]
+
+      - name: Upload artifact
+        uses: actions/upload-artifact@v3
+        with:
+          name: win${{env.ARCH}}Binaries
+          path: out
+
+
+  linux-build:
+    runs-on: ubuntu-20.04
+    env:
+      PLATFORM: linux64
+      OPAMYES: 1
+    strategy:
+      fail-fast: false
+      matrix:
+        ocaml: ["4.08.1", "5.0.0"]
+    steps:
+      - uses: actions/checkout@main
+        with:
+          submodules: recursive
+
+      - name: Cache opam
+        id: cache-opam
+        uses: actions/[email protected]
+        with:
+          path: ~/.opam/
+          key: ${{ runner.os }}-${{ matrix.ocaml }}-${{ hashFiles('./haxe.opam', './libs/') }}
+
+      - name: Install Neko from S3
+        run: |
+          set -ex
+
+          curl -sSL https://build.haxe.org/builds/neko/$PLATFORM/neko_latest.tar.gz -o $RUNNER_TEMP/neko_latest.tar.gz
+          tar -xf $RUNNER_TEMP/neko_latest.tar.gz -C $RUNNER_TEMP
+          NEKOPATH=`echo $RUNNER_TEMP/neko-*-*`
+          sudo mkdir -p /usr/local/bin
+          sudo mkdir -p /usr/local/lib/neko
+          sudo ln -s $NEKOPATH/{neko,nekoc,nekoml,nekotools}  /usr/local/bin/
+          sudo ln -s $NEKOPATH/libneko.*                      /usr/local/lib/
+          sudo ln -s $NEKOPATH/*.ndll                         /usr/local/lib/neko/
+          echo "NEKOPATH=$NEKOPATH" >> $GITHUB_ENV
+
+      - name: Print Neko version
+        run: neko -version 2>&1
+
+
+      - name: Install dependencies
+        run: |
+          set -ex
+          sudo add-apt-repository ppa:avsm/ppa -y # provides OPAM 2
+          sudo add-apt-repository ppa:haxe/ocaml -y # provides newer version of mbedtls
+          sudo apt-get update -qqy
+          sudo apt-get install -qqy ocaml-nox camlp5 opam libpcre2-dev zlib1g-dev libgtk2.0-dev libmbedtls-dev ninja-build libstring-shellquote-perl libipc-system-simple-perl
+
+      - name: Install OCaml libraries
+        if: steps.cache-opam.outputs.cache-hit != 'true'
+        run: |
+          set -ex
+          opam init # --disable-sandboxing
+          opam update
+          opam switch create ${{ matrix.ocaml }}
+          opam pin add haxe . --no-action
+          opam install haxe --deps-only --assume-depexts
+          opam list
+          ocamlopt -v
+
+      - name: Set ADD_REVISION=1 for non-release
+        if: ${{ !startsWith(github.ref, 'refs/tags/') }}
+        run: echo "ADD_REVISION=1" >> $GITHUB_ENV
+
+      - name: Build Haxe
+        run: |
+          set -ex
+          eval $(opam env)
+          opam config exec -- make -s -j`nproc` STATICLINK=1 haxe
+          opam config exec -- make -s haxelib
+          make -s package_unix
+          ls -l out
+          ldd -v ./haxe
+          ldd -v ./haxelib
+
+      # https://stackoverflow.com/questions/58033366/how-to-get-current-branch-within-github-actions
+      - name: Extract branch name
+        id: extract_branch
+        shell: bash
+        run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT
+
+      - name: Build xmldoc
+        if: matrix.ocaml == '4.08.1'
+        run: |
+          set -ex
+          make -s xmldoc
+          cat >extra/doc/info.json <<EOL
+            {
+              "commit": "$GITHUB_SHA",
+              "branch": "${{ steps.extract_branch.outputs.branch }}"
+            }
+          EOL
+
+      - name: Upload artifact
+        uses: actions/upload-artifact@v3
+        with:
+          name: linuxBinaries${{ (matrix.ocaml == '5.0.0' && '_ocaml5') || '' }}
+          path: out
+
+      - name: Upload xmldoc artifact
+        uses: actions/upload-artifact@v3
+        if: matrix.ocaml == '4.08.1'
+        with:
+          name: xmldoc
+          path: extra/doc
+
+  linux-test:
+    needs: linux-build
+    runs-on: ubuntu-20.04
+    env:
+      PLATFORM: linux64
+      TEST: ${{matrix.target}}
+      HXCPP_COMPILE_CACHE: ~/hxcache
+      HAXE_STD_PATH: /usr/local/share/haxe/std
+    strategy:
+      fail-fast: false
+      matrix:
+        ocaml: ["4.08.1", "5.0.0"]
+        target: [macro, js, hl, cpp, jvm, php, python, lua, flash, neko]
+        include:
+          - target: hl
+            APT_PACKAGES: cmake ninja-build libturbojpeg-dev
+          - target: cpp
+            APT_PACKAGES: gcc-multilib g++-multilib
+          - target: lua
+            APT_PACKAGES: ncurses-dev
+          - target: flash
+            APT_PACKAGES: libglib2.0-0 libgtk2.0-0 libfreetype6 xvfb
+    steps:
+      - uses: actions/checkout@main
+        with:
+          submodules: recursive
+      - uses: actions/download-artifact@v3
+        with:
+          name: linuxBinaries${{ (matrix.ocaml == '5.0.0' && '_ocaml5') || '' }}
+          path: linuxBinaries
+
+      - name: Install Neko from S3
+        run: |
+          set -ex
+
+          curl -sSL https://build.haxe.org/builds/neko/$PLATFORM/neko_latest.tar.gz -o $RUNNER_TEMP/neko_latest.tar.gz
+          tar -xf $RUNNER_TEMP/neko_latest.tar.gz -C $RUNNER_TEMP
+          NEKOPATH=`echo $RUNNER_TEMP/neko-*-*`
+          sudo mkdir -p /usr/local/bin
+          sudo mkdir -p /usr/local/lib/neko
+          sudo ln -s $NEKOPATH/{neko,nekoc,nekoml,nekotools}  /usr/local/bin/
+          sudo ln -s $NEKOPATH/libneko.*                      /usr/local/lib/
+          sudo ln -s $NEKOPATH/*.ndll                         /usr/local/lib/neko/
+          echo "NEKOPATH=$NEKOPATH" >> $GITHUB_ENV
+
+      - name: Print Neko version
+        run: neko -version 2>&1
+
+
+      - name: Setup Haxe
+        run: |
+          sudo apt install -qqy libmbedtls-dev
+
+          set -ex
+          tar -xf linuxBinaries/*_bin.tar.gz -C linuxBinaries --strip-components=1
+          sudo mkdir -p /usr/local/bin/
+          sudo mkdir -p /usr/local/share/haxe/
+          sudo ln -s `pwd`/linuxBinaries/haxe /usr/local/bin/haxe
+          sudo ln -s `pwd`/linuxBinaries/haxelib /usr/local/bin/haxelib
+          sudo ln -s `pwd`/linuxBinaries/std /usr/local/share/haxe/std
+
+      - name: Print Haxe version
+        run: haxe -version
+
+      - name: Setup haxelib
+        run: |
+          set -ex
+          mkdir ~/haxelib
+          haxelib setup ~/haxelib
+
+      - name: Install apt packages
+        if: matrix.APT_PACKAGES
+        run: |
+          set -ex
+          sudo apt update -qqy
+          sudo apt install -qqy ${{matrix.APT_PACKAGES}}
+
+      - name: Flash setup
+        if: matrix.target == 'flash'
+        run: export DISPLAY=:99.0
+
+      - name: Test
+        run: haxe RunCi.hxml
+        working-directory: ${{github.workspace}}/tests
+
+  test-docgen:
+    needs: linux-build
+    runs-on: ubuntu-20.04
+    env:
+      PLATFORM: linux64
+      HXCPP_COMPILE_CACHE: ~/hxcache
+    steps:
+      - uses: actions/checkout@main
+        with:
+          submodules: recursive
+
+      - uses: actions/download-artifact@v3
+        with:
+          name: linuxBinaries
+          path: linuxBinaries
+
+      - name: Download xmldoc artifact
+        uses: actions/download-artifact@v3
+        with:
+          name: xmldoc
+          path: xmldoc
+
+      - name: Install Neko from S3
+        run: |
+          set -ex
+
+          curl -sSL https://build.haxe.org/builds/neko/$PLATFORM/neko_latest.tar.gz -o $RUNNER_TEMP/neko_latest.tar.gz
+          tar -xf $RUNNER_TEMP/neko_latest.tar.gz -C $RUNNER_TEMP
+          NEKOPATH=`echo $RUNNER_TEMP/neko-*-*`
+          sudo mkdir -p /usr/local/bin
+          sudo mkdir -p /usr/local/lib/neko
+          sudo ln -s $NEKOPATH/{neko,nekoc,nekoml,nekotools}  /usr/local/bin/
+          sudo ln -s $NEKOPATH/libneko.*                      /usr/local/lib/
+          sudo ln -s $NEKOPATH/*.ndll                         /usr/local/lib/neko/
+          echo "NEKOPATH=$NEKOPATH" >> $GITHUB_ENV
+
+      - name: Print Neko version
+        run: neko -version 2>&1
+
+
+      - name: Setup Haxe
+        run: |
+          sudo apt install -qqy libmbedtls-dev
+
+          set -ex
+          tar -xf linuxBinaries/*_bin.tar.gz -C linuxBinaries --strip-components=1
+          sudo mkdir -p /usr/local/bin/
+          sudo mkdir -p /usr/local/share/haxe/
+          sudo ln -s `pwd`/linuxBinaries/haxe /usr/local/bin/haxe
+          sudo ln -s `pwd`/linuxBinaries/haxelib /usr/local/bin/haxelib
+          sudo ln -s `pwd`/linuxBinaries/std /usr/local/share/haxe/std
+
+      - name: Print Haxe version
+        run: haxe -version
+
+      - name: Setup haxelib
+        run: |
+          set -ex
+          mkdir ~/haxelib
+          haxelib setup ~/haxelib
+
+      - name: Test documentation generation
+        run: |
+          set -ex
+          haxelib git dox https://github.com/HaxeFoundation/dox.git
+          haxelib git hxtemplo https://github.com/Simn/hxtemplo.git
+          haxelib git hxargs https://github.com/Simn/hxargs.git
+          haxelib git markdown https://github.com/dpeek/haxe-markdown.git
+          haxelib git hxcpp https://github.com/HaxeFoundation/hxcpp.git
+          cd $(haxelib libpath hxcpp)/tools/hxcpp
+          haxe compile.hxml
+          cd -
+          haxe dox.hxml
+          mkdir resources
+          cp ../../src-json/* resources
+          cpp/Dox -i ../../xmldoc -ex microsoft -ex javax -theme $(haxelib libpath dox)/themes/default
+        working-directory: ${{github.workspace}}/tests/docgen
+
+  linux-arm64:
+    runs-on: ubuntu-20.04
+    permissions:
+      packages: write
+    env:
+      FORCE_COLOR: 1
+    steps:
+      - name: Login to GitHub Container Registry
+        uses: docker/login-action@v2
+        with:
+          registry: ghcr.io
+          username: ${{ github.actor }}
+          password: ${{ secrets.GITHUB_TOKEN }}
+
+      - name: Install Earthly
+        run: sudo /bin/sh -c 'wget https://github.com/earthly/earthly/releases/download/v0.6.13/earthly-linux-amd64 -O /usr/local/bin/earthly && chmod +x /usr/local/bin/earthly && /usr/local/bin/earthly bootstrap --with-autocomplete'
+
+      - name: Set up QEMU
+        id: qemu
+        uses: docker/setup-qemu-action@v2
+        with:
+            image: tonistiigi/binfmt:latest
+            platforms: all
+
+      - uses: actions/checkout@main
+        with:
+          submodules: recursive
+
+      - name: Set CONTAINER_ vars
+        run: |
+          echo "CONTAINER_REG=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV;
+          echo "CONTAINER_TAG=$(echo ${{ github.ref_name }} | sed -e 's/[^A-Za-z0-9\.]/-/g')" >> $GITHUB_ENV;
+
+      - name: Build devcontainer
+        run: earthly --platform=linux/arm64 +devcontainer --IMAGE_NAME="ghcr.io/${CONTAINER_REG}_devcontainer" --IMAGE_TAG="${CONTAINER_TAG}-arm64" --IMAGE_CACHE="ghcr.io/haxefoundation/haxe_devcontainer:development-arm64"
+        env:
+          EARTHLY_PUSH: "${{ github.event_name == 'push' }}"
+          EARTHLY_USE_INLINE_CACHE: true
+          EARTHLY_SAVE_INLINE_CACHE: true
+
+      - name: Set ADD_REVISION=1 for non-release
+        if: ${{ !startsWith(github.ref, 'refs/tags/') }}
+        run: echo "ADD_REVISION=1" >> $GITHUB_ENV
+
+      - name: Build
+        run: earthly --platform=linux/arm64 +build --ADD_REVISION="$ADD_REVISION" --SET_SAFE_DIRECTORY="true"
+        env:
+          EARTHLY_PUSH: "${{ github.event_name == 'push' }}"
+          EARTHLY_REMOTE_CACHE: "ghcr.io/${{env.CONTAINER_REG}}_cache:build-${{env.CONTAINER_TAG}}-arm64"
+
+      - name: Upload artifact
+        uses: actions/upload-artifact@v3
+        with:
+          name: linuxArm64Binaries
+          path: out/linux/arm64
+
+  mac-build:
+    runs-on: macos-latest
+    env:
+      PLATFORM: mac
+      OPAMYES: 1
+      MACOSX_DEPLOYMENT_TARGET: 10.13
+    steps:
+      - uses: actions/checkout@main
+        with:
+          submodules: recursive
+
+      - name: Cache opam
+        id: cache-opam
+        uses: actions/[email protected]
+        with:
+          path: ~/.opam/
+          key: ${{ runner.os }}-${{ hashFiles('./haxe.opam', './libs/') }}
+
+      - name: Install Neko from S3
+        run: |
+          set -ex
+
+          curl -sSL https://build.haxe.org/builds/neko/$PLATFORM/neko_latest.tar.gz -o $RUNNER_TEMP/neko_latest.tar.gz
+          tar -xf $RUNNER_TEMP/neko_latest.tar.gz -C $RUNNER_TEMP
+          NEKOPATH=`echo $RUNNER_TEMP/neko-*-*`
+          sudo mkdir -p /usr/local/bin
+          sudo mkdir -p /usr/local/lib/neko
+          sudo ln -s $NEKOPATH/{neko,nekoc,nekoml,nekotools}  /usr/local/bin/
+          sudo ln -s $NEKOPATH/libneko.*                      /usr/local/lib/
+          sudo ln -s $NEKOPATH/*.ndll                         /usr/local/lib/neko/
+          echo "NEKOPATH=$NEKOPATH" >> $GITHUB_ENV
+
+      - name: Print Neko version
+        run: neko -version 2>&1
+
+      - name: Install dependencies
+        env:
+          # For compatibility with macOS 10.13
+          ZLIB_VERSION: 1.3.1
+          MBEDTLS_VERSION: 2.28.5
+          PCRE2_VERSION: 10.42
+        run: |
+          set -ex
+          brew update
+          brew bundle --file=tests/Brewfile --no-upgrade
+          cpanm IPC::System::Simple
+          cpanm String::ShellQuote
+          curl -L https://github.com/madler/zlib/releases/download/v$ZLIB_VERSION/zlib-$ZLIB_VERSION.tar.gz | tar xz
+          cd zlib-$ZLIB_VERSION
+          ./configure
+          make && make install
+          cd ..
+          curl -L https://github.com/ARMmbed/mbedtls/archive/v$MBEDTLS_VERSION.tar.gz | tar xz
+          cd mbedtls-$MBEDTLS_VERSION
+          make && make install
+          cd ..
+          curl -L https://github.com/PCRE2Project/pcre2/releases/download/pcre2-$PCRE2_VERSION/pcre2-$PCRE2_VERSION.tar.gz | tar xz
+          cd pcre2-$PCRE2_VERSION
+          ./configure --enable-unicode --enable-pcre2-8 --enable-pcre2-16 --enable-pcre2-32 --enable-unicode-properties --enable-pcre2grep-libz --enable-pcre2grep-libbz2 --enable-jit
+          make && make install
+          cd ..
+
+      - name: Install OCaml libraries
+        if: steps.cache-opam.outputs.cache-hit != 'true'
+        run: |
+          set -ex
+          opam init # --disable-sandboxing
+          opam update
+          opam switch create 4.08.1
+          eval $(opam env)
+          opam env
+          opam pin add ctypes 0.17.1 --yes
+          opam pin add haxe . --no-action
+          opam install haxe --deps-only --assume-depexts
+          opam list
+          ocamlopt -v
+
+      - name: Set ADD_REVISION=1 for non-release
+        if: ${{ !startsWith(github.ref, 'refs/tags/') }}
+        run: echo "ADD_REVISION=1" >> $GITHUB_ENV
+
+      - name: Build Haxe
+        run: |
+          set -ex
+          eval $(opam env)
+          opam config exec -- make -s -j`sysctl -n hw.ncpu` STATICLINK=1 "LIB_PARAMS=/usr/local/lib/libz.a /usr/local/lib/libpcre2-8.a /usr/local/lib/libmbedtls.a /usr/local/lib/libmbedcrypto.a /usr/local/lib/libmbedx509.a -cclib '-framework Security -framework CoreFoundation'" haxe
+          opam config exec -- make -s haxelib
+          make -s package_unix package_installer_mac
+          ls -l out
+          otool -L ./haxe
+          otool -L ./haxelib
+
+      - name: Upload artifact
+        uses: actions/upload-artifact@v3
+        with:
+          name: macBinaries
+          path: out
+
+
+  windows64-test:
+    needs: windows64-build
+    runs-on: windows-latest
+    env:
+      ACTIONS_ALLOW_UNSECURE_COMMANDS: true
+      PLATFORM: windows64
+      TEST: ${{matrix.target}}
+      HXCPP_COMPILE_CACHE: ~/hxcache
+      ARCH: 64
+    strategy:
+      fail-fast: false
+      matrix:
+        # TODO enable lua after https://github.com/HaxeFoundation/haxe/issues/10919
+        target: [macro, js, hl, cpp, jvm, php, python, flash, neko]
+    steps:
+      - uses: actions/checkout@main
+        with:
+          submodules: recursive
+      - uses: actions/download-artifact@v3
+        with:
+          name: win${{env.ARCH}}Binaries
+          path: win${{env.ARCH}}Binaries
+
+      - name: Install Neko from S3
+        shell: pwsh
+        run: |
+          Invoke-WebRequest https://build.haxe.org/builds/neko/$env:PLATFORM/neko_latest.zip -OutFile $env:RUNNER_TEMP/neko_latest.zip
+          Expand-Archive $env:RUNNER_TEMP/neko_latest.zip -DestinationPath $env:RUNNER_TEMP
+          $NEKOPATH = Get-ChildItem $env:RUNNER_TEMP/neko-*-*
+          echo "$NEKOPATH" >> $env:GITHUB_PATH
+          echo "NEKOPATH=$NEKOPATH" >> $env:GITHUB_ENV
+
+      - name: Print Neko version
+        run: neko -version 2>&1
+
+      - uses: actions/setup-node@v3
+        with:
+          node-version: 18.17.1
+
+      # - name: Quick test
+      #   shell: pwsh
+      #   run: |
+      #     $DOWNLOADDIR="./win$($env:ARCH)Binaries"
+      #     new-item -Name $DOWNLOADDIR -ItemType directory
+      #     Invoke-WebRequest https://build.haxe.org/builds/haxe/$env:PLATFORM/haxe_latest.zip -OutFile $DOWNLOADDIR/haxe_bin.zip
+
+      - name: Setup Haxe
+        shell: pwsh
+        run: |
+          $DOWNLOADDIR="./win$($env:ARCH)Binaries"
+          Expand-Archive $DOWNLOADDIR/*_bin.zip -DestinationPath $DOWNLOADDIR
+          Set-PSDebug -Trace 1
+          $HAXEPATH = Get-ChildItem $DOWNLOADDIR/haxe_*_* -Directory
+          Write-Host "::add-path::$HAXEPATH"
+          Write-Host "::set-env name=HAXELIB_ROOT::$HAXEPATH\lib"
+
+      - name: Print Haxe version
+        shell: pwsh
+        run: haxe -version
+
+      - name: "Make Python 3 be available as python3 in the cmdline"
+        shell: pwsh
+        run: |
+          Set-PSDebug -Trace 1
+          $pypath = python -c "import sys; print(sys.executable)"
+          $py3path = $pypath.replace("python.exe","python3.exe")
+          cmd /c mklink $py3path $pypath
+          python3 -V
+
+      - name: Install hererocks
+        if: matrix.target == 'lua'
+        shell: cmd
+        run: |
+          pip install hererocks
+          hererocks lua53 -l5.3 -rlatest
+          call lua53/bin/activate
+
+      - name: Install wget
+        if: matrix.target == 'flash'
+        shell: cmd
+        run: |
+          choco install wget
+          wget --version
+
+      - name: Setup haxelib
+        shell: pwsh
+        run: |
+          mkdir "$env:HAXELIB_ROOT"
+          haxelib setup "$env:HAXELIB_ROOT"
+
+      - name: Test
+        shell: pwsh
+        run: haxe RunCi.hxml
+        working-directory: ${{github.workspace}}/tests
+
+
+  mac-test:
+    needs: mac-build
+    runs-on: macos-latest
+    env:
+      PLATFORM: mac
+      TEST: ${{matrix.target}}
+      HXCPP_COMPILE_CACHE: ~/hxcache
+      HAXE_STD_PATH: /usr/local/share/haxe/std
+    strategy:
+      fail-fast: false
+      matrix:
+        target: [macro, js, hl, cpp, jvm, php, python, flash, neko]
+        include:
+          - target: hl
+            BREW_PACKAGES: ninja
+    steps:
+      - uses: actions/checkout@main
+        with:
+          submodules: recursive
+      - uses: actions/download-artifact@v3
+        with:
+          name: macBinaries
+          path: macBinaries
+
+      - name: Install Neko from S3
+        run: |
+          set -ex
+
+          curl -sSL https://build.haxe.org/builds/neko/$PLATFORM/neko_latest.tar.gz -o $RUNNER_TEMP/neko_latest.tar.gz
+          tar -xf $RUNNER_TEMP/neko_latest.tar.gz -C $RUNNER_TEMP
+          NEKOPATH=`echo $RUNNER_TEMP/neko-*-*`
+          sudo mkdir -p /usr/local/bin
+          sudo mkdir -p /usr/local/lib/neko
+          sudo ln -s $NEKOPATH/{neko,nekoc,nekoml,nekotools}  /usr/local/bin/
+          sudo ln -s $NEKOPATH/libneko.*                      /usr/local/lib/
+          sudo ln -s $NEKOPATH/*.ndll                         /usr/local/lib/neko/
+          echo "NEKOPATH=$NEKOPATH" >> $GITHUB_ENV
+
+      - name: Print Neko version
+        run: neko -version 2>&1
+
+      - name: Setup Haxe
+        run: |
+          # mkdir ./macBinaries
+          # curl -sSL https://build.haxe.org/builds/haxe/mac/haxe_latest.tar.gz -o ./macBinaries/haxe_bin.tar.gz
+
+          set -ex
+          tar -xf macBinaries/*_bin.tar.gz -C macBinaries --strip-components=1
+          sudo mkdir -p /usr/local/bin/
+          sudo mkdir -p /usr/local/share/haxe/
+          sudo ln -s `pwd`/macBinaries/haxe /usr/local/bin/haxe
+          sudo ln -s `pwd`/macBinaries/haxelib /usr/local/bin/haxelib
+          sudo ln -s `pwd`/macBinaries/std /usr/local/share/haxe/std
+
+      - name: Print Haxe version
+        run: haxe -version
+
+      - name: Setup haxelib
+        run: |
+          set -ex
+          mkdir ~/haxelib
+          haxelib setup ~/haxelib
+
+      - name: Install homebrew packages
+        if: matrix.BREW_PACKAGES
+        run: brew install ${{matrix.BREW_PACKAGES}}
+
+      - name: Test
+        run: |
+          # disable invalid Unicode filenames on APFS
+          echo "" > sys/compile-fs.hxml
+          haxe RunCi.hxml
+        working-directory: ${{github.workspace}}/tests
+
+
+  deploy:
+    if: success() && github.repository_owner == 'HaxeFoundation' && github.event_name != 'pull_request'
+    needs: [linux-test, linux-arm64, mac-test, windows64-test]
+    runs-on: ubuntu-20.04
+    steps:
+      # this is only needed for to get `COMMIT_DATE`...
+      # maybe https://github.community/t/expose-commit-timestamp-in-the-github-context-data/16460/3
+      # would be faster
+      - name: Checkout the repository
+        uses: actions/checkout@main
+
+      - name: Download build artifacts
+        uses: actions/download-artifact@v3
+
+      - name: Install awscli
+        run: |
+          set -ex
+          sudo apt-get update -qqy
+          sudo apt-get install -qqy awscli
+
+      # https://stackoverflow.com/questions/58033366/how-to-get-current-branch-within-github-actions
+      - name: Extract branch name
+        id: extract_branch
+        shell: bash
+        run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT
+
+      - name: Upload binaries
+        shell: bash
+        env:
+          AWS_ACCESS_KEY_ID: ${{ secrets.HXBUILDS_AWS_ACCESS_KEY_ID }}
+          AWS_SECRET_ACCESS_KEY: ${{ secrets.HXBUILDS_AWS_SECRET_ACCESS_KEY }}
+          HXBUILDS_S3ADDR: ${{ secrets.HXBUILDS_S3ADDR }}
+          AWS_EC2_METADATA_DISABLED: true
+        run: |
+          set -ex
+          COMMIT_HASH_SHORT=${GITHUB_SHA:0:7}
+          COMMIT_DATE=`TZ=UTC git show --quiet --date='format-local:%Y-%m-%d' --format="%cd"`
+          FILE_NAME=haxe_${COMMIT_DATE}_${{ steps.extract_branch.outputs.branch }}_${COMMIT_HASH_SHORT}
+          aws s3 cp linuxBinaries/*_bin.tar.gz      ${HXBUILDS_S3ADDR}/haxe/linux64/${FILE_NAME}.tar.gz
+          aws s3 cp linuxArm64Binaries/*_bin.tar.gz ${HXBUILDS_S3ADDR}/haxe/linux-arm64/${FILE_NAME}.tar.gz
+          aws s3 cp macBinaries/*_bin.tar.gz        ${HXBUILDS_S3ADDR}/haxe/mac/${FILE_NAME}.tar.gz
+          aws s3 cp macBinaries/*_installer.tar.gz  ${HXBUILDS_S3ADDR}/haxe/mac-installer/${FILE_NAME}.tar.gz
+          aws s3 cp win64Binaries/*_bin.zip         ${HXBUILDS_S3ADDR}/haxe/windows64/${FILE_NAME}.zip
+          aws s3 cp win64Binaries/*_installer.zip   ${HXBUILDS_S3ADDR}/haxe/windows64-installer/${FILE_NAME}.zip
+          aws s3 cp win64Binaries/*.nupkg           ${HXBUILDS_S3ADDR}/haxe/windows64-choco/
+
+      - name: Update "latest"
+        if: github.ref == 'refs/heads/development'
+        shell: bash
+        env:
+          AWS_ACCESS_KEY_ID: ${{ secrets.HXBUILDS_AWS_ACCESS_KEY_ID }}
+          AWS_SECRET_ACCESS_KEY: ${{ secrets.HXBUILDS_AWS_SECRET_ACCESS_KEY }}
+          HXBUILDS_S3ADDR: ${{ secrets.HXBUILDS_S3ADDR }}
+          AWS_EC2_METADATA_DISABLED: true
+        run: |
+          set -ex
+          aws s3 cp linuxBinaries/*_bin.tar.gz      ${HXBUILDS_S3ADDR}/haxe/linux64/haxe_latest.tar.gz
+          aws s3 cp linuxArm64Binaries/*_bin.tar.gz ${HXBUILDS_S3ADDR}/haxe/linux-arm64/haxe_latest.tar.gz
+          aws s3 cp macBinaries/*_bin.tar.gz        ${HXBUILDS_S3ADDR}/haxe/mac/haxe_latest.tar.gz
+          aws s3 cp macBinaries/*_installer.tar.gz  ${HXBUILDS_S3ADDR}/haxe/mac-installer/haxe_latest.tar.gz
+          aws s3 cp win64Binaries/*_bin.zip         ${HXBUILDS_S3ADDR}/haxe/windows64/haxe_latest.zip
+          aws s3 cp win64Binaries/*_installer.zip   ${HXBUILDS_S3ADDR}/haxe/windows64-installer/haxe_latest.zip
+
+          # Chocolatey packages have to be named with version number,
+          # so let's use web redirection to keep the original file name.
+          [[ "$HXBUILDS_S3ADDR" =~ s3://([^/]+)(.*) ]] && HXBUILDS_S3BUCKET="${BASH_REMATCH[1]}" && HXBUILDS_S3PATH="${BASH_REMATCH[2]}"
+          [[ `echo win64Binaries/*.nupkg` =~ win64Binaries/(.+) ]] && FILE_NAME="${BASH_REMATCH[1]}"
+          aws s3 cp ${HXBUILDS_S3ADDR}/haxe/windows64-choco/${FILE_NAME} ${HXBUILDS_S3ADDR}/haxe/windows64-choco/haxe_latest.nupkg --acl public-read --website-redirect "${HXBUILDS_S3PATH}/haxe/windows64-choco/${FILE_NAME}"
+
+
+  deploy_apidoc:
+    if: success() && github.repository_owner == 'HaxeFoundation' && github.event_name != 'pull_request'
+    needs: [linux-test, linux-arm64, mac-test, windows64-test]
+    runs-on: ubuntu-20.04
+    steps:
+      - name: Install dependencies
+        run: |
+          set -ex
+          sudo apt-get install -qqy libc6
+
+      - name: Download Haxe
+        uses: actions/download-artifact@v3
+        with:
+          name: linuxBinaries
+          path: linuxBinaries
+
+      - name: Setup Haxe
+        run: |
+          set -ex
+          tar -xf linuxBinaries/*_bin.tar.gz -C linuxBinaries --strip-components=1
+          sudo mkdir -p /usr/local/bin/
+          sudo mkdir -p /usr/local/share/haxe/
+          sudo ln -s `pwd`/linuxBinaries/haxe /usr/local/bin/haxe
+          sudo ln -s `pwd`/linuxBinaries/haxelib /usr/local/bin/haxelib
+          sudo ln -s `pwd`/linuxBinaries/std /usr/local/share/haxe/std
+
+      - name: Download xmldoc artifact
+        uses: actions/download-artifact@v3
+        with:
+          name: xmldoc
+          path: xmldoc
+
+      - name: Deploy to api.haxe.org
+        env:
+          GHP_EMAIL: [email protected]
+          GHP_USERNAME: Haxe CI Bot
+          GHP_REMOTE: ${{ secrets.GHP_REMOTE }}
+        run: |
+          set -ex
+          LOCAL="`pwd`/extra/api.haxe.org"
+          git clone "${GHP_REMOTE}" "${LOCAL}"
+          haxe --cwd "${LOCAL}" --run ImportXml "`pwd`/xmldoc"

+ 4 - 0
.gitignore

@@ -12,6 +12,8 @@
 /out
 /installer
 
+.tmp-earthly-out*
+
 /extra/hxclasses
 /extra/*.swf
 /extra/*.swc
@@ -133,3 +135,5 @@ tests/server/test.js.map
 *.merlin
 lib.sexp
 src/compiler/version.ml
+tests/party
+tests/misc/projects/Issue10863/error.log

+ 8 - 0
.vscode/schemas/define.schema.json

@@ -57,6 +57,14 @@
 					"type": "string",
 					"format": "uri"
 				}
+			},
+			"reserved": {
+				"type": "boolean",
+				"markdownDescription": "Reserved defines may not be defined from the command line."
+			},
+			"deprecated": {
+				"type": "string",
+				"markdownDescription": "Reason for the define to be deprecated."
 			}
 		},
 		"required": [

+ 1 - 2
.vscode/schemas/meta.schema.json

@@ -29,8 +29,7 @@
 						"flash",
 						"php",
 						"cpp",
-						"cs",
-						"java",
+						"jvm",
 						"python",
 						"hl",
 						"eval"

+ 3 - 53
CONTRIBUTING.md

@@ -2,7 +2,7 @@
 
 - Check if you actually suspect that there's an issue in the Haxe code. If you find yourself writing "How do I..." you may want to consider a different communication channel. Refer to https://haxe.org/community/community-support.html for more information.
 - Reduce your code to a minimal example (see http://sscce.org/). In particular avoid library dependencies: If you cannot reproduce your issue without using a specific library, it might not be a Haxe issue to begin with.
-- Check if your problems are already resolved in the Haxe development version (for builds see http://builds.haxe.org/).
+- Check if your problems are already resolved in the Haxe development version (for builds see http://build.haxe.org/).
 - Most targets produce readable code. If you suspect the generated code to be wrong, try checking the output. Note that you can add `-D dump=pretty` to your compilation parameters and find the code which is passed to the generators in a `dump` subdirectory.
 
 ## Is this the right repository to report the issue?
@@ -10,63 +10,13 @@
 This repository is about the Haxe compiler itself and the Haxe standard library. Here's an overview of repositories that are part of the Haxe ecosystem:
 
 * The haxelib command line tool or lib.haxe.org: <https://github.com/HaxeFoundation/haxelib/issues>
-* Something on try.haxe.org: <https://github.com/clemos/try-haxe/issues>
+* Something on try.haxe.org: <https://github.com/HaxeFoundation/try.haxe.org/issues>
 * Something under haxe.org/manual: <https://github.com/HaxeFoundation/HaxeManual/issues>
 * Something on api.haxe.org: For content this is probably the right repository. If it's about the representation, try <https://github.com/HaxeFoundation/dox/issues> instead.
 * Something else on haxe.org: <https://github.com/HaxeFoundation/haxe.org/issues>
 
-## Submitting a Pull-Request
-
-Thank you for your interest in contributing to Haxe! Haxe is a
-community-driven project and your help is vital and appreciated!
-
-When preparing to submit a pull-request, please make your PR as easy
-as possible for core devs to evaluate and merge. To that end:
-
-  * In your PR comments, include:
-
-      * the reason for your proposed changes (What problem are you fixing?)
-      * some possible solutions, and rationale for the one you chose
-      * a summary of the code changes in your PR
-      * any pros and cons to note about the solution you implemented
-      * links to any relevant GitHub issues, PR's, and/or forum
-        discussions
-
-  * If you've found and fixed a bug, have you also included a
-    corresponding test for it?
-  * Does your code formatting match that of the rest of the project?
-  * If your changes require updates to the documentation, does your PR
-    include those as well?
-
-Please also bear the following in mind:
-
-  * Evaluating PR's takes time and effort. Even taking a look at a PR
-    in order to request more info or clarification is not zero-cost.
-  * Most members of the core team are volunteers too, and at any given time
-    are typically already busy working on other areas of Haxe.
-  * It's no fun providing negative feedback to a PR. The better you
-    can craft and champion your PR, the more likely it is to be
-    speedily evaluated.
-
-
-## Debugging Hints
-
-### Using a debugger
-
-To debug the Haxe compiler, you can use either a system debugger (`gdb`/`lldb`), or [ocamldebug](http://caml.inria.fr/pub/docs/manual-ocaml/debugger.html). `ocamldebug` provides a better debugging experience. To use it, compile with `make BYTECODE=1`.
-
-### Using printf
-
-To print information about a type, you can add the following before most lines:
-
-```ocaml
-Printf.printf "%s\n" (s_type_kind t);
-```
-
-There are lots of other stringifying functions, search for "Printing" in `src/core/type.ml` and scroll down to find them.
-
 ## Other remarks:
 
 - Sometimes people try to be particularly helpful by not only including broken parts in their code, but also "similar" code which is working. More often than not this is more distracting than helpful. If you want to highlight something like this, consider adding the working code commented out.
 - We do not require a classic "What do you see/what do you expect?" form, but in some cases it is hard to figure out where you think the actual problem is otherwise.
-- We're keeping this page quite short so there's a higher chance that people actually read it.
+- We're keeping this page quite short so there's a higher chance that people actually read it.

+ 411 - 0
Earthfile

@@ -0,0 +1,411 @@
+VERSION 0.6
+FROM mcr.microsoft.com/vscode/devcontainers/base:0-bionic
+ARG DEVCONTAINER_IMAGE_NAME_DEFAULT=ghcr.io/haxefoundation/haxe_devcontainer
+
+ARG USERNAME=vscode
+ARG USER_UID=1000
+ARG USER_GID=$USER_UID
+
+ARG WORKDIR=/workspace
+RUN mkdir -m 777 "$WORKDIR"
+WORKDIR "$WORKDIR"
+
+ARG --required TARGETARCH
+
+devcontainer-library-scripts:
+    RUN curl -fsSLO https://raw.githubusercontent.com/microsoft/vscode-dev-containers/main/script-library/common-debian.sh
+    RUN curl -fsSLO https://raw.githubusercontent.com/microsoft/vscode-dev-containers/main/script-library/docker-debian.sh
+    SAVE ARTIFACT --keep-ts *.sh AS LOCAL .devcontainer/library-scripts/
+
+devcontainer:
+    # Avoid warnings by switching to noninteractive
+    ENV DEBIAN_FRONTEND=noninteractive
+
+    ARG INSTALL_ZSH="false"
+    ARG UPGRADE_PACKAGES="true"
+    ARG ENABLE_NONROOT_DOCKER="true"
+    ARG USE_MOBY="false"
+    COPY .devcontainer/library-scripts/common-debian.sh .devcontainer/library-scripts/docker-debian.sh /tmp/library-scripts/
+    RUN apt-get update \
+        && /bin/bash /tmp/library-scripts/common-debian.sh "${INSTALL_ZSH}" "${USERNAME}" "${USER_UID}" "${USER_GID}" "${UPGRADE_PACKAGES}" "true" "true" \
+        && /bin/bash /tmp/library-scripts/docker-debian.sh "${ENABLE_NONROOT_DOCKER}" "/var/run/docker-host.sock" "/var/run/docker.sock" "${USERNAME}" "${USE_MOBY}" \
+        # Clean up
+        && apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts/
+
+    # Setting the ENTRYPOINT to docker-init.sh will configure non-root access
+    # to the Docker socket. The script will also execute CMD as needed.
+    ENTRYPOINT [ "/usr/local/share/docker-init.sh" ]
+    CMD [ "sleep", "infinity" ]
+
+    # Configure apt and install packages
+    RUN apt-get update \
+        && apt-get install -qqy --no-install-recommends apt-utils dialog 2>&1 \
+        && apt-get install -qqy --no-install-recommends \
+            iproute2 \
+            procps \
+            sudo \
+            bash-completion \
+            build-essential \
+            curl \
+            wget \
+            software-properties-common \
+            direnv \
+            tzdata \
+            # install docker engine for using `WITH DOCKER`
+            docker-ce \
+        # install node
+        && curl -sL https://deb.nodesource.com/setup_16.x | bash - \
+        && apt-get install -qqy --no-install-recommends nodejs=16.* \
+        # install ocaml and other haxe compiler deps
+        && add-apt-repository ppa:avsm/ppa \
+        && add-apt-repository ppa:haxe/ocaml \
+        && apt-get install -qqy --no-install-recommends \
+            ocaml-nox \
+            camlp5 \
+            opam \
+            libpcre2-dev \
+            zlib1g-dev \
+            libgtk2.0-dev \
+            libmbedtls-dev \
+            ninja-build \
+            libstring-shellquote-perl \
+            libipc-system-simple-perl \
+        #
+        # Clean up
+        && apt-get autoremove -y \
+        && apt-get clean -y \
+        && rm -rf /var/lib/apt/lists/*
+
+    # Switch back to dialog for any ad-hoc use of apt-get
+    ENV DEBIAN_FRONTEND=
+
+    DO +INSTALL_NEKO
+
+    COPY +earthly/earthly /usr/local/bin/
+    RUN earthly bootstrap --no-buildkit --with-autocomplete
+
+    USER $USERNAME
+
+    # Do not show git branch in bash prompt because it's slow
+    # https://github.com/microsoft/vscode-dev-containers/issues/1196#issuecomment-988388658
+    RUN git config --global codespaces-theme.hide-status 1
+
+    # Install OCaml libraries
+    COPY haxe.opam .
+    RUN opam init --disable-sandboxing
+    RUN opam switch create 4.08.1
+    RUN eval $(opam env)
+    RUN opam env
+    RUN opam install . --yes --deps-only --no-depexts
+    RUN opam list
+    RUN ocamlopt -v
+
+    USER root
+
+    ARG IMAGE_NAME="$DEVCONTAINER_IMAGE_NAME_DEFAULT"
+    ARG IMAGE_TAG="development"
+    ARG IMAGE_CACHE="$IMAGE_NAME:$IMAGE_TAG"
+    SAVE IMAGE --cache-from="$IMAGE_CACHE" --push "$IMAGE_NAME:$IMAGE_TAG"
+
+devcontainer-multiarch-amd64:
+    ARG IMAGE_NAME="$DEVCONTAINER_IMAGE_NAME_DEFAULT"
+    ARG IMAGE_TAG="development"
+    FROM --platform=linux/amd64 +devcontainer --IMAGE_NAME="$IMAGE_NAME" --IMAGE_TAG="$IMAGE_TAG-amd64"
+    SAVE IMAGE --push "$IMAGE_NAME:$IMAGE_TAG"
+
+devcontainer-multiarch-arm64:
+    ARG IMAGE_NAME="$DEVCONTAINER_IMAGE_NAME_DEFAULT"
+    ARG IMAGE_TAG="development"
+    FROM --platform=linux/arm64 +devcontainer --IMAGE_NAME="$IMAGE_NAME" --IMAGE_TAG="$IMAGE_TAG-arm64"
+    SAVE IMAGE --push "$IMAGE_NAME:$IMAGE_TAG"
+
+devcontainer-multiarch:
+    BUILD +devcontainer-multiarch-amd64
+    BUILD +devcontainer-multiarch-arm64
+
+# Usage:
+# COPY +earthly/earthly /usr/local/bin/
+# RUN earthly bootstrap --no-buildkit --with-autocomplete
+earthly:
+    ARG --required TARGETARCH
+    RUN curl -fsSL https://github.com/earthly/earthly/releases/download/v0.6.13/earthly-linux-${TARGETARCH} -o /usr/local/bin/earthly \
+        && chmod +x /usr/local/bin/earthly
+    SAVE ARTIFACT /usr/local/bin/earthly
+
+INSTALL_PACKAGES:
+    COMMAND
+    ARG PACKAGES
+    RUN apt-get update -qqy && \
+        apt-get install -qqy --no-install-recommends $PACKAGES && \
+        apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*
+
+INSTALL_NEKO:
+    COMMAND
+    ARG NEKOPATH=/neko
+    COPY +neko/* "$NEKOPATH/"
+    ARG PREFIX=/usr/local
+    RUN bash -c "ln -s \"$NEKOPATH\"/{neko,nekoc,nekoml,nekotools} \"$PREFIX/bin/\""
+    RUN bash -c "ln -s \"$NEKOPATH\"/libneko.* \"$PREFIX/lib/\""
+    RUN mkdir -p "$PREFIX/lib/neko/"
+    RUN bash -c "ln -s \"$NEKOPATH\"/*.ndll \"$PREFIX/lib/neko/\""
+    RUN ldconfig
+
+INSTALL_HAXE:
+    COMMAND
+    ARG PREFIX=/usr/local
+    COPY +build/haxe +build/haxelib "$PREFIX/bin/"
+    COPY std "$PREFIX/share/haxe/std"
+
+try-neko:
+    DO +INSTALL_NEKO
+    RUN neko -version
+    RUN nekotools
+
+try-haxe:
+    DO +INSTALL_NEKO
+    DO +INSTALL_HAXE
+    RUN haxe --version
+    RUN haxelib version
+
+neko:
+    RUN set -ex && \
+        case "$TARGETARCH" in \
+            amd64) PLATFORM=linux64;; \
+            arm64) PLATFORM=linux-arm64;; \
+            *) exit 1;; \
+        esac && \
+        curl -fsSL https://build.haxe.org/builds/neko/$PLATFORM/neko_latest.tar.gz -o neko_latest.tar.gz && \
+        tar -xf neko_latest.tar.gz && \
+        mv `echo neko-*-*` /tmp/neko-unpacked
+    SAVE ARTIFACT /tmp/neko-unpacked/*
+    SAVE IMAGE --cache-hint
+
+build:
+    FROM +devcontainer
+
+    USER $USERNAME
+
+    # Build Haxe
+    COPY --dir extra libs plugins src* std dune* Makefile* .
+
+    # the Makefile calls git to get commit sha
+    COPY .git .git
+    ARG SET_SAFE_DIRECTORY="false"
+    IF [ "$SET_SAFE_DIRECTORY" = "true" ]
+        RUN git config --global --add safe.directory "$WORKDIR"
+    END
+
+    ARG ADD_REVISION
+    ENV ADD_REVISION=$ADD_REVISION
+    RUN opam config exec -- make -s -j`nproc` STATICLINK=1 haxe && ldd -v ./haxe
+    RUN opam config exec -- make -s haxelib && ldd -v ./haxelib
+    RUN make -s package_unix && ls -l out
+
+    ARG TARGETPLATFORM
+    SAVE ARTIFACT --keep-ts ./out/* AS LOCAL out/$TARGETPLATFORM/
+    SAVE ARTIFACT --keep-ts ./haxe AS LOCAL out/$TARGETPLATFORM/
+    SAVE ARTIFACT --keep-ts ./haxelib AS LOCAL out/$TARGETPLATFORM/
+    SAVE IMAGE --cache-hint
+
+build-multiarch:
+    ARG ADD_REVISION
+    BUILD --platform=linux/amd64 --platform=linux/arm64 +build --ADD_REVISION=$ADD_REVISION
+
+xmldoc:
+    DO +INSTALL_NEKO
+    DO +INSTALL_HAXE
+
+    COPY --dir extra .
+
+    WORKDIR extra
+    RUN haxelib newrepo
+    RUN haxelib git hxcpp  https://github.com/HaxeFoundation/hxcpp
+    RUN haxelib git hxjava https://github.com/HaxeFoundation/hxjava
+    RUN haxe doc.hxml
+
+    ARG COMMIT
+    ARG BRANCH
+    RUN echo "{\"commit\":\"$COMMIT\",\"branch\":\"$BRANCH\"}" > doc/info.json
+
+    SAVE ARTIFACT --keep-ts ./doc AS LOCAL extra/doc
+
+test-environment:
+    # we use a sightly newer ubuntu for easier installation of the target runtimes (e.g. php)
+    FROM ubuntu:focal
+    DO +INSTALL_NEKO
+    DO +INSTALL_HAXE
+
+    ENV DEBIAN_FRONTEND=noninteractive
+    DO +INSTALL_PACKAGES --PACKAGES="ca-certificates curl wget git build-essential locales sqlite3"
+
+    # Node.js is required as there are tests that use it (search "-cmd node")
+    RUN curl -fsSL https://deb.nodesource.com/setup_16.x | bash - && \
+        apt-get install -qqy nodejs && \
+        apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*
+
+    # set locale
+    RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
+    ENV LANG=en_US.UTF-8
+    ENV LANGUAGE=en_US:en
+    ENV LC_ALL=en_US.UTF-8
+
+    SAVE IMAGE --cache-hint
+
+test-environment-java:
+    FROM +test-environment
+    DO +INSTALL_PACKAGES --PACKAGES="default-jdk"
+    SAVE IMAGE --cache-hint
+
+test-environment-js:
+    # somehow js tests require hxjava which in turns require javac
+    FROM +test-environment-java
+
+test-environment-python:
+    FROM +test-environment
+    DO +INSTALL_PACKAGES --PACKAGES="python3"
+    SAVE IMAGE --cache-hint
+
+test-environment-php:
+    FROM +test-environment
+    DO +INSTALL_PACKAGES --PACKAGES="php-cli php-mbstring php-sqlite3"
+    SAVE IMAGE --cache-hint
+
+test-environment-hl:
+    FROM +test-environment
+    DO +INSTALL_PACKAGES --PACKAGES="cmake ninja-build libturbojpeg-dev libpng-dev zlib1g-dev libvorbis-dev libsqlite3-dev"
+    SAVE IMAGE --cache-hint
+
+test-environment-lua:
+    # hererocks uses pip
+    FROM +test-environment-python
+    DO +INSTALL_PACKAGES --PACKAGES="libssl-dev libreadline-dev python3-pip unzip libpcre2-dev cmake"
+    RUN ln -s /root/.local/bin/hererocks /bin/
+    SAVE IMAGE --cache-hint
+
+test-environment-cpp:
+    FROM +test-environment
+
+    ARG TARGETPLATFORM
+
+    IF [ "$TARGETPLATFORM" = "linux/amd64" ]
+        DO +INSTALL_PACKAGES --PACKAGES="g++-multilib"
+    ELSE IF [ "$TARGETPLATFORM" = "linux/arm64" ]
+        DO +INSTALL_PACKAGES --PACKAGES="g++-multilib-arm-linux-gnueabi"
+    ELSE
+        RUN echo "Unsupported platform $TARGETPLATFORM" && exit 1
+    END
+
+    SAVE IMAGE --cache-hint
+
+test-environment-flash:
+    # apache flex requires java
+    FROM +test-environment-java
+    # requirements for running flash player
+    DO +INSTALL_PACKAGES --PACKAGES="libglib2.0-0 libfreetype6 xvfb libxcursor1 libnss3 libgtk2.0-0"
+    SAVE IMAGE --cache-hint
+
+RUN_CI:
+    COMMAND
+    COPY tests tests
+    RUN mkdir /haxelib && haxelib setup /haxelib
+    WORKDIR tests
+    ARG --required TEST
+    ENV TEST="$TEST"
+    RUN haxe RunCi.hxml
+
+test-macro:
+    FROM +test-environment
+    ARG GITHUB_ACTIONS
+    ENV GITHUB_ACTIONS=$GITHUB_ACTIONS
+    DO +RUN_CI --TEST=macro
+
+test-neko:
+    FROM +test-environment
+    ARG GITHUB_ACTIONS
+    ENV GITHUB_ACTIONS=$GITHUB_ACTIONS
+    DO +RUN_CI --TEST=neko
+
+test-js:
+    FROM +test-environment-js
+    ARG GITHUB_ACTIONS
+    ENV GITHUB_ACTIONS=$GITHUB_ACTIONS
+    DO +RUN_CI --TEST=js
+
+test-hl:
+    FROM +test-environment-hl
+    ARG GITHUB_ACTIONS
+    ENV GITHUB_ACTIONS=$GITHUB_ACTIONS
+    DO +RUN_CI --TEST=hl
+
+test-cpp:
+    FROM +test-environment-cpp
+    ARG GITHUB_ACTIONS
+    ENV GITHUB_ACTIONS=$GITHUB_ACTIONS
+    DO +RUN_CI --TEST=cpp
+
+test-java:
+    FROM +test-environment-java
+    ARG GITHUB_ACTIONS
+    ENV GITHUB_ACTIONS=$GITHUB_ACTIONS
+    DO +RUN_CI --TEST=java
+
+test-jvm:
+    FROM +test-environment-java
+    ARG GITHUB_ACTIONS
+    ENV GITHUB_ACTIONS=$GITHUB_ACTIONS
+    DO +RUN_CI --TEST=jvm
+
+test-php:
+    FROM +test-environment-php
+    ARG GITHUB_ACTIONS
+    ENV GITHUB_ACTIONS=$GITHUB_ACTIONS
+    DO +RUN_CI --TEST=php
+
+test-python:
+    FROM +test-environment-python
+    ARG GITHUB_ACTIONS
+    ENV GITHUB_ACTIONS=$GITHUB_ACTIONS
+    DO +RUN_CI --TEST=python
+
+test-lua:
+    FROM +test-environment-lua
+    ARG GITHUB_ACTIONS
+    ENV GITHUB_ACTIONS=$GITHUB_ACTIONS
+    DO +RUN_CI --TEST=lua
+
+test-flash:
+    FROM +test-environment-flash
+    ARG GITHUB_ACTIONS
+    ENV GITHUB_ACTIONS=$GITHUB_ACTIONS
+    DO +RUN_CI --TEST=flash
+
+test-all:
+    ARG TARGETPLATFORM
+
+    BUILD +test-macro
+    BUILD +test-neko
+    BUILD +test-php
+    BUILD +test-python
+    BUILD +test-java
+    BUILD +test-jvm
+    BUILD +test-cpp
+    BUILD +test-lua
+    BUILD +test-js
+    BUILD +test-flash
+
+    IF [ "$TARGETPLATFORM" = "linux/amd64" ]
+        BUILD +test-hl # FIXME: hl can't compile on arm64 (JIT issue?)
+    END
+
+github-actions:
+    DO +INSTALL_NEKO
+    DO +INSTALL_HAXE
+    RUN mkdir -p "$WORKDIR"/.github/workflows
+    COPY extra/github-actions extra/github-actions
+    WORKDIR extra/github-actions
+    RUN haxe build.hxml
+    SAVE ARTIFACT --keep-ts "$WORKDIR"/.github/workflows AS LOCAL .github/workflows
+
+ghcr-login:
+    LOCALLY
+    RUN echo "$GITHUB_CR_PAT" | docker login ghcr.io -u "$GITHUB_USERNAME" --password-stdin

+ 18 - 10
Makefile

@@ -46,7 +46,7 @@ endif
 
 ADD_REVISION?=0
 
-BRANCH=$(shell echo $$APPVEYOR_REPO_NAME | grep -q /haxe && echo $$APPVEYOR_REPO_BRANCH || echo $$TRAVIS_REPO_SLUG | grep -q /haxe && echo $$TRAVIS_BRANCH || git rev-parse --abbrev-ref HEAD)
+BRANCH=$(shell git rev-parse --abbrev-ref HEAD)
 COMMIT_SHA=$(shell git rev-parse --short HEAD)
 COMMIT_DATE=$(shell \
 	if [ "$$(uname)" = "Darwin" ]; then \
@@ -59,10 +59,14 @@ PACKAGE_FILE_NAME=haxe_$(COMMIT_DATE)_$(COMMIT_SHA)
 HAXE_VERSION=$(shell $(CURDIR)/$(HAXE_OUTPUT) -version 2>&1 | awk '{print $$1;}')
 HAXE_VERSION_SHORT=$(shell echo "$(HAXE_VERSION)" | grep -oE "^[0-9]+\.[0-9]+\.[0-9]+")
 
+NEKO_VERSION=2.3.0
+NEKO_MAJOR_VERSION=$(shell echo "$(NEKO_VERSION)" | grep -oE "^[0-9]+")
+NEKO_VERSION_TAG=v$(shell echo "$(NEKO_VERSION)" | sed "s/\./-/g")
+
 ifneq ($(STATICLINK),0)
-	LIB_PARAMS= -cclib '-Wl,-Bstatic -lpcre -lz -lmbedtls -lmbedx509 -lmbedcrypto -Wl,-Bdynamic '
+	LIB_PARAMS= -cclib '-Wl,-Bstatic -lpcre2-8 -lz -lmbedtls -lmbedx509 -lmbedcrypto -Wl,-Bdynamic '
 else
-	LIB_PARAMS?= -cclib -lpcre -cclib -lz -cclib -lmbedtls -cclib -lmbedx509 -cclib -lmbedcrypto
+	LIB_PARAMS?= -cclib -lpcre2-8 -cclib -lz -cclib -lmbedtls -cclib -lmbedx509 -cclib -lmbedcrypto
 endif
 ifeq ($(SYSTEM_NAME),Mac)
 	LIB_PARAMS+= -cclib '-framework Security -framework CoreFoundation'
@@ -73,9 +77,9 @@ all: haxe tools
 haxe:
 	$(DUNE_COMMAND) build --workspace dune-workspace.dev src-prebuild/prebuild.exe
 	_build/default/src-prebuild/prebuild.exe libparams $(LIB_PARAMS) > lib.sexp
-	_build/default/src-prebuild/prebuild.exe version $(ADD_REVISION) $(BRANCH) $(COMMIT_SHA) > src/compiler/version.ml
+	_build/default/src-prebuild/prebuild.exe version "$(ADD_REVISION)" "$(BRANCH)" "$(COMMIT_SHA)" > src/compiler/version.ml
 	$(DUNE_COMMAND) build --workspace dune-workspace.dev src/haxe.exe
-	cp -f _build/default/src/haxe.exe ./${HAXE_OUTPUT}
+	cp -f _build/default/src/haxe.exe ./"$(HAXE_OUTPUT)"
 
 plugin: haxe
 	$(DUNE_COMMAND) build --workspace dune-workspace.dev plugins/$(PLUGIN)/$(PLUGIN).cmxs
@@ -100,6 +104,7 @@ copy_haxetoolkit: /cygdrive/c/HaxeToolkit/haxe/haxe.exe
 	cp $< $@
 endif
 
+# haxelib should depends on haxe, but we don't want to do that...
 haxelib:
 	(cd $(CURDIR)/extra/haxelib_src && $(CURDIR)/$(HAXE_OUTPUT) client.hxml && nekotools boot run.n)
 	mv extra/haxelib_src/run$(EXTENSION) $(HAXELIB_OUTPUT)
@@ -157,14 +162,13 @@ xmldoc:
 	$(CURDIR)/$(HAXELIB_OUTPUT) newrepo && \
 	$(CURDIR)/$(HAXELIB_OUTPUT) git hxcpp  https://github.com/HaxeFoundation/hxcpp   && \
 	$(CURDIR)/$(HAXELIB_OUTPUT) git hxjava https://github.com/HaxeFoundation/hxjava  && \
-	$(CURDIR)/$(HAXELIB_OUTPUT) git hxcs   https://github.com/HaxeFoundation/hxcs    && \
 	PATH="$(CURDIR):$(PATH)" $(CURDIR)/$(HAXE_OUTPUT) doc.hxml
 
 $(INSTALLER_TMP_DIR):
 	mkdir -p $(INSTALLER_TMP_DIR)
 
 $(INSTALLER_TMP_DIR)/neko-osx64.tar.gz: $(INSTALLER_TMP_DIR)
-	wget -nv https://github.com/HaxeFoundation/neko/releases/download/v2-3-0/neko-2.3.0-osx64.tar.gz -O installer/neko-osx64.tar.gz
+	wget -nv https://github.com/HaxeFoundation/neko/releases/download/$(NEKO_VERSION_TAG)/neko-$(NEKO_VERSION)-osx64.tar.gz -O installer/neko-osx64.tar.gz
 
 # Installer
 
@@ -172,7 +176,6 @@ package_installer_mac: $(INSTALLER_TMP_DIR)/neko-osx64.tar.gz package_unix
 	$(eval OUTFILE := $(shell pwd)/$(PACKAGE_OUT_DIR)/$(PACKAGE_FILE_NAME)_installer.tar.gz)
 	$(eval PACKFILE := $(shell pwd)/$(PACKAGE_OUT_DIR)/$(PACKAGE_FILE_NAME)_bin.tar.gz)
 	$(eval VERSION := $(shell $(CURDIR)/$(HAXE_OUTPUT) -version 2>&1))
-	$(eval NEKOVER := $(shell neko -version 2>&1))
 	bash -c "rm -rf $(INSTALLER_TMP_DIR)/{resources,pkg,tgz,haxe.tar.gz}"
 	mkdir $(INSTALLER_TMP_DIR)/resources
 	# neko - unpack to change the dir name
@@ -185,6 +188,8 @@ package_installer_mac: $(INSTALLER_TMP_DIR)/neko-osx64.tar.gz package_unix
 	cd $(INSTALLER_TMP_DIR)/resources && tar -zcvf haxe.tar.gz haxe
 	# scripts
 	cp -rf extra/mac-installer/* $(INSTALLER_TMP_DIR)/resources
+	sed -i '' 's/%%NEKO_VERSION%%/$(NEKO_VERSION)/g' $(INSTALLER_TMP_DIR)/resources/scripts/neko-postinstall.sh
+	sed -i '' 's/%%NEKO_MAJOR_VERSION%%/$(NEKO_MAJOR_VERSION)/g' $(INSTALLER_TMP_DIR)/resources/scripts/neko-postinstall.sh
 	cd $(INSTALLER_TMP_DIR)/resources && tar -zcvf scripts.tar.gz scripts
 	# installer structure
 	mkdir -p $(INSTALLER_TMP_DIR)/pkg
@@ -200,12 +205,12 @@ package_installer_mac: $(INSTALLER_TMP_DIR)/neko-osx64.tar.gz package_unix
 	sed -i '' 's/%%VERSION%%/$(VERSION)/g' PackageInfo ;\
 	sed -i '' 's/%%VERSTRING%%/$(VERSION)/g' PackageInfo ;\
 	sed -i '' 's/%%VERLONG%%/$(VERSION)/g' PackageInfo ;\
-	sed -i '' 's/%%NEKOVER%%/$(NEKOVER)/g' PackageInfo ;\
+	sed -i '' 's/%%NEKOVER%%/$(NEKO_VERSION)/g' PackageInfo ;\
 	cd .. ;\
 	sed -i '' 's/%%VERSION%%/$(VERSION)/g' Distribution ;\
 	sed -i '' 's/%%VERSTRING%%/$(VERSION)/g' Distribution ;\
 	sed -i '' 's/%%VERLONG%%/$(VERSION)/g' Distribution ;\
-	sed -i '' 's/%%NEKOVER%%/$(NEKOVER)/g' Distribution ;\
+	sed -i '' 's/%%NEKOVER%%/$(NEKO_VERSION)/g' Distribution ;\
 	sed -i '' 's/%%INSTKB%%/$$INSTKBH/g' Distribution"
 	# repackage
 	cd $(INSTALLER_TMP_DIR)/pkg; xar --compression none -cf ../$(PACKAGE_FILE_NAME).pkg *
@@ -236,3 +241,6 @@ FORCE:
 	$(CC_CMD)
 
 .PHONY: haxe haxelib
+
+# our "all:" target doens't work in parallel mode
+.NOTPARALLEL:

+ 7 - 4
Makefile.win

@@ -43,12 +43,12 @@ CC_CMD=($(COMPILER) $(ALL_CFLAGS) -c $< 2>tmp.cmi && $(FILTER)) || ($(FILTER) &&
 endif
 
 ifeq ($(STATICLINK),0)
-	LIB_PARAMS = -cclib -lpcre -cclib -lz -cclib -lcrypt32 -cclib -lmbedtls -cclib -lmbedcrypto -cclib -lmbedx509
+	LIB_PARAMS = -cclib -lpcre2-8 -cclib -lz -cclib -lcrypt32 -cclib -lmbedtls -cclib -lmbedcrypto -cclib -lmbedx509
 endif
 
 PACKAGE_FILES=$(HAXE_OUTPUT) $(HAXELIB_OUTPUT) std \
 	"$$(cygcheck $(CURDIR)/$(HAXE_OUTPUT) | grep zlib1.dll | sed -e 's/^\s*//')" \
-	"$$(cygcheck $(CURDIR)/$(HAXE_OUTPUT) | grep libpcre-1.dll | sed -e 's/^\s*//')" \
+	"$$(cygcheck $(CURDIR)/$(HAXE_OUTPUT) | grep libpcre2-8-0.dll | sed -e 's/^\s*//')" \
 	"$$(cygcheck $(CURDIR)/$(HAXE_OUTPUT) | grep libmbedcrypto.dll | sed -e 's/^\s*//')" \
 	"$$(cygcheck $(CURDIR)/$(HAXE_OUTPUT) | grep libmbedtls.dll | sed -e 's/^\s*//')" \
 	"$$(cygcheck $(CURDIR)/$(HAXE_OUTPUT) | grep libmbedx509.dll | sed -e 's/^\s*//')"
@@ -75,13 +75,15 @@ package_choco:
 	mkdir -p OUTPUT
 	7z x -y out/$(PACKAGE_FILE_NAME)_bin.zip -oout > log.txt || type log.txt
 	mv out/$(PACKAGE_FILE_NAME) out/choco
-	sed -e 's/@SNAPSHOT_VERSION@/$(HAXE_VERSION_SHORT)-SNAP$(COMMIT_DATE)/g' extra/choco/haxe.nuspec > out/choco/haxe.nuspec
+	cp extra/choco/haxe.nuspec out/choco/haxe.nuspec
+	sed -i 's/@SNAPSHOT_VERSION@/$(HAXE_VERSION_SHORT)-SNAP$(COMMIT_DATE)/g' out/choco/haxe.nuspec
+	sed -i 's/@NEKO_VERSION@/$(NEKO_VERSION)/g' out/choco/haxe.nuspec
 	cd out/choco && choco pack
 	mv out/choco/haxe.*.nupkg out
 	rm -rf out/choco
 
 $(INSTALLER_TMP_DIR)/neko-win.zip: $(INSTALLER_TMP_DIR)
-	wget -nv https://github.com/HaxeFoundation/neko/releases/download/v2-3-0/neko-2.3.0-win$(NEKO_ARCH_STR).zip -O installer/neko-win.zip
+	curl -L https://github.com/HaxeFoundation/neko/releases/download/$(NEKO_VERSION_TAG)/neko-$(NEKO_VERSION)-win$(NEKO_ARCH_STR).zip -o installer/neko-win.zip
 
 package_installer_win: $(INSTALLER_TMP_DIR)/neko-win.zip package_win
 	$(eval OUTFILE := $(PACKAGE_OUT_DIR)/$(PACKAGE_FILE_NAME)_installer.zip)
@@ -104,6 +106,7 @@ package_installer_win: $(INSTALLER_TMP_DIR)/neko-win.zip package_win
 	sed -i "s/%%VERSION%%/$(HAXE_VERSION_SHORT)/g" $(INSTALLER_TMP_DIR)/installer.nsi
 	sed -i "s/%%VERSTRING%%/$(HAXE_VERSION)/g" $(INSTALLER_TMP_DIR)/installer.nsi
 	sed -i "s/%%VERLONG%%/$(HAXE_VERSION)/g" $(INSTALLER_TMP_DIR)/installer.nsi
+	sed -i "s/%%NEKO_VERSION%%/$(NEKO_VERSION)/g" $(INSTALLER_TMP_DIR)/installer.nsi
 	cd $(INSTALLER_TMP_DIR) && makensis installer.nsi
 	7z a -r -tzip $(OUTFILE) $(INSTALLER_TMP_DIR)/*.exe
 	dir $(PACKAGE_OUT_DIR)

+ 1 - 3
README.md

@@ -3,7 +3,7 @@
 </p>
 
 <p align="center">
-	<a href="https://dev.azure.com/HaxeFoundation/GitHubPublic/_build/latest?definitionId=1&branchName=development"><img src="https://dev.azure.com/HaxeFoundation/GitHubPublic/_apis/build/status/HaxeFoundation.haxe?branchName=development" alt="Azure Pipelines Build Status"></a>
+	<a href="https://github.com/HaxeFoundation/haxe/actions"><img src="https://github.com/HaxeFoundation/haxe/workflows/CI/badge.svg" alt="GitHub Build Status"></a>
 	<a href="https://saucelabs.com/u/haxe"><img src="https://saucelabs.com/buildstatus/haxe" alt="SauceLabs Test Status"></a>
 	<a href="https://gitter.im/HaxeFoundation/haxe?utm_source=badge&amp;utm_medium=badge&amp;utm_campaign=pr-badge"><img src="https://badges.gitter.im/Join%20Chat.svg" alt="Gitter"></a>
 	<a href="https://discordapp.com/invite/0uEuWH3spjck73Lo"><img src="https://img.shields.io/discord/162395145352904705.svg?logo=discord" alt="Discord"></a>
@@ -21,8 +21,6 @@ Haxe allows you to compile for the following targets:
 
  * JavaScript
  * C++
- * C#
- * Java
  * JVM
  * Lua
  * PHP 7

+ 0 - 315
azure-pipelines.yml

@@ -1,315 +0,0 @@
-variables:
-  - group: variables-haxe
-  - name: AZURE_PIPELINES_REPO_URL
-    value: $(Build.Repository.Uri)
-  - name: AZURE_PIPELINES_BRANCH
-    value: $(Build.SourceBranchName)
-
-trigger:
-  branches:
-    include:
-      - '*'
-  tags:
-    include:
-      - '*'
-
-stages:
-  - stage: StageTest
-    jobs:
-      - template: extra/azure-pipelines/build-linux.yml
-        parameters:
-          name: BuildLinux
-
-      - template: extra/azure-pipelines/build-mac.yml
-        parameters:
-          name: BuildMac
-
-      - template: extra/azure-pipelines/build-windows.yml
-        parameters:
-          name: BuildWin64
-          arch: '64'
-
-      - template: extra/azure-pipelines/build-windows.yml
-        parameters:
-          name: BuildWin32
-          arch: '32'
-
-      - job: TestLinux
-        dependsOn: BuildLinux
-        pool:
-          vmImage: 'ubuntu-16.04'
-        strategy:
-          matrix:
-            macro:
-              TEST: macro
-            neko:
-              TEST: neko
-            hl:
-              TEST: hl
-              APT_PACKAGES: cmake ninja-build
-            cpp:
-              TEST: cpp
-              HXCPP_COMPILE_CACHE: ~/hxcache
-              APT_PACKAGES: gcc-multilib g++-multilib
-            java:
-              TEST: java,jvm
-            cs:
-              TEST: cs
-            js:
-              TEST: js
-              SAUCE: 1
-              SAUCE_TUNNEL_ID: $(Agent.JobName)
-              SAUCE_BUILD: $(Build.BuildNumber)
-            php:
-              TEST: php
-            flash:
-              TEST: flash9
-              APT_PACKAGES: libglib2.0 libfreetype6 xvfb
-              DISPLAY: ':99.0'
-              AUDIODEV: 'null'
-            python:
-              TEST: python
-            lua:
-              TEST: lua
-              APT_PACKAGES: ncurses-dev
-        steps:
-          - checkout: self
-            fetchDepth: 20
-          - template: extra/azure-pipelines/install-neko-snapshot.yaml
-            parameters:
-              platform: linux64
-          - task: DownloadPipelineArtifact@0
-            inputs:
-              artifactName: 'linuxBinaries'
-              targetPath: linuxBinaries
-          - script: |
-              set -ex
-              tar -xf linuxBinaries/*_bin.tar.gz -C linuxBinaries --strip-components=1
-              sudo mkdir -p /usr/local/bin/
-              sudo mkdir -p /usr/local/share/haxe/
-              sudo ln -s `pwd`/linuxBinaries/haxe /usr/local/bin/haxe
-              sudo ln -s `pwd`/linuxBinaries/haxelib /usr/local/bin/haxelib
-              sudo ln -s `pwd`/linuxBinaries/std /usr/local/share/haxe/std
-            displayName: Setup Haxe
-          - script: haxe -version
-            displayName: Print Haxe version
-          - script: |
-              set -ex
-              mkdir ~/haxelib
-              haxelib setup ~/haxelib
-            displayName: Setup haxelib
-          - script: |
-              set -ex
-              sudo apt update -qqy
-              sudo apt install -qqy $APT_PACKAGES
-            condition: and(succeeded(), variables['APT_PACKAGES'])
-            displayName: Install apt packages
-          - script: haxe RunCi.hxml
-            condition: and(succeeded(), not(and(variables['SAUCE'], variables['SAUCE_ACCESS_KEY'])))
-            workingDirectory: $(Build.SourcesDirectory)/tests
-            displayName: Test
-          - script: haxe RunCi.hxml
-            condition: and(succeeded(), variables['SAUCE'], variables['SAUCE_ACCESS_KEY'])
-            workingDirectory: $(Build.SourcesDirectory)/tests
-            env:
-              SAUCE_ACCESS_KEY: $(SAUCE_ACCESS_KEY)
-            displayName: Test (with SauceLabs)
-
-      - job: TestMac
-        dependsOn: BuildMac
-        pool:
-          vmImage: 'macOS-10.13'
-        strategy:
-          matrix:
-            macro:
-              TEST: macro
-            neko:
-              TEST: neko
-            hl:
-              TEST: hl
-              BREW_PACKAGES: ninja
-            cpp:
-              TEST: cpp
-              HXCPP_COMPILE_CACHE: ~/hxcache
-            java:
-              TEST: java,jvm
-            cs:
-              TEST: cs
-            js:
-              TEST: js
-            php:
-              TEST: php
-            flash:
-              TEST: flash9
-            python:
-              TEST: python
-            lua:
-              TEST: lua
-        steps:
-          - checkout: self
-            fetchDepth: 20
-          - template: extra/azure-pipelines/install-neko-snapshot.yaml
-            parameters:
-              platform: mac
-          - task: DownloadPipelineArtifact@0
-            inputs:
-              artifactName: 'macBinaries'
-              targetPath: macBinaries
-          - script: |
-              set -ex
-              tar -xf macBinaries/*_bin.tar.gz -C macBinaries --strip-components=1
-              sudo mkdir -p /usr/local/bin/
-              sudo mkdir -p /usr/local/share/haxe/
-              sudo ln -s `pwd`/macBinaries/haxe /usr/local/bin/haxe
-              sudo ln -s `pwd`/macBinaries/haxelib /usr/local/bin/haxelib
-              sudo ln -s `pwd`/macBinaries/std /usr/local/share/haxe/std
-            displayName: Setup Haxe
-          - script: haxe -version
-            displayName: Print Haxe version
-          - script: |
-              set -ex
-              mkdir ~/haxelib
-              haxelib setup ~/haxelib
-            displayName: Setup haxelib
-          - script: brew install $BREW_PACKAGES
-            condition: and(succeeded(), variables['BREW_PACKAGES'])
-            displayName: Install homebrew packages
-          - script: haxe RunCi.hxml
-            workingDirectory: $(Build.SourcesDirectory)/tests
-            displayName: Test
-
-      - template: extra/azure-pipelines/test-windows.yml
-        parameters:
-          name: TestWin64
-          arch: '64'
-
-      - template: extra/azure-pipelines/test-windows.yml
-        parameters:
-          name: TestWin32
-          arch: '32'
-
-  - stage: StageDeploy
-    condition: and(succeeded(), not(variables['System.PullRequest.PullRequestId']))
-    jobs:
-      - job: S3
-        condition: and(succeeded(), variables['HXBUILDS_AWS_ACCESS_KEY_ID'], variables['HXBUILDS_S3ADDR'])
-        pool:
-          vmImage: 'ubuntu-16.04'
-        steps:
-          - checkout: self
-            fetchDepth: 20
-          - task: DownloadPipelineArtifact@0
-            inputs:
-              artifactName: 'linuxBinaries'
-              targetPath: linuxBinaries
-            displayName: Download linuxBinaries
-          - task: DownloadPipelineArtifact@0
-            inputs:
-              artifactName: 'macBinaries'
-              targetPath: macBinaries
-            displayName: Download macBinaries
-          - task: DownloadPipelineArtifact@0
-            inputs:
-              artifactName: 'win64Binaries'
-              targetPath: win64Binaries
-            displayName: Download win64Binaries
-          - task: DownloadPipelineArtifact@0
-            inputs:
-              artifactName: 'win32Binaries'
-              targetPath: win32Binaries
-            displayName: Download win32Binaries
-          - template: extra/azure-pipelines/install-neko-snapshot.yaml
-            parameters:
-              platform: linux64
-          - script: |
-              set -ex
-              tar -xf linuxBinaries/*_bin.tar.gz -C linuxBinaries --strip-components=1
-              sudo mkdir -p /usr/local/bin/
-              sudo mkdir -p /usr/local/share/haxe/
-              sudo ln -s `pwd`/linuxBinaries/haxe /usr/local/bin/haxe
-              sudo ln -s `pwd`/linuxBinaries/haxelib /usr/local/bin/haxelib
-              sudo ln -s `pwd`/linuxBinaries/std /usr/local/share/haxe/std
-            displayName: Setup Haxe
-          - script: |
-              set -ex
-              sudo apt-get update -qqy
-              sudo apt-get install -qqy awscli
-            displayName: "Install awscli"
-          - script: |
-              set -ex
-              COMMIT_HASH=`git rev-parse HEAD`
-              COMMIT_HASH_SHORT=${COMMIT_HASH:0:7}
-              COMMIT_DATE=`TZ=UTC git show --quiet --date='format-local:%Y-%m-%d' --format="%cd"`
-              FILE_NAME=haxe_${COMMIT_DATE}_$(Build.SourceBranchName)_${COMMIT_HASH_SHORT}
-              aws s3 cp linuxBinaries/*_bin.tar.gz      $(HXBUILDS_S3ADDR)/haxe/linux64/${FILE_NAME}.tar.gz
-              aws s3 cp macBinaries/*_bin.tar.gz        $(HXBUILDS_S3ADDR)/haxe/mac/${FILE_NAME}.tar.gz
-              aws s3 cp macBinaries/*_installer.tar.gz  $(HXBUILDS_S3ADDR)/haxe/mac-installer/${FILE_NAME}.tar.gz
-              aws s3 cp win64Binaries/*_bin.zip         $(HXBUILDS_S3ADDR)/haxe/windows64/${FILE_NAME}.zip
-              aws s3 cp win64Binaries/*_installer.zip   $(HXBUILDS_S3ADDR)/haxe/windows64-installer/${FILE_NAME}.zip
-              aws s3 cp win64Binaries/*.nupkg           $(HXBUILDS_S3ADDR)/haxe/windows64-choco/
-              aws s3 cp win32Binaries/*_bin.zip         $(HXBUILDS_S3ADDR)/haxe/windows/${FILE_NAME}.zip
-              aws s3 cp win32Binaries/*_installer.zip   $(HXBUILDS_S3ADDR)/haxe/windows-installer/${FILE_NAME}.zip
-              aws s3 cp win32Binaries/*.nupkg           $(HXBUILDS_S3ADDR)/haxe/windows-choco/
-            env:
-              AWS_ACCESS_KEY_ID: $(HXBUILDS_AWS_ACCESS_KEY_ID)
-              AWS_SECRET_ACCESS_KEY: $(HXBUILDS_AWS_SECRET_ACCESS_KEY)
-            displayName: Upload binaries
-          - script: |
-              set -ex
-              aws s3 cp linuxBinaries/*_bin.tar.gz      $(HXBUILDS_S3ADDR)/haxe/linux64/haxe_latest.tar.gz
-              aws s3 cp macBinaries/*_bin.tar.gz        $(HXBUILDS_S3ADDR)/haxe/mac/haxe_latest.tar.gz
-              aws s3 cp macBinaries/*_installer.tar.gz        $(HXBUILDS_S3ADDR)/haxe/mac-installer/haxe_latest.tar.gz
-              aws s3 cp win64Binaries/*_bin.zip         $(HXBUILDS_S3ADDR)/haxe/windows64/haxe_latest.zip
-              aws s3 cp win64Binaries/*_installer.zip   $(HXBUILDS_S3ADDR)/haxe/windows64-installer/haxe_latest.zip
-              aws s3 cp win32Binaries/*_bin.zip         $(HXBUILDS_S3ADDR)/haxe/windows/haxe_latest.zip
-              aws s3 cp win32Binaries/*_installer.zip   $(HXBUILDS_S3ADDR)/haxe/windows-installer/haxe_latest.zip
-
-              # Chocolatey packages have to be named with version number,
-              # so let's use web redirection to keep the original file name.
-              [[ "$HXBUILDS_S3ADDR" =~ s3://([^/]+)(.*) ]] && HXBUILDS_S3BUCKET="${BASH_REMATCH[1]}" && HXBUILDS_S3PATH="${BASH_REMATCH[2]}"
-              [[ `echo win64Binaries/*.nupkg` =~ win64Binaries/(.+) ]] && FILE_NAME="${BASH_REMATCH[1]}"
-              aws s3 cp $(HXBUILDS_S3ADDR)/haxe/windows64-choco/${FILE_NAME} $(HXBUILDS_S3ADDR)/haxe/windows64-choco/haxe_latest.nupkg --acl public-read --website-redirect "${HXBUILDS_S3PATH}/haxe/windows64-choco/${FILE_NAME}"
-              [[ `echo win32Binaries/*.nupkg` =~ win32Binaries/(.+) ]] && FILE_NAME="${BASH_REMATCH[1]}"
-              aws s3 cp $(HXBUILDS_S3ADDR)/haxe/windows-choco/${FILE_NAME}   $(HXBUILDS_S3ADDR)/haxe/windows-choco/haxe_latest.nupkg   --acl public-read --website-redirect "${HXBUILDS_S3PATH}/haxe/windows-choco/${FILE_NAME}"
-            env:
-              AWS_ACCESS_KEY_ID: $(HXBUILDS_AWS_ACCESS_KEY_ID)
-              AWS_SECRET_ACCESS_KEY: $(HXBUILDS_AWS_SECRET_ACCESS_KEY)
-            condition: and(succeeded(), eq(variables['Build.SourceBranchName'], 'development'))
-            displayName: Update "latest"
-
-      - job: ApiHaxeOrg
-        condition: and(succeeded(), variables['GHP_USERNAME'], variables['GHP_EMAIL'])
-        pool:
-          vmImage: 'ubuntu-16.04'
-        steps:
-          - checkout: none
-          - template: extra/azure-pipelines/install-neko-snapshot.yaml
-            parameters:
-              platform: linux64
-          - task: DownloadPipelineArtifact@0
-            inputs:
-              artifactName: 'linuxBinaries'
-              targetPath: linuxBinaries
-            displayName: Download linuxBinaries
-          - script: |
-              set -ex
-              tar -xf linuxBinaries/*_bin.tar.gz -C linuxBinaries --strip-components=1
-              sudo mkdir -p /usr/local/bin/
-              sudo mkdir -p /usr/local/share/haxe/
-              sudo ln -s `pwd`/linuxBinaries/haxe /usr/local/bin/haxe
-              sudo ln -s `pwd`/linuxBinaries/haxelib /usr/local/bin/haxelib
-              sudo ln -s `pwd`/linuxBinaries/std /usr/local/share/haxe/std
-            displayName: Setup Haxe
-          - task: DownloadPipelineArtifact@0
-            inputs:
-              artifactName: 'xmldoc'
-              targetPath: xmldoc
-            displayName: Download xmldoc
-          - script: |
-              set -ex
-              LOCAL="`pwd`/extra/api.haxe.org"
-              git clone "${GHP_REMOTE}" "${LOCAL}"
-              haxe --cwd "${LOCAL}" --run ImportXml "`pwd`/xmldoc"
-            env:
-              GHP_REMOTE: $(GHP_REMOTE)
-            displayName: Deploy to api.haxe.org

+ 2 - 1
dune

@@ -1 +1,2 @@
-(data_only_dirs extra lib std tests)
+(dirs :standard \ tests std extra)
+(data_only_dirs lib)

+ 2 - 2
dune-project

@@ -1,4 +1,4 @@
-(lang dune 1.11)
+(lang dune 3.0)
 (name haxe)
 
 (package
@@ -7,4 +7,4 @@
 
 (package
 	(name haxe_prebuild)
-)
+)

+ 3 - 3
extra/BUILDING.md

@@ -36,11 +36,11 @@ You need to install some native libraries as well as some OCaml libraries.
 To install the native libraries, use the appropriate system package manager.
 
  * Mac OS X
-    * Use [Homebrew](https://brew.sh/), `brew install zlib pcre`.
+    * Use [Homebrew](https://brew.sh/), `brew install zlib pcre2 mbedtls`.
  * Debian / Ubuntu
-    * `sudo apt install libpcre3-dev zlib1g-dev`.
+    * `sudo apt install libpcre2-dev zlib1g-dev libmbedtls-dev`.
  * Windows (Cygwin)
-    * Run the Cygwin [setup-x86_64.exe](https://cygwin.com/install.html) against the Cygwin installation directory. Install `make`, `git`, `zlib-devel`, `libpcre-devel`, `mingw64-x86_64-gcc-core`, `mingw64-x86_64-zlib`, and `mingw64-x86_64-pcre`. You may need to select "Not Installed" in the dropdown list to see the packages. Copy `zlib1.dll` and `libpcre-1.dll` from `path/to/cygwin/usr/x86_64-w64-mingw32/sys-root/mingw/bin` to the checked out Haxe source directory.
+    * Run the Cygwin [setup-x86_64.exe](https://cygwin.com/install.html) against the Cygwin installation directory. Install `make`, `git`, `zlib-devel`, `libpcre2-devel`, `mingw64-x86_64-gcc-core`, `mingw64-x86_64-zlib`, and `mingw64-x86_64-pcre2`. You may need to select "Not Installed" in the dropdown list to see the packages. Copy `zlib1.dll` and `libpcre2-8-0.dll` from `path/to/cygwin/usr/x86_64-w64-mingw32/sys-root/mingw/bin` to the checked out Haxe source directory.
     * Install Neko by either
       * Download the [Neko binaries](https://nekovm.org/download/), and add the extracted directory to the beginning of PATH.
       * Install the [Chocolatey Neko package](https://chocolatey.org/packages/neko).

+ 556 - 4
extra/CHANGES.txt

@@ -1,9 +1,561 @@
-????-??-??: 4.1.0
+2023-09-17 4.3.3
 
 	General improvements:
 
+	all : improve extra field error range (#11335)
+	all : better error messages for --connect
+	hl : improve error message when hl_version is missing (#11086)
+	hl/c : compiler now adds hlc define when targeting hl/c (#11382)
+	macro : update macro API restriction warnings when using -D haxe-next (#11377)
+
+	Bugfixes:
+
+	all : handle non existing files for positions in pretty errors (#11364)
+	all : metadata support for local static vars
+	all : catch trailing invalid syntax in string interpolation (#10287)
+	eval : fix Array.resize retaining values (#11317)
+	eval/hl : fix catching haxe.ValueException (#11321)
+	hl : make genhl respect Meta.NoExpr (#11257)
+	hl : don't add bindings for non existing methods
+	hl/c : add missing I64 mod support
+	hl/c : rework reserved keywords (#11293, #11378)
+	hl/c : fix Int64 unsigned right shift overflow (#11382)
+	java/cs: fix stack overflow from closures constraints (#11350)
+	js : DOMElement insertAdjacentElement should not be pure (#11333)
+	macro : catch trailing invalid syntax in Context.parseInlineString (#11368)
+	macro : fix TDAbstract without flags in haxe.macro.Printer
+
+2023-09-01 4.3.2
+
+	General improvements:
+
+	all : do not raise error on no-op reification outside macro
+
+	Bugfixes:
+
+	all : don't infer Null<?> if it already is Null<?> (#11286)
+	all : fix ?? inference and precedence (#11252)
+	all : bring back forced inline (#11217)
+	all : allow non constant "inline" var init with -D no-inline (#11192)
+	all : improve @:enum abstract deprecation warning handling (#11302)
+	all : fix some stack overflow with pretty errors
+	display : fix go to definition with final (#11173)
+	display : fix completion requests with @:forwardStatics (#11294)
+	eval : fix MainLoop.add not repeating (#11202)
+	hl/eval/neko : fix exception stack when wrapping native exceptions (#11249)
+	macro : map `this` when restoring typed expressions (#11212)
+	macro : safe navigation fix for ExprTools.map (#11204)
+	macro : safe navigation fix for haxe.macro.Printer (#11206)
+	macro : macro generated EVars position fixes (#11163)
+	macro : fix abstract casts for local statics (#11301)
+	macro : add flags to TDAbstract to be able to construct enum abstracts (#11230)
+	nullsafety : make break/continue expressions not-nullable (#11269)
+	nullsafety : handle return in assignment (#11114)
+
+2023-04-28 4.3.1
+
+	Breaking changes:
+
+	all : namespace message reporting defines (#11142)
+
+	General improvements:
+
+	all : support deprecation for defines
+
+	Bugfixes:
+
+	all : fix --times with compilation server (#11091)
+	all : fix default type parameters not respecting imports (#11161)
+	all : fix bytecode bindings issues (#11098)
+	macro : allow local statics in macro functions (#11096)
+	cpp : fix AtomicInt warnings on cppia (#11105)
+	cpp : fix deprecated implicit casts of cpp.Int64 (#10998)
+	cpp : add white space around template type syntax (#11107)
+	java : don't check native signatures on extern functions (#11131)
+	lua : remove non existent luautf8 charCodeAt extern (#11097)
+
+2023-04-06 4.3.0
+
+	New features:
+
+	all : support defaults for type parameters (#10518)
+	all : support @:op(a()) on abstracts (#10119)
+	all : support abstract keyword to reference the abstract (#10513)
+	all : support static var at expression-level (#10555)
+	all : support ?. safe navigation operator (#10561)
+	all : added ?? null coalescing operator (#10428)
+	all : add -w compiler option to configure warnings (#10612)
+	all : added new error reporting modes (#10863)
+	all : support custom metadata and defines (#10858)
+
+	General improvements:
+
+	all : made various optimizations in the analyzer
+	all : made various improvements to diagnostics
+	all : made various improvements to null-safety
+	all : optimize `.bind` for instance methods (#10737)
+	all : improved various parser error messages
+	all : improved compilation server performance
+	all : improved code generation for try/catch (#10519)
+	all : infer property accessor type from the property (#10569)
+	all : improved inference of local functions typed against abstracts (#10336)
+	all : improved completion on module-level fields
+	all : improved handling of native libraries on the compilation server
+	all : improved performance when generating locals (#10648)
+	all : made Std.parseInt more consistent across targets (#10664)
+	all : infer null literals as Null<?> (#7736)
+	all : made field access errors more consistent (#10896)
+	all : consistently allow trailing commas (#11009)
+	all : migrated all relevant targets to PCRE2 (#10491)
+	all : made analyzer reconstruct do-while loops (#7979)
+	all : improved restrictions on init macros (#11043)
+	all : improved positions of @:structInit fields (#9318)
+	macro : support map literals in Context.makeExpr (#10259)
+	macro : added haxe.macro.Compiler.getConfiguration() (#10871)
+	macro : added withImports and withOption to haxe.macro.Context
+	macro : added getMacroStack and onAfterInitMacros to haxe.macro.Context (#11043)
+	macro : added haxe.macro.Context.makeMonomorph (#10728)
+	eval : added dictionary mode to objects, increasing performance in some cases (#10284)
+	eval : fixed Sys.exit handling messing up the compilation server (#10642)
+	eval : added -D eval-print-depth and -D eval-pretty-print (#10952, #10963)
+	cpp : supported type parameters on extern classes (#10415)
+	cpp : haxe.Int64 improvements (#9935)
+	cpp : non-blocking process exit code reading (#10321)
+	js : improved type names for debugger (#10894)
+	lua : added SSL implementation (#10593)
+	lua : fixed String API when -D no-inline was in place (#11057)
+	lua : non-zero exit code in case of uncaught exception (#11082)
+	java : deal with default implementations when loading extern libraries (#10466)
+	jvm : improved closure naming (#10571)
+	jvm : supported --jvm dir (#10614)
+	jvm : added some missing TShort and TFloat handling (#10722)
+	jvm : added experimental support for functional interfaces (#11019)
+	php : added and fixed several extern functions
+
+	Standard Library:
+
+	all : added atomic operations to several targets (#10610)
+	all : added Vector.fill (#10687)
+	sys : added sys.thread.Condition and Semaphore (#10503)
+	sys : added Http.getResponseHeaderValues to deal with multiple values of same key (#10812)
+	sys : make Sys.environment consistent between targets (#10460)
+	sys : consistent way to unset environment variables with Sys.putEnv (#10402)
+
+	Bugfixes:
+
+	all : properly disallowed macro reification in invalid places (#10883)
+	all : fixed behavior when extending abstract classes with final fields (#10139)
+	all : addressed some issues with constructor inlining (#10304)
+	all : fixed pattern matcher bug related to null-guards (#10291)
+	all : fixed weird parser behavior on first offset in files (#10322)
+	all : fixed various issues related to the final modifier
+	all : fixed various issues related to overload handling
+	all : fixed precedence of => vs. ?: (#10455)
+	all : made error positions in structure declarations more accurate (#9584)
+	all : brought back proper check when accessing super fields (#10521)
+	all : fixed @:publicFields on abstracts (#10541)
+	all : inherited some metadata to @:generic implementation classes (#10557)
+	all : fixed various problems in EventLoop and MainLoop
+	all : fixed infinite recursion from invalid inheritance (#10245)
+	all : fixed strange interaction between static extensions and macro functions (#10587)
+	all : fixed problems with @:generic on the compilation server (#10635)
+	all : fixed Context.onTypeNotFound being called multiple times for the same thing (#10678)
+	all : fixed type parameter problem involving abstract classes and interfaces (#10748)
+	all : fixed #if (a != b) yielding true for nonexistent values (#10868)
+	all : fixed interaction between @:generic and abstract class (#10735)
+	all : fixed @:using loading types too eagerly (#10107)
+	all : fixed parser ignoring subsequent documentation comments (#10171)
+	all : fixed parser function messing up unrelated file state in some cases (#10763)
+	all : unified Map printing to always use [] (#9260)
+	cpp : fixed problem with cpp.Pointer being used in enum arguments (#10831)
+	macro : improved handling of macro this expressions (#10793)
+	eval : fixed bit shift operations > 31 (#10752)
+	eval : fixed Bytes.toString causing an internal exception (#10623)
+	jvm : fixed @:native processing (#10280)
+	jvm : fixed Type.getEnumConstructs on native enums (#10508)
+	jvm : fixed @:volatile being ignored (#10594)
+	jvm : fixed some hashing issue when pattern matching on emojis (#10720)
+	jvm : fixed stack handling on return return (#10743)
+	hl : fixed various code generation problems
+	python : fixed SslSocket for newer python versions (#8401)
+	python : fixed syntax issue related to Vector (#11060)
+
+2021-03-06 4.2.5:
+
+	New features:
+
+	php : support PHP attributes generation (#9964)
+
+	Bugfixes:
+
+	all : fixed compiler crash in complex constraints chains (#10445)
+	all : fixed timers execution order for timers with small time delta (#10567)
+	js : fixed constructors with rest arguments when compiling for ES3, ES5 (#10490)
+	php : excluded E_DEPRECATED notices from error reporting (#10502)
+	php : fixed safe casts to native arrays (#10576)
+	nullsafety : fixed false error on extern var fields without initialization (#10448)
+
+2021-10-22 4.2.4:
+
+	New features:
+
+	hl : add clipboard support in hl 1.12 (#10320)
+
+	General improvements:
+
+	all : improved error messages upon directory creation failures (#10361)
+	eval : added `%` operator to `eval.numbers.Int64` and `eval.numbers.UInt64` (#10411)
+
+	Bugfixes:
+
+	all : fixed errors on final vars modification with `+=`, `*=` etc operations (#10325)
+	all : fixed hanging of MainLoop.add on threaded targets (#10308, #10329)
+	all : fixed compiler crash when resolving overloads with not enough arguments (#10434)
+	all : fixed non-static `@:to` methods on `@:multiType` abstracts (#10145)
+	analyzer : fixed analyzer on overloads (#10405)
+	analyzer : fixed issues with fields initialization expressions (#10405)
+	display : improved code completion in anonymous objects declarations (#10414)
+	js : fixed IntMap for keys greater than 2^31 (#10316)
+	js : workaround to fix sourcemaps on Firefox in Windows (#10217)
+	js : delayed truncation of the output file on `Compiler.setCustomJSGenerator` (#10387)
+	cs/java : fixed rest arguments for cases when only one argument is provided (#10315)
+	php : fixed type of `php.db.PDO.ATTR_DRIVER_NAME` (#10319)
+	eval : fixed signature of `eval.luv.Tcp.noDelay` method
+	lua : fixed `string.length` when `string` has type of a type parameter constrained to `String` (#10343)
+	jvm : fixed `Reflect.compare()` for different number types (#10350)
+	python : fixed exceptions on tracing some native values (#10440)
+
+2021-07-01 4.2.3:
+
+	General improvements:
+
+	all : analyzer optimizations
+	macro : support maps in `haxe.macro.Context.makeExpr` (#10259)
+	js : added `-D js-global=globalThis` to customize global object name (#10282)
+	php : added externs for `quoted_printable_decode`, `quoted_printable_encode`, `Attribute`, `NumberFormat`, `IntlCalendar` and other `Intl*` classes
+
+	Bugfixes:
+
+	all : fixed compiler crash on some unreachable code blocks (#10261)
+	jvm : fixed `@:native` (#10280)
+	jvm : fixed `--xml` generation (#10279)
+
+2021-05-14 4.2.2:
+
+	Bugfixes:
+
+	all : fixed piping stdin/stdout in `--cmd` (#4669, #6726)
+	all : fixed rest args typing for overloaded functions (#10143)
+	all : fixed using `var` fields as static extensions (#10144)
+	all : fixed completion for a type in `expr is Type` (#10167)
+	all : fixed subtypes in `expr is Module.SubType` expressions (#10174)
+	all : fixed typing chains of calls with constrained type params (#10198)
+	all : fixed mixed constraints of anonymous structures and other types (#10162)
+	all : fixed operator overloading for enum abstracts (#10173)
+	hl : fixed debugging of `catch` blocks (#10109)
+	jvm : fixed manifest generation for cases with a lot of jar libraries (#10157)
+	js : fixed extending extern classes for es5 (#10192)
+	js : fixed checking `this` before `super` for es6 (#10193)
+	eval : fixed null pointer exception in `eval.NativeString.fromString(null)`
+	eval : fixed multiple locks of `sys.thread.Mutex` from the same thread (#10249)
+
+2021-02-26 4.2.1:
+
+	General improvements:
+
+	threads : changed main thread initialization to make main event loop available during static initialization (#10114)
+	php : added extern for `number_format` function (#10115)
+	python : rewrote `sys.thread.Thread`, `Mutex` and `Lock` as classes instead of abstracts.
+
+	Bugfixes:
+
+	all : fixed compiler compatibility with OS X 10.13 (#10110)
+	all : fixed compiler hanging on `switch` for abstracts with implicit casts involving type parameters and constraints (#10082)
+	all : fixed inlining of `haxe.DynamicAccess.keyValueIterator` (#10118)
+	all : fixed rest arguments typing against type parameters (#10124)
+	analyzer : fixed side effect handling for enums (#10032)
+	cpp : fixed handling of `cpp.ConstCharStar` with analyzer enabled (#9733)
+	php : fixed failure with trailing slash in output dir (#6212)
+	hl : fixed call stack of rethrown exceptions (#10109)
+
+2021-02-09 4.2.0:
+
+	New features:
+
+	all : implemented "classic" abstract classes and functions (see [haxe-evolution#69](https://github.com/HaxeFoundation/haxe-evolution/pull/69)) (#9716)
+	all : module-level static declarations (#8460)
+	all : implemented rest arguments (variadic functions) for all targets with `haxe.Rest` type (#9961)
+	all : per-thread event loops `sys.thread.Thread.events` (#9868)
+	all : added `@:inheritDoc` meta to inherit documentation for a type or field from another type or field (#9817)
+	all : support method overloading for extern methods on all targets (#9793)
+	all : constructors forwarding for abstracts with `@:forward.new` (#9735)
+	all : added `EIs` constructor to `haxe.macro.Expr` (#9689)
+	all : added variance forwarding with `@:forward.variance` (#9741)
+	all : treat `Any` as `Dynamic` in variance unification (#6649)
+	all : added some common exception types to `haxe.exceptions` package
+	all : support metadata in var declaration syntax (#9618)
+	all : added `StringTools.unsafeCharAt` (#9467)
+	eval : added libuv bindings under `eval.luv` package (#9903)
+	eval : added bindings to native `Int64` and `UInt64` implementations under `eval.integers` package (#9903)
+	cs : UDP socket implementation (#8498)
+	cs : added `cs.Syntax` module (#10051)
+	jvm : added `-D jvm.dynamic-level` to control the amount of dynamic support code being generated. 0 = none, 1 = field read/write optimization (default), 2 = compile-time method closures
+	java,jvm : support `--java-lib <directory>` (#9551)
+	python : threading API implementation (#9754)
+
+	General improvements:
+
+	all : `expr is SomeType` doesn't require parentheses anymore (#9672)
+	all : increased priority of @:using extensions (#9681)
+	all : allowed usage of static extensions with super (#10062)
+	all : allow @:noDoc on fields too (#9893)
+	all : made `Map` abstract transitive (#9877)
+	all : support `@:native` on enum constructors (#9806)
+	all : support `@:using` on typedefs (#9749)
+	all : changed multiline errors format to use "..." as a prefix for subsequent lines (#9651)
+	all : improved type inference with constrained monomorphs (#9549)
+	all : print no-argument function types as `()->...` instead of `Void->...` (#8148)
+	all : allow `function` as package name
+	all : improved object inlining (#9599)
+	display : narrow range for hover on parametrized types (#8073)
+	cs : added .NET 5.0 support (#10043)
+	cpp : support native constructors on extern classes (#9516)
+	php: `php.Syntax.customArrayDecl` (#9113)
+	php : added externs for various php functions and classes
+	php : optimized anonymous objects instantiation (#7916)
+	hl : skip compilation if no module has been changed (#9922)
+	lua : use hx-lua-simdjson for Lua json parsing (#9885)
+	jvm : less CPU consuming `sys.thread.Lock` implementation
+
+	Bugfixes:
+
+	all : fixed Template.resolve when current context is not an object (#9372)
+	all : `get` and `set` functions of `haxe.io.Float64Array` actually use 64-bit floats now (#9972)
+	all : treat empty blocks `{}` as object declarations in array comprehension (fixes #9971)
+	all : `haxe.format.JsonParser`: preserve Float-typed values when they are written as such in JSON (ie. "5.0" or "0.0") (#9844)
+	all : fixed priority of forwarded static extensions (#9680)
+	all : fixed some inconsistency in variance unification for abstracts (#9743)
+	display : fixed completion with platform-specific files (#9423)
+	cpp : fixed conversion of `cpp.Int64` to/from `haxe.Int64` (#10101)
+	cpp : fixed extending extern classes with `@:nativeGen` classes (#9431)
+	php : fixed generation with subdirectories in `-D php-front=subdir/index.php` (#10037)
+	php : fixed local vars with the same names as super global vars (#9924)
+	eval : allow full range of 32bit integers in `Std.random` (#9974)
+	js : fixed `haxe.CallStack.exceptionStack` (#9968)
+	js : fixed compatibility issue with closure compiler upon unused `catch` vars (#9617)
+	lua : fixed anonymous object printing issue with null fields on tables
+	hl : drop data of terminated threads (#9875)
+	macro : fixed `haxe.macro.Context.storeTypedExpr` for enum constructs (#9828)
+	macro : emit a deprecation warning upon a macro call instead of upon a macro function declaration (#9425)
+	macro : fixed uncatchable error from `haxe.macro.Context.getType` (#9449)
+	jvm : fixed `Type.resolveEnum` for enums in the root package (#9809)
+	jvm : fixed `Type.resolveEnumName` for enums in the root package (#9759)
+	cs : fixed cs.Lib.rethrow (#9738)
+	nullsafety : respect `@:nullSafety(Off)` on var declarations: `var @:nullSafety(Off) v`
+	nullsafety : respect `@:nullSafety(Off)` in closures in constructors (#9643)
+	nullsafety : fixed error "Type not found : haxe.macro._Compiler.NullSafetyMode_Impl_" (#9483)
+
+2020-12-31 4.1.5:
+
+	General improvements:
+
+	all : added an argument to `haxe.CallStack.exceptionStack` to return full stack up to the topmost call (#9947)
+	php : compatibility with PHP 8
+
+	Bugfixes:
+
+	all : fixed empty object declarations in array comprehension (#9971)
+	jvm : fixed equality checks for `Null<Float>` and `Null<Int>` (#9897)
+	hl : fixed crash if a thread finishes without invoking `sendMessage`/`readMessage` (#9920)
+	php : fixed local vars with certain names (_SERVER, _GET etc) overriding super global values (#9924)
+	php : fixed generation with directories in `-D php-front`. For example `-D php-front=sub/index.php` (#10037)
+	macro : added return type hint to haxe.macro.MacroStringTools.formatString (#9928)
+	cs : fixed catching exceptions from static closures (#9957)
+	eval : fixed `Std.random(arg)` for `arg` values of more than 30 bits (#9974)
+	js : fixed `haxe.CallStack.exceptionStack` (#9968)
+
+2020-09-11 4.1.4:
+
+	General improvements:
+
+	all : allowed `Any` as type parameter in `catch(e:SomeType<Any>)` (#9641)
+	all : improved compilation speed for `try..catch` expressions (#9848)
+
+	Bugfixes:
+
+	all : fixed `switch` typing error for arrow functions with `Void` return type (#9813)
+	all : fixed typing of arrow functions with empty blocks as bodies (closes #9843)
+	macro : fixed `haxe.macro.Context.getResources()` (#9838)
+	php : fixed false detection of `catch` vars in anonymous functions as captured from outer scope
+	php : fixed return type of extern definition for `fseek` function
+	cs,java : fixed generation of `@:generic` classes with anonymous functions (#9799)
+	jvm : fixed sending/reading messages with `sys.thread.Threads` for threads created outside of Haxe (#9863)
+	jvm : fixed multiplication of `Null<Float>` and `Int` (#9870)
+	flash : fixed loading swc libraries containing `Vector` without a type parameter (#9805)
+	hl : fixed messages being send to wrong threads with `sendMessage`/`readMessage` in `sys.thread.Thread` (#9875)
+	cpp : fixed `cpp.Lib.stringReference()` (#8457)
+
+2020-07-22 4.1.3
+
+	General improvements:
+
+	all : added an error on `return` outside of a function (#9659)
+	php : support @:native("") for extern classes (#6448)
+	python : support @:native("") for extern classes (#6448)
+
+	Bugfixes:
+
+	all : fixed compilation server bug caused by removing `inline` from a method (#9690)
+	macro : fixed compiler crash if `@:genericBuild` meta is removed by a macro during building (#9391)
+	jvm : fixed "--java-lib-extern" (#9515)
+	flash : fixed var shadowing issue for variables captured in a closure inside of a loop (#9624)
+	flash : fixed `VerifyError` exception when `Void` end up as an argument type after inlining (#9678)
+	php : fixed runtime error "cannot use temporary expression in write context" for call arguments passed by reference
+	cs : fixed `cs.Lib.rethrow` (#9738)
+	nullsafety: fixed `@:nullSafety(Off)` in closures inside of constructors (#9643)
+	nullsafety: fixed "Type not found NullSafetyMode_Impl_" (#9483)
+
+2020-06-19 4.1.2
+
+	Bugfixes:
+
+	all : added `contains` and `keyValueIterator` methods to haxe.ds.ReadOnlyArray
+	all : fixed super constructor call when extending externs (#7837, #9501)
+	all : fixed compiler crash for "--run" argument without a value (#9513)
+	all : fixed local variable name collision in `try..catch` (#9533)
+	all : fixed memory leak in completion server related to haxe.Exception (#9537)
+	display : fixed completion for out-of-bounds argument in a call (#9435)
+	display : fixed "find references" through interfaces (#9470)
+	display : optimized "find references" (#9504)
+	display : optimized "server/invalidate" requests (#9509)
+	analyzer : fixed compiler crash upon handling code branches with enums with optional arguments (#9591)
+	jvm : added "--java-lib-extern" to use jar files as externs without adding them to the compiled project (#9515)
+	macro : fixed type intersection syntax in macro reification (#9404)
+	eval : fixed exception message when catching compiler-generated `haxe.macro.Error` as `Dynamic` (#9600)
+	lua : fixed lua code generation without `--main` compilation argument (#9489)
+	php : added an overload signature for `session_set_cookie_params` function (#9507)
+	js : fixed name collisions for catch variables to avoid closure compiler errors (#9617)
+	nullsafety : fixed various scenarios of `if..else` branching (#9474)
+
+2020-05-22 4.1.1
+
+	New features:
+
+	jvm : added `--jvm path/to.jar` CLI argument
+
+	Bugfixes:
+
+	all : fixed arguments ordering for @:structInit constructors (#9418)
+	all : fixed display/references completion server request for static fields (#9440)
+	all : fixed "Module not found" error reporting during macro execution in display requests (#9449)
+	all : fixed module name completion for target-specific modules like `Mod.js.hx` (#9423)
+	all : fixed completion for packages named "function" (#7697)
+	all : fixed recursive typedefs with optional arguments in `@:overload` functions (#9455)
+	cpp : fixed StringTools.endsWith() for unicode characters (#8980)
+	cpp : fixed broken externs in `cpp` package (#9452)
+	js/cpp : fixed catch var naming collision (#9413)
+	interp : fixed throwing `haxe.macro.Error` outside of a macro context (#9390)
+	lua : fixed lua.PairTools.ipairsMap method
+	php : fixed an edge case in String methods generation (#9464)
+
+2020-05-13: 4.1.0
+
+	New features:
+
+	all : added tail recursion elimination (#8908)
+	all : added unified exception handling (#9124)
+	all : allow `try {} catch(e) {}` as a shortcut for `try {} catch(e:haxe.Exception) {}` (#9269)
+	eval : added SSL support (#9009)
+	jvm : the JVM target is no longer considered experimental
+
+	General improvements:
+
+	all : implemented different display support approach (#8962)
+	all : improved display services related to reference finding
+	all : added go-to-implementation support (#9043)
+	all : made various improvements to diagnostics
+	all : support completion for map keys (#9133)
+	all : improved parser robustness for incomplete syntax (#9148)
+	all : disallowed the combination of `@:overload` and inline (#3846)
+	all : improved renaming of local variables (#9304)
+	all : better inlining of for-loops with anonymous iterators (#8848)
+	all : remove redundant final `return` in `Void` functions (#6420)
+	all : remove redundant `continue` in loops (#8952)
+	all : improved various compilation errors reporting
+	all : allowed `(get,default)` property access combination (#6195, #8825)
+	all : allowed ++ and -- on member properties of abstracts (#8930)
 	js : use abstract type name for generating its implementation class (#9006)
 	js : improve haxe.ds.StringMap implementation (#8909)
+	js : improve interface checking and make it more minifier-friendly (#9178)
+	js : generate `let` instead of `var` when compiler with `-D js-es=6` (#9280)
+	js : optimize `.bind` on constructors (#9227)
+	jvm : rewrote function handling to me much faster and more portable (#9208)
+	jvm : generate interfaces for typedefs for improved performance (#9195)
+	jvm : added support for haxe.MainLoop
+	jvm : support `@:jvm.synthetic` and use it to hide some generated fields (#9213)
+	jvm : respect `@:private` and `@:protected`
+	lua : improve error handling behavior when throwing objects/instances
+	lua : optimize `haxe.iterators.StringIterator`
+	php : optimize `Std.isOfType` for String, Bool and Float
+	php : make Haxe Array implement native interfaces Iterator, IteratorAggregate, Countable (#8821, 9377)
+	cs : support `@:assemblyMeta` and `@:assemblyStrict` (#8347)
+	python : added `__contains__` and `__getitem__` implementations to generated python code for `_hx_AnonObject`, so it is subscribable and behaves like a python dict (#9109)
+
+	Standard Library:
+
+	all : negative `startIndex` argument of `String.indexOf` and `String.lastIndexOf` is unspecified (#8365)
+	all : changed Array.iterator() to return instances of haxe.iterators.ArrayIterator (#8987)
+	all : added Array.contains (#9179)
+	all : added Array.keyValueIterator (#7422)
+	all : added haxe.Constraints.NotVoid (#8357)
+	all : added Lambda.findIndex() (#9071)
+	all : added Lambda.foldi() (#9054)
+	all : added array access and key-value iteration support to haxe.ds.HashMap (#9056)
+	jvm : added JVM-specific versions of sys.thread.Lock and sys.thread.Thread
+	jvm : added JVM-specific version of haxe.ds.StringMap
+	java/jvm : use native versions of MD-5, SHA-1 and SHA-256 for `haxe.crypto` modules (#9298)
+	macro : added haxe.macro.Context.containsDisplayPosition(pos) (#9077)
+	nullsafety : treat Strict as a single-threaded mode; added StrictThreaded (#8895)
+
+	Deprecations:
+
+	all : deprecated `Std.is`; use `Std.isOfType` instead (#2976)
+	all : added a warning for an uninitialized variable usage captured in a closure (#7447)
+	js : deprecated `untyped __js__(code, args)`; use `js.Syntax.code(code, args)` instead
+	php/neko : deprecated neko.Web and php.Web; will be moved to hx4compat library later (#9153)
+
+	Bugfixes:
+
+	all : fixed display support for static imports (#9012)
+	all : fixed completion in macro mode picking up the wrong type (#7703)
+	all : fixed wonky analyzer transformation related to locals captured in closures (#9305)
+	all : allow `return;` in abstract constructors (#7809)
+	all : fixed static @:op([]) functions (#9347)
+	all : fixed `@:optional` handling in the inheritance of `@:structInit` classes (#7559)
+	all : support negative numbers as constant type parameters for `@:generic` types (#9149)
+	all : fixed false positive compilation server error with empty methods in inheritance (#9029)
+	all : fixed default values for manually defined @:structInit constructors (#9177, #9258)
+	all : fixed inference of `Void` return type for arrow functions (#9181)
+	all : fixed inconsistencies in wildcard imports resolution (#9189, #9190)
+	all : fix array comprehension for a chain of `if..else if` without final `else` (#9040)
+	all : prohibit @:structInit on interfaces (#9017)
+	macro : fixed handling `TAnonymous` in `haxe.macro.TypeTools.map` (#9147)
+	eval : fixed EReg.matchSub handling with negative length (#9333)
+	eval : fixed extern classes being generated and causing errors in some cases (#9366)
+	eval : fixed StringBuf.addSub unicode handling (#9382)
+	jvm : fixed Void being generated with the wrong casing (#8717)
+	jvm : fixed debugging-related data being generated in the wrong place
+	jvm : fixed switches on string values being too optimistic
+	jvm : fixed problems with Std.parseInt and Std.parseFloat
+	jvm : made sure type parameter types are boxed
+	jvm : fixed dynamic access on `null` yielding `null` (#8452)
+	cpp : fixed native compilation if there is a `hx` package in a project (#8543)
+	cs : fixed `null` to `0` conversion in parametrized functions for `Null<Int>` params (#7428)
+	cs : fixed integer division handling (#9232)
+	php : fixed closure creation out of fields with `null` value (#9316)
+	js : fixed interface generation for minification with Google Closure Compiler in advanced mode (#9172)
+	js : fixed a crash at startup in IE8 (#9062)
+	hl : fixed BLOB handling in SQLite (#9048)
 
 2019-12-17: 4.0.5
 
@@ -564,7 +1116,7 @@
 	Bugfixes:
 
 	php7: fix Reflect.field() for strings (#6276)
-	php7: fix `@:enum abstract` generation  without `-dce full` (#6175)
+	php7: fix `@:enum abstract` generation without `-dce full` (#6175)
 	php7: fix using enum constructor with arguments as a call argument (#6177)
 	php7: fix `null` property access (#6281)
 	php7: fix setting values in a map stored in another map (#6257)
@@ -610,7 +1162,7 @@
 
 	all : fixed DCE issue with interface fields (#6502)
 	cpp : fixed return typing for embedded closures (#6121)
-	php7: fixed `@:enum abstract` generation  without `-dce full` (#6175)
+	php7: fixed `@:enum abstract` generation without `-dce full` (#6175)
 	php7: fixed using enum constructor with arguments as a call argument (#6177)
 	php7: fixed accessing methods on dynamic values (#6211)
 	php7: fixed `null` property access (#6281)
@@ -1326,7 +1878,7 @@
 	all : allow to access root package with std prefix (std.Type for example)
 	all : added haxe.EnumFlags
 	sys : io.File.getChar/stdin/stdout/stderr are now in Sys class
-	cpp : Reflect.getField and Reflect.setField no longer call property functions.  Use Reflect.getProperty and Refelect.setProperty instead.
+	cpp : Reflect.getField and Reflect.setField no longer call property functions. Use Reflect.getProperty and Refelect.setProperty instead.
 	cpp : Default arguments now use Null<T> for performance increase and interface compatibility
 	cpp : Added metadata options for injecting native cpp code into headers, classes and functions
 	php : added php.Lib.mail

+ 1 - 1
extra/EnvVarUpdate.nsh

@@ -43,7 +43,7 @@
   !ifndef Un${StrFuncName}_INCLUDED
     ${Un${StrFuncName}}
   !endif
-  !define un.${StrFuncName} "${Un${StrFuncName}}"
+  !define un.${StrFuncName} '${Un${StrFuncName}}'
 !macroend
 
 !insertmacro _IncludeStrFunction StrTok

+ 38 - 41
extra/ImportAll.hx

@@ -25,8 +25,8 @@ class ImportAll {
 
 	static function isSysTarget() {
 		return Context.defined("neko") || Context.defined("php") || Context.defined("cpp") ||
-		       Context.defined("java") || Context.defined("python") ||
-		       Context.defined("lua") || Context.defined("hl") || Context.defined("eval"); // TODO: have to add cs here, SPOD gets in the way at the moment
+		       Context.defined("jvm") || Context.defined("python") ||
+		       Context.defined("lua") || Context.defined("hl") || Context.defined("eval");
 	}
 
 	public static function run( ?pack ) {
@@ -34,9 +34,6 @@ class ImportAll {
 			pack = "";
 			haxe.macro.Compiler.define("doc_gen");
 		}
-		if (Context.defined("interp")) {
-			haxe.macro.Compiler.define("macro");
-		}
 		switch( pack ) {
 		case "php":
 			if( !Context.defined("php") ) return;
@@ -54,12 +51,8 @@ class ImportAll {
 			if(!isSysTarget()) return;
 		case "sys.thread":
 			if ( !Context.defined("target.threaded") ) return;
-		case "java":
-			if( !Context.defined("java") ) return;
-		case "jvm":
+		case "java" | "jvm":
 			if( !Context.defined("jvm") ) return;
-		case "cs":
-			if( !Context.defined("cs") ) return;
 		case "python":
 			if ( !Context.defined("python") ) return;
 		case "hl":
@@ -72,39 +65,43 @@ class ImportAll {
 			if (!Context.defined("neko") && !Context.defined("cpp")) return;
 		case "tools", "build-tool", "jar-tool": return;
 		}
-		for( p in Context.getClassPath() ) {
-			if( p == "/" )
-				continue;
-			// skip if we have a classpath to haxe
-			if( pack.length == 0 && sys.FileSystem.exists(p+"std") )
-				continue;
-			var p = p + pack.split(".").join("/");
-			if( StringTools.endsWith(p,"/") )
-				p = p.substr(0,-1);
-			if( !sys.FileSystem.exists(p) || !sys.FileSystem.isDirectory(p) )
-				continue;
-			for( file in sys.FileSystem.readDirectory(p) ) {
-				if( file == ".svn" || file == "_std" )
+		Context.onAfterInitMacros(() -> {
+			for( p in Context.getClassPath() ) {
+				if( p == "/" || p == "" )
+					continue;
+				// skip if we have a classpath to haxe
+				if( pack.length == 0 && sys.FileSystem.exists(p+"std") )
 					continue;
-				var full = (pack == "") ? file : pack + "." + file;
-				if( StringTools.endsWith(file, ".hx") && file.substr(0, file.length - 3).indexOf(".") < 0 ) {
-					var cl = full.substr(0, full.length - 3);
-					switch( cl ) {
-					case "ImportAll", "neko.db.MacroManager": continue;
-					case "haxe.TimerQueue": if( Context.defined("neko") || Context.defined("php") || Context.defined("cpp") ) continue;
-					case "Sys": if(!isSysTarget()) continue;
-					case "haxe.web.Request": if( !(Context.defined("neko") || Context.defined("php") || Context.defined("js")) ) continue;
-					case "haxe.macro.ExampleJSGenerator","haxe.macro.Context", "haxe.macro.Compiler": if( !Context.defined("eval") ) continue;
-					case "haxe.remoting.SocketWrapper": if( !Context.defined("flash") ) continue;
-					case "haxe.remoting.SyncSocketConnection": if( !(Context.defined("neko") || Context.defined("php") || Context.defined("cpp")) ) continue;
-					case "neko.vm.Ui" | "sys.db.Sqlite" | "sys.db.Mysql" if ( Context.defined("interp") ): continue;
-					case "sys.db.Sqlite" | "sys.db.Mysql" | "cs.db.AdoNet" if ( Context.defined("cs") ): continue;
-					}
-					Context.getModule(cl);
-				} else if( sys.FileSystem.isDirectory(p + "/" + file) )
-					run(full);
+				var p = p + pack.split(".").join("/");
+				if( StringTools.endsWith(p,"/") )
+					p = p.substr(0,-1);
+				if( !sys.FileSystem.exists(p) || !sys.FileSystem.isDirectory(p) )
+					continue;
+				for( file in sys.FileSystem.readDirectory(p) ) {
+					if( file == ".svn" || file == "_std" )
+						continue;
+					var full = (pack == "") ? file : pack + "." + file;
+					if( StringTools.endsWith(file, ".hx") && file.substr(0, file.length - 3).indexOf(".") < 0 ) {
+						var cl = full.substr(0, full.length - 3);
+						switch( cl ) {
+						case "ImportAll", "neko.db.MacroManager": continue;
+						case "haxe.TimerQueue": if( Context.defined("neko") || Context.defined("php") || Context.defined("cpp") ) continue;
+						case "Sys": if(!isSysTarget()) continue;
+						case "haxe.web.Request": if( !(Context.defined("neko") || Context.defined("php") || Context.defined("js")) ) continue;
+						case "haxe.macro.ExampleJSGenerator","haxe.macro.Context", "haxe.macro.Compiler": if( !Context.defined("eval") ) continue;
+						case "haxe.remoting.SocketWrapper": if( !Context.defined("flash") ) continue;
+						case "haxe.remoting.SyncSocketConnection": if( !(Context.defined("neko") || Context.defined("php") || Context.defined("cpp")) ) continue;
+						case "neko.vm.Ui" | "sys.db.Sqlite" | "sys.db.Mysql" if ( Context.defined("interp") ): continue;
+						case "haxe.atomic.AtomicBool" if(!Context.defined("target.atomics")): continue;
+						case "haxe.atomic.AtomicInt" if(!Context.defined("target.atomics")): continue;
+						case "haxe.atomic.AtomicObject" if(!Context.defined("target.atomics") || Context.defined("js") || Context.defined("cpp")): continue;
+						}
+						Context.getModule(cl);
+					} else if( sys.FileSystem.isDirectory(p + "/" + file) )
+						run(full);
+				}
 			}
-		}
+		});
 	}
 
 }

+ 1 - 11
extra/all.hxml

@@ -29,19 +29,9 @@
 -D HXCPP_MULTI_THREADED
 
 --next
--java all_java
--xml java.xml
-
---next
--java all_jvm
--D jvm
+--jvm all_jvm
 -xml jvm.xml
 
---next
--cs all_cs
--D unsafe
--xml cs.xml
-
 --next
 -python all_python
 -xml python.xml

+ 0 - 61
extra/azure-pipelines/build-linux.yml

@@ -1,61 +0,0 @@
-parameters:
-  name: 'BuildLinux'
-  vmImage: 'ubuntu-16.04'
-
-jobs:
-  - job: ${{ parameters.name }}
-    pool:
-      vmImage: ${{ parameters.vmImage }}
-    variables:
-      OPAMYES: 1
-      ${{ if not(startsWith(variables['Build.SourceBranch'], 'refs/tags/')) }}:
-        ADD_REVISION: 1
-    steps:
-      - checkout: self
-        submodules: recursive
-      - script: |
-          set -ex
-          sudo add-apt-repository ppa:avsm/ppa -y # provides OPAM 2
-          sudo add-apt-repository ppa:haxe/ocaml -y # provides newer version of mbedtls
-          sudo apt-get update -qqy
-          sudo apt-get install -qqy ocaml-nox camlp5 opam libpcre3-dev zlib1g-dev libgtk2.0-dev libmbedtls-dev ninja-build
-        displayName: Install dependencies
-      - template: install-neko-snapshot.yaml
-        parameters:
-          platform: linux64
-      - script: |
-          set -ex
-          opam init
-          opam update
-          opam pin add haxe . --no-action
-          opam install haxe --deps-only
-          opam list
-          ocamlopt -v
-        displayName: Install OCaml libraries
-      - script: |
-          set -ex
-          opam config exec -- make -s -j`nproc` STATICLINK=1 haxe
-          opam config exec -- make -s haxelib
-          make -s package_bin
-          ls -l out
-          ldd -v ./haxe
-          ldd -v ./haxelib
-        displayName: Build Haxe
-      - task: PublishPipelineArtifact@0
-        inputs:
-          artifactName: 'linuxBinaries'
-          targetPath: out
-      - script: |
-          set -ex
-          make -s xmldoc
-          cat >extra/doc/info.json <<EOL
-            {
-              "commit": "$(Build.SourceVersion)",
-              "branch": "$(Build.SourceBranchName)"
-            }
-          EOL
-        displayName: Build xmldoc
-      - task: PublishPipelineArtifact@0
-        inputs:
-          artifactName: 'xmldoc'
-          targetPath: extra/doc

+ 0 - 46
extra/azure-pipelines/build-mac.yml

@@ -1,46 +0,0 @@
-parameters:
-  name: 'BuildMac'
-  vmImage: 'macOS-10.13'
-
-jobs:
-  - job: ${{ parameters.name }}
-    pool:
-      vmImage: ${{ parameters.vmImage }}
-    variables:
-      OPAMYES: 1
-      ${{ if not(startsWith(variables['Build.SourceBranch'], 'refs/tags/')) }}:
-        ADD_REVISION: 1
-    steps:
-      - checkout: self
-        submodules: recursive
-      - script: |
-          set -ex
-          brew update || brew update || brew update
-          brew unlink python@2
-          brew bundle --file=tests/Brewfile --no-upgrade
-        displayName: Install dependencies
-      - template: install-neko-snapshot.yaml
-        parameters:
-          platform: mac
-      - script: |
-          set -ex
-          opam init
-          opam update
-          opam pin add haxe . --no-action
-          opam install haxe --deps-only
-          opam list
-          ocamlopt -v
-        displayName: Install OCaml libraries
-      - script: |
-          set -ex
-          opam config exec -- make -s -j`sysctl -n hw.ncpu` STATICLINK=1 "LIB_PARAMS=/usr/local/opt/zlib/lib/libz.a /usr/local/lib/libpcre.a /usr/local/lib/libmbedtls.a /usr/local/lib/libmbedcrypto.a /usr/local/lib/libmbedx509.a -cclib '-framework Security -framework CoreFoundation'" haxe
-          opam config exec -- make -s haxelib
-          make -s package_bin package_installer_mac
-          ls -l out
-          otool -L ./haxe
-          otool -L ./haxelib
-        displayName: Build Haxe
-      - task: PublishPipelineArtifact@0
-        inputs:
-          artifactName: 'macBinaries'
-          targetPath: out

+ 0 - 72
extra/azure-pipelines/build-windows.yml

@@ -1,72 +0,0 @@
-parameters:
-  name: 'BuildWindows'
-  vmImage: 'windows-2019'
-  arch: '64' # or '32'
-
-jobs:
-  - job: ${{ parameters.name }}
-    pool:
-      vmImage: ${{ parameters.vmImage }}
-    variables:
-      OPAMYES: 1
-      ${{ if not(startsWith(variables['Build.SourceBranch'], 'refs/tags/')) }}:
-        ADD_REVISION: 1
-      CYG_MIRROR: http://mirrors.kernel.org/sourceware/cygwin/
-      ${{ if eq(parameters.arch, '64') }}:
-        ARCH: 64
-        MINGW_ARCH: x86_64
-        CYGWIN_SETUP: https://cygwin.com/setup-x86_64.exe
-        CYG_ROOT: C:/cygwin64
-      ${{ if eq(parameters.arch, '32') }}:
-        ARCH: 32
-        MINGW_ARCH: i686
-        CYGWIN_SETUP: https://cygwin.com/setup-x86.exe
-        CYG_ROOT: C:/cygwin
-    steps:
-      - checkout: self
-        submodules: recursive
-      - powershell: |
-          Set-PSDebug -Trace 1
-          choco install --no-progress nsis.portable --version 3.02 -y
-          choco install --no-progress curl wget 7zip.portable -y
-        displayName: Install dependencies
-      - powershell: Write-Host "##vso[task.prependpath]C:\ProgramData\chocolatey\bin"
-        displayName: Prepend Chocolatey path
-      - template: install-neko-snapshot.yaml
-        parameters:
-          ${{ if eq(parameters.arch, '64') }}:
-            platform: windows64
-          ${{ if eq(parameters.arch, '32') }}:
-            platform: windows
-      - powershell: |
-          Set-PSDebug -Trace 1
-          curl.exe -fsSL -o cygwin-setup.exe --retry 3 $(CYGWIN_SETUP)
-          Start-Process -FilePath "cygwin-setup.exe" -ArgumentList "-B -q -R $(CYG_ROOT) -l C:/tmp -s $(CYG_MIRROR) -P default -P make -P git -P zlib-devel -P rsync -P patch -P diffutils -P curl -P unzip -P tar -P m4 -P perl -P libpcre-devel -P mbedtls-devel -P mingw64-$(MINGW_ARCH)-zlib -P mingw64-$(MINGW_ARCH)-gcc-core -P mingw64-$(MINGW_ARCH)-pcre" -Wait
-          curl.exe -fsSL -o "opam.tar.xz" --retry 3 https://github.com/fdopen/opam-repository-mingw/releases/download/0.0.0.2/opam$(ARCH).tar.xz
-          curl.exe -fsSL -o "libmbedtls.tar.xz" --retry 3 https://github.com/Simn/mingw64-mbedtls/releases/download/2.16.3/mingw64-$(MINGW_ARCH)-mbedtls-2.16.3-1.tar.xz
-          & "$(CYG_ROOT)/bin/bash.exe" @('-lc', 'echo "$OLDPWD"')
-          & "$(CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && tar -C / -xvf libmbedtls.tar.xz')
-          & "$(CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && tar -xf opam.tar.xz')
-          & "$(CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && bash opam$(ARCH)/install.sh')
-          & "$(CYG_ROOT)/bin/bash.exe" @('-lc', 'opam init mingw "https://github.com/fdopen/opam-repository-mingw.git#opam2" --comp 4.07.0+mingw$(ARCH)c --switch 4.07.0+mingw$(ARCH)c --auto-setup --yes 2>&1')
-          & "$(CYG_ROOT)/bin/bash.exe" @('-lc', 'opam update --yes 2>&1')
-          & "$(CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && opam pin add haxe . --kind=path --no-action --yes 2>&1')
-          & "$(CYG_ROOT)/bin/bash.exe" @('-lc', 'opam install haxe --deps-only --yes 2>&1')
-          & "$(CYG_ROOT)/bin/bash.exe" @('-lc', 'opam list')
-          & "$(CYG_ROOT)/bin/bash.exe" @('-lc', 'ocamlopt -v')
-        displayName: Install OCaml and OCaml libraries
-      - powershell: Write-Host "##vso[task.prependpath]${env:CYG_ROOT}/usr/$(MINGW_ARCH)-w64-mingw32/sys-root/mingw/bin"
-        displayName: Expose mingw dll files
-      - powershell: |
-          Set-PSDebug -Trace 1
-          & "$(CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && opam config exec -- make -s -f Makefile.win -j`nproc` haxe 2>&1')
-          & "$(CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && opam config exec -- make -s -f Makefile.win haxelib 2>&1')
-          & "$(CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && opam config exec -- make -f Makefile.win echo_package_files package_bin package_installer_win package_choco 2>&1')
-          dir out
-          & "$(CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && cygcheck ./haxe.exe')
-          & "$(CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && cygcheck ./haxelib.exe')
-        displayName: Build Haxe
-      - task: PublishPipelineArtifact@0
-        inputs:
-          artifactName: 'win$(ARCH)Binaries'
-          targetPath: out

+ 0 - 33
extra/azure-pipelines/install-neko-snapshot.yaml

@@ -1,33 +0,0 @@
-parameters:
-  platform: '' # can be linux64, mac, windows, or windows64
-
-steps:
-  - ${{ if startsWith(parameters.platform, 'windows') }}:
-    - powershell: |
-        Invoke-WebRequest https://build.haxe.org/builds/neko/${{parameters.platform}}/neko_latest.zip -OutFile $(Agent.TempDirectory)/neko_latest.zip
-        Expand-Archive $(Agent.TempDirectory)/neko_latest.zip -DestinationPath $(Agent.TempDirectory)
-        $NEKOPATH = Get-ChildItem $(Agent.TempDirectory)/neko-*-*
-        Write-Host "##vso[task.prependpath]$NEKOPATH"
-        Write-Host "##vso[task.setvariable variable=NEKOPATH]$NEKOPATH"
-      displayName: Install Neko using snapshot from S3
-  - ${{ if not(startsWith(parameters.platform, 'windows')) }}:
-    - bash: |
-        set -ex
-        DOWNLOADDIR=$(Agent.TempDirectory)
-        curl -sSL https://build.haxe.org/builds/neko/${{parameters.platform}}/neko_latest.tar.gz -o $(Agent.TempDirectory)/neko_latest.tar.gz
-        tar -xf $(Agent.TempDirectory)/neko_latest.tar.gz -C $(Agent.TempDirectory)
-        NEKOPATH=`echo $(Agent.TempDirectory)/neko-*-*`
-        sudo mkdir -p /usr/local/bin
-        sudo mkdir -p /usr/local/lib/neko
-        sudo ln -s $NEKOPATH/{neko,nekoc,nekoml,nekotools}  /usr/local/bin/
-        sudo ln -s $NEKOPATH/libneko.*                      /usr/local/lib/
-        sudo ln -s $NEKOPATH/*.ndll                         /usr/local/lib/neko/
-        set +x
-        echo "##vso[task.prependpath]$NEKOPATH"
-        echo "##vso[task.setvariable variable=NEKOPATH]$NEKOPATH"
-      displayName: Install Neko using snapshot from S3
-  - ${{ if eq(parameters.platform, 'linux64') }}:
-    - bash: sudo ldconfig
-      displayName: ldconfig
-  - script: neko -version 2>&1
-    displayName: Print Neko version

+ 0 - 87
extra/azure-pipelines/test-windows.yml

@@ -1,87 +0,0 @@
-parameters:
-  name: 'TestWindows'
-  vmImage: 'windows-2019'
-  arch: '64' # or '32'
-
-jobs:
-  - job: ${{ parameters.name }}
-    dependsOn: BuildWin${{ parameters.arch }}
-    pool:
-      vmImage: ${{ parameters.vmImage }}
-    variables:
-      HAXELIB_ROOT: C:/haxelib
-    strategy:
-      matrix:
-        # https://github.com/HaxeFoundation/haxe/issues/8600
-        ${{ if eq(parameters.arch, '64') }}:
-          macro:
-            TEST: macro
-        neko:
-          TEST: neko
-        hl:
-          TEST: hl
-        cpp:
-          TEST: cpp
-          HXCPP_COMPILE_CACHE: C:/hxcache
-        java:
-          # https://github.com/HaxeFoundation/haxe/issues/8601
-          ${{ if eq(parameters.arch, '64') }}:
-            TEST: java,jvm
-          ${{ if eq(parameters.arch, '32') }}:
-            TEST: java
-        cs:
-          TEST: cs
-        js:
-          TEST: js
-        php:
-          TEST: php
-        # TODO. flash has never been enabled on our AppVeyor builds.
-        # flash:
-        #   TEST: flash9
-        python:
-          TEST: python
-        # TODO. Lua has never been enabled on our AppVeyor builds.
-        # lua:
-        #   TEST: lua
-    steps:
-      - checkout: self
-        fetchDepth: 20
-      - template: install-neko-snapshot.yaml
-        parameters:
-          ${{ if eq(parameters.arch, '64') }}:
-            platform: windows64
-          ${{ if eq(parameters.arch, '32') }}:
-            platform: windows
-      - task: DownloadPipelineArtifact@0
-        inputs:
-          artifactName: 'win${{ parameters.arch }}Binaries'
-          targetPath: win${{ parameters.arch }}Binaries
-      - powershell: |
-          Set-PSDebug -Trace 1
-          7z x win${{ parameters.arch }}Binaries/*_bin.zip -owin${{ parameters.arch }}Binaries
-          $dir = Get-ChildItem win${{ parameters.arch }}Binaries/* -Name -Directory
-          Rename-Item win${{ parameters.arch }}Binaries/$dir haxe
-          $dir = '' + ( get-location ) + '\win${{ parameters.arch }}Binaries\haxe'
-          dir $dir
-          Set-PSDebug -Trace 0
-          Write-Host "##vso[task.prependpath]$dir"
-        displayName: Setup Haxe
-      - script: haxe -version
-        displayName: Print Haxe version
-      - task: UsePythonVersion@0
-        inputs:
-          versionSpec: '3.7'
-      - powershell: |
-          Set-PSDebug -Trace 1
-          $pypath = python -c "import sys; print(sys.executable)"
-          $py3path = $pypath.replace("python.exe","python3.exe")
-          cmd /c mklink $py3path $pypath
-          python3 -V
-        displayName: "Make Python 3 be available as python3 in the cmdline"
-      - script: |
-          mkdir "$(HAXELIB_ROOT)"
-          haxelib setup "$(HAXELIB_ROOT)"
-        displayName: Setup haxelib
-      - script: haxe RunCi.hxml
-        workingDirectory: $(Build.SourcesDirectory)/tests
-        displayName: Test

+ 3 - 3
extra/choco/haxe.nuspec

@@ -17,12 +17,12 @@
         <requireLicenseAcceptance>false</requireLicenseAcceptance>
         <summary>Haxe is an open source toolkit based on a modern, high level, strictly typed programming language, a cross-compiler, a complete cross-platform standard library and ways to access each platform's native capabilities.</summary>
         <description>Haxe is an open source toolkit based on a modern, high level, strictly typed programming language, a cross-compiler, a complete cross-platform standard library and ways to access each platform's native capabilities.
- 
+
 This package will install haxe and haxelib. After installation, you should run `haxelib setup %path%;`, where `%path%` is the haxelib repository folder for placing third-party libraries. The folder should be created manually before running the command.</description>
         <releaseNotes>https://github.com/HaxeFoundation/haxe/blob/master/extra/CHANGES.txt</releaseNotes>
         <tags>haxe programming development foss cross-platform</tags>
         <dependencies>
-            <dependency id="neko" version="2.1.0" />
+            <dependency id="neko" version="@NEKO_VERSION@" />
         </dependencies>
     </metadata>
-</package>
+</package>

+ 2 - 7
extra/doc.hxml

@@ -31,13 +31,8 @@
 -D HXCPP_MULTI_THREADED
 
 --next
--java all_java
--xml doc/java.xml
-
---next
--cs all_cs
--D unsafe
--xml doc/cs.xml
+--jvm all_jvm
+-xml doc/jvm.xml
 
 --next
 -python all_py

+ 47 - 0
extra/github-actions/Main.hx

@@ -0,0 +1,47 @@
+package;
+
+import sys.FileSystem;
+import sys.io.File;
+import haxe.io.Path;
+using StringTools;
+
+class Main {
+
+	static final matchImport = ~/^([ \t]*)@import (.+)$/gm;
+	static final matchRunnable = ~/^([ \t]*)jobs:/gm;
+
+	static function main():Void {
+		final folder = FileSystem.absolutePath(".");
+		final outFolder = "../../.github";
+
+		iterFolderItems(folder, (dir, name) -> {
+			final ext = Path.extension(name);
+			if (ext != "yaml" && ext != "yml") return;
+
+			final data = File.getContent('$dir/$name');
+			var newData = matchImport.map(data, reg -> {
+				final spaces = reg.matched(1);
+				final path = reg.matched(2);
+				final template = File.getContent('./$path');
+				final lines = template.split("\n");
+				for (i in 0...lines.length)
+					lines[i] = (spaces + lines[i]).rtrim();
+				lines.join("\n");
+			});
+
+			if (!matchRunnable.match(newData)) return;
+			final first = "# DO NOT EDIT. Generated from /extra/github-actions\n";
+			newData = first + newData;
+			final relativeDir = dir.replace(folder, "");
+			File.saveContent('$outFolder$relativeDir/$name', newData);
+		});
+	}
+
+	static function iterFolderItems(dir:String, func:(dir:String, name:String)->Void):Void {
+		for (name in FileSystem.readDirectory(dir)) {
+			if (FileSystem.isDirectory(name)) iterFolderItems('$dir/$name', func);
+			func(dir, name);
+		}
+	}
+
+}

+ 62 - 0
extra/github-actions/build-mac.yml

@@ -0,0 +1,62 @@
+- name: Install dependencies
+  env:
+    # For compatibility with macOS 10.13
+    ZLIB_VERSION: 1.3.1
+    MBEDTLS_VERSION: 2.28.5
+    PCRE2_VERSION: 10.42
+  run: |
+    set -ex
+    brew update
+    brew bundle --file=tests/Brewfile --no-upgrade
+    cpanm IPC::System::Simple
+    cpanm String::ShellQuote
+    curl -L https://github.com/madler/zlib/releases/download/v$ZLIB_VERSION/zlib-$ZLIB_VERSION.tar.gz | tar xz
+    cd zlib-$ZLIB_VERSION
+    ./configure
+    make && make install
+    cd ..
+    curl -L https://github.com/ARMmbed/mbedtls/archive/v$MBEDTLS_VERSION.tar.gz | tar xz
+    cd mbedtls-$MBEDTLS_VERSION
+    make && make install
+    cd ..
+    curl -L https://github.com/PCRE2Project/pcre2/releases/download/pcre2-$PCRE2_VERSION/pcre2-$PCRE2_VERSION.tar.gz | tar xz
+    cd pcre2-$PCRE2_VERSION
+    ./configure --enable-unicode --enable-pcre2-8 --enable-pcre2-16 --enable-pcre2-32 --enable-unicode-properties --enable-pcre2grep-libz --enable-pcre2grep-libbz2 --enable-jit
+    make && make install
+    cd ..
+
+- name: Install OCaml libraries
+  if: steps.cache-opam.outputs.cache-hit != 'true'
+  run: |
+    set -ex
+    opam init # --disable-sandboxing
+    opam update
+    opam switch create 4.08.1
+    eval $(opam env)
+    opam env
+    opam pin add ctypes 0.17.1 --yes
+    opam pin add haxe . --no-action
+    opam install haxe --deps-only --assume-depexts
+    opam list
+    ocamlopt -v
+
+- name: Set ADD_REVISION=1 for non-release
+  if: ${{ !startsWith(github.ref, 'refs/tags/') }}
+  run: echo "ADD_REVISION=1" >> $GITHUB_ENV
+
+- name: Build Haxe
+  run: |
+    set -ex
+    eval $(opam env)
+    opam config exec -- make -s -j`sysctl -n hw.ncpu` STATICLINK=1 "LIB_PARAMS=/usr/local/lib/libz.a /usr/local/lib/libpcre2-8.a /usr/local/lib/libmbedtls.a /usr/local/lib/libmbedcrypto.a /usr/local/lib/libmbedx509.a -cclib '-framework Security -framework CoreFoundation'" haxe
+    opam config exec -- make -s haxelib
+    make -s package_unix package_installer_mac
+    ls -l out
+    otool -L ./haxe
+    otool -L ./haxelib
+
+- name: Upload artifact
+  uses: actions/upload-artifact@v3
+  with:
+    name: macBinaries
+    path: out

+ 40 - 0
extra/github-actions/build-windows.yml

@@ -0,0 +1,40 @@
+- name: Expose mingw dll files
+  shell: pwsh
+  run: Write-Host "::add-path::${env:CYG_ROOT}/usr/$($env:MINGW_ARCH)-w64-mingw32/sys-root/mingw/bin"
+
+# required to be able to retrieve the revision
+- name: Mark directory as safe
+  shell: pwsh
+  run: |
+    Set-PSDebug -Trace 1
+    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'git config --global --add safe.directory "$OLDPWD"')
+
+- name: Set ADD_REVISION=1 for non-release
+  if: ${{ !startsWith(github.ref, 'refs/tags/') }}
+  shell: pwsh
+  run: echo "ADD_REVISION=1" >> $Env:GITHUB_ENV
+
+- name: Build Haxe
+  shell: pwsh
+  run: |
+    Set-PSDebug -Trace 1
+    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && opam config exec -- make -s -f Makefile.win -j`nproc` haxe 2>&1')
+    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && opam config exec -- make -s -f Makefile.win haxelib 2>&1')
+    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && opam config exec -- make -f Makefile.win echo_package_files package_bin package_installer_win package_choco 2>&1')
+    dir out
+    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && cygcheck ./haxe.exe')
+    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && cygcheck ./haxelib.exe')
+    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && ls ./out')
+
+- name: Check artifact
+  shell: bash
+  run: |
+    ls out
+    # Output should contain binaries zip, installer zip and nupkg
+    [ $(ls -1 out | wc -l) -eq "3" ]
+
+- name: Upload artifact
+  uses: actions/upload-artifact@v3
+  with:
+    name: win${{env.ARCH}}Binaries
+    path: out

+ 2 - 0
extra/github-actions/build.hxml

@@ -0,0 +1,2 @@
+--main Main
+--interp

+ 16 - 0
extra/github-actions/install-neko-unix.yml

@@ -0,0 +1,16 @@
+- name: Install Neko from S3
+  run: |
+    set -ex
+
+    curl -sSL https://build.haxe.org/builds/neko/$PLATFORM/neko_latest.tar.gz -o $RUNNER_TEMP/neko_latest.tar.gz
+    tar -xf $RUNNER_TEMP/neko_latest.tar.gz -C $RUNNER_TEMP
+    NEKOPATH=`echo $RUNNER_TEMP/neko-*-*`
+    sudo mkdir -p /usr/local/bin
+    sudo mkdir -p /usr/local/lib/neko
+    sudo ln -s $NEKOPATH/{neko,nekoc,nekoml,nekotools}  /usr/local/bin/
+    sudo ln -s $NEKOPATH/libneko.*                      /usr/local/lib/
+    sudo ln -s $NEKOPATH/*.ndll                         /usr/local/lib/neko/
+    echo "NEKOPATH=$NEKOPATH" >> $GITHUB_ENV
+
+- name: Print Neko version
+  run: neko -version 2>&1

+ 11 - 0
extra/github-actions/install-neko-windows.yml

@@ -0,0 +1,11 @@
+- name: Install Neko from S3
+  shell: pwsh
+  run: |
+    Invoke-WebRequest https://build.haxe.org/builds/neko/$env:PLATFORM/neko_latest.zip -OutFile $env:RUNNER_TEMP/neko_latest.zip
+    Expand-Archive $env:RUNNER_TEMP/neko_latest.zip -DestinationPath $env:RUNNER_TEMP
+    $NEKOPATH = Get-ChildItem $env:RUNNER_TEMP/neko-*-*
+    echo "$NEKOPATH" >> $env:GITHUB_PATH
+    echo "NEKOPATH=$NEKOPATH" >> $env:GITHUB_ENV
+
+- name: Print Neko version
+  run: neko -version 2>&1

+ 14 - 0
extra/github-actions/install-nsis.yml

@@ -0,0 +1,14 @@
+- name: choco install nsis
+  uses: nick-invision/retry@v2
+  with:
+    timeout_minutes: 10
+    max_attempts: 10
+    command: choco install --no-progress nsis.portable --version 3.09 -y
+
+- name: choco install things
+  shell: pwsh
+  run: choco install --no-progress curl wget 7zip.portable -y
+
+- name: Prepend Chocolatey path
+  shell: pwsh
+  run: Write-Host "::add-path::C:\ProgramData\chocolatey\bin"

+ 6 - 0
extra/github-actions/install-ocaml-libs-windows.yml

@@ -0,0 +1,6 @@
+- name: Install OCaml libraries
+  shell: pwsh
+  run: |
+    Set-PSDebug -Trace 1
+    opam install haxe --deps-only
+    opam list

+ 39 - 0
extra/github-actions/install-ocaml-windows.yml

@@ -0,0 +1,39 @@
+- name: Setup ocaml
+  id: ocaml
+  continue-on-error: true
+  uses: kLabz/setup-ocaml@win32
+  with:
+    ocaml-compiler: 4.08.1
+    opam-depext: false
+    opam-repositories: |
+      opam-repository-mingw: https://github.com/ocaml-opam/opam-repository-mingw.git#sunset
+      default: https://github.com/ocaml/opam-repository.git
+    opam-local-packages: |
+      haxe.opam
+    cache-prefix: w32-v1
+
+# TODO make it work on first try
+# (when cygwin cache doesn't exist, ocaml install fails with a curl error)
+- name: Setup ocaml (second chance)
+  if: steps.ocaml.outcome == 'failure'
+  uses: kLabz/setup-ocaml@win32
+  with:
+    ocaml-compiler: 4.08.1
+    opam-depext: false
+    opam-repositories: |
+      opam-repository-mingw: https://github.com/ocaml-opam/opam-repository-mingw.git#sunset
+      default: https://github.com/ocaml/opam-repository.git
+    opam-local-packages: |
+      haxe.opam
+    cache-prefix: w32-v1
+
+- name: Install dependencies
+  shell: pwsh
+  run: |
+    Set-PSDebug -Trace 1
+    curl.exe -fsSL -o "libmbedtls.tar.xz" --retry 3 https://github.com/Simn/mingw64-mbedtls/releases/download/2.16.3/mingw64-$($env:MINGW_ARCH)-mbedtls-2.16.3-1.tar.xz
+    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'curl -L https://cpanmin.us | perl - App::cpanminus')
+    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm IPC::System::Simple module')
+    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm String::ShellQuote')
+    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'echo "$OLDPWD"')
+    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && tar -C / -xvf libmbedtls.tar.xz')

+ 20 - 0
extra/github-actions/install-ocaml-windows64.yml

@@ -0,0 +1,20 @@
+- name: Setup ocaml
+  uses: ocaml/setup-ocaml@v2
+  with:
+    ocaml-compiler: 4.08.1
+    opam-repositories: |
+      opam-repository-mingw: https://github.com/ocaml-opam/opam-repository-mingw.git#sunset
+      default: https://github.com/ocaml/opam-repository.git
+    opam-local-packages: |
+      haxe.opam
+
+- name: Install dependencies
+  shell: pwsh
+  run: |
+    Set-PSDebug -Trace 1
+    curl.exe -fsSL -o "libmbedtls.tar.xz" --retry 3 https://github.com/Simn/mingw64-mbedtls/releases/download/2.16.3/mingw64-$($env:MINGW_ARCH)-mbedtls-2.16.3-1.tar.xz
+    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'curl -L https://cpanmin.us | perl - App::cpanminus')
+    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm IPC::System::Simple module')
+    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cpanm String::ShellQuote')
+    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'echo "$OLDPWD"')
+    & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && tar -C / -xvf libmbedtls.tar.xz')

+ 32 - 0
extra/github-actions/test-mac.yml

@@ -0,0 +1,32 @@
+- name: Setup Haxe
+  run: |
+    # mkdir ./macBinaries
+    # curl -sSL https://build.haxe.org/builds/haxe/mac/haxe_latest.tar.gz -o ./macBinaries/haxe_bin.tar.gz
+
+    set -ex
+    tar -xf macBinaries/*_bin.tar.gz -C macBinaries --strip-components=1
+    sudo mkdir -p /usr/local/bin/
+    sudo mkdir -p /usr/local/share/haxe/
+    sudo ln -s `pwd`/macBinaries/haxe /usr/local/bin/haxe
+    sudo ln -s `pwd`/macBinaries/haxelib /usr/local/bin/haxelib
+    sudo ln -s `pwd`/macBinaries/std /usr/local/share/haxe/std
+
+- name: Print Haxe version
+  run: haxe -version
+
+- name: Setup haxelib
+  run: |
+    set -ex
+    mkdir ~/haxelib
+    haxelib setup ~/haxelib
+
+- name: Install homebrew packages
+  if: matrix.BREW_PACKAGES
+  run: brew install ${{matrix.BREW_PACKAGES}}
+
+- name: Test
+  run: |
+    # disable invalid Unicode filenames on APFS
+    echo "" > sys/compile-fs.hxml
+    haxe RunCi.hxml
+  working-directory: ${{github.workspace}}/tests

+ 59 - 0
extra/github-actions/test-windows.yml

@@ -0,0 +1,59 @@
+- uses: actions/setup-node@v3
+  with:
+    node-version: 18.17.1
+
+# - name: Quick test
+#   shell: pwsh
+#   run: |
+#     $DOWNLOADDIR="./win$($env:ARCH)Binaries"
+#     new-item -Name $DOWNLOADDIR -ItemType directory
+#     Invoke-WebRequest https://build.haxe.org/builds/haxe/$env:PLATFORM/haxe_latest.zip -OutFile $DOWNLOADDIR/haxe_bin.zip
+
+- name: Setup Haxe
+  shell: pwsh
+  run: |
+    $DOWNLOADDIR="./win$($env:ARCH)Binaries"
+    Expand-Archive $DOWNLOADDIR/*_bin.zip -DestinationPath $DOWNLOADDIR
+    Set-PSDebug -Trace 1
+    $HAXEPATH = Get-ChildItem $DOWNLOADDIR/haxe_*_* -Directory
+    Write-Host "::add-path::$HAXEPATH"
+    Write-Host "::set-env name=HAXELIB_ROOT::$HAXEPATH\lib"
+
+- name: Print Haxe version
+  shell: pwsh
+  run: haxe -version
+
+- name: "Make Python 3 be available as python3 in the cmdline"
+  shell: pwsh
+  run: |
+    Set-PSDebug -Trace 1
+    $pypath = python -c "import sys; print(sys.executable)"
+    $py3path = $pypath.replace("python.exe","python3.exe")
+    cmd /c mklink $py3path $pypath
+    python3 -V
+
+- name: Install hererocks
+  if: matrix.target == 'lua'
+  shell: cmd
+  run: |
+    pip install hererocks
+    hererocks lua53 -l5.3 -rlatest
+    call lua53/bin/activate
+
+- name: Install wget
+  if: matrix.target == 'flash'
+  shell: cmd
+  run: |
+    choco install wget
+    wget --version
+
+- name: Setup haxelib
+  shell: pwsh
+  run: |
+    mkdir "$env:HAXELIB_ROOT"
+    haxelib setup "$env:HAXELIB_ROOT"
+
+- name: Test
+  shell: pwsh
+  run: haxe RunCi.hxml
+  working-directory: ${{github.workspace}}/tests

+ 492 - 0
extra/github-actions/workflows/main.yml

@@ -0,0 +1,492 @@
+# TODO: support skip ci (https://github.community/t/github-actions-does-not-respect-skip-ci/17325/8)
+
+name: CI
+on: [push, pull_request]
+
+jobs:
+  windows64-build:
+    runs-on: windows-latest
+    env:
+      ACTIONS_ALLOW_UNSECURE_COMMANDS: true
+      PLATFORM: windows64
+      ARCH: 64
+      MINGW_ARCH: x86_64
+      CYG_ROOT: D:\cygwin
+    steps:
+      - uses: actions/checkout@main
+        with:
+          submodules: recursive
+
+      - name: Use GNU Tar from msys
+        run: |
+          echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
+          rm C:\msys64\usr\bin\bash.exe
+
+      @import install-nsis.yml
+      @import install-neko-windows.yml
+      @import install-ocaml-windows64.yml
+      @import install-ocaml-libs-windows.yml
+      @import build-windows.yml
+
+  linux-build:
+    runs-on: ubuntu-20.04
+    env:
+      PLATFORM: linux64
+      OPAMYES: 1
+    strategy:
+      fail-fast: false
+      matrix:
+        ocaml: ["4.08.1", "5.0.0"]
+    steps:
+      - uses: actions/checkout@main
+        with:
+          submodules: recursive
+
+      - name: Cache opam
+        id: cache-opam
+        uses: actions/[email protected]
+        with:
+          path: ~/.opam/
+          key: ${{ runner.os }}-${{ matrix.ocaml }}-${{ hashFiles('./haxe.opam', './libs/') }}
+
+      @import install-neko-unix.yml
+
+      - name: Install dependencies
+        run: |
+          set -ex
+          sudo add-apt-repository ppa:avsm/ppa -y # provides OPAM 2
+          sudo add-apt-repository ppa:haxe/ocaml -y # provides newer version of mbedtls
+          sudo apt-get update -qqy
+          sudo apt-get install -qqy ocaml-nox camlp5 opam libpcre2-dev zlib1g-dev libgtk2.0-dev libmbedtls-dev ninja-build libstring-shellquote-perl libipc-system-simple-perl
+
+      - name: Install OCaml libraries
+        if: steps.cache-opam.outputs.cache-hit != 'true'
+        run: |
+          set -ex
+          opam init # --disable-sandboxing
+          opam update
+          opam switch create ${{ matrix.ocaml }}
+          opam pin add haxe . --no-action
+          opam install haxe --deps-only --assume-depexts
+          opam list
+          ocamlopt -v
+
+      - name: Set ADD_REVISION=1 for non-release
+        if: ${{ !startsWith(github.ref, 'refs/tags/') }}
+        run: echo "ADD_REVISION=1" >> $GITHUB_ENV
+
+      - name: Build Haxe
+        run: |
+          set -ex
+          eval $(opam env)
+          opam config exec -- make -s -j`nproc` STATICLINK=1 haxe
+          opam config exec -- make -s haxelib
+          make -s package_unix
+          ls -l out
+          ldd -v ./haxe
+          ldd -v ./haxelib
+
+      # https://stackoverflow.com/questions/58033366/how-to-get-current-branch-within-github-actions
+      - name: Extract branch name
+        id: extract_branch
+        shell: bash
+        run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT
+
+      - name: Build xmldoc
+        if: matrix.ocaml == '4.08.1'
+        run: |
+          set -ex
+          make -s xmldoc
+          cat >extra/doc/info.json <<EOL
+            {
+              "commit": "$GITHUB_SHA",
+              "branch": "${{ steps.extract_branch.outputs.branch }}"
+            }
+          EOL
+
+      - name: Upload artifact
+        uses: actions/upload-artifact@v3
+        with:
+          name: linuxBinaries${{ (matrix.ocaml == '5.0.0' && '_ocaml5') || '' }}
+          path: out
+
+      - name: Upload xmldoc artifact
+        uses: actions/upload-artifact@v3
+        if: matrix.ocaml == '4.08.1'
+        with:
+          name: xmldoc
+          path: extra/doc
+
+  linux-test:
+    needs: linux-build
+    runs-on: ubuntu-20.04
+    env:
+      PLATFORM: linux64
+      TEST: ${{matrix.target}}
+      HXCPP_COMPILE_CACHE: ~/hxcache
+      HAXE_STD_PATH: /usr/local/share/haxe/std
+    strategy:
+      fail-fast: false
+      matrix:
+        ocaml: ["4.08.1", "5.0.0"]
+        target: [macro, js, hl, cpp, jvm, php, python, lua, flash, neko]
+        include:
+          - target: hl
+            APT_PACKAGES: cmake ninja-build libturbojpeg-dev
+          - target: cpp
+            APT_PACKAGES: gcc-multilib g++-multilib
+          - target: lua
+            APT_PACKAGES: ncurses-dev
+          - target: flash
+            APT_PACKAGES: libglib2.0-0 libgtk2.0-0 libfreetype6 xvfb
+    steps:
+      - uses: actions/checkout@main
+        with:
+          submodules: recursive
+      - uses: actions/download-artifact@v3
+        with:
+          name: linuxBinaries${{ (matrix.ocaml == '5.0.0' && '_ocaml5') || '' }}
+          path: linuxBinaries
+
+      @import install-neko-unix.yml
+
+      - name: Setup Haxe
+        run: |
+          sudo apt install -qqy libmbedtls-dev
+
+          set -ex
+          tar -xf linuxBinaries/*_bin.tar.gz -C linuxBinaries --strip-components=1
+          sudo mkdir -p /usr/local/bin/
+          sudo mkdir -p /usr/local/share/haxe/
+          sudo ln -s `pwd`/linuxBinaries/haxe /usr/local/bin/haxe
+          sudo ln -s `pwd`/linuxBinaries/haxelib /usr/local/bin/haxelib
+          sudo ln -s `pwd`/linuxBinaries/std /usr/local/share/haxe/std
+
+      - name: Print Haxe version
+        run: haxe -version
+
+      - name: Setup haxelib
+        run: |
+          set -ex
+          mkdir ~/haxelib
+          haxelib setup ~/haxelib
+
+      - name: Install apt packages
+        if: matrix.APT_PACKAGES
+        run: |
+          set -ex
+          sudo apt update -qqy
+          sudo apt install -qqy ${{matrix.APT_PACKAGES}}
+
+      - name: Flash setup
+        if: matrix.target == 'flash'
+        run: export DISPLAY=:99.0
+
+      - name: Test
+        run: haxe RunCi.hxml
+        working-directory: ${{github.workspace}}/tests
+
+  test-docgen:
+    needs: linux-build
+    runs-on: ubuntu-20.04
+    env:
+      PLATFORM: linux64
+      HXCPP_COMPILE_CACHE: ~/hxcache
+    steps:
+      - uses: actions/checkout@main
+        with:
+          submodules: recursive
+
+      - uses: actions/download-artifact@v3
+        with:
+          name: linuxBinaries
+          path: linuxBinaries
+
+      - name: Download xmldoc artifact
+        uses: actions/download-artifact@v3
+        with:
+          name: xmldoc
+          path: xmldoc
+
+      @import install-neko-unix.yml
+
+      - name: Setup Haxe
+        run: |
+          sudo apt install -qqy libmbedtls-dev
+
+          set -ex
+          tar -xf linuxBinaries/*_bin.tar.gz -C linuxBinaries --strip-components=1
+          sudo mkdir -p /usr/local/bin/
+          sudo mkdir -p /usr/local/share/haxe/
+          sudo ln -s `pwd`/linuxBinaries/haxe /usr/local/bin/haxe
+          sudo ln -s `pwd`/linuxBinaries/haxelib /usr/local/bin/haxelib
+          sudo ln -s `pwd`/linuxBinaries/std /usr/local/share/haxe/std
+
+      - name: Print Haxe version
+        run: haxe -version
+
+      - name: Setup haxelib
+        run: |
+          set -ex
+          mkdir ~/haxelib
+          haxelib setup ~/haxelib
+
+      - name: Test documentation generation
+        run: |
+          set -ex
+          haxelib git dox https://github.com/HaxeFoundation/dox.git
+          haxelib git hxtemplo https://github.com/Simn/hxtemplo.git
+          haxelib git hxargs https://github.com/Simn/hxargs.git
+          haxelib git markdown https://github.com/dpeek/haxe-markdown.git
+          haxelib git hxcpp https://github.com/HaxeFoundation/hxcpp.git
+          cd $(haxelib libpath hxcpp)/tools/hxcpp
+          haxe compile.hxml
+          cd -
+          haxe dox.hxml
+          mkdir resources
+          cp ../../src-json/* resources
+          cpp/Dox -i ../../xmldoc -ex microsoft -ex javax -theme $(haxelib libpath dox)/themes/default
+        working-directory: ${{github.workspace}}/tests/docgen
+
+  linux-arm64:
+    runs-on: ubuntu-20.04
+    permissions:
+      packages: write
+    env:
+      FORCE_COLOR: 1
+    steps:
+      - name: Login to GitHub Container Registry
+        uses: docker/login-action@v2
+        with:
+          registry: ghcr.io
+          username: ${{ github.actor }}
+          password: ${{ secrets.GITHUB_TOKEN }}
+
+      - name: Install Earthly
+        run: sudo /bin/sh -c 'wget https://github.com/earthly/earthly/releases/download/v0.6.13/earthly-linux-amd64 -O /usr/local/bin/earthly && chmod +x /usr/local/bin/earthly && /usr/local/bin/earthly bootstrap --with-autocomplete'
+
+      - name: Set up QEMU
+        id: qemu
+        uses: docker/setup-qemu-action@v2
+        with:
+            image: tonistiigi/binfmt:latest
+            platforms: all
+
+      - uses: actions/checkout@main
+        with:
+          submodules: recursive
+
+      - name: Set CONTAINER_ vars
+        run: |
+          echo "CONTAINER_REG=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV;
+          echo "CONTAINER_TAG=$(echo ${{ github.ref_name }} | sed -e 's/[^A-Za-z0-9\.]/-/g')" >> $GITHUB_ENV;
+
+      - name: Build devcontainer
+        run: earthly --platform=linux/arm64 +devcontainer --IMAGE_NAME="ghcr.io/${CONTAINER_REG}_devcontainer" --IMAGE_TAG="${CONTAINER_TAG}-arm64" --IMAGE_CACHE="ghcr.io/haxefoundation/haxe_devcontainer:development-arm64"
+        env:
+          EARTHLY_PUSH: "${{ github.event_name == 'push' }}"
+          EARTHLY_USE_INLINE_CACHE: true
+          EARTHLY_SAVE_INLINE_CACHE: true
+
+      - name: Set ADD_REVISION=1 for non-release
+        if: ${{ !startsWith(github.ref, 'refs/tags/') }}
+        run: echo "ADD_REVISION=1" >> $GITHUB_ENV
+
+      - name: Build
+        run: earthly --platform=linux/arm64 +build --ADD_REVISION="$ADD_REVISION" --SET_SAFE_DIRECTORY="true"
+        env:
+          EARTHLY_PUSH: "${{ github.event_name == 'push' }}"
+          EARTHLY_REMOTE_CACHE: "ghcr.io/${{env.CONTAINER_REG}}_cache:build-${{env.CONTAINER_TAG}}-arm64"
+
+      - name: Upload artifact
+        uses: actions/upload-artifact@v3
+        with:
+          name: linuxArm64Binaries
+          path: out/linux/arm64
+
+  mac-build:
+    runs-on: macos-latest
+    env:
+      PLATFORM: mac
+      OPAMYES: 1
+      MACOSX_DEPLOYMENT_TARGET: 10.13
+    steps:
+      - uses: actions/checkout@main
+        with:
+          submodules: recursive
+
+      - name: Cache opam
+        id: cache-opam
+        uses: actions/[email protected]
+        with:
+          path: ~/.opam/
+          key: ${{ runner.os }}-${{ hashFiles('./haxe.opam', './libs/') }}
+
+      @import install-neko-unix.yml
+      @import build-mac.yml
+
+  windows64-test:
+    needs: windows64-build
+    runs-on: windows-latest
+    env:
+      ACTIONS_ALLOW_UNSECURE_COMMANDS: true
+      PLATFORM: windows64
+      TEST: ${{matrix.target}}
+      HXCPP_COMPILE_CACHE: ~/hxcache
+      ARCH: 64
+    strategy:
+      fail-fast: false
+      matrix:
+        # TODO enable lua after https://github.com/HaxeFoundation/haxe/issues/10919
+        target: [macro, js, hl, cpp, jvm, php, python, flash, neko]
+    steps:
+      - uses: actions/checkout@main
+        with:
+          submodules: recursive
+      - uses: actions/download-artifact@v3
+        with:
+          name: win${{env.ARCH}}Binaries
+          path: win${{env.ARCH}}Binaries
+
+      @import install-neko-windows.yml
+      @import test-windows.yml
+
+  mac-test:
+    needs: mac-build
+    runs-on: macos-latest
+    env:
+      PLATFORM: mac
+      TEST: ${{matrix.target}}
+      HXCPP_COMPILE_CACHE: ~/hxcache
+      HAXE_STD_PATH: /usr/local/share/haxe/std
+    strategy:
+      fail-fast: false
+      matrix:
+        target: [macro, js, hl, cpp, jvm, php, python, flash, neko]
+        include:
+          - target: hl
+            BREW_PACKAGES: ninja
+    steps:
+      - uses: actions/checkout@main
+        with:
+          submodules: recursive
+      - uses: actions/download-artifact@v3
+        with:
+          name: macBinaries
+          path: macBinaries
+
+      @import install-neko-unix.yml
+      @import test-mac.yml
+
+  deploy:
+    if: success() && github.repository_owner == 'HaxeFoundation' && github.event_name != 'pull_request'
+    needs: [linux-test, linux-arm64, mac-test, windows64-test]
+    runs-on: ubuntu-20.04
+    steps:
+      # this is only needed for to get `COMMIT_DATE`...
+      # maybe https://github.community/t/expose-commit-timestamp-in-the-github-context-data/16460/3
+      # would be faster
+      - name: Checkout the repository
+        uses: actions/checkout@main
+
+      - name: Download build artifacts
+        uses: actions/download-artifact@v3
+
+      - name: Install awscli
+        run: |
+          set -ex
+          sudo apt-get update -qqy
+          sudo apt-get install -qqy awscli
+
+      # https://stackoverflow.com/questions/58033366/how-to-get-current-branch-within-github-actions
+      - name: Extract branch name
+        id: extract_branch
+        shell: bash
+        run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT
+
+      - name: Upload binaries
+        shell: bash
+        env:
+          AWS_ACCESS_KEY_ID: ${{ secrets.HXBUILDS_AWS_ACCESS_KEY_ID }}
+          AWS_SECRET_ACCESS_KEY: ${{ secrets.HXBUILDS_AWS_SECRET_ACCESS_KEY }}
+          HXBUILDS_S3ADDR: ${{ secrets.HXBUILDS_S3ADDR }}
+          AWS_EC2_METADATA_DISABLED: true
+        run: |
+          set -ex
+          COMMIT_HASH_SHORT=${GITHUB_SHA:0:7}
+          COMMIT_DATE=`TZ=UTC git show --quiet --date='format-local:%Y-%m-%d' --format="%cd"`
+          FILE_NAME=haxe_${COMMIT_DATE}_${{ steps.extract_branch.outputs.branch }}_${COMMIT_HASH_SHORT}
+          aws s3 cp linuxBinaries/*_bin.tar.gz      ${HXBUILDS_S3ADDR}/haxe/linux64/${FILE_NAME}.tar.gz
+          aws s3 cp linuxArm64Binaries/*_bin.tar.gz ${HXBUILDS_S3ADDR}/haxe/linux-arm64/${FILE_NAME}.tar.gz
+          aws s3 cp macBinaries/*_bin.tar.gz        ${HXBUILDS_S3ADDR}/haxe/mac/${FILE_NAME}.tar.gz
+          aws s3 cp macBinaries/*_installer.tar.gz  ${HXBUILDS_S3ADDR}/haxe/mac-installer/${FILE_NAME}.tar.gz
+          aws s3 cp win64Binaries/*_bin.zip         ${HXBUILDS_S3ADDR}/haxe/windows64/${FILE_NAME}.zip
+          aws s3 cp win64Binaries/*_installer.zip   ${HXBUILDS_S3ADDR}/haxe/windows64-installer/${FILE_NAME}.zip
+          aws s3 cp win64Binaries/*.nupkg           ${HXBUILDS_S3ADDR}/haxe/windows64-choco/
+
+      - name: Update "latest"
+        if: github.ref == 'refs/heads/development'
+        shell: bash
+        env:
+          AWS_ACCESS_KEY_ID: ${{ secrets.HXBUILDS_AWS_ACCESS_KEY_ID }}
+          AWS_SECRET_ACCESS_KEY: ${{ secrets.HXBUILDS_AWS_SECRET_ACCESS_KEY }}
+          HXBUILDS_S3ADDR: ${{ secrets.HXBUILDS_S3ADDR }}
+          AWS_EC2_METADATA_DISABLED: true
+        run: |
+          set -ex
+          aws s3 cp linuxBinaries/*_bin.tar.gz      ${HXBUILDS_S3ADDR}/haxe/linux64/haxe_latest.tar.gz
+          aws s3 cp linuxArm64Binaries/*_bin.tar.gz ${HXBUILDS_S3ADDR}/haxe/linux-arm64/haxe_latest.tar.gz
+          aws s3 cp macBinaries/*_bin.tar.gz        ${HXBUILDS_S3ADDR}/haxe/mac/haxe_latest.tar.gz
+          aws s3 cp macBinaries/*_installer.tar.gz  ${HXBUILDS_S3ADDR}/haxe/mac-installer/haxe_latest.tar.gz
+          aws s3 cp win64Binaries/*_bin.zip         ${HXBUILDS_S3ADDR}/haxe/windows64/haxe_latest.zip
+          aws s3 cp win64Binaries/*_installer.zip   ${HXBUILDS_S3ADDR}/haxe/windows64-installer/haxe_latest.zip
+
+          # Chocolatey packages have to be named with version number,
+          # so let's use web redirection to keep the original file name.
+          [[ "$HXBUILDS_S3ADDR" =~ s3://([^/]+)(.*) ]] && HXBUILDS_S3BUCKET="${BASH_REMATCH[1]}" && HXBUILDS_S3PATH="${BASH_REMATCH[2]}"
+          [[ `echo win64Binaries/*.nupkg` =~ win64Binaries/(.+) ]] && FILE_NAME="${BASH_REMATCH[1]}"
+          aws s3 cp ${HXBUILDS_S3ADDR}/haxe/windows64-choco/${FILE_NAME} ${HXBUILDS_S3ADDR}/haxe/windows64-choco/haxe_latest.nupkg --acl public-read --website-redirect "${HXBUILDS_S3PATH}/haxe/windows64-choco/${FILE_NAME}"
+
+
+  deploy_apidoc:
+    if: success() && github.repository_owner == 'HaxeFoundation' && github.event_name != 'pull_request'
+    needs: [linux-test, linux-arm64, mac-test, windows64-test]
+    runs-on: ubuntu-20.04
+    steps:
+      - name: Install dependencies
+        run: |
+          set -ex
+          sudo apt-get install -qqy libc6
+
+      - name: Download Haxe
+        uses: actions/download-artifact@v3
+        with:
+          name: linuxBinaries
+          path: linuxBinaries
+
+      - name: Setup Haxe
+        run: |
+          set -ex
+          tar -xf linuxBinaries/*_bin.tar.gz -C linuxBinaries --strip-components=1
+          sudo mkdir -p /usr/local/bin/
+          sudo mkdir -p /usr/local/share/haxe/
+          sudo ln -s `pwd`/linuxBinaries/haxe /usr/local/bin/haxe
+          sudo ln -s `pwd`/linuxBinaries/haxelib /usr/local/bin/haxelib
+          sudo ln -s `pwd`/linuxBinaries/std /usr/local/share/haxe/std
+
+      - name: Download xmldoc artifact
+        uses: actions/download-artifact@v3
+        with:
+          name: xmldoc
+          path: xmldoc
+
+      - name: Deploy to api.haxe.org
+        env:
+          GHP_EMAIL: [email protected]
+          GHP_USERNAME: Haxe CI Bot
+          GHP_REMOTE: ${{ secrets.GHP_REMOTE }}
+        run: |
+          set -ex
+          LOCAL="`pwd`/extra/api.haxe.org"
+          git clone "${GHP_REMOTE}" "${LOCAL}"
+          haxe --cwd "${LOCAL}" --run ImportXml "`pwd`/xmldoc"

+ 1 - 1
extra/haxelib_src

@@ -1 +1 @@
-Subproject commit 4b27f91d8a4ff279d9903091680fee2c93a0d574
+Subproject commit 98637027327d8cf385d302acaaf104bd6107d2bf

BIN
extra/images/Readme.png


+ 1 - 1
extra/installer.nsi

@@ -21,7 +21,7 @@
 !define VERLONG "%%VERLONG%%"
 
 ; Define Neko info
-!define NEKO_VERSION "2.3.0"
+!define NEKO_VERSION "%%NEKO_VERSION%%"
 
 ; Installer details
 VIAddVersionKey "CompanyName" "Haxe Foundation"

+ 2 - 2
extra/mac-installer/scripts/neko-postinstall.sh

@@ -15,5 +15,5 @@ ln -s /usr/local/lib/neko/nekoc /usr/local/bin/nekoc
 ln -s /usr/local/lib/neko/nekoml /usr/local/bin/nekoml
 ln -s /usr/local/lib/neko/nekotools /usr/local/bin/nekotools
 ln -s /usr/local/lib/neko/libneko.dylib /usr/local/lib/libneko.dylib
-ln -s /usr/local/lib/neko/libneko.2.dylib /usr/local/lib/libneko.2.dylib
-ln -s /usr/local/lib/neko/libneko.2.1.0.dylib /usr/local/lib/libneko.2.1.0.dylib
+ln -s /usr/local/lib/neko/libneko.%%NEKO_MAJOR_VERSION%%.dylib /usr/local/lib/libneko.%%NEKO_MAJOR_VERSION%%.dylib
+ln -s /usr/local/lib/neko/libneko.%%NEKO_VERSION%%.dylib /usr/local/lib/libneko.%%NEKO_VERSION%%.dylib

+ 22 - 11
extra/release-checklist.txt

@@ -2,24 +2,35 @@
 
 - Check that haxelib is working
 - Make sure to update the haxelib submodule
-- Check that the run-time haxelibs are ready for release: hxcpp, hxjava, hxcs
-- Check that the osx & windows installers has the latest neko release in "Makefile" and "Makefile.win" files
+- Check that the run-time haxelibs are ready for release: hxcpp, hxjava
+- Check that the NEKO_VERSION variable in the "Makefile" is set to the latest Neko version
 
 # Making the release
 
 - Make sure CHANGES.txt has a proper date set!
 - Make sure `version` in globals.ml has the correct value
+- Make sure the copyright year in args.ml has the correct value
+- Update `version` in `haxe.opam`
 - Check if the protocolVersion in displayJson.ml has to be updated
-- Make an empty GitHub release in https://github.com/HaxeFoundation/haxe/releases (do this first because we need the tag for the builds)
-- Wait for the CI to build (check https://build.haxe.org/builds/haxe/)
-- Get https://github.com/simn/hxgithub
-- Store your GitHub personal access token in .github-token
-- Run something like this: `neko release.n -h 4.0.0-rc.1 -u -uw -ur -d haxe_2019-02-01_development_1fdd3d5.zip --dry`
-- Tell yourself that you're gonna fix `-doc` generation next time
-- Write the announcement to `./haxe-version/RELEASE.md`
-- If everything was working, run the command again without `--dry` (and probably without the `-d`)
+- Create a version tag and push it with above changes (CI needs to run on the tag)
+- Make an empty GitHub release in https://github.com/HaxeFoundation/haxe/releases
+- Wait for the CI to build (check https://build.haxe.org/builds/haxe/, look for `haxe_[date]_refs/tags`)
+- Get https://github.com/HaxeFoundation/hxgithub
+- Follow "Haxe releases" section of hxgithub README, with the equivalent of `-d haxe_2023-04-28_refs/tags/4.3.1_964c84c.tar.gz`
+	- Tell yourself that you're gonna fix `-doc` generation next time
+	- Make sure changelog isn't empty in `./haxe-version/CHANGES.md`
+	- Write the announcement to `./haxe-version/RELEASE.md`
+	- If everything was working, run the command again without `--dry`
 - Update https://github.com/HaxeFoundation/haxe.org/blob/staging/downloads/versions.json
+- Wait for staging to update, check everything related to release and merge to master
+- Update https://github.com/HaxeFoundation/api.haxe.org/blob/master/theme/templates/topbar.mtt
+- Update https://github.com/HaxeFoundation/code-cookbook/blob/master/assets/content/index.mtt#L62-L63
+
+# Cleanup
+
+- Remove issues with released fixes from the "Hotfix" milestone: https://github.com/HaxeFoundation/haxe/milestone/18
+- Set back the version in `globals.ml` to something appropriate for nightlies
 
 # Announcing the release
 
-- Find someone to announce the release on our various communication channels
+- Find someone to announce the release on our various communication channels

+ 15 - 12
opam → haxe.opam

@@ -1,6 +1,6 @@
 opam-version: "2.0"
 name: "haxe"
-version: "4.0.0"
+version: "4.3.0"
 synopsis: "Multi-target universal programming language"
 description: """
 Haxe is an open source toolkit based on a modern,
@@ -19,16 +19,19 @@ build: [
 install: [make "install" "INSTALL_DIR=%{prefix}%"]
 remove: [make "uninstall" "INSTALL_DIR=%{prefix}%"]
 depends: [
-  "ocaml"               {>= "4.02"}
-  "ocamlfind"           {build}
-  "camlp5"              {build}
-  "sedlex"              {build}
-  "ppx_tools_versioned" {build & != "5.2.1"} #https://github.com/alainfrisch/sedlex/issues/64
-  "xml-light"           {build}
-  "extlib"              {build & >= "1.7.6"}
-  "ptmap"               {build}
-  "sha"                 {build}
-  "conf-libpcre"
+  ("ocaml" {>= "5.0"} & ("camlp5" {build}))
+    | ("ocaml" {>= "4.08" & < "5.0"} & ("camlp5" {build & = "8.00.03"}))
+  "ocamlfind" {build}
+  "dune" {>= "1.11"}
+  "sedlex" {>= "2.0"}
+  "xml-light"
+  "extlib" {>= "1.7.8"}
+  "sha"
+  "camlp-streams"
+  "conf-libpcre2-8"
   "conf-zlib"
   "conf-neko"
-]
+  "luv" {>= "0.5.12"}
+  "ipaddr"
+  "terminal_size"
+]

+ 2 - 3
libs/Makefile

@@ -1,7 +1,7 @@
 OCAMLOPT = ocamlopt
 OCAMLC = ocamlc
 TARGET_FLAG = all
-LIBS=extlib-leftovers extc neko javalib ilib swflib ttflib objsize pcre ziplib
+LIBS=extlib-leftovers extc neko javalib ilib swflib objsize pcre2 ziplib
 
 all: $(LIBS)
 $(LIBS):
@@ -14,9 +14,8 @@ clean:
 	$(MAKE) -C javalib clean
 	$(MAKE) -C ilib clean
 	$(MAKE) -C swflib clean
-	$(MAKE) -C ttflib clean
 	$(MAKE) -C objsize clean
-	$(MAKE) -C pcre clean
+	$(MAKE) -C pcre2 clean
 	$(MAKE) -C ziplib clean
 
 .PHONY: all clean $(LIBS)

+ 0 - 5
libs/README.md

@@ -1,5 +0,0 @@
-# ocamllibs
-
-[![TravisCI Build Status](https://travis-ci.org/HaxeFoundation/ocamllibs.svg?branch=master)](https://travis-ci.org/HaxeFoundation/ocamllibs)
-
-Various OCaml libraries.

+ 7 - 3
libs/extc/dune

@@ -3,14 +3,18 @@
 (library
 	(name extc)
 	(libraries extlib)
-	(c_names extc_stubs)
+	(foreign_stubs
+		(language c)
+		(names extc_stubs))
 	(modules extc)
 	(wrapped false)
 )
 
 (library
 	(name extproc)
-	(c_names process_stubs)
+	(foreign_stubs
+		(language c)
+		(names process_stubs))
 	(modules process)
 	(wrapped false)
-)
+)

+ 3 - 3
libs/extc/extc.ml

@@ -110,10 +110,10 @@ let input_zip ?(bufsize=65536) ch =
 	let buf = ref "" in
 	let p = ref 0 in
 	let z = zlib_inflate_init() in
-	let rec fill_buffer() =
+	let fill_buffer() =
 		let rec loop pos len =
 			if len > 0 || pos = 0 then begin
-				let r = zlib_inflate z (Bytes.unsafe_to_string tmp_in) pos len tmp_out 0 bufsize (if pos = 0 && len = 0 then Z_FINISH else Z_SYNC_FLUSH) in
+				let r = zlib_inflate z ~src:(Bytes.unsafe_to_string tmp_in) ~spos:pos ~slen:len ~dst:tmp_out ~dpos:0 ~dlen:bufsize (if pos = 0 && len = 0 then Z_FINISH else Z_SYNC_FLUSH) in
 				Buffer.add_subbytes tmp_buf tmp_out 0 r.z_wrote;
 				loop (pos + r.z_read) (len - r.z_read);
 			end
@@ -155,7 +155,7 @@ let output_zip ?(bufsize=65536) ?(level=9) ch =
 	let tmp_out = Bytes.create bufsize in
 	let p = ref 0 in
 	let rec flush finish =
-		let r = zlib_deflate z (Bytes.unsafe_to_string out) 0 !p tmp_out 0 bufsize (if finish then Z_FINISH else Z_SYNC_FLUSH) in
+		let r = zlib_deflate z ~src:(Bytes.unsafe_to_string out) ~spos:0 ~slen:!p ~dst:tmp_out ~dpos:0 ~dlen:bufsize (if finish then Z_FINISH else Z_SYNC_FLUSH) in
 		ignore(IO.really_output ch tmp_out 0 r.z_wrote);
 		let remain = !p - r.z_read in
 		Bytes.blit out r.z_read out 0 remain;

+ 21 - 21
libs/extc/extc_stubs.c

@@ -92,7 +92,7 @@ int Zflush_val(value zflush_val) {
 		case 4: return Z_FINISH;
 		// TODO: support Z_BLOCK and Z_TREE
 		// TODO: append the received value
-		default: failwith("Error in `Zflush_val` (extc_stubs.c): Unknown zflush value");
+		default: caml_failwith("Error in `Zflush_val` (extc_stubs.c): Unknown zflush value");
 	}
 	assert(0);
 }
@@ -222,14 +222,14 @@ CAMLprim value zlib_deflate_init2(value level_val, value window_bits_val) {
 			break;
 		case Z_STREAM_ERROR:
 			// TODO: use stream->msg to get _zlib_'s text message
-			failwith("Error in `zlib_deflate_init2` (extc_stubs.c): call to `deflateInit2` failed: Z_STREAM_ERROR");
+			caml_failwith("Error in `zlib_deflate_init2` (extc_stubs.c): call to `deflateInit2` failed: Z_STREAM_ERROR");
 			break;
 		case Z_VERSION_ERROR:
 			// TODO: use stream->msg to get _zlib_'s text message
-			failwith("Error in `zlib_deflate_init2` (extc_stubs.c): call to `deflateInit2` failed: Z_VERSION_ERROR");
+			caml_failwith("Error in `zlib_deflate_init2` (extc_stubs.c): call to `deflateInit2` failed: Z_VERSION_ERROR");
 			break;
 		default:
-			failwith("Error in `zlib_deflate_init2` (extc_stubs.c): unknown return code from `deflateInit2`");
+			caml_failwith("Error in `zlib_deflate_init2` (extc_stubs.c): unknown return code from `deflateInit2`");
 	}
 	assert(0);
 }
@@ -275,7 +275,7 @@ CAMLprim value zlib_deflate(value stream_val, value src, value spos, value slen,
 	if (deflate_result == Z_OK || deflate_result == Z_STREAM_END) {
 		stream->next_in = NULL;
 		stream->next_out = NULL;
-		value zresult = alloc_small(3, 0);
+		value zresult = caml_alloc_small(3, 0);
 		// z_finish
 		Field(zresult, 0) = Val_bool(deflate_result == Z_STREAM_END);
 		// z_read
@@ -291,14 +291,14 @@ CAMLprim value zlib_deflate(value stream_val, value src, value spos, value slen,
 			break;
 		case Z_STREAM_ERROR:
 			// TODO: use stream->msg to get _zlib_'s text message
-			failwith("Error in `zlib_deflate` (extc_stubs.c): call to `deflate` failed: Z_STREAM_ERROR");
+			caml_failwith("Error in `zlib_deflate` (extc_stubs.c): call to `deflate` failed: Z_STREAM_ERROR");
 			break;
 		case Z_BUF_ERROR:
 			// TODO: use stream->msg to get _zlib_'s text message
-			failwith("Error in `zlib_deflate` (extc_stubs.c): call to `deflate` failed: Z_BUF_ERROR");
+			caml_failwith("Error in `zlib_deflate` (extc_stubs.c): call to `deflate` failed: Z_BUF_ERROR");
 			break;
 		default:
-			failwith("Error in `zlib_deflate` (extc_stubs.c): unknown return code from `deflate`");
+			caml_failwith("Error in `zlib_deflate` (extc_stubs.c): unknown return code from `deflate`");
 	}
 	assert(0);
 }
@@ -309,14 +309,14 @@ CAMLprim value zlib_deflate_bytecode(value *arg, int nargs) {
 
 CAMLprim value zlib_deflate_end(value zv) {
 	if( deflateEnd(ZStreamP_val(zv)) != 0 )
-		failwith("zlib_deflate_end");
+		caml_failwith("zlib_deflate_end");
 	return Val_unit;
 }
 
 CAMLprim value zlib_inflate_init(value wbits) {
 	value z = zlib_new_stream();
 	if( inflateInit2(ZStreamP_val(z),Int_val(wbits)) != Z_OK )
-		failwith("zlib_inflate_init");
+		caml_failwith("zlib_inflate_init");
 	return z;
 }
 
@@ -330,12 +330,12 @@ CAMLprim value zlib_inflate( value zv, value src, value spos, value slen, value
 	z->avail_in = Int_val(slen);
 	z->avail_out = Int_val(dlen);
 	if( (r = inflate(z,Int_val(flush))) < 0 )
-		failwith("zlib_inflate");
+		caml_failwith("zlib_inflate");
 
 	z->next_in = NULL;
 	z->next_out = NULL;
 
-	res = alloc_small(3, 0);
+	res = caml_alloc_small(3, 0);
 	Field(res, 0) = Val_bool(r == Z_STREAM_END);
 	Field(res, 1) = Val_int(Int_val(slen) - z->avail_in);
 	Field(res, 2) = Val_int(Int_val(dlen) - z->avail_out);
@@ -348,7 +348,7 @@ CAMLprim value zlib_inflate_bytecode(value * arg, int nargs) {
 
 CAMLprim value zlib_inflate_end(value zv) {
 	if( inflateEnd(ZStreamP_val(zv)) != 0 )
-		failwith("zlib_inflate_end");
+		caml_failwith("zlib_inflate_end");
 	return Val_unit;
 }
 
@@ -368,13 +368,13 @@ CAMLprim value executable_path(value u) {
 #ifdef _WIN32
 	char path[MAX_PATH];
 	if( GetModuleFileName(NULL,path,MAX_PATH) == 0 )
-		failwith("executable_path");
+		caml_failwith("executable_path");
 	return caml_copy_string(path);
 #elif __APPLE__
 	char path[MAXPATHLEN+1];
 	uint32_t path_len = MAXPATHLEN;
 	if ( _NSGetExecutablePath(path, &path_len) )
-		failwith("executable_path");
+		caml_failwith("executable_path");
 	return caml_copy_string(path);
 #elif __FreeBSD__
 	char path[PATH_MAX];
@@ -387,7 +387,7 @@ CAMLprim value executable_path(value u) {
 	len = sizeof(path);
 	error = sysctl(name, 4, path, &len, NULL, 0);
 	if( error < 0 )
-		failwith("executable_path");
+		caml_failwith("executable_path");
 	return caml_copy_string(path);
 #else
 	char path[PATH_MAX];
@@ -397,7 +397,7 @@ CAMLprim value executable_path(value u) {
 		if( p != NULL )
 			return caml_copy_string(p);
 		else
-			failwith("executable_path");
+			caml_failwith("executable_path");
 	}
 	path[length] = '\0';
 	return caml_copy_string(path);
@@ -408,12 +408,12 @@ CAMLprim value get_full_path( value f ) {
 #ifdef _WIN32
 	char path[MAX_PATH];
 	if( GetFullPathName(String_val(f),MAX_PATH,path,NULL) == 0 )
-		failwith("get_full_path");
+		caml_failwith("get_full_path");
 	return caml_copy_string(path);
 #else
 	char path[4096];
 	if( realpath(String_val(f),path) == NULL )
-		failwith("get_full_path");
+		caml_failwith("get_full_path");
 	return caml_copy_string(path);
 #endif
 }
@@ -428,7 +428,7 @@ CAMLprim value get_real_path( value path ) {
 
 	// this will ensure the full class path with proper casing
 	if( GetFullPathName(String_val(path),MAX_PATH,out,NULL) == 0 )
-		failwith("get_real_path");
+		caml_failwith("get_real_path");
 
 	len = strlen(out);
 	i = 0;
@@ -501,7 +501,7 @@ CAMLprim value sys_time() {
 		ULARGE_INTEGER ui;
 		GetSystemTime(&t);
 		if( !SystemTimeToFileTime(&t,&ft) )
-			failwith("sys_cpu_time");
+			caml_failwith("sys_cpu_time");
 		ui.LowPart = ft.dwLowDateTime;
 		ui.HighPart = ft.dwHighDateTime;
 		return caml_copy_double( ((double)ui.QuadPart) / 10000000.0 - EPOCH_DIFF );

+ 46 - 52
libs/extc/process_stubs.c

@@ -25,6 +25,7 @@
 #include <caml/alloc.h>
 #include <caml/memory.h>
 #include <caml/callback.h>
+#include <caml/custom.h>
 #include <caml/mlvalues.h>
 #include <caml/fail.h>
 
@@ -57,24 +58,19 @@
 #endif
 
 // --- neko-to-caml api --
-#define val_check(v,t)
-#define val_check_kind(v,k)
 #define val_data(v) v
 #define val_array_size(v) Wosize_val(v)
 #define val_array_ptr(v) (&Field(v,0))
 #define val_string(v) String_val(v)
 #define val_strlen(v) caml_string_length(v)
-#define alloc_abstract(_,data) ((value)data)
 #define alloc_int(i) Val_int(i)
-#define val_gc(v,callb)
 #define val_null Val_int(0)
 #define val_some(v) Field(v,0)
 #define val_int(v) Int_val(v)
-#define DEFINE_KIND(_)
-#define neko_error() failwith(__FUNCTION__)
+#define neko_error() caml_failwith(__FUNCTION__)
 
 static value alloc_private( int size ) {
-	return alloc((size + sizeof(value) - 1) / sizeof(value), Abstract_tag);
+	return caml_alloc((size + sizeof(value) - 1) / sizeof(value), Abstract_tag);
 }
 
 // --- buffer api
@@ -200,9 +196,7 @@ typedef struct {
 #endif
 } vprocess;
 
-DEFINE_KIND(k_process);
-
-#define val_process(v)	((vprocess*)val_data(v))
+#define val_process(v) (*((vprocess**) Data_custom_val(v)))
 
 /**
 	<doc>
@@ -225,6 +219,9 @@ static int do_close( int fd ) {
 
 static void free_process( value vp ) {
 	vprocess *p = val_process(vp);
+	if (p == NULL) {
+		return;
+	}
 #	ifdef _WIN32
 	CloseHandle(p->eread);
 	CloseHandle(p->oread);
@@ -236,8 +233,18 @@ static void free_process( value vp ) {
 	do_close(p->oread);
 	do_close(p->iwrite);
 #	endif
+	free(p);
 }
 
+static struct custom_operations vprocess_ops = {
+	.identifier  = "vprocess_ops",
+	.finalize    = custom_finalize_default,
+	.compare     = custom_compare_default,
+	.hash        = custom_hash_default,
+	.serialize   = custom_serialize_default,
+	.deserialize = custom_deserialize_default,
+};
+
 /**
 	process_run : cmd:string -> args:string array option -> 'process
 	<doc>
@@ -249,13 +256,13 @@ static void free_process( value vp ) {
 	</doc>
 **/
 CAMLprim value process_run( value cmd, value vargs ) {
-	CAMLparam2(cmd,vargs);
+	CAMLparam2(cmd, vargs);
+	CAMLlocal1(vp);
 	int i, isRaw;
 	vprocess *p;
-	val_check(cmd,string);
+	vp = caml_alloc_custom(&vprocess_ops, sizeof(vprocess*), 0, 1);
 	isRaw = vargs == val_null;
 	if (!isRaw) {
-		val_check(vargs,array);
 		vargs = val_some(vargs);
 	}
 #	ifdef _WIN32
@@ -286,7 +293,6 @@ CAMLprim value process_run( value cmd, value vargs ) {
 				int j,len;
 				unsigned int bs_count = 0;
 				unsigned int k;
-				val_check(v,string);
 				len = val_strlen(v);
 				buffer_append_str(b," \"");
 				for(j=0;j<len;j++) {
@@ -322,7 +328,7 @@ CAMLprim value process_run( value cmd, value vargs ) {
 			}
 		}
 		sargs = buffer_to_string(b);
-		p = (vprocess*)alloc_private(sizeof(vprocess));
+		p = (vprocess*)malloc(sizeof(vprocess));
 		// startup process
 		sattr.nLength = sizeof(sattr);
 		sattr.bInheritHandle = TRUE;
@@ -367,7 +373,6 @@ CAMLprim value process_run( value cmd, value vargs ) {
 		argv[0] = val_string(cmd);
 		for(i=0;i<val_array_size(vargs);i++) {
 			value v = val_array_ptr(vargs)[i];
-			val_check(v,string);
 			argv[i+1] = val_string(v);
 		}
 		argv[i+1] = NULL;
@@ -375,7 +380,7 @@ CAMLprim value process_run( value cmd, value vargs ) {
 	int input[2], output[2], error[2];
 	if( pipe(input) || pipe(output) || pipe(error) )
 		neko_error();
-	p = (vprocess*)alloc_private(sizeof(vprocess));
+	p = (vprocess*)malloc(sizeof(vprocess));
 	p->pid = fork();
 	if( p->pid == -1 ) {
 		do_close(input[0]);
@@ -406,20 +411,13 @@ CAMLprim value process_run( value cmd, value vargs ) {
 	p->oread = output[0];
 	p->eread = error[0];
 #	endif
-	{
-		CAMLlocal1(vp);
-		vp = alloc_abstract(k_process,p);
-		val_gc(vp,free_process);
-		CAMLreturn(vp);
-	}
+	val_process(vp) = p;
+	CAMLreturn(vp);
 }
 
 #define CHECK_ARGS()	\
+	CAMLparam4(vp, str, pos, len); \
 	vprocess *p; \
-	val_check_kind(vp,k_process); \
-	val_check(str,string); \
-	val_check(pos,int); \
-	val_check(len,int); \
 	if( val_int(pos) < 0 || val_int(len) < 0 || val_int(pos) + val_int(len) > val_strlen(str) ) \
 		neko_error(); \
 	p = val_process(vp); \
@@ -440,7 +438,7 @@ CAMLprim value process_stdout_read( value vp, value str, value pos, value len )
 		DWORD nbytes;
 		if( !ReadFile(p->oread,val_string(str)+val_int(pos),val_int(len),&nbytes,NULL) )
 			neko_error();
-		return alloc_int(nbytes);
+		CAMLreturn(alloc_int(nbytes));
 	}
 #	else
 	int nbytes;
@@ -452,7 +450,7 @@ CAMLprim value process_stdout_read( value vp, value str, value pos, value len )
 	}
 	if( nbytes == 0 )
 		neko_error();
-	return alloc_int(nbytes);
+	CAMLreturn(alloc_int(nbytes));
 #	endif
 }
 
@@ -471,7 +469,7 @@ CAMLprim value process_stderr_read( value vp, value str, value pos, value len )
 		DWORD nbytes;
 		if( !ReadFile(p->eread,val_string(str)+val_int(pos),val_int(len),&nbytes,NULL) )
 			neko_error();
-		return alloc_int(nbytes);
+		CAMLreturn(alloc_int(nbytes));
 	}
 #	else
 	int nbytes;
@@ -483,7 +481,7 @@ CAMLprim value process_stderr_read( value vp, value str, value pos, value len )
 	}
 	if( nbytes == 0 )
 		neko_error();
-	return alloc_int(nbytes);
+	CAMLreturn(alloc_int(nbytes));
 #	endif
 }
 
@@ -502,7 +500,7 @@ CAMLprim value process_stdin_write( value vp, value str, value pos, value len )
 		DWORD nbytes;
 		if( !WriteFile(p->iwrite,val_string(str)+val_int(pos),val_int(len),&nbytes,NULL) )
 			neko_error();
-		return alloc_int(nbytes);
+		CAMLreturn(alloc_int(nbytes));
 	}
 #	else
 	int nbytes;
@@ -512,7 +510,7 @@ CAMLprim value process_stdin_write( value vp, value str, value pos, value len )
 		HANDLE_EINTR(stdin_write_again);
 		neko_error();
 	}
-	return alloc_int(nbytes);
+	CAMLreturn(alloc_int(nbytes));
 #	endif
 }
 
@@ -523,9 +521,8 @@ CAMLprim value process_stdin_write( value vp, value str, value pos, value len )
 	</doc>
 **/
 CAMLprim value process_stdin_close( value vp ) {
-	vprocess *p;
-	val_check_kind(vp,k_process);
-	p = val_process(vp);
+	CAMLparam1(vp);
+	vprocess *p = val_process(vp);
 #	ifdef _WIN32
 	if( !CloseHandle(p->iwrite) )
 		neko_error();
@@ -534,7 +531,7 @@ CAMLprim value process_stdin_close( value vp ) {
 		neko_error();
 	p->iwrite = -1;
 #	endif
-	return val_null;
+	CAMLreturn(val_null);
 }
 
 /**
@@ -544,16 +541,15 @@ CAMLprim value process_stdin_close( value vp ) {
 	</doc>
 **/
 CAMLprim value process_exit( value vp ) {
-	vprocess *p;
-	val_check_kind(vp,k_process);
-	p = val_process(vp);
+	CAMLparam1(vp);
+	vprocess *p = val_process(vp);
 #	ifdef _WIN32
 	{
 		DWORD rval;
 		WaitForSingleObject(p->pinf.hProcess,INFINITE);
 		if( !GetExitCodeProcess(p->pinf.hProcess,&rval) )
 			neko_error();
-		return alloc_int(rval);
+		CAMLreturn(alloc_int(rval));
 	}
 #	else
 	int rval;
@@ -564,7 +560,7 @@ CAMLprim value process_exit( value vp ) {
 	}
 	if( !WIFEXITED(rval) )
 		neko_error();
-	return alloc_int(WEXITSTATUS(rval));
+	CAMLreturn(alloc_int(WEXITSTATUS(rval)));
 #	endif
 }
 
@@ -575,13 +571,12 @@ CAMLprim value process_exit( value vp ) {
 	</doc>
 **/
 CAMLprim value process_pid( value vp ) {
-	vprocess *p;
-	val_check_kind(vp,k_process);
-	p = val_process(vp);
+	CAMLparam1(vp);
+	vprocess *p = val_process(vp);
 #	ifdef _WIN32
-	return alloc_int(p->pinf.dwProcessId);
+	CAMLreturn(alloc_int(p->pinf.dwProcessId));
 #	else
-	return alloc_int(p->pid);
+	CAMLreturn(alloc_int(p->pid));
 #	endif
 }
 
@@ -592,11 +587,10 @@ CAMLprim value process_pid( value vp ) {
 	</doc>
 **/
 CAMLprim value process_close( value vp ) {
-	val_check_kind(vp,k_process);
+	CAMLparam1(vp);
 	free_process(vp);
 	//val_kind(vp) = NULL;
-	//val_gc(vp,NULL);
-	return val_null;
+	CAMLreturn(val_null);
 }
 
 /**
@@ -606,13 +600,13 @@ CAMLprim value process_close( value vp ) {
 	</doc>
 **/
 CAMLprim value process_kill( value vp ) {
-	val_check_kind(vp,k_process);
+	CAMLparam1(vp);
 #	ifdef _WIN32
 	TerminateProcess(val_process(vp)->pinf.hProcess,-1);
 #	else
 	kill(val_process(vp)->pid,9);
 #	endif
-	return val_null;
+	CAMLreturn(val_null);
 }
 
 

+ 130 - 0
libs/extlib-leftovers/base64.ml

@@ -0,0 +1,130 @@
+(*
+ * Base64 - Base64 codec
+ * Copyright (C) 2003 Nicolas Cannasse
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version,
+ * with the special exception on linking described in file LICENSE.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *)
+
+open ExtBytes
+
+exception Invalid_char
+exception Invalid_table
+
+external unsafe_char_of_int : int -> char = "%identity"
+
+type encoding_table = char array
+type decoding_table = int array
+
+let chars = [|
+  'A';'B';'C';'D';'E';'F';'G';'H';'I';'J';'K';'L';'M';'N';'O';'P';
+  'Q';'R';'S';'T';'U';'V';'W';'X';'Y';'Z';'a';'b';'c';'d';'e';'f';
+  'g';'h';'i';'j';'k';'l';'m';'n';'o';'p';'q';'r';'s';'t';'u';'v';
+  'w';'x';'y';'z';'0';'1';'2';'3';'4';'5';'6';'7';'8';'9';'+';'/'
+|]
+
+let make_decoding_table tbl =
+  if Array.length tbl <> 64 then raise Invalid_table;
+  let d = Array.make 256 (-1) in
+  for i = 0 to 63 do
+    Array.unsafe_set d (int_of_char (Array.unsafe_get tbl i)) i;
+  done;
+  d
+
+let inv_chars = make_decoding_table chars
+
+let encode ?(tbl=chars) ch =
+  if Array.length tbl <> 64 then raise Invalid_table;
+  let data = ref 0 in
+  let count = ref 0 in
+  let flush() =
+    if !count > 0 then begin
+      let d = (!data lsl (6 - !count)) land 63 in
+      IO.write ch (Array.unsafe_get tbl d);
+    end;    
+  in
+  let write c =
+    let c = int_of_char c in
+    data := (!data lsl 8) lor c;
+    count := !count + 8;
+    while !count >= 6 do
+      count := !count - 6;
+      let d = (!data asr !count) land 63 in
+      IO.write ch (Array.unsafe_get tbl d)
+    done;
+  in
+  let output s p l =
+    for i = p to p + l - 1 do
+      write (Bytes.unsafe_get s i)
+    done;
+    l
+  in
+  IO.create_out ~write ~output
+    ~flush:(fun () -> flush(); IO.flush ch)
+    ~close:(fun() -> flush(); IO.close_out ch)
+
+let decode ?(tbl=inv_chars) ch =
+  if Array.length tbl <> 256 then raise Invalid_table;
+  let data = ref 0 in
+  let count = ref 0 in
+  let rec fetch() =
+    if !count >= 8 then begin
+      count := !count - 8;
+      let d = (!data asr !count) land 0xFF in
+      unsafe_char_of_int d
+    end else
+      let c = int_of_char (IO.read ch) in
+      let c = Array.unsafe_get tbl c in
+      if c = -1 then raise Invalid_char;
+      data := (!data lsl 6) lor c;
+      count := !count + 6;
+      fetch()
+  in
+  let read = fetch in
+  let input s p l =
+    let i = ref 0 in
+    try
+      while !i < l do
+        Bytes.unsafe_set s (p + !i) (fetch());
+        incr i;
+      done;
+      l
+    with
+      IO.No_more_input when !i > 0 ->
+        !i
+  in
+  let close() =
+    count := 0;
+    IO.close_in ch
+  in
+  IO.create_in ~read ~input ~close
+
+let str_encode ?(tbl=chars) s =
+  let ch = encode ~tbl (IO.output_bytes()) in
+  IO.nwrite_string ch s;
+  IO.close_out ch
+
+let str_decode ?(tbl=inv_chars) s =
+  let ch = decode ~tbl (IO.input_bytes s) in
+  IO.nread_string ch ((Bytes.length s * 6) / 8)
+
+let encode_string ?(tbl=chars) s =
+  let ch = encode ~tbl (IO.output_string ()) in
+  IO.nwrite_string ch s;
+  IO.close_out ch
+
+let decode_string ?(tbl=inv_chars) s =
+  let ch = decode ~tbl (IO.input_string s) in
+  IO.nread_string ch ((String.length s * 6) / 8)

+ 65 - 0
libs/extlib-leftovers/base64.mli

@@ -0,0 +1,65 @@
+(*
+ * Base64 - Base64 codec
+ * Copyright (C) 2003 Nicolas Cannasse
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version,
+ * with the special exception on linking described in file LICENSE.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *)
+
+(** Base64 codec.
+
+  8-bit characters are encoded into 6-bit ones using ASCII lookup tables.
+  Default tables maps 0..63 values on characters A-Z, a-z, 0-9, '+' and '/'
+  (in that order). 
+*)
+
+open ExtBytes
+
+(** This exception is raised when reading an invalid character
+  from a base64 input. *)
+exception Invalid_char
+
+(** This exception is raised if the encoding or decoding table
+  size is not correct. *)
+exception Invalid_table
+
+(** An encoding table maps integers 0..63 to the corresponding char. *)
+type encoding_table = char array
+
+(** A decoding table maps chars 0..255 to the corresponding 0..63 value
+ or -1 if the char is not accepted. *)
+type decoding_table = int array
+
+(** erroneous interface, kept for compatibility use [encode_string] instead *)
+val str_encode : ?tbl:encoding_table -> string -> Bytes.t
+
+(** erroneous interface, kept for compatibility use [decode_string] instead *)
+val str_decode : ?tbl:decoding_table -> Bytes.t -> string
+
+(** Encode a string into Base64. *)
+val encode_string : ?tbl:encoding_table -> string -> string
+
+(** Decode a string encoded into Base64, raise [Invalid_char] if a
+  character in the input string is not a valid one. *)
+val decode_string : ?tbl:decoding_table -> string -> string
+
+(** Generic base64 encoding over an output. *)
+val encode : ?tbl:encoding_table -> 'a IO.output -> 'a IO.output
+
+(** Generic base64 decoding over an input. *)
+val decode : ?tbl:decoding_table -> IO.input -> IO.input
+
+(** Create a valid decoding table from an encoding one. *)
+val make_decoding_table : encoding_table -> decoding_table

+ 8 - 2
libs/extlib-leftovers/dune

@@ -1,7 +1,13 @@
 (include_subdirs no)
 
+(env
+	(_
+		(flags (-w -3 -w -27 -w -32))
+	)
+)
+
 (library
 	(name extlib_leftovers)
 	(libraries extlib)
-	(wrapped false)
-)
+	; (wrapped false)
+)

+ 5 - 5
libs/extlib-leftovers/multiArray.ml

@@ -77,7 +77,7 @@ let init len f =
 			len = len;
 			arr = imake 0 0;
 			darr = Some arr;
-		}		
+		}
 	end
 
 let make len e =
@@ -124,7 +124,7 @@ let set d idx v =
 	| None -> iset (iget d.arr (idx lsr nbits)) (idx land mask) v
 	| Some arr -> iset arr idx v
 
-let rec add d v =
+let add d v =
 	(match d.darr with
 	| None ->
 		let asize = ilen d.arr in
@@ -140,7 +140,7 @@ let rec add d v =
 	| Some arr ->
 		if d.len < ilen arr then begin
 			(* set *)
-			iset arr d.len v;			
+			iset arr d.len v;
 		end else if d.len lsl 1 >= Sys.max_array_length then begin
 			(* promote *)
 			let count = (d.len + size) lsr nbits in
@@ -180,7 +180,7 @@ let of_list src =
 	let c = create() in
 	List.iter (add c) src;
 	c
-	
+
 let iter f d = match d.darr with
 	| None ->
 	 	let max = ilen d.arr - 1 in
@@ -281,4 +281,4 @@ let fold_left f acc d = match d.darr with
 		for i = 0 to d.len - 1 do
 			acc := f !acc (iget arr i)
 		done;
-		!acc
+		!acc

+ 1 - 1
libs/extlib-leftovers/uTF8.ml

@@ -177,7 +177,7 @@ let rec iter_aux proc s i =
 
 let iter proc s = iter_aux proc s 0
 
-let compare s1 s2 = Pervasives.compare s1 s2
+let compare s1 s2 = Stdlib.compare s1 s2
 
 exception Malformed_code
 

+ 0 - 26
libs/ilib/Makefile

@@ -1,26 +0,0 @@
-OCAMLOPT=ocamlopt
-OCAMLC=ocamlc
-
-SRCS=peData.ml peReader.ml peWriter.ml ilMeta.mli ilData.mli ilMetaTools.ml ilMetaDebug.ml ilMetaReader.ml
-
-all: native bytecode
-
-native: ilib.cmxa
-bytecode: ilib.cma
-
-ilib.cmxa: $(SRCS)
-	ocamlfind $(OCAMLOPT) -g -package extlib -safe-string -a -o ilib.cmxa $(SRCS)
-
-ilib.cma: $(SRCS)
-	ocamlfind $(OCAMLC) -g -package extlib -safe-string -a -o ilib.cma $(SRCS)
-
-dump: ilib.cmxa dump.ml peDataDebug.ml ilMetaDebug.ml
-	ocamlfind $(OCAMLOPT) -g -package extlib -safe-string -o dump ../extlib/extLib.cmxa ilib.cmxa peDataDebug.ml dump.ml
-
-clean:
-	rm -f ilib.cma ilib.cmxa ilib.lib ilib.a $(wildcard *.cmx) $(wildcard *.cmo) $(wildcard *.obj) $(wildcard *.o) $(wildcard *.cmi) dump
-
-.PHONY: all bytecode native clean
-
-Makefile: ;
-$(SRCS): ;

+ 0 - 38
libs/ilib/dump.ml

@@ -1,38 +0,0 @@
-open PeDataDebug;;
-open PeData;;
-open PeReader;;
-open Printf;;
-open IlData;;
-open IlMetaTools;;
-open IlMetaDebug;;
-
-let main () =
-	if Array.length Sys.argv <> 2 then
-		print_endline "Usage: dump <exe-path>"
-	else begin
-		let r = create_r (open_in Sys.argv.(1)) PMap.empty in
-		let ctx = read r in
-		let pe = ctx.pe_header in
-		print_endline (coff_header_s pe.pe_coff_header);
-		print_endline (pe_header_s pe);
-		let idata = read_idata ctx in
-		List.iter (fun t -> print_endline (idata_table_s t)) idata;
-		let clr_header = read_clr_header ctx in
-		print_endline (clr_header_s (clr_header));
-		let cache = IlMetaReader.create_cache () in
-		let meta = IlMetaReader.read_meta_tables ctx clr_header cache in
-		Hashtbl.iter (fun path _ ->
-			print_endline ("\n\nclass " ^ path_s path ^ ": ");
-			let cls = convert_class meta path in
-			List.iter (fun t -> printf "%d: <%s> " t.tnumber (if t.tname = None then "_" else Option.get t.tname)) cls.ctypes;
-			printf "\n\tis nested: %s - %s\n" (string_of_bool (cls.cenclosing <> None)) (if cls.cenclosing = None then "None" else path_s (Option.get cls.cenclosing));
-			print_endline "\tfields:";
-			List.iter (fun f -> printf "\t\t%s : %s\n" f.fname (ilsig_s f.fsig.ssig)) cls.cfields;
-			print_endline "\tmethods:";
-			List.iter (fun m -> printf "\t\t%s : %s\n" m.mname (ilsig_s m.msig.ssig)) cls.cmethods;
-			print_endline "\tprops:";
-			List.iter (fun p -> printf "\t\t%s : %s\n" p.pname (ilsig_s p.psig.ssig)) cls.cprops;
-		) meta.il_typedefs
-	end;;
-
-main()

+ 0 - 9
libs/ilib/dune

@@ -1,9 +0,0 @@
-(include_subdirs no)
-
-(library
-	(name ilib)
-	(modules_without_implementation ilData ilMeta)
-	(modules (:standard \ dump))
-	(libraries extlib)
-	(wrapped false)
-)

+ 0 - 115
libs/ilib/ilData.mli

@@ -1,115 +0,0 @@
-(*
- *  This file is part of ilLib
- *  Copyright (c)2004-2013 Haxe Foundation
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *)
-open IlMeta;;
-
-type ilpath = string list * string list * string
-
-type ilsig = IlMeta.ilsig
-
-and ilsig_norm =
-	| LVoid | LBool | LChar
-	| LInt8 | LUInt8 | LInt16
-	| LUInt16 | LInt32 | LUInt32
-	| LInt64 | LUInt64 | LFloat32
-	| LFloat64 | LString | LObject
-	| LPointer of ilsig_norm
-	| LTypedReference | LIntPtr | LUIntPtr
-	| LManagedPointer of ilsig_norm
-	| LValueType of ilpath * ilsig_norm list
-	| LClass of ilpath * ilsig_norm list
-	| LTypeParam of int
-	| LMethodTypeParam of int
-	| LVector of ilsig_norm
-	| LArray of ilsig_norm * (int option * int option) array
-	| LMethod of callconv list * ilsig_norm * (ilsig_norm list)
-	| LSentinel
-
-and ilsig_t = {
-	snorm : ilsig_norm;
-	ssig : ilsig;
-}
-
-type ilversion = int * int (* minor + major *)
-
-type ilclass = {
-	cpath : ilpath;
-	cflags : type_def_flags;
-	csuper : ilsig_t option;
-	cfields : ilfield list;
-	cmethods : ilmethod list;
-	cimplements : ilsig_t list;
-	ctypes : type_param list;
-	cprops : ilprop list;
-	cevents : ilevent list;
-	(* cevents :  *)
-	cenclosing : ilpath option;
-	cnested : ilpath list;
-  cattrs : meta_custom_attribute list;
-}
-
-and type_param = {
-	tnumber : int;
-	tflags : generic_flags;
-	tname : string option;
-	tconstraints : ilsig_t list;
-}
-
-and ilevent = {
-	ename : string;
-	eflags : event_flags;
-	eadd : (string * method_flags) option;
-	eremove : (string * method_flags) option;
-	eraise : (string * method_flags) option;
-	esig : ilsig_t;
-}
-
-and ilfield = {
-	fname : string;
-	fflags : field_flags;
-	fsig : ilsig_t;
-  fconstant : constant option;
-}
-
-and ilmethod = {
-	mname : string;
-	mflags : method_flags;
-	msig : ilsig_t;
-	margs : ilmethod_arg list;
-	mret : ilsig_t;
-	moverride : (ilpath * string) option; (* method_impl *)
-		(* refers to the signature of the declaring class *)
-	mtypes : type_param list;
-  msemantics : semantic_flags;
-}
-
-and ilmethod_arg = string * param_flags * ilsig_t
-
-and ilprop = {
-	pname : string;
-	psig : ilsig_t;
-	pflags : property_flags;
-	pget : (string * method_flags) option;
-	pset : (string * method_flags) option;
-}
-
-type ilctx = {
-	il_tables : (clr_meta DynArray.t) array;
-	il_relations : (meta_pointer, clr_meta) Hashtbl.t;
-	il_typedefs : (ilpath, meta_type_def) Hashtbl.t;
-}

+ 0 - 1204
libs/ilib/ilMeta.mli

@@ -1,1204 +0,0 @@
-(*
- *  This file is part of ilLib
- *  Copyright (c)2004-2013 Haxe Foundation
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *)
-
-open PeData;;
-
-(* useful types for describing CLI metadata *)
-type guid = string
-	(* reference from the #GUID stream *)
-type stringref = string
-	(* reference from the #Strings stream *)
-type blobref = string
-	(* reference from the #Blob stream *)
-type id = stringref
-	(* a stringref that references an identifier. *)
-	(* must begin with an alphabetic character, or the following characters: *)
-		(* #, $, @, _ *)
-	(* and continue with alphanumeric characters or one of the following: *)
-		(* ?, $, @, _, ` *)
-
-type ns = id list
-
-type rid = int
-	(* record id on a specified meta table *)
-
-type clr_meta_idx =
-	(* strongly-type each table index *)
-	| IModule | ITypeRef | ITypeDef | IFieldPtr
-	| IField | IMethodPtr | IMethod | IParamPtr
-	| IParam | IInterfaceImpl | IMemberRef | IConstant
-	| ICustomAttribute | IFieldMarshal | IDeclSecurity
-	| IClassLayout | IFieldLayout | IStandAloneSig
-	| IEventMap | IEventPtr | IEvent | IPropertyMap
-	| IPropertyPtr | IProperty | IMethodSemantics
-	| IMethodImpl | IModuleRef | ITypeSpec | IImplMap
-	| IFieldRVA | IENCLog | IENCMap | IAssembly
-	| IAssemblyProcessor | IAssemblyOS | IAssemblyRef
-	| IAssemblyRefProcessor | IAssemblyRefOS
-	| IFile | IExportedType | IManifestResource | INestedClass
-	| IGenericParam | IMethodSpec | IGenericParamConstraint
-	(* reserved metas *)
-	| IR0x2D | IR0x2E | IR0x2F
-	| IR0x30 | IR0x31 | IR0x32 | IR0x33 | IR0x34 | IR0x35 | IR0x36 | IR0x37 
-	| IR0x38 | IR0x39 | IR0x3A | IR0x3B | IR0x3C | IR0x3D | IR0x3E | IR0x3F
-	(* coded tokens *)
-	| ITypeDefOrRef | IHasConstant | IHasCustomAttribute
-	| IHasFieldMarshal | IHasDeclSecurity | IMemberRefParent
-	| IHasSemantics | IMethodDefOrRef | IMemberForwarded | IImplementation
-	| ICustomAttributeType | IResolutionScope | ITypeOrMethodDef
-
-type meta_pointer = clr_meta_idx * rid
-	(* generic reference to the meta table *)
-
-(* starting with all annotations of special coded types *)
-type type_def_or_ref = clr_meta
-and has_const = clr_meta
-and has_custom_attribute = clr_meta
-and has_field_marshal = clr_meta
-and has_decl_security = clr_meta
-and member_ref_parent = clr_meta
-and has_semantics = clr_meta
-and method_def_or_ref = clr_meta
-and member_forwarded = clr_meta
-and implementation = clr_meta
-and custom_attribute_type = clr_meta
-and resolution_scope = clr_meta
-and type_or_method_def = clr_meta
-
-and clr_meta =
-	| Module of meta_module
-		(* the current module descriptor *)
-	| TypeRef of meta_type_ref
-		(* class reference descriptors *)
-	| TypeDef of meta_type_def
-		(* class or interface definition descriptors *)
-	| FieldPtr of meta_field_ptr
-		(* a class-to-fields lookup table - does not exist in optimized metadatas *)
-	| Field of meta_field
-		(* field definition descriptors *)
-	| MethodPtr of meta_method_ptr
-		(* a class-to-methods lookup table - does not exist in optimized metadatas *)
-	| Method of meta_method
-		(* method definition descriptors *)
-	| ParamPtr of meta_param_ptr
-		(* a method-to-parameters lookup table - does not exist in optimized metadatas *)
-	| Param of meta_param
-		(* parameter definition descriptors *)
-	| InterfaceImpl of meta_interface_impl
-		(* interface implementation descriptors *)
-	| MemberRef of meta_member_ref
-		(* member (field or method) reference descriptors *)
-	| Constant of meta_constant
-		(* constant value that map the default values stored in the #Blob stream to *)
-		(* respective fields, parameters and properties *)
-	| CustomAttribute of meta_custom_attribute
-		(* custom attribute descriptors *)
-	| FieldMarshal of meta_field_marshal
-		(* field or parameter marshaling descriptors for managed/unmanaged interop *)
-	| DeclSecurity of meta_decl_security
-		(* security descriptors *)
-	| ClassLayout of meta_class_layout	
-		(* class layout descriptors that hold information about how the loader should lay out respective classes *)
-	| FieldLayout of meta_field_layout
-		(* field layout descriptors that specify the offset or oridnal of individual fields *)
-	| StandAloneSig of meta_stand_alone_sig
-		(* stand-alone signature descriptors. used in two capacities: *)
-		(* as composite signatures of local variables of methods *)
-		(* and as parameters of the call indirect (calli) IL instruction *)
-	| EventMap of meta_event_map
-		(* a class-to-events mapping table. exists also in optimized metadatas *)
-	| EventPtr of meta_event_ptr
-		(* an event map-to-events lookup table - does not exist in optimized metadata *)
-	| Event of meta_event
-		(* event descriptors *)
-	| PropertyMap of meta_property_map
-		(* a class-to-properties mapping table. exists also in optimized metadatas *)
-	| PropertyPtr of meta_property_ptr
-		(* a property map-to-properties lookup table - does not exist in optimized metadata *)
-	| Property of meta_property
-		(* property descriptors *)
-	| MethodSemantics of meta_method_semantics
-		(* method semantics descriptors that hold information about which method is associated *)
-		(* with a specific property or event and in what capacity *)
-	| MethodImpl of meta_method_impl
-		(* method implementation descriptors *)
-	| ModuleRef of meta_module_ref
-		(* module reference descriptors *)
-	| TypeSpec of meta_type_spec
-		(* Type specification descriptors *)
-	| ImplMap of meta_impl_map
-		(* implementation map descriptors used for platform invocation (P/Invoke) *)
-	| FieldRVA of meta_field_rva
-		(* field-to-data mapping descriptors *)
-	| ENCLog of meta_enc_log
-		(* edit-and-continue log descriptors that hold information about what changes *)
-		(* have been made to specific metadata items during in-memory editing *)
-		(* this table does not exist on optimized metadata *)
-	| ENCMap of meta_enc_map
-		(* edit-and-continue mapping descriptors. does not exist on optimized metadata *)
-	| Assembly of meta_assembly
-		(* the current assembly descriptor, which should appear only in the prime module metadata *)
-	| AssemblyProcessor of meta_assembly_processor | AssemblyOS of meta_assembly_os
-		(* unused *)
-	| AssemblyRef of meta_assembly_ref
-		(* assembly reference descriptors *)
-	| AssemblyRefProcessor of meta_assembly_ref_processor | AssemblyRefOS of meta_assembly_ref_os
-		(* unused *)
-	| File of meta_file
-		(* file descriptors that contain information about other files in the current assembly *)
-	| ExportedType of meta_exported_type
-		(* exported type descriptors that contain information about public classes *)
-		(* exported by the current assembly, which are declared in other modules of the assembly *)
-		(* only the prime module of the assembly should carry this table *)
-	| ManifestResource of meta_manifest_resource
-		(* managed resource descriptors *)
-	| NestedClass of meta_nested_class
-		(* nested class descriptors that provide mapping of nested classes to their respective enclosing classes *)
-	| GenericParam of meta_generic_param
-		(* type parameter descriptors for generic classes and methods *)
-	| MethodSpec of meta_method_spec
-		(* generic method instantiation descriptors *)
-	| GenericParamConstraint of meta_generic_param_constraint
-		(* descriptors of constraints specified for type parameters of generic classes and methods *)
-	| UnknownMeta of int
-
-(* all fields here need to be mutable, as they will first be initialized empty *)
-
-and meta_root = {
-	root_id : int;
-}
-
-and meta_root_ptr = {
-	ptr_id : int;
-	ptr_to : meta_root;
-}
-
-and meta_module = {
-	mutable md_id : int;
-	mutable md_generation : int;
-	mutable md_name : id;
-	mutable md_vid : guid;
-	mutable md_encid : guid;
-	mutable md_encbase_id : guid;
-}
-
-and meta_type_ref = {
-	mutable tr_id : int;
-	mutable tr_resolution_scope : resolution_scope;
-	mutable tr_name : id;
-	mutable tr_namespace : ns;
-}
-
-and meta_type_def = {
-	mutable td_id : int;
-	mutable td_flags : type_def_flags;
-	mutable td_name : id;
-	mutable td_namespace : ns;
-	mutable td_extends : type_def_or_ref option;
-	mutable td_field_list : meta_field list;
-	mutable td_method_list : meta_method list;
-
-	(* extra field *)
-	mutable td_extra_enclosing : meta_type_def option;
-}
-
-and meta_field_ptr = {
-	mutable fp_id : int;
-	mutable fp_field : meta_field;
-}
-
-and meta_field = {
-	mutable f_id : int;
-	mutable f_flags : field_flags;
-	mutable f_name : id;
-	mutable f_signature : ilsig;
-}
-
-and meta_method_ptr = {
-	mutable mp_id : int;
-	mutable mp_method : meta_method;
-}
-
-and meta_method = {
-	mutable m_id : int;
-	mutable m_rva : rva;
-	mutable m_flags : method_flags;
-	mutable m_name : id;
-	mutable m_signature : ilsig;
-	mutable m_param_list : meta_param list; (* rid: Param *)
-
-	(* extra field *)
-	mutable m_declaring : meta_type_def option;
-}
-
-and meta_param_ptr = {
-	mutable pp_id : int;
-	mutable pp_param : meta_param;
-}
-
-and meta_param = {
-	mutable p_id : int;
-	mutable p_flags : param_flags;
-	mutable p_sequence : int;
-		(* 0 means return value *)
-	mutable p_name : id;
-}
-
-and meta_interface_impl = {
-	mutable ii_id : int;
-	mutable ii_class : meta_type_def; (* TypeDef rid *)
-	mutable ii_interface : type_def_or_ref;
-}
-
-and meta_member_ref = {
-	mutable memr_id : int;
-	mutable memr_class : member_ref_parent;
-	mutable memr_name : id;
-	mutable memr_signature : ilsig;
-}
-
-and meta_constant = {
-	mutable c_id : int;
-	mutable c_type : constant_type;
-	mutable c_parent : has_const;
-	mutable c_value : constant;
-}
-
-and named_attribute = bool * string * instance (* is_property * name * instance *)
-
-and meta_custom_attribute = {
-	mutable ca_id : int;
-	mutable ca_parent : has_custom_attribute;
-	mutable ca_type : custom_attribute_type;
-	mutable ca_value : (instance list * named_attribute list) option;
-		(* can be 0 *)
-}
-
-and meta_field_marshal = {
-	mutable fm_id : int;
-	mutable fm_parent : has_field_marshal;
-	mutable fm_native_type : nativesig;
-}
-
-and meta_decl_security = {
-	mutable ds_id : int;
-	mutable ds_action : action_security;
-	mutable ds_parent : has_decl_security;
-	mutable ds_permission_set : blobref;
-		(* an xml with the permission set *)
-}
-
-and meta_class_layout = {
-	mutable cl_id : int;
-	mutable cl_packing_size : int;
-		(* power of two; from 1 through 128 *)
-	mutable cl_class_size : int;
-	mutable cl_parent : meta_type_def; (* TypeDef rid *)
-}
-
-and meta_field_layout = {
-	mutable fl_id : int;
-	mutable fl_offset : int;
-		(* offset in bytes or ordinal *)
-	mutable fl_field : meta_field; (* Field rid *)
-}
-
-and meta_stand_alone_sig = {
-	mutable sa_id : int;
-	mutable sa_signature : ilsig;
-}
-
-and meta_event_map = {
-	mutable em_id : int;
-	mutable em_parent : meta_type_def; (* TypeDef rid *)
-	mutable em_event_list : meta_event list; (* Event rid *)
-}
-
-and meta_event_ptr = {
-	mutable ep_id : int;
-	mutable ep_event : meta_event; (* Event rid *)
-}
-
-and meta_event = {
-	mutable e_id : int;
-	mutable e_flags : event_flags;
-	mutable e_name : stringref;
-	mutable e_event_type : type_def_or_ref;
-}
-
-and meta_property_map = {
-	mutable pm_id : int;
-	mutable pm_parent : meta_type_def; (* TypeDef rid *)
-	mutable pm_property_list : meta_property list; (* Property rid *)
-}
-
-and meta_property_ptr = {
-	mutable prp_id : int;
-	mutable prp_property : meta_property; (* Property rid *)
-}
-
-and meta_property = {
-	mutable prop_id : int;
-	mutable prop_flags : property_flags;
-	mutable prop_name : stringref;
-	mutable prop_type : ilsig;
-}
-
-and meta_method_semantics = {
-	mutable ms_id : int;
-	mutable ms_semantic : semantic_flags;
-	mutable ms_method : meta_method; (* Method rid *)
-	mutable ms_association : has_semantics;
-}
-
-and meta_method_impl = {
-	mutable mi_id : int;
-	mutable mi_class : meta_type_def; (* TypeDef rid *)
-	mutable mi_method_body : method_def_or_ref;
-		(* overriding method *)
-	mutable mi_method_declaration : method_def_or_ref;
-		(* overridden method *)
-}
-
-and meta_module_ref = {
-	mutable modr_id : int;
-	mutable modr_name : stringref;
-}
-
-and meta_type_spec = {
-	mutable ts_id : int;
-	mutable ts_signature : ilsig;
-}
-
-(* reserved ? *)
-and meta_enc_log = {
-	mutable el_id : int;
-	mutable el_token : to_det;
-	mutable el_func_code : to_det;
-}
-
-and meta_impl_map = {
-	mutable im_id : int;
-	mutable im_flags : impl_flags; (* mapping_flags *)
-	mutable im_forwarded : member_forwarded; (* method only *)
-	mutable im_import_name : stringref;
-	mutable im_import_scope : meta_module_ref; (* ModuleRef rid *)
-}
-
-(* reserved ? *)
-and meta_enc_map = {
-	mutable encm_id : int;
-	mutable encm_token : to_det;
-}
-
-and meta_field_rva = {
-	mutable fr_id : int;
-	mutable fr_rva : rva;
-	mutable fr_field : meta_field; (* Field rid *)
-}
-
-and meta_assembly = {
-	mutable a_id : int;
-	mutable a_hash_algo : hash_algo;
-	mutable a_major : int;
-	mutable a_minor : int;
-	mutable a_build : int;
-	mutable a_rev : int;
-	mutable a_flags : assembly_flags; (* assembly_flags *)
-	mutable a_public_key : blobref;
-	mutable a_name : stringref;
-	mutable a_locale : stringref;
-}
-
-(* unused *)
-and meta_assembly_processor = {
-	mutable ap_id : int;
-	mutable ap_processor : to_det;
-}
-
-(* unused *)
-and meta_assembly_os = {
-	mutable aos_id : int;
-	mutable aos_platform_id : to_det;
-	mutable aos_major_version : to_det;
-	mutable aos_minor_version : to_det;
-}
-
-and meta_assembly_ref = {
-	mutable ar_id : int;
-	mutable ar_major : int;
-	mutable ar_minor : int;
-	mutable ar_build : int;
-	mutable ar_rev : int;
-	mutable ar_flags : assembly_flags;
-	mutable ar_public_key : blobref;
-	mutable ar_name : stringref; (* no path, no extension *)
-	mutable ar_locale : stringref;
-	mutable ar_hash_value : blobref;
-}
-
-(* unused *)
-and meta_assembly_ref_processor = {
-	mutable arp_id : int;
-	mutable arp_processor : to_det;
-	mutable arp_assembly_ref : meta_assembly_ref; (* AssemblyRef rid *)
-}
-
-(* unused *)
-and meta_assembly_ref_os = {
-	mutable aros_id : int;
-	mutable aros_platform_id : to_det;
-	mutable aros_major : int;
-	mutable aros_minor : int;
-	mutable aros_assembly_ref : meta_assembly_ref; (* AssemblyRef rid *)
-}
-
-and meta_file = {
-	mutable file_id : int;
-	mutable file_flags : file_flag; (* file_flags *)
-	mutable file_name : stringref; (* no path; only file name *)
-	mutable file_hash_value : blobref;
-}
-
-and meta_exported_type = {
-	mutable et_id : int;
-	mutable et_flags : type_def_flags;
-	mutable et_type_def_id : int;
-		(* TypeDef token in another module *)
-	mutable et_type_name : stringref;
-	mutable et_type_namespace : ns;
-	mutable et_implementation : implementation;
-}
-
-and meta_manifest_resource = {
-	mutable mr_id : int;
-	mutable mr_offset : int;
-	mutable mr_flags : manifest_resource_flag; (* manifest_resource_flags *)
-	mutable mr_name : stringref;
-	mutable mr_implementation : implementation option;
-}
-
-and meta_nested_class = {
-	mutable nc_id : int;
-	mutable nc_nested : meta_type_def; (* TypeDef rid *)
-	mutable nc_enclosing : meta_type_def; (* TypeDef rid *)
-}
-
-and meta_generic_param = {
-	mutable gp_id : int;
-	mutable gp_number : int; (* ordinal *)
-	mutable gp_flags : generic_flags;
-	mutable gp_owner : type_or_method_def;
-		(* generic type or method *)
-	mutable gp_name : stringref option;
-}
-
-and meta_method_spec = {
-	mutable mspec_id : int;
-	mutable mspec_method : method_def_or_ref;
-		(* instantiated method *)
-	mutable mspec_instantiation : ilsig;
-		(* instantiated signature *)
-}
-
-and meta_generic_param_constraint = {
-	mutable gc_id : int;
-	mutable gc_owner : meta_generic_param; (* GenericParam rid *)
-		(* constrained parameter *)
-	mutable gc_constraint : type_def_or_ref;
-		(* type the parameter must extend or implement *)
-}
-
-and to_det = int
-
-and not_implemented = int
-
-and constant =
-	| IBool of bool
-	| IChar of int
-	| IByte of int
-	| IShort of int
-	| IInt of int32
-	| IInt64 of int64
-	| IFloat32 of float
-	| IFloat64 of float
-	| IString of string
-	| INull
-
-and instance =
-	| InstConstant of constant
-	| InstBoxed of instance
-	| InstType of string
-	| InstArray of instance list
-	| InstEnum of int
-
-and constant_type =
-	| CBool (* 0x2 *)
-	| CChar (* 0x3 *)
-	| CInt8 (* 0x4 *)
-	| CUInt8 (* 0x5 *)
-	| CInt16 (* 0x6 *)
-	| CUInt16 (* 0x7 *)
-	| CInt32 (* 0x8 *)
-	| CUInt32 (* 0x9 *)
-	| CInt64 (* 0xA *)
-	| CUInt64 (* 0xB *)
-	| CFloat32 (* 0xC *)
-	| CFloat64 (* 0xD *)
-	| CString (* 0xE *)
-	| CNullRef (* 0x12 *)
-		(* null object reference - the value of the constant *)
-		(* of this type must be a 4-byte integer containing 0 *)
-
-and type_def_vis =
-	(* visibility flags - mask 0x7 *)
-	| VPrivate (* 0x0 *)
-		(* type is not visible outside the assembly. default *)
-	| VPublic (* 0x1 *)
-		(* type visible outside the assembly *)
-	| VNestedPublic (* 0x2 *)
-		(* the nested type has public visibility *)
-	| VNestedPrivate (* 0x3 *)
-		(* nested type has private visibility - it's not visible outside the enclosing class *)
-	| VNestedFamily (* 0x4 *)
-		(* nested type has family visibility - it's visible to descendants of the enclosing class only *)
-	| VNestedAssembly (* 0x5 *)
-		(* nested type visible within the assembly only *)
-	| VNestedFamAndAssem (* 0x6 *)
-		(* nested type is visible to the descendants of the enclosing class residing in the same assembly *)
-	| VNestedFamOrAssem (* 0x7 *)
-		(* nested type is visible to the descendants of the enclosing class either within *)
-		(* or outside the assembly and to every type within the assembly *)
-	
-and type_def_layout =
-	(* layout flags - mask 0x18 *)
-	| LAuto (* 0x0 *)
-		(* type fields are laid out automatically *)
-	| LSequential (* 0x8 *)
-		(* loader must preserve the order of the instance fields *)
-	| LExplicit (* 0x10 *)
-		(* type layout is specified explicitly *)
-
-and type_def_semantics =
-	(* semantics flags - mask 0x5A0 *)
-	| SInterface (* 0x20 *)
-		(* type is an interface. If specified, the default parent is set to nil *)
-	| SAbstract (* 0x80 *)
-	| SSealed (* 0x100 *)
-	| SSpecialName (* 0x400 *)
-		(* type has a special name. how special depends on the name itself *)
-		(* e.g. .ctor or .cctor *)
-
-and type_def_impl =
-	(* type implementation flags - mask 0x103000 *)
-	| IImport (* 0x1000 *)
-		(* the type is imported from a COM type library *)
-	| ISerializable (* 0x2000 *)
-		(* the type can be serialized into sequential data *)
-	| IBeforeFieldInit (* 0x00100000 *)
-		(* the type can be initialized any time before the first access *)
-		(* to a static field. *)
-	
-and type_def_string =
-	(* string formatting flags - mask 0x00030000 *)
-	| SAnsi (* 0x0 *)
-		(* managed strings are marshaled to and from ANSI strings *)
-	| SUnicode (* 0x00010000 *)
-		(* managed strings are marshaled to and from UTF-16 *)
-	| SAutoChar (* 0x00020000 *)
-		(* marshaling is defined by the underlying platform *)
-
-and type_def_flags = {
-	tdf_vis : type_def_vis;
-	tdf_layout : type_def_layout;
-	tdf_semantics : type_def_semantics list;
-	tdf_impl : type_def_impl list;
-	tdf_string : type_def_string;
-}
-
-and field_access =
-	(* access flags - mask 0x07 *)
-	| FAPrivateScope (* 0x0 *)
-		(* default - exempt from the requirement of having a unique triad of owner, name and signature *)
-		(* so it must always be referenced by a FieldDef token and never by a MemberRef *)
-		(* privatescope fields are accessible from anywhere within the current module *)
-	| FAPrivate (* 0x1 *)
-		(* field is accessible from its owner and from classes nested in the field's owner. *)
-		(* global private fields are accessible from anywhere within current module *)
-	| FAFamAndAssem (* 0x2 *)
-		(* accessible from types belonging to the owner's family defined in the current assembly *)
-		(* family means the type itself and all its descendants *)
-	| FAAssembly (* 0x3 *)
-		(* accessible from types defined in the current assembly *)
-	| FAFamily (* 0x4 *)
-		(* accessible from the owner's family - defined in this or any other assembly *)
-	| FAFamOrAssem (* 0x5 *)
-		(* accessible from the owner's family and from all types defined in the current assembly *)
-	| FAPublic (* 0x6 *)
-		(* field is accessible from any type *)
-
-and field_contract =
-	(* contract flags - mask 0x02F0 *)
-	| CStatic (* 0x10 *)
-		(* static field. global fields must be static *)
-	| CInitOnly (* 0x20 *)
-		(* field can be initialized only and cannot be written to later. *)
-		(* Initialization takes place in an instance constructor (.ctor) for instance fields *)
-		(* and in a class constructor (.cctor) for static fields. *)
-		(* this flag is not enforced by the CLR *)
-	| CLiteral (* 0x40 *)
-		(* field is a compile-time constant. the loader does not lay out this field *)
-		(* and does not create an internal handle for it *)
-		(* it cannot be directly addressed from IL and can only be used as a Reflection reference *)
-	| CNotSerialized (* 0x80 *)
-		(* field is not serialized when the owner is remoted *)
-	| CSpecialName (* 0x200 *)
-		(* the field is special in some way, as defined by its name *)
-		(* example is the field value__ of an enumeration type *)
-
-and field_reserved = 
-	(* reserved flags - cannot be set explicitly. mask 0x9500 *)
-	| RSpecialName (* 0x400 *)
-		(* has a special name that is reserved for internal use of the CLR *)
-		(* two field names are reserved: value_, for instance fields in enumerations *)
-		(* and _Deleted* for fields marked for deletion but not actually removed from metadata *)
-	| RMarshal (* 0x1000 *)
-		(* The field has an associated FieldMarshal record specifying how the field must be *)
-		(* marshaled when consumed by unmanaged code. *)
-	| RConstant (* 0x8000 *)
-		(* field has an associated Constant record *)
-	| RFieldRVA (* 0x0100 *)
-		(* field is mapped to data and has an associated FieldRVA record *)
-
-and field_flags = {
-	ff_access : field_access;
-	ff_contract : field_contract list;
-	ff_reserved : field_reserved list;
-}
-
-and method_contract =
-	(* contract flags - mask 0xF0 *)
-	| CMStatic (* 0x10 *)
-	| CMFinal (* 0x20 *)
-		(* must be paired with the virtual flag - otherwise it is meaningless *)
-	| CMVirtual (* 0x40 *)
-	| CMHideBySig (* 0x80 *)
-		(* the method hides all methods of the parent classes that have a matching *)
-		(* signature and name (as opposed to having a matching name only). ignored by the CLR *)
-
-and method_vtable =
-	(* vtable flags - mask 0x300 *)
-	| VNewSlot (* 0x100 *)
-		(* a new vtable slot is created, so it doesn't override the old implementation *)
-	| VStrict (* 0x200 *)
-		(* virtual method can be overridden only if it is accessible from the overriding class *)
-
-and method_impl =
-	(* implementation flags - mask 0x2C08 *)
-	| IAbstract (* 0x0400 *)
-	| ISpecialName (* 0x0800 *)
-	| IPInvokeImpl (* 0x2000 *)
-		(* the method has an unmanaged implementation and is called through the platform *)
-		(* invocation mechanism. the rva field must be 0, since the method is implemented externally *)
-	| IUnmanagedExp (* 0x0008 *)
-		(* the managed method is exposed as an unmanaged export. not used by the CLR currently *)
-
-and method_reserved =
-	(* reserved flags - cannot be set explicitly. mask 0xD000 *)
-	| RTSpecialName (* 0x1000 *)
-		(* has a special name: .ctor, .cctor, _VtblGap* and _Deleted* *)
-	| RHasSecurity (* 0x4000 *)
-		(* either has an associated DeclSecurity metadata or the custom attribte *)
-		(* System.Security.SuppressUnmanagedCodeSecurityAttribute *)
-	| RReqSecObj (* 0x8000 *)
-		(* this method calls another method containing security code, so it requires *)
-		(* an additional stack slot for a security object. *)
-
-and method_code_type =
-	(* code type - mask 0x3 *)
-	| CCil (* 0x0 *)
-	| CNative (* 0x1 *)
-		(* implemented in native platform-specific code *)
-	| COptIl (* 0x2 *)
-		(* optimized il - not supported; must not be set *)
-	| CRuntime (* 0x3 *)
-		(* automatically generated by the runtime itself (intrinsic) *)
-
-and method_code_mngmt =
-	(* code management - mask 0x4 *)
-	| MManaged (* 0x0 *)
-	| MUnmanaged (* 0x4 *)
-		(* must be paired with the native flag *)
-
-and method_interop =
-	(* method implementation and interop - mask 0x10D8 *)
-	| OForwardRef (* 0x10 *)
-		(* managed object fiels and edit-and-continue scenarios only *)
-	| OPreserveSig (* 0x80 *)
-		(* method signature must not be mangled during interop with classic COM code *)
-	| OInternalCall (* 0x1000 *)
-		(* reserved for internal use. if set, RVA must be 0 *)
-	| OSynchronized (* 0x20 *)
-		(* automatically insert code to take a lock on entry to the method and release it *)
-		(* on exit from the method. Value types cannot have this flag set *)
-	| ONoInlining (* 0x08 *)
-		(* the runtime is not allowed to inline the method *)
-
-and method_flags = {
-	mf_access : field_access;
-	mf_contract : method_contract list;
-	mf_vtable : method_vtable list;
-	mf_impl : method_impl list;
-	mf_reserved : method_reserved list;
-	mf_code_type : method_code_type;
-	mf_code_mngmt : method_code_mngmt;
-	mf_interop : method_interop list;
-}
-
-and param_io =
-	(* input/output flags - mask 0x13 *)
-	| PIn (* 0x1 *)
-	| POut (* 0x2 *)
-	| POpt (* 0x10 *)
-
-and param_reserved =
-	(* reserved flags - mask 0xF000 *)
-	| PHasConstant (* 0x1000 *)
-		(* the parameter has an associated Constant record *)
-	| PMarshal (* 0x2000 *)
-		(* the parameter has an associated FieldMarshal record specifying how the parameter *)
-		(* must be marshaled when consumed by unmanaged code *)
-
-and param_flags = {
-	pf_io : param_io list;
-	pf_reserved : param_reserved list;
-}
-
-and event_flag =
-	| ESpecialName (* 0x0200 *)
-		(* event is special *)
-	| ERTSpecialName (* 0x0400 *)
-		(* CLI provides special behavior, depending on the name of the event *)
-
-and event_flags = event_flag list
-
-and property_flag =
-	| PSpecialName (* 0x0200 *)
-		(* property is special *)
-	| PRTSpecialName (* 0x0400 *)
-		(* runtime (intrinsic) should check name encoding *)
-	| PHasDefault (* 0x1000 *)
-		(* property has default *)
-	| PUnused (* 0xE9FF *)
-		(* reserved *)
-
-and property_flags = property_flag list
-
-and semantic_flag =
-	| SSetter (* 0x0001 *)
-		(* setter for property *)
-	| SGetter (* 0x0002 *)
-		(* getter for property *)
-	| SOther (* 0x0004 *)
-		(* other method for property or event *)
-	| SAddOn (* 0x0008 *)
-		(* addon method for event - refers to the required add_ method for events *)
-	| SRemoveOn (* 0x0010 *)
-		(* removeon method for event - refers to the required remove_ method for events *)
-	| SFire (* 0x0020 *)
-		(* fire method for event. this refers to the optional raise_ method for events *)
-
-and semantic_flags = semantic_flag list
-
-and action_security =
-	| SecNull
-	| SecRequest (* 0x1 *)
-	| SecDemand (* 0x2 *)
-	| SecAssert (* 0x3 *)
-	| SecDeny (* 0x4 *)
-	| SecPermitOnly (* 0x5 *)
-	| SecLinkCheck (* 0x6 *)
-	| SecInheritCheck (* 0x7 *)
-	| SecReqMin (* 0x8 *)
-	| SecReqOpt (* 0x9 *)
-	| SecReqRefuse (* 0xA *)
-	| SecPreJitGrant (* 0xB *)
-	| SecPreJitDeny (* 0xC *)
-	| SecNonCasDemand (* 0xD *)
-	| SecNonCasLinkDemand (* 0xE *)
-	| SecNonCasInheritance (* 0xF *)
-
-and impl_charset =
-	| IDefault (* 0x0 *)
-	| IAnsi (* 0x2 *)
-		(* method parameters of type string must be marshaled as ANSI zero-terminated *)
-		(* strings unless explicitly specified otherwise *)
-	| IUnicode (* 0x4 *)
-		(* method parameters of type string must be marshaled as Unicode strings *)
-	| IAutoChar (* 0x6 *)
-		(* method parameters of type string must be marshaled as ANSI or Unicode strings *)
-		(* depending on the platform *)
-
-and impl_callconv =
-	| IDefaultCall (* 0x0 *)
-	| IWinApi (* 0x100 *)
-		(* the native method uses the calling convention standard for the underlying platform *)
-	| ICDecl (* 0x200 *)
-		(* the native method uses the C/C++ style calling convention *)
-	| IStdCall (* 0x300 *)
-		(* native method uses the standard Win32 API calling convention *)
-	| IThisCall (* 0x400 *)
-		(* native method uses the C++ member method (non-vararg) calling convention *)
-	| IFastCall (* 0x500 *)
-
-and impl_flag =
-	| INoMangle (* 0x1 *)
-		(* exported method's name must be matched literally *)
-	| IBestFit (* 0x10 *)
-		(* allow "best fit" guessing when converting the strings *)
-	| IBestFitOff (* 0x20 *)
-		(* disallow "best fit" guessing *)
-	| ILastErr (* 0x40 *)
-		(* the native method supports the last error querying by the Win32 API GetLastError *)
-	| ICharMapError (* 0x1000 *)
-		(* throw an exception when an unmappable character is encountered in a string *)
-	| ICharMapErrorOff (* 0x2000 *)
-		(* don't throw an exception when an unmappable character is encountered *)
-	
-and impl_flags = {
-	if_charset : impl_charset;
-	if_callconv : impl_callconv;
-	if_flags : impl_flag list;
-}
-
-and hash_algo =
-	| HNone (* 0x0 *)
-	| HReserved (* 0x8003 *)
-		(* MD5 ? *)
-	| HSha1 (* 0x8004 *)
-		(* SHA1 *)
-
-and assembly_flag =
-	| APublicKey (* 0x1 *)
-		(* assembly reference holds the full (unhashed) public key *)
-	| ARetargetable (* 0x100 *)
-		(* implementation of this assembly used at runtime is not expected to match *)
-		(* the version seen at compile-time *)
-	| ADisableJitCompileOptimizer (* 0x4000 *)
-		(* Reserved *)
-	| AEnableJitCompileTracking (* 0x8000 *)
-		(* Reserved *)
-
-and assembly_flags = assembly_flag list
-
-and file_flag =
-	| ContainsMetadata (* 0x0 *)
-	| ContainsNoMetadata (* 0x1 *)
-
-and manifest_resource_flag =
-	(* mask 0x7 *)
-	| RNone (* 0x0 *)
-	| RPublic (* 0x1 *)
-	| RPrivate (* 0x2 *)
-
-and generic_variance =
-	(* mask 0x3 *)
-	| VNone (* 0x0 *)
-	| VCovariant (* 0x1 *)
-	| VContravariant (* 0x2 *)
-
-and generic_constraint =
-	(* mask 0x1C *)
-	| CInstanceType (* 0x4 *)
-		(* generic parameter has the special class constraint *)
-	| CValueType (* 0x8 *)
-		(* generic parameter has the special valuetype constraint *)
-	| CDefaultCtor (* 0x10 *)
-		(* has the special .ctor constraint *)
-
-and generic_flags = {
-	gf_variance : generic_variance;
-	gf_constraint : generic_constraint list;
-}
-
-and ilsig =
-	(* primitive types *)
-	| SVoid (* 0x1 *)
-	| SBool (* 0x2 *)
-	| SChar (* 0x3 *)
-	| SInt8 (* 0x4 *)
-	| SUInt8 (* 0x5 *)
-	| SInt16 (* 0x6 *)
-	| SUInt16 (* 0x7 *)
-	| SInt32 (* 0x8 *)
-	| SUInt32 (* 0x9 *)
-	| SInt64 (* 0xA *)
-	| SUInt64 (* 0xB *)
-	| SFloat32 (* 0xC *)
-	| SFloat64 (* 0xD *)
-	| SString (* 0xE *)
-	| SPointer of ilsig (* 0xF *)
-		(* unmanaged pointer to type ( * ) *)
-	| SManagedPointer of ilsig (* 0x10 *)
-		(* managed pointer to type ( & ) *)
-	| SValueType of type_def_or_ref (* 0x11 *)
-		(* a value type modifier, followed by TypeDef or TypeRef token *)
-	| SClass of type_def_or_ref (* 0x12 *)
-		(* a class type modifier, followed by TypeDef or TypeRef token *)
-	| STypeParam of int (* 0x13 *)
-		(* generic parameter in a generic type definition. represented by a number *)
-	| SArray of ilsig * (int option * int option) array (* 0x14 *)
-		(* ilsig * ( bound * size ) *)
-		(* a multi-dimensional array type modifier *)
-		(* encoded like: *)
-			(* SArray <underlying type><rank><num_sizes><size1>...<sizeN>
-			          <num_lower_bounds><lower_bound1>...<lower_boundM> *)
-			(* <rank> is the number of dimensions (K>0) *)
-			(* <num_sizes> num of specified sizes for dimensions (N <= K) *)
-			(* <num_lower_bounds> num of lower bounds (M <= K) *)
-			(* all int values are compressed *)
-	| SGenericInst of ilsig * (ilsig list) (* 0x15 *)
-		(* A generic type instantiation. encoded like: *)
-			(* SGenericInst <type> <type-arg-count> <type1>...<typeN> *)
-	| STypedReference (* 0x16 *)
-		(* typed reference, carrying both a reference to a type *)
-		(* and information identifying the referenced type *)
-	| SIntPtr (* 0x18 *)
-		(* pointer-sized managed integer *)
-	| SUIntPtr (* 0x19 *)
-		(* pointer-size managed unsigned integer *)
-	(* | SNativeFloat (* 0x1A *) *)
-		(* refer to http://stackoverflow.com/questions/13961205/native-float-type-usage-in-clr *)
-	| SFunPtr of callconv list * ilsig * (ilsig list) (* 0x1B *)
-		(* a pointer to a function, followed by full method signature *)
-	| SObject (* 0x1C *)
-		(* System.Object *)
-	| SVector of ilsig (* 0x1D *)
-		(* followed by the encoding of the underlying type *)
-	| SMethodTypeParam of int (* 0x1E *)
-		(* generic parameter in a generic method definition *)
-	| SReqModifier of type_def_or_ref * ilsig (* 0x1F *)
-		(* modreq: required custom modifier : indicate that the item to which they are attached *)
-		(* must be treated in a special way *)
-	| SOptModifier of type_def_or_ref * ilsig (* 0x20 *)
-		(* modopt: optional custom modifier *)
-	| SSentinel (* 0x41 *)
-		(* ... - signifies the beginning of optional arguments supplied for a vararg method call *)
-		(* This can only appear at call site, since varargs optional parameters are not specified *)
-		(* when a method is declared *)
-	| SPinned of ilsig (* 0x45 *)
-		(* pinned reference: it's only applicable to local variables only *)
-	(* special undocumented (yay) *)
-	| SType (* 0x50 *)
-	| SBoxed (* 0x51 *)
-	| SEnum of string (* 0x55 *)
-
-and callconv =
-	| CallDefault (* 0x0 *)
-	| CallCDecl (* 0x1 *)
-	| CallStdCall (* 0x2 *)
-	| CallThisCall (* 0x3 *)
-	| CallFastCall (* 0x4 *)
-	| CallVararg (* 0x5 *)
-	| CallField (* 0x6 *)
-		(* field call *)
-	| CallLocal (* 0x7 *)
-		(* local variable call *)
-	| CallProp (* 0x8 *)
-		(* property call *)
-	| CallUnmanaged (* 0x9 *)
-		(* unmanaged calling convention. not used *)
-	| CallGenericInst (* 0xA *)
-		(* generic instantiation - MethodSpec *)
-	| CallGeneric of int (* 0x10 *)
-		(* also contains the number of generic arguments *)
-	| CallHasThis (* 0x20 *)
-		(* instance method that has an instance pointer (this) *)
-		(* as an implicit first argument - ilasm 'instance' *)
-	| CallExplicitThis (* 0x40 *)
-		(* the first explicitly specified parameter is the instance pointer *)
-		(* ilasm 'explicit' *)
-	
-and nativesig =
-	| NVoid (* 0x01 *)
-		(* obsolete *)
-	| NBool (* 0x02 *)
-	| NInt8 (* 0x03 *)
-	| NUInt8 (* 0x4 *)
-	| NInt16 (* 0x5 *)
-	| NUInt16 (* 0x6 *)
-	| NInt32 (* 0x7 *)
-	| NUInt32 (* 0x8 *)
-	| NInt64 (* 0x9 *)
-	| NUInt64 (* 0xA *)
-	| NFloat32 (* 0xB *)
-	| NFloat64 (* 0xC *)
-	| NSysChar (* 0xD *)
-		(* obsolete *)
-	| NVariant (* 0xE *)
-		(* obsolete *)
-	| NCurrency (* 0xF *)
-	| NPointer (* 0x10 *)
-		(* obsolete - use NativeInt *)
-	| NDecimal (* 0x11 *)
-		(* obsolete *)
-	| NDate (* 0x12 *)
-		(* obsolete *)
-	| NBStr (* 0x13 *)
-		(* unicode VB-style: used in COM operations *)
-	| NLPStr (* 0x14 *)
-		(* pointer to a zero-terminated ANSI string *)
-	| NLPWStr (* 0x15 *)
-		(* pointer to a zero-terminated Unicode string *)
-	| NLPTStr (* 0x16 *)
-		(* pointer to a zero-terminated ANSI or Unicode string - depends on platform *)
-	| NFixedString of int (* 0x17 *)
-		(* fixed-size system string of size <size> bytes; applicable to field marshalling only *)
-	| NObjectRef (* 0x18 *)
-		(* obsolete *)
-	| NUnknown (* 0x19 *)
-		(* IUnknown interface pointer *)
-	| NDispatch (* 0x1A *)
-		(* IDispatch interface pointer *)
-	| NStruct (* 0x1B *)
-		(* C-style structure, for marshaling the formatted managed types *)
-	| NInterface (* 0x1C *)
-		(* interface pointer *)
-	| NSafeArray of variantsig (* 0x1D *)
-		(* safe array of type <variant-type> *)
-	| NFixedArray of int * variantsig (* 0x1E *)
-		(* fixed-size array, of size <size> bytes *)
-	| NIntPointer (* 0x1F *)
-		(* signed pointer-size integer *)
-	| NUIntPointer (* 0x20 *)
-		(* unsigned pointer-sized integer *)
-	| NNestedStruct (* 0x21 *)
-		(* obsolete *)
-	| NByValStr (* 0x22 *)
-		(* VB-style string in a fixed-length buffer *)
-	| NAnsiBStr (* 0x23 *)
-		(* ansi bstr - ANSI VB-style string *)
-	| NTBStr (* 0x24 *)
-		(* tbstr - bstr or ansi bstr, depending on the platform *)
-	| NVariantBool (* 0x25 *)
-		(* variant bool - 2-byte Boolean: true = -1; false = 0 *)
-	| NFunctionPtr (* 0x26 *)
-	| NAsAny (* 0x28 *)
-		(* as any - object: type defined at run time (?) *)
-	| NArray of nativesig * int * int * int (* 0x2A *)
-		(* fixed-size array of a native type *)
-		(* if size is empty, the size of the native array is derived from the size  *)
-		(* of the managed type being marshaled *)
-	| NLPStruct (* 0x2B *)
-		(* pointer to a c-style structure *)
-	| NCustomMarshaler of string * string (* 0x2C *)
-		(* custom (<class_str>, <cookie_str>) *)
-	| NError (* 0x2D *)
-		(* maps in32 to VT_HRESULT *)
-  | NCustom of int
-
-and variantsig =
-	| VT_EMPTY (* 0x00 *)
-		(* No <empty> *)
-	| VT_NULL (* 0x01 *)
-		(* No null *)
-	| VT_I2 (* 0x02 *)
-		(* Yes int16 *)
-	| VT_I4 (* 0x03 *)
-		(* Yes int32 *)
-	| VT_R4 (* 0x04 *)
-		(* Yes float32 *)
-	| VT_R8 (* 0x05 *)
-		(* Yes float64 *)
-	| VT_CY (* 0x06 *)
-		(* Yes currency *)
-	| VT_DATE (* 0x07 *)
-		(* Yes date *)
-	| VT_BSTR (* 0x08 *)
-		(* Yes bstr *)
-	| VT_DISPATCH (* 0x09 *)
-		(* Yes idispatch *)
-	| VT_ERROR (* 0x0A *)
-		(* Yes error *)
-	| VT_BOOL (* 0x0B *)
-		(* Yes bool *)
-	| VT_VARIANT (* 0x0C *)
-		(* Yes variant *)
-	| VT_UNKNOWN (* 0x0D *)
-		(* Yes iunknown *)
-	| VT_DECIMAL (* 0x0E *)
-		(* Yes decimal *)
-	| VT_I1 (* 0x10 *)
-		(* Yes int8 *)
-	| VT_UI1 (* 0x11 *)
-		(* Yes unsigned int8, uint8 *)
-	| VT_UI2 (* 0x12 *)
-		(* Yes unsigned int16, uint16 *)
-	| VT_UI4 (* 0x13 *)
-		(* Yes unsigned int32, uint32 *)
-	| VT_I8 (* 0x14 *)
-		(* No int64 *)
-	| VT_UI8 (* 0x15 *)
-		(* No unsigned int64, uint64 *)
-	| VT_INT (* 0x16 *)
-		(* Yes int *)
-	| VT_UINT (* 0x17 *)
-		(* Yes unsigned int, uint *)
-	| VT_VOID (* 0x18 *)
-		(* No void *)
-	| VT_HRESULT (* 0x19 *)
-		(* No hresult *)
-	| VT_PTR (* 0x1A *)
-		(* No * *)
-	| VT_SAFEARRAY (* 0x1B *)
-		(* No safearray *)
-	| VT_CARRAY (* 0x1C *)
-		(* No carray *)
-	| VT_USERDEFINED (* 0x1D *)
-		(* No userdefined *)
-	| VT_LPSTR (* 0x1E *)
-		(* No lpstr *)
-	| VT_LPWSTR (* 0x1F *)
-		(* No lpwstr *)
-	| VT_RECORD (* 0x24 *)
-		(* Yes record *)
-	| VT_FILETIME (* 0x40 *)
-		(* No filetime *)
-	| VT_BLOB (* 0x41 *)
-		(* No blob *)
-	| VT_STREAM (* 0x42 *)
-		(* No stream *)
-	| VT_STORAGE (* 0x43 *)
-		(* No storage *)
-	| VT_STREAMED_OBJECT (* 0x44 *)
-		(* No streamed_object *)
-	| VT_STORED_OBJECT (* 0x45 *)
-		(* No stored_object *)
-	| VT_BLOB_OBJECT (* 0x46 *)
-		(* No blob_object *)
-	| VT_CF (* 0x47 *)
-		(* No cf *)
-	| VT_CLSID (* 0x48 *)
-		(* No clsid *)
-	(* | VT_VECTOR of variantsig (* 0x1000 *) *)
-	(* 	(* Yes <v_type> vector *) *)
-	(* | VT_ARRAY of variantsig (* 0x2000 *) *)
-	(* 	(* Yes <v_type> [ ] *) *)
-	(* | VT_BYREF of variantsig (* 0x4000 *) *)
-	(* 	(* Yes <v_type> & *) *)

+ 0 - 24
libs/ilib/ilMetaDebug.ml

@@ -1,24 +0,0 @@
-(*
- *  This file is part of ilLib
- *  Copyright (c)2004-2013 Haxe Foundation
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *)
-open IlMeta;;
-open IlMetaTools;;
-
-let path_s = IlMetaTools.path_s
-let ilsig_s = IlMetaTools.ilsig_s
-let instance_s = IlMetaTools.instance_s

+ 0 - 2403
libs/ilib/ilMetaReader.ml

@@ -1,2403 +0,0 @@
-(*
- *  This file is part of ilLib
- *  Copyright (c)2004-2013 Haxe Foundation
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *)
-
-open PeData;;
-open PeReader;;
-open IlMeta;;
-open IO;;
-open Printf;;
-open IlMetaTools;;
-open ExtString;;
-open IlData;;
-
-(* *)
-let get_field = function
-	| Field f -> f
-	| _ -> assert false
-
-let get_method = function
-	| Method m -> m
-	| _ -> assert false
-
-let get_param = function
-	| Param p -> p
-	| _ -> assert false
-
-let get_type_def = function
-	| TypeDef p -> p
-	| _ -> assert false
-
-let get_event = function
-	| Event e -> e
-	| _ -> assert false
-
-let get_property = function
-	| Property p -> p
-	| _ -> assert false
-
-let get_module_ref = function
-	| ModuleRef r -> r
-	| _ -> assert false
-
-let get_assembly_ref = function
-	| AssemblyRef r -> r
-	| _ -> assert false
-
-let get_generic_param = function
-	| GenericParam p -> p
-	| _ -> assert false
-
-(* decoding helpers *)
-let type_def_vis_of_int i = match i land 0x7 with
-	(* visibility flags - mask 0x7 *)
-	| 0x0 -> VPrivate (* 0x0 *)
-	| 0x1 -> VPublic (* 0x1 *)
-	| 0x2 -> VNestedPublic (* 0x2 *)
-	| 0x3 -> VNestedPrivate (* 0x3 *)
-	| 0x4 -> VNestedFamily (* 0x4 *)
-	| 0x5 -> VNestedAssembly (* 0x5 *)
-	| 0x6 -> VNestedFamAndAssem (* 0x6 *)
-	| 0x7 -> VNestedFamOrAssem (* 0x7 *)
-	| _ -> assert false
-
-let type_def_layout_of_int i = match i land 0x18 with
-	(* layout flags - mask 0x18 *)
-	| 0x0 -> LAuto (* 0x0 *)
-	| 0x8 -> LSequential (* 0x8 *)
-	| 0x10 -> LExplicit (* 0x10 *)
-	| _ -> assert false
-
-let type_def_semantics_of_int iprops = List.fold_left (fun acc i ->
-	if (iprops land i) = i then (match i with
-		(* semantics flags - mask 0x5A0 *)
-		| 0x20 -> SInterface (* 0x20 *)
-		| 0x80 -> SAbstract (* 0x80 *)
-		| 0x100 -> SSealed (* 0x100 *)
-		| 0x400 -> SSpecialName (* 0x400 *)
-		| _ -> assert false) :: acc
-	else
-		acc) [] [0x20;0x80;0x100;0x400]
-
-let type_def_impl_of_int iprops = List.fold_left (fun acc i ->
-	if (iprops land i) = i then (match i with
-		(* type implementation flags - mask 0x103000 *)
-		| 0x1000 -> IImport (* 0x1000 *)
-		| 0x2000 -> ISerializable (* 0x2000 *)
-		| 0x00100000 -> IBeforeFieldInit (* 0x00100000 *)
-		| _ -> assert false) :: acc
-	else
-		acc) [] [0x1000;0x2000;0x00100000]
-
-let type_def_string_of_int i = match i land 0x00030000 with
-	(* string formatting flags - mask 0x00030000 *)
-	| 0x0 -> SAnsi (* 0x0 *)
-	| 0x00010000 -> SUnicode (* 0x00010000 *)
-	| 0x00020000 -> SAutoChar (* 0x00020000 *)
-	| _ -> assert false
-
-let type_def_flags_of_int i =
-	{
-		tdf_vis = type_def_vis_of_int i;
-		tdf_layout = type_def_layout_of_int i;
-		tdf_semantics = type_def_semantics_of_int i;
-		tdf_impl = type_def_impl_of_int i;
-		tdf_string = type_def_string_of_int i;
-	}
-
-let null_type_def_flags = type_def_flags_of_int 0
-
-let field_access_of_int i = match i land 0x07 with
-	(* access flags - mask 0x07 *)
-	| 0x0 -> FAPrivateScope (* 0x0 *)
-	| 0x1 -> FAPrivate (* 0x1 *)
-	| 0x2 -> FAFamAndAssem (* 0x2 *)
-	| 0x3 -> FAAssembly (* 0x3 *)
-	| 0x4 -> FAFamily (* 0x4 *)
-	| 0x5 -> FAFamOrAssem (* 0x5 *)
-	| 0x6 -> FAPublic (* 0x6 *)
-	| _ -> assert false
-
-let field_contract_of_int iprops = List.fold_left (fun acc i ->
-	if (iprops land i) = i then (match i with
-		(* contract flags - mask 0x02F0 *)
-		| 0x10 -> CStatic (* 0x10 *)
-		| 0x20 -> CInitOnly (* 0x20 *)
-		| 0x40 -> CLiteral (* 0x40 *)
-		| 0x80 -> CNotSerialized (* 0x80 *)
-		| 0x200 -> CSpecialName (* 0x200 *)
-		| _ -> assert false) :: acc
-	else
-		acc) [] [0x10;0x20;0x40;0x80;0x200]
-
-let field_reserved_of_int iprops = List.fold_left (fun acc i ->
-	if (iprops land i) = i then (match i with
-		(* reserved flags - cannot be set explicitly. mask 0x9500 *)
-		| 0x400 -> RSpecialName (* 0x400 *)
-		| 0x1000 -> RMarshal (* 0x1000 *)
-		| 0x8000 -> RConstant (* 0x8000 *)
-		| 0x0100 -> RFieldRVA (* 0x0100 *)
-		| _ -> assert false) :: acc
-	else
-		acc) [] [0x400;0x1000;0x8000;0x100]
-
-let field_flags_of_int i =
-	{
-		ff_access = field_access_of_int i;
-		ff_contract = field_contract_of_int i;
-		ff_reserved = field_reserved_of_int i;
-	}
-
-let null_field_flags = field_flags_of_int 0
-
-let method_contract_of_int iprops = List.fold_left (fun acc i ->
-	if (iprops land i) = i then (match i with
-		(* contract flags - mask 0xF0 *)
-		| 0x10 -> CMStatic (* 0x10 *)
-		| 0x20 -> CMFinal (* 0x20 *)
-		| 0x40 -> CMVirtual (* 0x40 *)
-		| 0x80 -> CMHideBySig (* 0x80 *)
-		| _ -> assert false) :: acc
-	else
-		acc) [] [0x10;0x20;0x40;0x80]
-
-let method_vtable_of_int iprops = List.fold_left (fun acc i ->
-	if (iprops land i) = i then (match i with
-		(* vtable flags - mask 0x300 *)
-		| 0x100 -> VNewSlot (* 0x100 *)
-		| 0x200 -> VStrict (* 0x200 *)
-		| _ -> assert false) :: acc
-	else
-		acc) [] [0x100;0x200]
-
-let method_impl_of_int iprops = List.fold_left (fun acc i ->
-	if (iprops land i) = i then (match i with
-		(* implementation flags - mask 0x2C08 *)
-		| 0x0400 -> IAbstract (* 0x0400 *)
-		| 0x0800 -> ISpecialName (* 0x0800 *)
-		| 0x2000 -> IPInvokeImpl (* 0x2000 *)
-		| 0x0008 -> IUnmanagedExp (* 0x0008 *)
-		| _ -> assert false) :: acc
-	else
-		acc) [] [0x0400;0x0800;0x2000;0x0008]
-
-let method_reserved_of_int iprops = List.fold_left (fun acc i ->
-	if (iprops land i) = i then (match i with
-		(* reserved flags - cannot be set explicitly. mask 0xD000 *)
-		| 0x1000 -> RTSpecialName (* 0x1000 *)
-		| 0x4000 -> RHasSecurity (* 0x4000 *)
-		| 0x8000 -> RReqSecObj (* 0x8000 *)
-		| _ -> assert false) :: acc
-	else
-		acc) [] [0x1000;0x4000;0x8000]
-
-let method_code_type_of_int i = match i land 0x3 with
-	| 0x0 -> CCil (* 0x0 *)
-	| 0x1 -> CNative (* 0x1 *)
-	| 0x2 -> COptIl (* 0x2 *)
-	| 0x3 -> CRuntime (* 0x3 *)
-	| _ -> assert false
-
-let method_code_mngmt_of_int i = match i land 0x4 with
-	| 0x0 -> MManaged (* 0x0 *)
-	| 0x4 -> MUnmanaged (* 0x4 *)
-	| _ -> assert false
-
-let method_interop_of_int iprops = List.fold_left (fun acc i ->
-	if (iprops land i) = i then (match i with
-		| 0x10 -> OForwardRef (* 0x10 *)
-		| 0x80 -> OPreserveSig (* 0x80 *)
-		| 0x1000 -> OInternalCall (* 0x1000 *)
-		| 0x20 -> OSynchronized (* 0x20 *)
-		| 0x08 -> ONoInlining (* 0x08 *)
-		| _ -> assert false) :: acc
-	else
-		acc) [] [0x10;0x80;0x1000;0x20;0x08]
-
-let method_flags_of_int iflags flags =
-	{
-		mf_access = field_access_of_int flags;
-		mf_contract = method_contract_of_int flags;
-		mf_vtable = method_vtable_of_int flags;
-		mf_impl = method_impl_of_int flags;
-		mf_reserved = method_reserved_of_int flags;
-		mf_code_type = method_code_type_of_int iflags;
-		mf_code_mngmt = method_code_mngmt_of_int iflags;
-		mf_interop = method_interop_of_int iflags;
-	}
-
-let null_method_flags = method_flags_of_int 0 0
-
-let param_io_of_int iprops = List.fold_left (fun acc i ->
-	if (iprops land i) = i then (match i with
-		(* input/output flags - mask 0x13 *)
-		| 0x1 -> PIn (* 0x1 *)
-		| 0x2 -> POut (* 0x2 *)
-		| 0x10 -> POpt (* 0x10 *)
-		| _ -> assert false) :: acc
-	else
-		acc) [] [0x1;0x2;0x10]
-
-let param_reserved_of_int iprops = List.fold_left (fun acc i ->
-	if (iprops land i) = i then (match i with
-		(* reserved flags - mask 0xF000 *)
-		| 0x1000 -> PHasConstant (* 0x1000 *)
-		| 0x2000 -> PMarshal (* 0x2000 *)
-		| _ -> assert false) :: acc
-	else
-		acc) [] [0x1000;0x2000]
-
-let param_flags_of_int i =
-	{
-		pf_io = param_io_of_int i;
-		pf_reserved = param_reserved_of_int i;
-	}
-
-let null_param_flags = param_flags_of_int 0
-
-let callconv_of_int ?match_generic_inst:(match_generic_inst=false) i =
-	let basic = match i land 0xF with
-		| 0x0 -> CallDefault (* 0x0 *)
-		| 0x1 -> CallCDecl
-		| 0x2 -> CallStdCall
-		| 0x3 -> CallThisCall
-		| 0x4 -> CallFastCall
-		| 0x5 -> CallVararg (* 0x5 *)
-		| 0x6 -> CallField (* 0x6 *)
-		| 0x7 -> CallLocal (* 0x7 *)
-		| 0x8 -> CallProp (* 0x8 *)
-		| 0x9 -> CallUnmanaged (* 0x9 *)
-		| 0xa when match_generic_inst -> CallGenericInst (* 0xA *)
-		| i -> printf "error 0x%x\n\n" i; assert false
-	in
-	match i land 0x20 with
-		| 0x20 ->
-			[CallHasThis;basic]
-		| _ when i land 0x40 = 0x40 ->
-			[CallExplicitThis;basic]
-		| _ -> [basic]
-
-let event_flags_of_int iprops = List.fold_left (fun acc i ->
-	if (iprops land i) = i then (match i with
-		| 0x0200 -> ESpecialName (* 0x0200 *)
-		| 0x0400 -> ERTSpecialName (* 0x0400 *)
-		| _ -> assert false) :: acc
-	else
-		acc) [] [0x0200;0x0400]
-
-let property_flags_of_int iprops = List.fold_left (fun acc i ->
-	if (iprops land i) = i then (match i with
-		| 0x0200 -> PSpecialName (* 0x0200 *)
-		| 0x0400 -> PRTSpecialName (* 0x0400 *)
-		| 0x1000 -> PHasDefault (* 0x1000 *)
-		| 0xE9FF -> PUnused (* 0xE9FF *)
-		| _ -> assert false) :: acc
-	else
-		acc) [] [0x0200;0x0400;0x1000;0xE9FF]
-
-let semantic_flags_of_int iprops = List.fold_left (fun acc i ->
-	if (iprops land i) = i then (match i with
-		| 0x0001 -> SSetter (* 0x0001 *)
-		| 0x0002 -> SGetter (* 0x0002 *)
-		| 0x0004 -> SOther (* 0x0004 *)
-		| 0x0008 -> SAddOn (* 0x0008 *)
-		| 0x0010 -> SRemoveOn (* 0x0010 *)
-		| 0x0020 -> SFire (* 0x0020 *)
-		| _ -> assert false) :: acc
-	else
-		acc) [] [0x0001;0x0002;0x0004;0x0008;0x0010;0x0020]
-
-let impl_charset_of_int = function
-	| 0x0 -> IDefault (* 0x0 *)
-	| 0x2 -> IAnsi (* 0x2 *)
-	| 0x4 -> IUnicode (* 0x4 *)
-	| 0x6 -> IAutoChar (* 0x6 *)
-	| _ -> assert false
-
-let impl_callconv_of_int = function
-	| 0x0 -> IDefaultCall (* 0x0 *)
-	| 0x100 -> IWinApi (* 0x100 *)
-	| 0x200 -> ICDecl (* 0x200 *)
-	| 0x300 -> IStdCall (* 0x300 *)
-	| 0x400 -> IThisCall (* 0x400 *)
-	| 0x500 -> IFastCall (* 0x500 *)
-	| _ -> assert false
-
-let impl_flag_of_int iprops = List.fold_left (fun acc i ->
-	if (iprops land i) = i then (match i with
-		| 0x1 -> INoMangle (* 0x1 *)
-		| 0x10 -> IBestFit (* 0x10 *)
-		| 0x20 -> IBestFitOff (* 0x20 *)
-		| 0x40 -> ILastErr (* 0x40 *)
-		| 0x1000 -> ICharMapError (* 0x1000 *)
-		| 0x2000 -> ICharMapErrorOff (* 0x2000 *)
-		| _ -> assert false) :: acc
-	else
-		acc) [] [0x1;0x10;0x20;0x40;0x1000;0x2000]
-
-let impl_flags_of_int i =
-	{
-		if_charset = impl_charset_of_int (i land 0x6);
-		if_callconv = impl_callconv_of_int (i land 0x700);
-		if_flags = impl_flag_of_int i;
-	}
-
-let null_impl_flags = impl_flags_of_int 0
-
-let assembly_flags_of_int iprops = List.fold_left (fun acc i ->
-	if (iprops land i) = i then (match i with
-		| 0x1 -> APublicKey (* 0x1 *)
-		| 0x100 -> ARetargetable (* 0x100 *)
-		| 0x4000 -> ADisableJitCompileOptimizer (* 0x4000 *)
-		| 0x8000 -> AEnableJitCompileTracking (* 0x8000 *)
-		| _ -> assert false) :: acc
-	else
-		acc) [] [0x1;0x100;0x4000;0x8000]
-
-let hash_algo_of_int = function
-	| 0x0 -> HNone (* 0x0 *)
-	| 0x8003 -> HReserved (* 0x8003 *)
-	| 0x8004 -> HSha1 (* 0x8004 *)
-	| _ -> assert false
-
-let file_flag_of_int = function
-	| 0x0 -> ContainsMetadata (* 0x0 *)
-	| 0x1 -> ContainsNoMetadata (* 0x1 *)
-	| _ -> assert false
-
-let manifest_resource_flag_of_int i = match i land 0x7 with
-	| 0x0 -> RNone (* 0x0 *)
-	| 0x1 -> RPublic (* 0x1 *)
-	| 0x2 -> RPrivate (* 0x2 *)
-	| _ -> assert false
-
-let generic_variance_of_int = function
-	(* mask 0x3 *)
-	| 0x0 -> VNone (* 0x0 *)
-	| 0x1 -> VCovariant (* 0x1 *)
-	| 0x2 -> VContravariant (* 0x2 *)
-	| _ -> assert false
-
-let generic_constraint_of_int iprops = List.fold_left (fun acc i ->
-	if (iprops land i) = i then (match i with
-		(* mask 0x1C *)
-		| 0x4 -> CInstanceType (* 0x4 *)
-		| 0x8 -> CValueType (* 0x8 *)
-		| 0x10 -> CDefaultCtor (* 0x10 *)
-		| _ -> assert false) :: acc
-	else
-		acc) [] [0x4;0x8;0x10]
-
-let generic_flags_of_int i =
-	{
-		gf_variance = generic_variance_of_int (i land 0x3);
-		gf_constraint = generic_constraint_of_int (i land 0x1C);
-	}
-
-let null_generic_flags = generic_flags_of_int 0
-
-(* TODO: convert from string to Bigstring if OCaml 4 is available *)
-type meta_ctx = {
-	compressed : bool;
-		(* is a compressed stream *)
-	strings_stream : string;
-	mutable strings_offset : int;
-		(* #Strings: a string heap containing the names of metadata items *)
-	blob_stream : string;
-	mutable blob_offset : int;
-		(* #Blob: blob heap containing internal metadata binary object, such as default values, signatures, etc *)
-	guid_stream : string;
-	mutable guid_offset : int;
-		(* #GUID: a GUID heap *)
-	us_stream : string;
-		(* #US: user-defined strings *)
-	meta_stream : string;
-		(* may be either: *)
-			(* #~: compressed (optimized) metadata stream *)
-			(* #-: uncompressed (unoptimized) metadata stream *)
-	mutable meta_edit_continue : bool;
-	mutable meta_has_deleted : bool;
-
-  module_cache : meta_cache;
-	tables : (clr_meta DynArray.t) array;
-	table_sizes : ( string -> int -> int * int ) array;
-	extra_streams : clr_stream_header list;
-	relations : (meta_pointer, clr_meta) Hashtbl.t;
-	typedefs : (ilpath, meta_type_def) Hashtbl.t;
-
-	mutable delays : (unit -> unit) list;
-}
-
-and meta_cache = {
-	mutable lookups : (string -> meta_ctx option) list;
-	mutable mcache : (meta_module * meta_ctx) list;
-}
-
-let empty = "<not initialized>"
-
-let create_cache () =
-	{
-		lookups = [];
-		mcache = [];
-	}
-
-let add_lookup cache fn =
-	cache.lookups <- fn :: cache.lookups
-
-(* ******* Reading from Strings ********* *)
-
-let sget s pos = Char.code (String.get s pos)
-
-let read_compressed_i32 s pos =
-	let v = sget s pos in
-	(* Printf.printf "compressed: %x (18 0x%x 19 0x%x)\n" v (sget s (pos+20)) (sget s (pos+21)); *)
-	if v land 0x80 = 0x00 then
-		pos+1, v
-	else if v land 0xC0 = 0x80 then
-		pos+2, ((v land 0x3F) lsl 8) lor (sget s (pos+1))
-	else if v land 0xE0 = 0xC0 then
-		pos+4, ((v land 0x1F) lsl 24) lor ((sget s (pos+1)) lsl 16) lor ((sget s (pos+2)) lsl 8) lor (sget s (pos+3))
-	else
-		error (Printf.sprintf "Error reading compressed data. Invalid first byte: %x" v)
-
-let int_of_table (idx : clr_meta_idx) : int = Obj.magic idx
-let table_of_int (idx : int) : clr_meta_idx = Obj.magic idx
-
-let sread_ui8 s pos =
-	let n1 = sget s pos in
-	pos+1,n1
-
-let sread_i32 s pos =
-	let n1 = sget s pos in
-	let n2 = sget s (pos+1) in
-	let n3 = sget s (pos+2) in
-	let n4 = sget s (pos+3) in
-	pos+4, (n4 lsl 24) lor (n3 lsl 16) lor (n2 lsl 8) lor n1
-
-let sread_real_i32 s pos =
-	let n1 = sget s pos in
-	let n2 = sget s (pos+1) in
-	let n3 = sget s (pos+2) in
-	let n4 = Int32.of_int (sget s (pos+3)) in
-	let n = Int32.of_int ((n3 lsl 16) lor (n2 lsl 8) lor n1) in
-	let n4 = Int32.shift_left n4 24 in
-	pos+4, (Int32.logor n4 n)
-
-let sread_i64 s pos =
-	let pos, v1 = sread_real_i32 s (pos+1) in
-	let v1 = Int64.of_int32 v1 in
-	let pos, v2 = sread_real_i32 s pos in
-	let v2 = Int64.of_int32 v2 in
-	let v2 = Int64.shift_left v2 32 in
-	pos, (Int64.logor v1 v2)
-
-let sread_ui16 s pos =
-	let n1 = sget s pos in
-	let n2 = sget s (pos+1) in
-	pos+2, (n2 lsl 8) lor n1
-
-let read_cstring ctx pos =
-	let s = ctx.strings_stream in
-	let rec loop en =
-		match String.get s en with
-		| '\x00' -> en - pos
-		| _ -> loop (en+1)
-	in
-	(* printf "len 0x%x - pos 0x%x\n" (String.length s) pos; *)
-	let len = loop pos in
-	String.sub s pos len
-
-let read_sstring_idx ctx pos =
-	let s = ctx.meta_stream in
-	let metapos,i = if ctx.strings_offset = 2 then
-		sread_ui16 s pos
-	else
-		sread_i32 s pos
-	in
-	match i with
-	| 0 ->
-		metapos, ""
-	| _ ->
-		metapos, read_cstring ctx i
-
-let read_sblob_idx ctx pos =
-	let s = ctx.meta_stream in
-	let metapos, i = if ctx.blob_offset = 2 then
-		sread_ui16 s pos
-	else
-		sread_i32 s pos
-	in
-	match i with
-	| 0 ->
-		metapos,""
-	| _ ->
-		let bpos, len = read_compressed_i32 ctx.blob_stream i in
-		metapos, String.sub ctx.blob_stream bpos len
-
-let read_sguid_idx ctx pos =
-	let s = ctx.meta_stream in
-	let metapos,i = if ctx.guid_offset = 2 then
-		sread_ui16 s pos
-	else
-		sread_i32 s pos
-	in
-	match i with
-	| 0 ->
-		metapos, ""
-	| _ ->
-		let s = ctx.guid_stream in
-		let i = i - 1 in
-		let pos = i * 16 in
-		metapos, String.sub s pos 16
-
-let read_callconv ctx s pos =
-	let pos, conv = read_compressed_i32 s pos in
-	let callconv = callconv_of_int conv ~match_generic_inst:true in
-	let pos = match conv land 0x10 with
-		| 0x10 -> fst (read_compressed_i32 s pos)
-		| _ -> pos
-	in
-	pos, callconv
-
-let read_constant ctx with_type s pos =
-	match with_type with
-	| CBool ->
-		pos+1, IBool (sget s (pos) <> 0)
-	| CChar ->
-		let pos, v = sread_ui16 s (pos) in
-		pos, IChar v
-	| CInt8 | CUInt8 ->
-		pos+1,IByte (sget s (pos))
-	| CInt16 | CUInt16 ->
-		let pos, v = sread_ui16 s (pos) in
-		pos, IShort v
-	| CInt32 | CUInt32 ->
-		let pos, v = sread_real_i32 s (pos) in
-		pos, IInt v
-	| CInt64 | CUInt64 ->
-		let pos, v = sread_i64 s (pos) in
-		pos, IInt64 v
-	| CFloat32 ->
-		let pos, v1 = sread_real_i32 s (pos) in
-		pos, IFloat32 (Int32.float_of_bits v1)
-	| CFloat64 ->
-		let pos, v1 = sread_i64 s (pos) in
-		pos, IFloat64 (Int64.float_of_bits v1)
-	| CString ->
-		if sget s pos = 0xff then
-			pos+1,IString ""
-		else
-			let pos, len = read_compressed_i32 s pos in
-			pos+len, IString (String.sub s pos len)
-	| CNullRef ->
-		pos+1, INull
-
-let sig_to_const = function
-	| SBool -> CBool
-	| SChar -> CChar
-	| SInt8 -> CInt8
-	| SUInt8 -> CUInt8
-	| SInt16 -> CInt16
-	| SUInt16 -> CUInt16
-	| SInt32 -> CInt32
-	| SUInt32 -> CUInt32
-	| SInt64 -> CInt64
-	| SUInt64 -> CUInt64
-	| SFloat32 -> CFloat32
-	| SFloat64 -> CFloat64
-	| SString -> CString
-	| _ -> CNullRef
-
-let read_constant_type ctx s pos = match sget s pos with
-	| 0x2 -> pos+1, CBool (* 0x2 *)
-	| 0x3 -> pos+1, CChar (* 0x3 *)
-	| 0x4 -> pos+1, CInt8 (* 0x4 *)
-	| 0x5 -> pos+1, CUInt8 (* 0x5 *)
-	| 0x6 -> pos+1, CInt16 (* 0x6 *)
-	| 0x7 -> pos+1, CUInt16 (* 0x7 *)
-	| 0x8 -> pos+1, CInt32 (* 0x8 *)
-	| 0x9 -> pos+1, CUInt32 (* 0x9 *)
-	| 0xA -> pos+1, CInt64 (* 0xA *)
-	| 0xB -> pos+1, CUInt64 (* 0xB *)
-	| 0xC -> pos+1, CFloat32 (* 0xC *)
-	| 0xD -> pos+1, CFloat64 (* 0xD *)
-	| 0xE -> pos+1, CString (* 0xE *)
-	| 0x12 -> pos+1, CNullRef (* 0x12 *)
-	| i -> Printf.printf "0x%x\n" i; assert false
-
-let action_security_of_int = function
-	| 0x1 -> SecRequest (* 0x1 *)
-	| 0x2 -> SecDemand (* 0x2 *)
-	| 0x3 -> SecAssert (* 0x3 *)
-	| 0x4 -> SecDeny (* 0x4 *)
-	| 0x5 -> SecPermitOnly (* 0x5 *)
-	| 0x6 -> SecLinkCheck (* 0x6 *)
-	| 0x7 -> SecInheritCheck (* 0x7 *)
-	| 0x8 -> SecReqMin (* 0x8 *)
-	| 0x9 -> SecReqOpt (* 0x9 *)
-	| 0xA -> SecReqRefuse (* 0xA *)
-	| 0xB -> SecPreJitGrant (* 0xB *)
-	| 0xC -> SecPreJitDeny (* 0xC *)
-	| 0xD -> SecNonCasDemand (* 0xD *)
-	| 0xE -> SecNonCasLinkDemand (* 0xE *)
-	| 0xF -> SecNonCasInheritance (* 0xF *)
-	| _ -> assert false
-
-(* ******* Metadata Tables ********* *)
-let null_meta = UnknownMeta (-1)
-
-let mk_module id =
-	{
-		md_id = id;
-		md_generation = 0;
-		md_name = empty;
-		md_vid = empty;
-		md_encid = empty;
-		md_encbase_id = empty;
-	}
-
-let null_module = mk_module (-1)
-
-let mk_type_ref id =
-	{
-		tr_id = id;
-		tr_resolution_scope = null_meta;
-		tr_name = empty;
-		tr_namespace = [];
-	}
-
-let null_type_ref = mk_type_ref (-1)
-
-let mk_type_def id =
-	{
-		td_id = id;
-		td_flags = null_type_def_flags;
-		td_name = empty;
-		td_namespace = [];
-		td_extends = None;
-		td_field_list = [];
-		td_method_list = [];
-		td_extra_enclosing = None;
-	}
-
-let null_type_def = mk_type_def (-1)
-
-let mk_field id =
-	{
-		f_id = id;
-		f_flags = null_field_flags;
-		f_name = empty;
-		f_signature = SVoid;
-	}
-
-let null_field = mk_field (-1)
-
-let mk_field_ptr id =
-	{
-		fp_id = id;
-		fp_field = null_field;
-	}
-
-let null_field_ptr = mk_field_ptr (-1)
-
-let mk_method id =
-	{
-		m_id = id;
-		m_rva = Int32.of_int (-1);
-		m_flags = null_method_flags;
-		m_name = empty;
-		m_signature = SVoid;
-		m_param_list = [];
-		m_declaring = None;
-	}
-
-let null_method = mk_method (-1)
-
-let mk_method_ptr id =
-	{
-		mp_id = id;
-		mp_method = null_method;
-	}
-
-let null_method_ptr = mk_method_ptr (-1)
-
-let mk_param id =
-	{
-		p_id = id;
-		p_flags = null_param_flags;
-		p_sequence = -1;
-		p_name = empty;
-	}
-
-let null_param = mk_param (-1)
-
-let mk_param_ptr id =
-	{
-		pp_id = id;
-		pp_param = null_param;
-	}
-
-let null_param_ptr = mk_param_ptr (-1)
-
-let mk_interface_impl id =
-	{
-		ii_id = id;
-		ii_class = null_type_def; (* TypeDef rid *)
-		ii_interface = null_meta;
-	}
-
-let null_interface_impl = mk_interface_impl (-1)
-
-let mk_member_ref id =
-	{
-		memr_id = id;
-		memr_class = null_meta;
-		memr_name = empty;
-		memr_signature = SVoid;
-	}
-
-let null_member_ref = mk_member_ref (-1)
-
-let mk_constant id =
-	{
-		c_id = id;
-		c_type = CNullRef;
-		c_parent = null_meta;
-		c_value = INull;
-	}
-
-let null_constant = mk_constant (-1)
-
-let mk_custom_attribute id =
-	{
-		ca_id = id;
-		ca_parent = null_meta;
-		ca_type = null_meta;
-		ca_value = None;
-	}
-
-let null_custom_attribute = mk_custom_attribute (-1)
-
-let mk_field_marshal id =
-	{
-		fm_id = id;
-		fm_parent = null_meta;
-		fm_native_type = NVoid;
-	}
-
-let null_field_marshal = mk_field_marshal (-1)
-
-let mk_decl_security id =
-	{
-		ds_id = id;
-		ds_action = SecNull;
-		ds_parent = null_meta;
-		ds_permission_set = empty;
-	}
-
-let mk_class_layout id =
-	{
-		cl_id = id;
-		cl_packing_size = -1;
-		cl_class_size = -1;
-		cl_parent = null_type_def;
-	}
-
-let mk_field_layout id =
-	{
-		fl_id = id;
-		fl_offset = -1;
-		fl_field = null_field;
-	}
-
-let mk_stand_alone_sig id =
-	{
-		sa_id = id;
-		sa_signature = SVoid;
-	}
-
-let mk_event id =
-	{
-		e_id = id;
-		e_flags = [];
-		e_name = empty;
-		e_event_type = null_meta;
-	}
-
-let null_event = mk_event (-1)
-
-let mk_event_map id =
-	{
-		em_id = id;
-		em_parent = null_type_def;
-		em_event_list = [];
-	}
-
-let mk_event_ptr id =
-	{
-		ep_id = id;
-		ep_event = null_event;
-	}
-
-let mk_property id =
-	{
-		prop_id = id;
-		prop_flags = [];
-		prop_name = empty;
-		prop_type = SVoid;
-	}
-
-let null_property = mk_property (-1)
-
-let mk_property_map id =
-	{
-		pm_id = id;
-		pm_parent = null_type_def;
-		pm_property_list = [];
-	}
-
-let mk_property_ptr id =
-	{
-		prp_id = id;
-		prp_property = null_property;
-	}
-
-let mk_method_semantics id =
-	{
-		ms_id = id;
-		ms_semantic = [];
-		ms_method = null_method;
-		ms_association = null_meta;
-	}
-
-let mk_method_impl id =
-	{
-		mi_id = id;
-		mi_class = null_type_def;
-		mi_method_body = null_meta;
-		mi_method_declaration = null_meta;
-	}
-
-let mk_module_ref id =
-	{
-		modr_id = id;
-		modr_name = empty;
-	}
-
-let null_module_ref = mk_module_ref (-1)
-
-let mk_type_spec id =
-	{
-		ts_id = id;
-		ts_signature = SVoid;
-	}
-
-let mk_enc_log id =
-	{
-		el_id = id;
-		el_token = -1;
-		el_func_code = -1;
-	}
-
-let mk_impl_map id =
-	{
-		im_id = id;
-		im_flags = null_impl_flags;
-		im_forwarded = null_meta;
-		im_import_name = empty;
-		im_import_scope = null_module_ref;
-	}
-
-let mk_enc_map id =
-	{
-		encm_id = id;
-		encm_token = -1;
-	}
-
-let mk_field_rva id =
-	{
-		fr_id = id;
-		fr_rva = Int32.zero;
-		fr_field = null_field;
-	}
-
-let mk_assembly id =
-	{
-		a_id = id;
-		a_hash_algo = HNone;
-		a_major = -1;
-		a_minor = -1;
-		a_build = -1;
-		a_rev = -1;
-		a_flags = [];
-		a_public_key = empty;
-		a_name = empty;
-		a_locale = empty;
-	}
-
-let mk_assembly_processor id =
-	{
-		ap_id = id;
-		ap_processor = -1;
-	}
-
-let mk_assembly_os id =
-	{
-		aos_id = id;
-		aos_platform_id = -1;
-		aos_major_version = -1;
-		aos_minor_version = -1;
-	}
-
-let mk_assembly_ref id =
-	{
-		ar_id = id;
-		ar_major = -1;
-		ar_minor = -1;
-		ar_build = -1;
-		ar_rev = -1;
-		ar_flags = [];
-		ar_public_key = empty;
-		ar_name = empty;
-		ar_locale = empty;
-		ar_hash_value = empty;
-	}
-
-let null_assembly_ref = mk_assembly_ref (-1)
-
-let mk_assembly_ref_processor id =
-	{
-		arp_id = id;
-		arp_processor = -1;
-		arp_assembly_ref = null_assembly_ref;
-	}
-
-let mk_assembly_ref_os id =
-	{
-		aros_id = id;
-		aros_platform_id = -1;
-		aros_major = -1;
-		aros_minor = -1;
-		aros_assembly_ref = null_assembly_ref;
-	}
-
-let mk_file id =
-	{
-		file_id = id;
-		file_flags = ContainsMetadata;
-		file_name = empty;
-		file_hash_value = empty;
-	}
-
-let mk_exported_type id =
-	{
-		et_id = id;
-		et_flags = null_type_def_flags;
-		et_type_def_id = -1;
-		et_type_name = empty;
-		et_type_namespace = [];
-		et_implementation = null_meta;
-	}
-
-let mk_manifest_resource id =
-	{
-		mr_id = id;
-		mr_offset = -1;
-		mr_flags = RNone;
-		mr_name = empty;
-		mr_implementation = None;
-	}
-
-let mk_nested_class id =
-	{
-		nc_id = id;
-		nc_nested = null_type_def;
-		nc_enclosing = null_type_def;
-	}
-
-let mk_generic_param id =
-	{
-		gp_id = id;
-		gp_number = -1;
-		gp_flags = null_generic_flags;
-		gp_owner = null_meta;
-		gp_name = None;
-	}
-
-let null_generic_param = mk_generic_param (-1)
-
-let mk_method_spec id =
-	{
-		mspec_id = id;
-		mspec_method = null_meta;
-		mspec_instantiation = SVoid;
-	}
-
-let mk_generic_param_constraint id =
-	{
-		gc_id = id;
-		gc_owner = null_generic_param;
-		gc_constraint = null_meta;
-	}
-
-let mk_meta tbl id = match tbl with
-	| IModule -> Module (mk_module id)
-	| ITypeRef -> TypeRef (mk_type_ref id)
-	| ITypeDef -> TypeDef (mk_type_def id)
-	| IFieldPtr -> FieldPtr (mk_field_ptr id)
-	| IField -> Field (mk_field id)
-	| IMethodPtr -> MethodPtr (mk_method_ptr id)
-	| IMethod -> Method (mk_method id)
-	| IParamPtr -> ParamPtr (mk_param_ptr id)
-	| IParam -> Param (mk_param id)
-	| IInterfaceImpl -> InterfaceImpl (mk_interface_impl id)
-	| IMemberRef -> MemberRef (mk_member_ref id)
-	| IConstant -> Constant (mk_constant id)
-	| ICustomAttribute -> CustomAttribute (mk_custom_attribute id)
-	| IFieldMarshal -> FieldMarshal(mk_field_marshal id)
-	| IDeclSecurity -> DeclSecurity(mk_decl_security id)
-	| IClassLayout -> ClassLayout(mk_class_layout id)
-	| IFieldLayout -> FieldLayout(mk_field_layout id)
-	| IStandAloneSig -> StandAloneSig(mk_stand_alone_sig id)
-	| IEventMap -> EventMap(mk_event_map id)
-	| IEventPtr -> EventPtr(mk_event_ptr id)
-	| IEvent -> Event(mk_event id)
-	| IPropertyMap -> PropertyMap(mk_property_map id)
-	| IPropertyPtr -> PropertyPtr(mk_property_ptr id)
-	| IProperty -> Property(mk_property id)
-	| IMethodSemantics -> MethodSemantics(mk_method_semantics id)
-	| IMethodImpl -> MethodImpl(mk_method_impl id)
-	| IModuleRef -> ModuleRef(mk_module_ref id)
-	| ITypeSpec -> TypeSpec(mk_type_spec id)
-	| IImplMap -> ImplMap(mk_impl_map id)
-	| IFieldRVA -> FieldRVA(mk_field_rva id)
-	| IENCLog -> ENCLog(mk_enc_log id)
-	| IENCMap -> ENCMap(mk_enc_map id)
-	| IAssembly -> Assembly(mk_assembly id)
-	| IAssemblyProcessor -> AssemblyProcessor(mk_assembly_processor id)
-	| IAssemblyOS -> AssemblyOS(mk_assembly_os id)
-	| IAssemblyRef -> AssemblyRef(mk_assembly_ref id)
-	| IAssemblyRefProcessor -> AssemblyRefProcessor(mk_assembly_ref_processor id)
-	| IAssemblyRefOS -> AssemblyRefOS(mk_assembly_ref_os id)
-	| IFile -> File(mk_file id)
-	| IExportedType -> ExportedType(mk_exported_type id)
-	| IManifestResource -> ManifestResource(mk_manifest_resource id)
-	| INestedClass -> NestedClass(mk_nested_class id)
-	| IGenericParam -> GenericParam(mk_generic_param id)
-	| IMethodSpec -> MethodSpec(mk_method_spec id)
-	| IGenericParamConstraint -> GenericParamConstraint(mk_generic_param_constraint id)
-	| i -> UnknownMeta (int_of_table i)
-
-let get_table ctx idx rid =
-	let cur = ctx.tables.(int_of_table idx) in
-	DynArray.get cur (rid-1)
-
-(* special coded types  *)
-let max_clr_meta_idx = 76
-
-let coded_description = Array.init (max_clr_meta_idx - 63) (fun i ->
-	let i = 64 + i in
-	match table_of_int i with
-		| ITypeDefOrRef ->
-			Array.of_list [ITypeDef;ITypeRef;ITypeSpec], 2
-		| IHasConstant ->
-			Array.of_list [IField;IParam;IProperty], 2
-		| IHasCustomAttribute ->
-			Array.of_list
-			[IMethod;IField;ITypeRef;ITypeDef;IParam;IInterfaceImpl;IMemberRef;
-			 IModule;IDeclSecurity;IProperty;IEvent;IStandAloneSig;IModuleRef;
-			 ITypeSpec;IAssembly;IAssemblyRef;IFile;IExportedType;IManifestResource;
-			 IGenericParam;IGenericParamConstraint;IMethodSpec], 5
-		| IHasFieldMarshal ->
-			Array.of_list [IField;IParam], 1
-		| IHasDeclSecurity ->
-			Array.of_list [ITypeDef;IMethod;IAssembly], 2
-		| IMemberRefParent ->
-			Array.of_list [ITypeDef;ITypeRef;IModuleRef;IMethod;ITypeSpec], 3
-		| IHasSemantics ->
-			Array.of_list [IEvent;IProperty], 1
-		| IMethodDefOrRef ->
-			Array.of_list [IMethod;IMemberRef], 1
-		| IMemberForwarded ->
-			Array.of_list [IField;IMethod], 1
-		| IImplementation ->
-			Array.of_list [IFile;IAssemblyRef;IExportedType], 2
-		| ICustomAttributeType ->
-			Array.of_list [ITypeRef(* unused ? *);ITypeDef (* unused ? *);IMethod;IMemberRef(*;IString FIXME *)], 3
-		| IResolutionScope ->
-			Array.of_list [IModule;IModuleRef;IAssemblyRef;ITypeRef], 2
-		| ITypeOrMethodDef ->
-			Array.of_list [ITypeDef;IMethod], 1
-		| _ ->
-			print_endline ("Unknown coded index: " ^ string_of_int i);
-			assert false)
-
-let set_coded_sizes ctx rows =
-	let check i tbls max =
-		if List.exists (fun t ->
-			let _, nrows = rows.(int_of_table t) in
-			nrows >= max
-		) tbls then
-			ctx.table_sizes.(i) <- sread_i32
-	in
-	for i = 64 to (max_clr_meta_idx) do
-		let tbls, size = coded_description.(i - 64) in
-		let max = 1 lsl (16 - size) in
-		check i (Array.to_list tbls) max
-	done
-
-let sread_from_table_opt ctx in_blob tbl s pos =
-	let i = int_of_table tbl in
-	let sread = if in_blob then
-		read_compressed_i32
-	else
-		ctx.table_sizes.(i)
-	in
-	let pos, rid = sread s pos in
-	if i >= 64 then begin
-		let tbls,size = coded_description.(i-64) in
-		let mask = (1 lsl size) - 1 in
-		let mask = if mask = 0 then 1 else mask in
-		let tidx = rid land mask in
-		let real_rid = rid lsr size in
-		let real_tbl = tbls.(tidx) in
-		(* printf "rid 0x%x - table idx 0x%x - real_rid 0x%x\n\n" rid tidx real_rid; *)
-		if real_rid = 0 then
-			pos, None
-		else
-			pos, Some (get_table ctx real_tbl real_rid)
-	end else if rid = 0 then
-		pos, None
-	else
-		pos, Some (get_table ctx tbl rid)
-
-let sread_from_table ctx in_blob tbl s pos =
-	let pos, opt = sread_from_table_opt ctx in_blob tbl s pos in
-	pos, Option.get opt
-
-(* ******* SIGNATURE READING ********* *)
-let read_inline_str s pos =
-	let pos, len = read_compressed_i32 s pos in
-	let ret = String.sub s pos len in
-	pos+len,ret
-
-let rec read_ilsig ctx s pos =
-	let i = sget s pos in
-	(* printf "0x%x\n" i; *)
-	let pos = pos + 1 in
-	match i with
-		| 0x1 -> pos, SVoid (* 0x1 *)
-		| 0x2 -> pos, SBool (* 0x2 *)
-		| 0x3 -> pos, SChar (* 0x3 *)
-		| 0x4 -> pos, SInt8 (* 0x4 *)
-		| 0x5 -> pos, SUInt8 (* 0x5 *)
-		| 0x6 -> pos, SInt16 (* 0x6 *)
-		| 0x7 -> pos, SUInt16 (* 0x7 *)
-		| 0x8 -> pos, SInt32 (* 0x8 *)
-		| 0x9 -> pos, SUInt32 (* 0x9 *)
-		| 0xA -> pos, SInt64 (* 0xA *)
-		| 0xB -> pos, SUInt64 (* 0xB *)
-		| 0xC -> pos, SFloat32 (* 0xC *)
-		| 0xD -> pos, SFloat64 (* 0xD *)
-		| 0xE -> pos, SString (* 0xE *)
-		| 0xF ->
-			let pos, s = read_ilsig ctx s pos in
-			pos, SPointer s
-		| 0x10 ->
-			let pos, s = read_ilsig ctx s pos in
-			pos, SManagedPointer s
-		| 0x11 ->
-			let pos, vt = sread_from_table ctx true ITypeDefOrRef s pos in
-			pos, SValueType vt
-		| 0x12 ->
-			let pos, c = sread_from_table ctx true ITypeDefOrRef s pos in
-			pos, SClass c
-		| 0x13 ->
-			let n = sget s pos in
-			pos + 1, STypeParam n
-		| 0x14 ->
-			let pos, ssig = read_ilsig ctx s pos in
-			let pos, rank = read_compressed_i32 s pos in
-			let pos, numsizes = read_compressed_i32 s pos in
-			let pos = ref pos in
-			let sizearray = Array.init numsizes (fun _ ->
-				let p, size = read_compressed_i32 s !pos in
-				pos := p;
-				size
-			) in
-			let pos, bounds = read_compressed_i32 s !pos in
-			let pos = ref pos in
-			let boundsarray = Array.init bounds (fun _ ->
-				let p, b = read_compressed_i32 s !pos in
-				pos := p;
-				let signed = b land 0x1 = 0x1 in
-				let b = b lsr 1 in
-				if signed then -b else b
-			) in
-			let ret = Array.init rank (fun i ->
-				(if i >= bounds then None else Some boundsarray.(i))
-				, (if i >= numsizes then None else Some sizearray.(i))
-			) in
-			!pos, SArray(ssig, ret)
-		| 0x15 ->
-			(* let pos, c = sread_from_table ctx ITypeDefOrRef s pos in *)
-			let pos, ssig = read_ilsig ctx s pos in
-			let pos, ntypes = read_compressed_i32 s pos in
-			let rec loop acc pos n =
-				if n > ntypes then
-					pos, List.rev acc
-				else
-					let pos, ssig = read_ilsig ctx s pos in
-					loop (ssig :: acc) pos (n+1)
-			in
-			let pos, args = loop [] pos 1 in
-			pos, SGenericInst (ssig, args)
-		| 0x16 -> pos, STypedReference (* 0x16 *)
-		| 0x18 -> pos, SIntPtr (* 0x18 *)
-		| 0x19 -> pos, SUIntPtr (* 0x19 *)
-		| 0x1B ->
-			let pos, conv = read_compressed_i32 s pos in
-			let callconv = callconv_of_int conv in
-			let pos, ntypes = read_compressed_i32 s pos in
-			let pos, ret = read_ilsig ctx s pos in
-			let rec loop acc pos n =
-				if n >= ntypes then
-					pos, List.rev acc
-				else
-					let pos, ssig = read_ilsig ctx s pos in
-					loop (ssig :: acc) pos (n+1)
-			in
-			let pos, args = loop [] pos 1 in
-			pos, SFunPtr (callconv, ret, args)
-		| 0x1C -> pos, SObject (* 0x1C *)
-		| 0x1D ->
-			let pos, ssig = read_ilsig ctx s pos in
-			pos, SVector ssig
-		| 0x1E ->
-			let pos, conv = read_compressed_i32 s pos in
-			pos, SMethodTypeParam conv
-		| 0x1F ->
-			let pos, tdef = sread_from_table ctx true ITypeDefOrRef s pos in
-			let pos, ilsig = read_ilsig ctx s pos in
-			pos, SReqModifier (tdef, ilsig)
-		| 0x20 ->
-			let pos, tdef = sread_from_table ctx true ITypeDefOrRef s pos in
-			let pos, ilsig = read_ilsig ctx s pos in
-			pos, SOptModifier (tdef, ilsig)
-		| 0x41 -> pos, SSentinel (* 0x41 *)
-		| 0x45 ->
-			let pos, ssig = read_ilsig ctx s pos in
-			pos,SPinned ssig (* 0x45 *)
-		(* special undocumented constants *)
-		| 0x50 -> pos, SType
-		| 0x51 -> pos, SBoxed
-		| 0x55 ->
-			let pos, vt = read_inline_str s pos in
-			pos, SEnum vt
-		| _ ->
-			Printf.printf "unknown ilsig 0x%x\n\n" i;
-			assert false
-
-let rec read_variantsig ctx s pos =
-	let pos, b = sread_ui8 s pos in
-	match b with
-		| 0x00 -> pos, VT_EMPTY (* 0x00 *)
-		| 0x01 -> pos, VT_NULL (* 0x01 *)
-		| 0x02 -> pos, VT_I2 (* 0x02 *)
-		| 0x03 -> pos, VT_I4 (* 0x03 *)
-		| 0x04 -> pos, VT_R4 (* 0x04 *)
-		| 0x05 -> pos, VT_R8 (* 0x05 *)
-		| 0x06 -> pos, VT_CY (* 0x06 *)
-		| 0x07 -> pos, VT_DATE (* 0x07 *)
-		| 0x08 -> pos, VT_BSTR (* 0x08 *)
-		| 0x09 -> pos, VT_DISPATCH (* 0x09 *)
-		| 0x0A -> pos, VT_ERROR (* 0x0A *)
-		| 0x0B -> pos, VT_BOOL (* 0x0B *)
-		| 0x0C -> pos, VT_VARIANT (* 0x0C *)
-		| 0x0D -> pos, VT_UNKNOWN (* 0x0D *)
-		| 0x0E -> pos, VT_DECIMAL (* 0x0E *)
-		| 0x10 -> pos, VT_I1 (* 0x10 *)
-		| 0x11 -> pos, VT_UI1 (* 0x11 *)
-		| 0x12 -> pos, VT_UI2 (* 0x12 *)
-		| 0x13 -> pos, VT_UI4 (* 0x13 *)
-		| 0x14 -> pos, VT_I8 (* 0x14 *)
-		| 0x15 -> pos, VT_UI8 (* 0x15 *)
-		| 0x16 -> pos, VT_INT (* 0x16 *)
-		| 0x17 -> pos, VT_UINT (* 0x17 *)
-		| 0x18 -> pos, VT_VOID (* 0x18 *)
-		| 0x19 -> pos, VT_HRESULT (* 0x19 *)
-		| 0x1A -> pos, VT_PTR (* 0x1A *)
-		| 0x1B -> pos, VT_SAFEARRAY (* 0x1B *)
-		| 0x1C -> pos, VT_CARRAY (* 0x1C *)
-		| 0x1D -> pos, VT_USERDEFINED (* 0x1D *)
-		| 0x1E -> pos, VT_LPSTR (* 0x1E *)
-		| 0x1F -> pos, VT_LPWSTR (* 0x1F *)
-		| 0x24 -> pos, VT_RECORD (* 0x24 *)
-		| 0x40 -> pos, VT_FILETIME (* 0x40 *)
-		| 0x41 -> pos, VT_BLOB (* 0x41 *)
-		| 0x42 -> pos, VT_STREAM (* 0x42 *)
-		| 0x43 -> pos, VT_STORAGE (* 0x43 *)
-		| 0x44 -> pos, VT_STREAMED_OBJECT (* 0x44 *)
-		| 0x45 -> pos, VT_STORED_OBJECT (* 0x45 *)
-		| 0x46 -> pos, VT_BLOB_OBJECT (* 0x46 *)
-		| 0x47 -> pos, VT_CF (* 0x47 *)
-		| 0x48 -> pos, VT_CLSID (* 0x48 *)
-		| _ -> assert false
-
-let rec read_nativesig ctx s pos : int * nativesig =
-	let pos, b = sread_ui8 s pos in
-	match b with
-		| 0x01 -> pos, NVoid (* 0x01 *)
-		| 0x02 -> pos, NBool (* 0x02 *)
-		| 0x03 -> pos, NInt8 (* 0x03 *)
-		| 0x4 -> pos, NUInt8 (* 0x4 *)
-		| 0x5 -> pos, NInt16 (* 0x5 *)
-		| 0x6 -> pos, NUInt16 (* 0x6 *)
-		| 0x7 -> pos, NInt32 (* 0x7 *)
-		| 0x8 -> pos, NUInt32 (* 0x8 *)
-		| 0x9 -> pos, NInt64 (* 0x9 *)
-		| 0xA -> pos, NUInt64 (* 0xA *)
-		| 0xB -> pos, NFloat32 (* 0xB *)
-		| 0xC -> pos, NFloat64 (* 0xC *)
-		| 0xD -> pos, NSysChar (* 0xD *)
-		| 0xE -> pos, NVariant (* 0xE *)
-		| 0xF -> pos, NCurrency (* 0xF *)
-		| 0x10 -> pos, NPointer (* 0x10 *)
-		| 0x11 -> pos, NDecimal (* 0x11 *)
-		| 0x12 -> pos, NDate (* 0x12 *)
-		| 0x13 -> pos, NBStr (* 0x13 *)
-		| 0x14 -> pos, NLPStr (* 0x14 *)
-		| 0x15 -> pos, NLPWStr (* 0x15 *)
-		| 0x16 -> pos, NLPTStr (* 0x16 *)
-		| 0x17 ->
-			let pos, size = read_compressed_i32 s pos in
-			pos, NFixedString size
-		| 0x18 -> pos, NObjectRef (* 0x18 *)
-		| 0x19 -> pos, NUnknown (* 0x19 *)
-		| 0x1A -> pos, NDispatch (* 0x1A *)
-		| 0x1B -> pos, NStruct (* 0x1B *)
-		| 0x1C -> pos, NInterface (* 0x1C *)
-		| 0x1D ->
-			let pos, v = read_variantsig ctx s pos in
-			pos, NSafeArray v
-		| 0x1E ->
-			let pos, size = read_compressed_i32 s pos in
-			let pos, t = read_variantsig ctx s pos in
-			pos, NFixedArray (size,t)
-		| 0x1F -> pos, NIntPointer (* 0x1F *)
-		| 0x20 -> pos, NUIntPointer (* 0x20 *)
-		| 0x21 -> pos, NNestedStruct (* 0x21 *)
-		| 0x22 -> pos, NByValStr (* 0x22 *)
-		| 0x23 -> pos, NAnsiBStr (* 0x23 *)
-		| 0x24 -> pos, NTBStr (* 0x24 *)
-		| 0x25 -> pos, NVariantBool (* 0x25 *)
-		| 0x26 -> pos, NFunctionPtr (* 0x26 *)
-		| 0x28 -> pos, NAsAny (* 0x28 *)
-		| 0x2A ->
-			let pos, elt = read_nativesig ctx s pos in
-			let pos, paramidx = read_compressed_i32 s pos in
-			let pos, size = read_compressed_i32 s pos in
-			let pos, param_mult = read_compressed_i32 s pos in
-			pos, NArray(elt,paramidx,size,param_mult)
-		| 0x2B -> pos, NLPStruct (* 0x2B *)
-		| 0x2C ->
-			let pos, guid_val = read_inline_str s pos in
-			let pos, unmanaged = read_inline_str s pos in
-			(* FIXME: read TypeRef *)
-			pos, NCustomMarshaler (guid_val,unmanaged)
-		| 0x2D -> pos, NError (* 0x2D *)
-		| i -> pos, NCustom i
-
-let read_blob_idx ctx s pos =
-	let metapos,i = if ctx.blob_offset = 2 then
-			sread_ui16 s pos
-		else
-			sread_i32 s pos
-	in
-	metapos, i
-
-
-let read_nativesig_idx ctx s pos =
-	let s = ctx.meta_stream in
-	let metapos,i = if ctx.blob_offset = 2 then
-		sread_ui16 s pos
-	else
-		sread_i32 s pos
-	in
-	let s = ctx.blob_stream in
-	let _, ret = read_nativesig ctx s i in
-	metapos, ret
-
-let read_method_ilsig_idx ctx pos =
-	let s = ctx.meta_stream in
-	let metapos,i = if ctx.blob_offset = 2 then
-		sread_ui16 s pos
-	else
-		sread_i32 s pos
-	in
-	let s = ctx.blob_stream in
-	let pos, len = read_compressed_i32 s i in
-	(* for x = 0 to len do *)
-	(* 	printf "%x " (sget s (i+x)) *)
-	(* done; *)
-	let endpos = pos + len in
-	(* printf "\n"; *)
-	let pos, callconv = read_callconv ctx s pos in
-	let pos, ntypes = read_compressed_i32 s pos in
-	let pos, ret = read_ilsig ctx s pos in
-	let rec loop acc pos n =
-		if n > ntypes || pos >= endpos then
-			pos, List.rev acc
-		else
-			let pos, ssig = read_ilsig ctx s pos in
-			loop (ssig :: acc) pos (n+1)
-	in
-	let pos, args = loop [] pos 1 in
-	metapos, SFunPtr (callconv, ret, args)
-
-let read_ilsig_idx ctx pos =
-	let s = ctx.meta_stream in
-	let metapos,i = if ctx.blob_offset = 2 then
-		sread_ui16 s pos
-	else
-		sread_i32 s pos
-	in
-	let s = ctx.blob_stream in
-	let i, _ = read_compressed_i32 s i in
-	let _, ilsig = read_ilsig ctx s i in
-	metapos, ilsig
-
-let read_field_ilsig_idx ?(force_field=true) ctx pos =
-	let s = ctx.meta_stream in
-	let metapos,i = if ctx.blob_offset = 2 then
-		sread_ui16 s pos
-	else
-		sread_i32 s pos
-	in
-	let s = ctx.blob_stream in
-	let i, _ = read_compressed_i32 s i in
-	if sget s i <> 0x6 then
-		if force_field then
-			error ("Invalid field signature: " ^ string_of_int (sget s i))
-		else
-			read_method_ilsig_idx ctx pos
-	else
-		let _, ilsig = read_ilsig ctx s (i+1) in
-		metapos, ilsig
-
-let get_underlying_enum_type ctx name =
-  (* first try to get a typedef *)
-	let ns, name = match List.rev (String.nsplit name ".") with
-		| name :: ns -> List.rev ns, name
-		| _ -> assert false
-	in
-	try
-		let tdefs = ctx.tables.(int_of_table ITypeDef) in
-		let len = DynArray.length tdefs in
-		let rec loop_find idx =
-			if idx >= len then
-				raise Not_found
-			else
-				let tdef = match DynArray.get tdefs idx with | TypeDef td -> td | _ -> assert false in
-				if tdef.td_name = name && tdef.td_namespace = ns then
-					tdef
-				else
-					loop_find (idx+1)
-		in
-		let tdef = loop_find 1 in
-		(* now find the first static field associated with it *)
-		try
-			let nonstatic = List.find (fun f ->
-				not (List.mem CStatic f.f_flags.ff_contract)
-			) tdef.td_field_list in
-			nonstatic.f_signature
-		with | Not_found -> assert false (* should never happen! *)
-	with | Not_found ->
-		(* FIXME: in order to correctly handle SEnum, we need to look it up *)
-		(* from either this assembly or from any other assembly that we reference *)
-		(* this is tricky - specially since this reader does not intend to handle file system *)
-		(* operations by itself. For now, if an enum is referenced from another module, *)
-		(* we won't handle it. The `cache` structure is laid out to deal with these problems *)
-		(* but isn't implemented yet *)
-		raise Exit
-
-let read_custom_attr ctx attr_type s pos =
-	let pos, prolog = sread_ui16 s pos in
-	if prolog <> 0x0001 then error (sprintf "Error reading custom attribute: Expected prolog 0x0001 ; got 0x%x" prolog);
-	let isig = match attr_type with
-		| Method m -> m.m_signature
-		| MemberRef mr -> mr.memr_signature
-		| _ -> assert false
-	in
-	let args = match follow isig with
-		| SFunPtr (_,ret,args) -> args
-		| _ -> assert false
-	in
-	let rec read_instance ilsig pos =
-		(* print_endline (IlMetaDebug.ilsig_s ilsig); *)
-		match follow ilsig with
-		| SBool | SChar	| SInt8 | SUInt8 | SInt16 | SUInt16
-		| SInt32 | SUInt32 | SInt64 | SUInt64 | SFloat32 | SFloat64 | SString ->
-			let pos, cons = read_constant ctx (sig_to_const ilsig) s pos in
-			pos, InstConstant (cons)
-		| SClass c when is_type (["System"],"Type") c ->
-			let pos, len = read_compressed_i32 s pos in
-			pos+len, InstType (String.sub s pos len)
-		| SType ->
-			let pos, len = read_compressed_i32 s pos in
-			pos+len, InstType (String.sub s pos len)
-		| SObject | SBoxed -> (* boxed *)
-			let pos = if sget s pos = 0x51 then pos+1 else pos in
-			let pos, ilsig = read_ilsig ctx s pos in
-			let pos, ret = read_instance ilsig pos in
-			pos, InstBoxed( ret )
-			(* (match follow ilsig with *)
-			(* | SEnum e -> *)
-			(* 		let ilsig = get_underlying_enum_type ctx e; *)
-			(* 	let pos,e = if is_boxed then sread_i32 s pos else read_compressed_i32 s pos in *)
-			(* 	pos, InstBoxed(InstEnum e) *)
-			(* | _ -> *)
-			(* 	let pos, boxed = read_constant ctx (sig_to_const ilsig) s pos in *)
-			(* 	pos, InstBoxed (InstConstant boxed)) *)
-		| SEnum e ->
-			let ilsig = get_underlying_enum_type ctx e in
-			read_instance ilsig pos
-		| SValueType _ -> (* enum *)
-			let pos, e = sread_i32 s pos in
-			pos, InstEnum e
-		| _ -> assert false
-	in
-	let rec read_fixed acc args pos = match args with
-		| [] ->
-			pos, List.rev acc
-		| SVector isig :: args ->
-			(* print_endline "vec"; *)
-			let pos, nelem = sread_real_i32 s pos in
-			let pos, ret = if nelem = -1l then
-				pos, InstConstant INull
-			else
-				let nelem = Int32.to_int nelem in
-				let rec loop acc pos n =
-					if n = nelem then
-						pos, InstArray (List.rev acc)
-					else
-						let pos, inst = read_instance isig pos in
-						loop (inst :: acc) pos (n+1)
-				in
-				loop [] pos 0
-			in
-			read_fixed (ret :: acc) args pos
-		| isig :: args ->
-			let pos, i = read_instance isig pos in
-			read_fixed (i :: acc) args pos
-	in
-	(* let tpos = pos in *)
-	let pos, fixed = read_fixed [] args pos in
-	(* printf "fixed %d : " (List.length args); *)
-	(* for x = tpos to pos do *)
-	(* 	printf "%x " (sget s x) *)
-	(* done; *)
-	(* printf "\n"; *)
-	(* let len = String.length s - pos - 1 in *)
-	(* let len = if len > 10 then 10 else len in *)
-	(* for x = 0 to len do *)
-	(* 	printf "%x " (sget s (pos + x)) *)
-	(* done; *)
-	(* printf "\n"; *)
-	let pos, nnamed = read_compressed_i32 s pos in
-	let pos = if nnamed > 0 then pos+1 else pos in
-	(* FIXME: this is a hack / quick fix around #3485 . We need to actually read named arguments *)
-	(* let rec read_named acc pos n = *)
-	(* 	if n = nnamed then *)
-	(* 		pos, List.rev acc *)
-	(* 	else *)
-	(* 		let pos, forp = sread_ui8 s pos in *)
-	(* 		let is_prop = if forp = 0x53 then *)
-	(* 				false *)
-	(* 			else if forp = 0x54 then *)
-	(* 				true *)
-	(* 			else *)
-	(* 				error (sprintf "named custom attribute error: expected 0x53 or 0x54 - got 0x%x" forp) *)
-	(* 		in *)
-	(* 		let pos, t = read_ilsig ctx s pos in *)
-	(* 		let pos, len = read_compressed_i32 s pos in *)
-	(* 		let name = String.sub s pos len in *)
-	(* 		let pos = pos+len in *)
-	(* 		let pos, inst = read_instance t pos in *)
-	(* 		read_named ( (is_prop, name, inst) :: acc ) pos (n+1) *)
-	(* in *)
-	(* let pos, named = read_named [] pos 0 in *)
-	pos, (fixed, [])
-	(* pos, (fixed, named) *)
-
-let read_custom_attr_idx ctx ca attr_type pos =
-	let s = ctx.meta_stream in
-	let metapos,i = if ctx.blob_offset = 2 then
-		sread_ui16 s pos
-	else
-		sread_i32 s pos
-	in
-	if i = 0 then
-		metapos
-	else
-		let s = ctx.blob_stream in
-		let i, _ = read_compressed_i32 s i in
-		ctx.delays <- (fun () ->
-			try
-				let _, attr = read_custom_attr ctx attr_type s i in
-				ca.ca_value <- Some attr
-			with | Exit ->
-				()
-		) :: ctx.delays;
-		metapos
-
-let read_next_index ctx offset table last pos =
-	if last then
-		DynArray.length ctx.tables.(int_of_table table) + 1
-	else
-		let s = ctx.meta_stream in
-		let _, idx = ctx.table_sizes.(int_of_table table) s (pos+offset) in
-		idx
-
-let get_rev_list ctx table ptr_table begin_idx end_idx =
-	(* first check if index exists on pointer table *)
-	let ptr_table_t = ctx.tables.(int_of_table ptr_table) in
-	(* printf "table %d begin %d end %d\n" (int_of_table table) begin_idx end_idx; *)
-	match ctx.compressed, DynArray.length ptr_table_t with
-	| true, _ | _, 0 ->
-		(* use direct index *)
-		let rec loop idx acc =
-			if idx >= end_idx then
-				acc
-			else
-				loop (idx+1) (get_table ctx table idx :: acc)
-		in
-		loop begin_idx []
-	| _ ->
-		(* use indirect index *)
-		let rec loop idx acc =
-			if idx > end_idx then
-				acc
-			else
-				loop (idx+1) (get_table ctx ptr_table idx :: acc)
-		in
-		let ret = loop begin_idx [] in
-		List.map (fun meta ->
-			let p = meta_root_ptr meta in
-			get_table ctx table p.ptr_to.root_id
-		) ret
-
-let read_list ctx table ptr_table begin_idx offset last pos =
-	let end_idx = read_next_index ctx offset table last pos in
-	get_rev_list ctx table ptr_table begin_idx end_idx
-
-let parse_ns id = match String.nsplit id "." with
-	| [""] -> []
-	| ns -> ns
-
-let get_meta_pointer = function
-	| Module r -> IModule, r.md_id
-	| TypeRef r -> ITypeRef, r.tr_id
-	| TypeDef r -> ITypeDef, r.td_id
-	| FieldPtr r -> IFieldPtr, r.fp_id
-	| Field r -> IField, r.f_id
-	| MethodPtr r -> IMethodPtr, r.mp_id
-	| Method r -> IMethod, r.m_id
-	| ParamPtr r -> IParamPtr, r.pp_id
-	| Param r -> IParam, r.p_id
-	| InterfaceImpl r -> IInterfaceImpl, r.ii_id
-	| MemberRef r -> IMemberRef, r.memr_id
-	| Constant r -> IConstant, r.c_id
-	| CustomAttribute r -> ICustomAttribute, r.ca_id
-	| FieldMarshal r -> IFieldMarshal, r.fm_id
-	| DeclSecurity r -> IDeclSecurity, r.ds_id
-	| ClassLayout r -> IClassLayout, r.cl_id
-	| FieldLayout r -> IFieldLayout, r.fl_id
-	| StandAloneSig r -> IStandAloneSig, r.sa_id
-	| EventMap r -> IEventMap, r.em_id
-	| EventPtr r -> IEventPtr, r.ep_id
-	| Event r -> IEvent, r.e_id
-	| PropertyMap r -> IPropertyMap, r.pm_id
-	| PropertyPtr r -> IPropertyPtr, r.prp_id
-	| Property r -> IProperty, r.prop_id
-	| MethodSemantics r -> IMethodSemantics, r.ms_id
-	| MethodImpl r -> IMethodImpl, r.mi_id
-	| ModuleRef r -> IModuleRef, r.modr_id
-	| TypeSpec r -> ITypeSpec, r.ts_id
-	| ImplMap r -> IImplMap, r.im_id
-	| FieldRVA r -> IFieldRVA, r.fr_id
-	| ENCLog r -> IENCLog, r.el_id
-	| ENCMap r -> IENCMap, r.encm_id
-	| Assembly r -> IAssembly, r.a_id
-	| AssemblyProcessor r -> IAssemblyProcessor, r.ap_id
-	| AssemblyOS r -> IAssemblyOS, r.aos_id
-	| AssemblyRef r -> IAssemblyRef, r.ar_id
-	| AssemblyRefProcessor r -> IAssemblyRefProcessor, r.arp_id
-	| AssemblyRefOS r -> IAssemblyRefOS, r.aros_id
-	| File r -> IFile, r.file_id
-	| ExportedType r -> IExportedType, r.et_id
-	| ManifestResource r -> IManifestResource, r.mr_id
-	| NestedClass r -> INestedClass, r.nc_id
-	| GenericParam r -> IGenericParam, r.gp_id
-	| MethodSpec r -> IMethodSpec, r.mspec_id
-	| GenericParamConstraint r -> IGenericParamConstraint, r.gc_id
-	| _ -> assert false
-
-let add_relation ctx key v =
-	let ptr = get_meta_pointer key in
-	Hashtbl.add ctx.relations ptr v
-
-let read_table_at ctx tbl n last pos =
-	(* print_endline ("rr " ^ string_of_int (n+1)); *)
-	let s = ctx.meta_stream in
-	match get_table ctx tbl (n+1 (* indices start at 1 *)) with
-	| Module m ->
-		let pos, gen = sread_ui16 s pos in
-		let pos, name = read_sstring_idx ctx pos in
-		let pos, vid = read_sguid_idx ctx pos in
-		let pos, encid = read_sguid_idx ctx pos in
-		let pos, encbase_id = read_sguid_idx ctx pos in
-		m.md_generation <- gen;
-		m.md_name <- name;
-		m.md_vid <- vid;
-		m.md_encid <- encid;
-		m.md_encbase_id <- encbase_id;
-		pos, Module m
-	| TypeRef tr ->
-		let pos, scope = sread_from_table ctx false IResolutionScope s pos in
-		let pos, name = read_sstring_idx ctx pos in
-		let pos, ns = read_sstring_idx ctx pos in
-		tr.tr_resolution_scope <- scope;
-		tr.tr_name <- name;
-		tr.tr_namespace <- parse_ns ns;
-		(* print_endline name; *)
-		(* print_endline ns; *)
-		pos, TypeRef tr
-	| TypeDef td ->
-		let startpos = pos in
-		let pos, flags = sread_i32 s pos in
-		let pos, name = read_sstring_idx ctx pos in
-		let pos, ns = read_sstring_idx ctx pos in
-		let ns = parse_ns ns in
-		let pos, extends = sread_from_table_opt ctx false ITypeDefOrRef s pos in
-		let field_offset = pos - startpos in
-		let pos, flist_begin = ctx.table_sizes.(int_of_table IField) s pos in
-		let method_offset = pos - startpos in
-		let pos, mlist_begin = ctx.table_sizes.(int_of_table IMethod) s pos in
-		td.td_flags <- type_def_flags_of_int flags;
-		td.td_name <- name;
-		td.td_namespace <- ns;
-		td.td_extends <- extends;
-		td.td_field_list <- List.rev_map get_field (read_list ctx IField IFieldPtr flist_begin field_offset last pos);
-		td.td_method_list <- List.rev_map get_method (read_list ctx IMethod IMethodPtr mlist_begin method_offset last pos);
-		List.iter (fun m -> m.m_declaring <- Some td) td.td_method_list;
-		let path = get_path (TypeDef td) in
-		Hashtbl.add ctx.typedefs path td;
-		(* print_endline "Type Def!"; *)
-		(* print_endline name; *)
-		(* print_endline ns; *)
-		pos, TypeDef td
-	| FieldPtr fp ->
-		let pos, field = sread_from_table ctx false IField s pos in
-		let field = get_field field in
-		fp.fp_field <- field;
-		pos, FieldPtr fp
-	| Field f ->
-		let pos, flags = sread_ui16 s pos in
-		let pos, name = read_sstring_idx ctx pos in
-		(* print_endline ("FIELD NAME " ^ name); *)
-		let pos, ilsig = read_field_ilsig_idx ctx pos in
-		(* print_endline (ilsig_s ilsig); *)
-		f.f_flags <- field_flags_of_int flags;
-		f.f_name <- name;
-		f.f_signature <- ilsig;
-		pos, Field f
-	| MethodPtr mp ->
-		let pos, m = sread_from_table ctx false IMethod s pos in
-		let m = get_method m in
-		mp.mp_method <- m;
-		pos, MethodPtr mp
-	| Method m ->
-		let startpos = pos in
-		let pos, rva = sread_i32 s pos in
-		let pos, iflags = sread_ui16 s pos in
-		let pos, flags = sread_ui16 s pos in
-		let pos, name = read_sstring_idx ctx pos in
-		let pos, ilsig = read_method_ilsig_idx ctx pos in
-		let offset = pos - startpos in
-		let pos, paramlist = ctx.table_sizes.(int_of_table IParam) s pos in
-		m.m_rva <- Int32.of_int rva;
-		m.m_flags <- method_flags_of_int iflags flags;
-		m.m_name <- name;
-		m.m_signature <- ilsig;
-		m.m_param_list <- List.rev_map get_param (read_list ctx IParam IParamPtr paramlist offset last pos);
-		pos, Method m
-	| ParamPtr pp ->
-		let pos, p = sread_from_table ctx false IParam s pos in
-		let p = get_param p in
-		pp.pp_param <- p;
-		pos, ParamPtr pp
-	| Param p ->
-		let pos, flags = sread_ui16 s pos in
-		let pos, sequence = sread_ui16 s pos in
-		let pos, name = read_sstring_idx ctx pos in
-		p.p_flags <- param_flags_of_int flags;
-		p.p_sequence <- sequence;
-		p.p_name <- name;
-		pos, Param p
-	| InterfaceImpl ii ->
-		let pos, cls = sread_from_table ctx false ITypeDef s pos in
-		add_relation ctx cls (InterfaceImpl ii);
-		let cls = get_type_def cls in
-		let pos, interface  = sread_from_table ctx false ITypeDefOrRef s pos in
-		ii.ii_class <- cls;
-		ii.ii_interface <- interface;
-		pos, InterfaceImpl ii
-	| MemberRef mr ->
-		let pos, cls = sread_from_table ctx false IMemberRefParent s pos in
-		let pos, name = read_sstring_idx ctx pos in
-		(* print_endline name; *)
-		(* let pos, signature = read_ilsig_idx ctx pos in *)
-		let pos, signature = read_field_ilsig_idx ~force_field:false ctx pos in
-		(* print_endline (ilsig_s signature); *)
-		mr.memr_class <- cls;
-		mr.memr_name <- name;
-		mr.memr_signature <- signature;
-		add_relation ctx cls (MemberRef mr);
-		pos, MemberRef mr
-	| Constant c ->
-		let pos, ctype = read_constant_type ctx s pos in
-		let pos = pos+1 in
-		let pos, parent = sread_from_table ctx false IHasConstant s pos in
-		let pos, blobpos = if ctx.blob_offset = 2 then
-				sread_ui16 s pos
-			else
-				sread_i32 s pos
-		in
-		let blob = ctx.blob_stream in
-		let blobpos, _ = read_compressed_i32 blob blobpos in
-		let _, value = read_constant ctx ctype blob blobpos in
-		c.c_type <- ctype;
-		c.c_parent <- parent;
-		c.c_value <- value;
-		add_relation ctx parent (Constant c);
-		pos, Constant c
-	| CustomAttribute ca ->
-		let pos, parent = sread_from_table ctx false IHasCustomAttribute s pos in
-		let pos, t = sread_from_table ctx false ICustomAttributeType s pos in
-		let pos = read_custom_attr_idx ctx ca t pos in
-		ca.ca_parent <- parent;
-		ca.ca_type <- t;
-		ca.ca_value <- None; (* this will be delayed by read_custom_attr_idx *)
-		add_relation ctx parent (CustomAttribute ca);
-		pos, CustomAttribute ca
-	| FieldMarshal fm ->
-		let pos, parent = sread_from_table ctx false IHasFieldMarshal s pos in
-		let pos, nativesig = read_nativesig_idx ctx s pos in
-		fm.fm_parent <- parent;
-		fm.fm_native_type <- nativesig;
-		add_relation ctx parent (FieldMarshal fm);
-		pos, FieldMarshal fm
-	| DeclSecurity ds ->
-		let pos, action = sread_ui16 s pos in
-		let action = action_security_of_int action in
-		let pos, parent = sread_from_table ctx false IHasDeclSecurity s pos in
-		let pos, permission_set = read_sblob_idx ctx pos in
-		ds.ds_action <- action;
-		ds.ds_parent <- parent;
-		ds.ds_permission_set <- permission_set;
-		add_relation ctx parent (DeclSecurity ds);
-		pos, DeclSecurity ds
-	| ClassLayout cl ->
-		let pos, psize = sread_ui16 s pos in
-		let pos, csize = sread_i32 s pos in
-		let pos, parent = sread_from_table ctx false ITypeDef s pos in
-		add_relation ctx parent (ClassLayout cl);
-		let parent = get_type_def parent in
-		cl.cl_packing_size <- psize;
-		cl.cl_class_size <- csize;
-		cl.cl_parent <- parent;
-		pos, ClassLayout cl
-	| FieldLayout fl ->
-		let pos, offset = sread_i32 s pos in
-		let pos, field = sread_from_table ctx false IField s pos in
-		fl.fl_offset <- offset;
-		fl.fl_field <- get_field field;
-		add_relation ctx field (FieldLayout fl);
-		pos, FieldLayout fl
-	| StandAloneSig sa ->
-		let pos, ilsig = read_field_ilsig_idx ~force_field:false ctx pos in
-		(* print_endline (ilsig_s ilsig); *)
-		sa.sa_signature <- ilsig;
-		pos, StandAloneSig sa
-	| EventMap em ->
-		let startpos = pos in
-		let pos, parent = sread_from_table ctx false ITypeDef s pos in
-		let offset = pos - startpos in
-		let pos, event_list = ctx.table_sizes.(int_of_table IEvent) s pos in
-		em.em_parent <- get_type_def parent;
-		em.em_event_list <- List.rev_map get_event (read_list ctx IEvent IEventPtr event_list offset last pos);
-		add_relation ctx parent (EventMap em);
-		pos, EventMap em
-	| EventPtr ep ->
-		let pos, event = sread_from_table ctx false IEvent s pos in
-		ep.ep_event <- get_event event;
-		pos, EventPtr ep
-	| Event e ->
-		let pos, flags = sread_ui16 s pos in
-		let pos, name = read_sstring_idx ctx pos in
-		let pos, event_type = sread_from_table ctx false ITypeDefOrRef s pos in
-		e.e_flags <- event_flags_of_int flags;
-		e.e_name <- name;
-		(* print_endline name; *)
-		e.e_event_type <- event_type;
-		add_relation ctx event_type (Event e);
-		pos, Event e
-	| PropertyMap pm ->
-		let startpos = pos in
-		let pos, parent = sread_from_table ctx false ITypeDef s pos in
-		let offset = pos - startpos in
-		let pos, property_list = ctx.table_sizes.(int_of_table IProperty) s pos in
-		pm.pm_parent <- get_type_def parent;
-		pm.pm_property_list <- List.rev_map get_property (read_list ctx IProperty IPropertyPtr property_list offset last pos);
-		add_relation ctx parent (PropertyMap pm);
-		pos, PropertyMap pm
-	| PropertyPtr pp ->
-		let pos, property = sread_from_table ctx false IProperty s pos in
-		pp.prp_property <- get_property property;
-		pos, PropertyPtr pp
-	| Property prop ->
-		let pos, flags = sread_ui16 s pos in
-		let pos, name = read_sstring_idx ctx pos in
-		let pos, t = read_field_ilsig_idx ~force_field:false ctx pos in
-		prop.prop_flags <- property_flags_of_int flags;
-		prop.prop_name <- name;
-		(* print_endline name; *)
-		prop.prop_type <- t;
-		(* print_endline (ilsig_s t); *)
-		pos, Property prop
-	| MethodSemantics ms ->
-		let pos, semantic = sread_ui16 s pos in
-		let pos, m = sread_from_table ctx false IMethod s pos in
-		let pos, association = sread_from_table ctx false IHasSemantics s pos in
-		ms.ms_semantic <- semantic_flags_of_int semantic;
-		ms.ms_method <- get_method m;
-		ms.ms_association <- association;
-		add_relation ctx m (MethodSemantics ms);
-		add_relation ctx association (MethodSemantics ms);
-		pos, MethodSemantics ms
-	| MethodImpl mi ->
-		let pos, cls = sread_from_table ctx false ITypeDef s pos in
-		let pos, method_body = sread_from_table ctx false IMethodDefOrRef s pos in
-		let pos, method_declaration = sread_from_table ctx false IMethodDefOrRef s pos in
-		mi.mi_class <- get_type_def cls;
-		mi.mi_method_body <- method_body;
-		mi.mi_method_declaration <- method_declaration;
-		add_relation ctx method_body (MethodImpl mi);
-		pos, MethodImpl mi
-	| ModuleRef modr ->
-		let pos, name = read_sstring_idx ctx pos in
-		modr.modr_name <- name;
-		(* print_endline name; *)
-		pos, ModuleRef modr
-	| TypeSpec ts ->
-		let pos, signature = read_ilsig_idx ctx pos in
-		(* print_endline (ilsig_s signature); *)
-		ts.ts_signature <- signature;
-		pos, TypeSpec ts
-	| ENCLog el ->
-		let pos, token = sread_i32 s pos in
-		let pos, func_code = sread_i32 s pos in
-		el.el_token <- token;
-		el.el_func_code <- func_code;
-		pos, ENCLog el
-	| ImplMap im ->
-		let pos, flags = sread_ui16 s pos in
-		let pos, forwarded = sread_from_table ctx false IMemberForwarded s pos in
-		let pos, import_name = read_sstring_idx ctx pos in
-		let pos, import_scope = sread_from_table ctx false IModuleRef s pos in
-		im.im_flags <- impl_flags_of_int flags;
-		im.im_forwarded <- forwarded;
-		im.im_import_name <- import_name;
-		im.im_import_scope <- get_module_ref import_scope;
-		add_relation ctx forwarded (ImplMap im);
-		pos, ImplMap im
-	| ENCMap em ->
-		let pos, token = sread_i32 s pos in
-		em.encm_token <- token;
-		pos, ENCMap em
-	| FieldRVA f ->
-		let pos, rva = sread_real_i32 s pos in
-		let pos, field = sread_from_table ctx false IField s pos in
-		f.fr_rva <- rva;
-		f.fr_field <- get_field field;
-		add_relation ctx field (FieldRVA f);
-		pos, FieldRVA f
-	| Assembly a ->
-		let pos, hash_algo = sread_i32 s pos in
-		let pos, major = sread_ui16 s pos in
-		let pos, minor = sread_ui16 s pos in
-		let pos, build = sread_ui16 s pos in
-		let pos, rev = sread_ui16 s pos in
-		let pos, flags = sread_i32 s pos in
-		let pos, public_key = read_sblob_idx ctx pos in
-		let pos, name = read_sstring_idx ctx pos in
-		let pos, locale = read_sstring_idx ctx pos in
-		a.a_hash_algo <- hash_algo_of_int hash_algo;
-		a.a_major <- major;
-		a.a_minor <- minor;
-		a.a_build <- build;
-		a.a_rev <- rev;
-		a.a_flags <- assembly_flags_of_int flags;
-		a.a_public_key <- public_key;
-		a.a_name <- name;
-		a.a_locale <- locale;
-		pos, Assembly a
-	| AssemblyProcessor ap ->
-		let pos, processor = sread_i32 s pos in
-		ap.ap_processor <- processor;
-		pos, AssemblyProcessor ap
-	| AssemblyOS aos ->
-		let pos, platform_id = sread_i32 s pos in
-		let pos, major = sread_i32 s pos in
-		let pos, minor = sread_i32 s pos in
-		aos.aos_platform_id <- platform_id;
-		aos.aos_major_version <- major;
-		aos.aos_minor_version <- minor;
-		pos, AssemblyOS aos
-	| AssemblyRef ar ->
-		let pos, major = sread_ui16 s pos in
-		let pos, minor = sread_ui16 s pos in
-		let pos, build = sread_ui16 s pos in
-		let pos, rev = sread_ui16 s pos in
-		let pos, flags = sread_i32 s pos in
-		let pos, public_key = read_sblob_idx ctx pos in
-		let pos, name = read_sstring_idx ctx pos in
-		let pos, locale = read_sstring_idx ctx pos in
-		let pos, hash_value = read_sblob_idx ctx pos in
-		ar.ar_major <- major;
-		ar.ar_minor <- minor;
-		ar.ar_build <- build;
-		ar.ar_rev <- rev;
-		ar.ar_flags <- assembly_flags_of_int flags;
-		ar.ar_public_key <- public_key;
-		ar.ar_name <- name;
-		(* print_endline name; *)
-		ar.ar_locale <- locale;
-		(* print_endline locale; *)
-		ar.ar_hash_value <- hash_value;
-		pos, AssemblyRef ar
-	| AssemblyRefProcessor arp ->
-		let pos, processor = sread_i32 s pos in
-		let pos, assembly_ref = sread_from_table ctx false IAssemblyRef s pos in
-		arp.arp_processor <- processor;
-		arp.arp_assembly_ref <- get_assembly_ref assembly_ref;
-		pos, AssemblyRefProcessor arp
-	| AssemblyRefOS aros ->
-		let pos, platform_id = sread_i32 s pos in
-		let pos, major = sread_i32 s pos in
-		let pos, minor = sread_i32 s pos in
-		let pos, assembly_ref = sread_from_table ctx false IAssemblyRef s pos in
-		aros.aros_platform_id <- platform_id;
-		aros.aros_major <- major;
-		aros.aros_minor <- minor;
-		aros.aros_assembly_ref <- get_assembly_ref assembly_ref;
-		pos, AssemblyRefOS aros
-	| File file ->
-		let pos, flags = sread_i32 s pos in
-		let pos, name = read_sstring_idx ctx pos in
-		let pos, hash_value = read_sblob_idx ctx pos in
-		file.file_flags <- file_flag_of_int flags;
-		file.file_name <- name;
-		(* print_endline ("file " ^ name); *)
-		file.file_hash_value <- hash_value;
-		pos, File file
-	| ExportedType et ->
-		let pos, flags = sread_i32 s pos in
-		let pos, type_def_id = sread_i32 s pos in
-		let pos, type_name = read_sstring_idx ctx pos in
-		let pos, type_namespace = read_sstring_idx ctx pos in
-		let pos, impl = sread_from_table ctx false IImplementation s pos in
-		et.et_flags <- type_def_flags_of_int flags;
-		et.et_type_def_id <- type_def_id;
-		et.et_type_name <- type_name;
-		et.et_type_namespace <- parse_ns type_namespace;
-		et.et_implementation <- impl;
-		add_relation ctx impl (ExportedType et);
-		pos, ExportedType et
-	| ManifestResource mr ->
-		let pos, offset = sread_i32 s pos in
-		let pos, flags = sread_i32 s pos in
-		(* printf "offset 0x%x flags 0x%x\n" offset flags; *)
-		let pos, name = read_sstring_idx ctx pos in
-		let rpos, i = ctx.table_sizes.(int_of_table IImplementation) s pos in
-		let pos, impl =
-			if i = 0 then
-				rpos, None
-			else
-				let pos, ret = sread_from_table ctx false IImplementation s pos in
-				add_relation ctx ret (ManifestResource mr);
-				pos, Some ret
-		in
-		mr.mr_offset <- offset;
-		mr.mr_flags <- manifest_resource_flag_of_int flags;
-		mr.mr_name <- name;
-		mr.mr_implementation <- impl;
-		pos, ManifestResource mr
-	| NestedClass nc ->
-		let pos, nested = sread_from_table ctx false ITypeDef s pos in
-		let pos, enclosing = sread_from_table ctx false ITypeDef s pos in
-		nc.nc_nested <- get_type_def nested;
-		nc.nc_enclosing <- get_type_def enclosing;
-
-		assert (nc.nc_nested.td_extra_enclosing = None);
-		nc.nc_nested.td_extra_enclosing <- Some nc.nc_enclosing;
-		add_relation ctx enclosing (NestedClass nc);
-		pos, NestedClass nc
-	| GenericParam gp ->
-		let pos, number = sread_ui16 s pos in
-		let pos, flags = sread_ui16 s pos in
-		let pos, owner = sread_from_table ctx false ITypeOrMethodDef s pos in
-		let spos, nidx =
-			if ctx.strings_offset = 2 then
-				sread_ui16 s pos
-			else
-				sread_i32 s pos
-		in
-		let pos, name =
-			if nidx = 0 then
-				spos, None
-			else
-				let pos, ret = read_sstring_idx ctx pos in
-				(* print_endline ret; *)
-				pos, Some ret
-		in
-		gp.gp_number <- number;
-		gp.gp_flags <- generic_flags_of_int flags;
-		gp.gp_owner <- owner;
-		gp.gp_name <- name;
-		add_relation ctx owner (GenericParam gp);
-		pos, GenericParam gp
-	| MethodSpec mspec ->
-		let pos, meth = sread_from_table ctx false IMethodDefOrRef s pos in
-		let pos, instantiation = read_method_ilsig_idx ctx pos in
-		(* print_endline (ilsig_s instantiation); *)
-		mspec.mspec_method <- meth;
-		mspec.mspec_instantiation <- instantiation;
-		add_relation ctx meth (MethodSpec mspec);
-		pos, MethodSpec mspec
-	| GenericParamConstraint gc ->
-		let pos, owner = sread_from_table ctx false IGenericParam s pos in
-		let pos, c = sread_from_table ctx false ITypeDefOrRef s pos in
-		gc.gc_owner <- get_generic_param owner;
-		gc.gc_constraint <- c;
-		add_relation ctx owner (GenericParamConstraint gc);
-		pos, GenericParamConstraint gc
-	| _ -> assert false
-
-(* ******* META READING ********* *)
-
-let preset_sizes ctx rows =
-	Array.iteri (fun n r -> match r with
-		| false,_ -> ()
-		| true,nrows ->
-			(* printf "table %d nrows %d\n" n nrows; *)
-			let tbl = table_of_int n in
-			ctx.tables.(n) <- DynArray.init (nrows) (fun id -> mk_meta tbl (id+1))
-	) rows
-
-(* let read_ *)
-let read_meta ctx =
-	(* read header *)
-	let s = ctx.meta_stream in
-	let pos = 4 + 1 + 1 in
-	let flags = sget s pos in
-	List.iter (fun i -> if flags land i = i then match i with
-		| 0x01 ->
-			ctx.strings_offset <- 4
-		| 0x02 ->
-			ctx.guid_offset <- 4
-		| 0x04 ->
-			ctx.blob_offset <- 4
-		| 0x20 ->
-			assert (not ctx.compressed);
-			ctx.meta_edit_continue <- true
-		| 0x80 ->
-			assert (not ctx.compressed);
-			ctx.meta_has_deleted <- true
-		| _ -> assert false
-	) [0x01;0x02;0x04;0x20;0x80];
-	let rid = sget s (pos+1) in
-	ignore rid;
-	let pos = pos + 2 in
-	let mask = Array.init 8 ( fun n -> sget s (pos + n) ) in
-	(* loop over masks and check which table is set *)
-	let set_table = Array.init 64 (fun n ->
-		let idx = n / 8 in
-		let bit = n mod 8 in
-		(mask.(idx) lsr bit) land 0x1 = 0x1
-	) in
-	let pos = ref (pos + 8 + 8) in (* there is an extra 'sorted' field, which we do not use *)
-	let rows = Array.mapi (fun i b -> match b with
-		| false -> false,0
-		| true ->
-			let nidx, nrows = sread_i32 s !pos in
-			if nrows > 0xFFFF then ctx.table_sizes.(i) <- sread_i32;
-			pos := nidx;
-			true,nrows
-	) set_table in
-	set_coded_sizes ctx rows;
-	(* pre-set all sizes *)
-	preset_sizes ctx rows;
-	Array.iteri (fun n r -> match r with
-		| false,_ -> ()
-		| true,nrows ->
-			(* print_endline (string_of_int n); *)
-			let fn = read_table_at ctx (table_of_int n) in
-			let rec loop_fn n =
-				if n = nrows then
-					()
-				else begin
-					let p, _ = fn n (n = (nrows-1)) !pos in
-					pos := p;
-					loop_fn (n+1)
-				end
-			in
-			loop_fn 0
-	) rows;
-	()
-
-let read_padded i npad =
-	let buf = Buffer.create 10 in
-	let rec loop n =
-		let chr = read i in
-		if chr = '\x00' then begin
-			let npad = n land 0x3 in
-			if npad <> 0 then ignore (nread i (4 - npad));
-			Buffer.contents buf
-		end else begin
-			Buffer.add_char buf chr;
-			if n = npad then
-				Buffer.contents buf
-			else
-				loop (n+1)
-		end
-	in
-	loop 1
-
-let read_meta_tables pctx header module_cache =
-	let i = pctx.r.i in
-	seek_rva pctx (fst header.clr_meta);
-	let magic = nread_string i 4 in
-	if magic <> "BSJB" then error ("Error reading metadata table: Expected magic 'BSJB'. Got " ^ magic);
-	let major = read_ui16 i in
-	let minor = read_ui16 i in
-	ignore major; ignore minor; (* no use for them *)
-	ignore (read_i32 i); (* reserved *)
-	let vlen = read_i32 i in
-	let ver = nread i vlen in
-	ignore ver;
-
-	(* meta storage header *)
-	ignore (read_ui16 i); (* reserved *)
-	let nstreams = read_ui16 i in
-	let rec streams n acc =
-		let offset = read_i32 i in
-		let size = read_real_i32 i in
-		let name = read_padded i 32 in
-		let acc = {
-			str_offset = offset;
-			str_size = size;
-			str_name = name;
-		} :: acc in
-		if (n+1) = nstreams then
-			acc
-		else
-			streams (n+1) acc
-	in
-	let streams = streams 0 [] in
-
-	(* streams *)
-	let compressed = ref None in
-	let sstrings = ref "" in
-	let sblob = ref "" in
-	let sguid = ref "" in
-	let sus = ref "" in
-	let smeta = ref "" in
-	let extra = ref [] in
-	List.iter (fun s ->
-		let rva = Int32.add (fst header.clr_meta) (Int32.of_int s.str_offset) in
-		seek_rva pctx rva;
-		match String.lowercase s.str_name with
-		| "#guid" ->
-			sguid := nread_string i (Int32.to_int s.str_size)
-		| "#strings" ->
-			sstrings := nread_string i (Int32.to_int s.str_size)
-		| "#us" ->
-			sus := nread_string i (Int32.to_int s.str_size)
-		| "#blob" ->
-			sblob := nread_string i (Int32.to_int s.str_size)
-		| "#~" ->
-			assert (Option.is_none !compressed);
-			compressed := Some true;
-			smeta := nread_string i (Int32.to_int s.str_size)
-		| "#-" ->
-			assert (Option.is_none !compressed);
-			compressed := Some false;
-			smeta := nread_string i (Int32.to_int s.str_size)
-		| _ ->
-			extra := s :: !extra
-	) streams;
-	let compressed = match !compressed with
-		| None -> error "No compressed or uncompressed metadata streams was found!"
-		| Some c -> c
-	in
-	let tables = Array.init 64 (fun _ -> DynArray.create ()) in
-	let ctx = {
-		compressed = compressed;
-		strings_stream = !sstrings;
-		strings_offset = 2;
-		blob_stream = !sblob;
-		blob_offset = 2;
-		guid_stream = !sguid;
-		guid_offset = 2;
-		us_stream = !sus;
-		meta_stream = !smeta;
-		meta_edit_continue = false;
-		meta_has_deleted = false;
-
-    module_cache = module_cache;
-		extra_streams = !extra;
-		relations = Hashtbl.create 64;
-		typedefs = Hashtbl.create 64;
-		tables = tables;
-		table_sizes = Array.make (max_clr_meta_idx+1) sread_ui16;
-
-		delays = [];
-	} in
-	read_meta ctx;
-	let delays = ctx.delays in
-	ctx.delays <- [];
-	List.iter (fun fn -> fn()) delays;
-	assert (ctx.delays = []);
-	{
-		il_tables = ctx.tables;
-		il_relations = ctx.relations;
-		il_typedefs = ctx.typedefs;
-	}
-

+ 0 - 472
libs/ilib/ilMetaTools.ml

@@ -1,472 +0,0 @@
-(*
- *  This file is part of ilLib
- *  Copyright (c)2004-2013 Haxe Foundation
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *)
-open IlMeta;;
-open IlData;;
-open PeReader;;
-open ExtString;;
-
-let rec follow s = match s with
-	| SReqModifier (_,s)
-	| SOptModifier (_,s) ->
-		follow s
-	| SPinned s ->
-		follow s
-	| s -> s
-
-(* tells if a type_def_or_ref is of type `path` *)
-let rec is_type path = function
-	| TypeDef td ->
-		td.td_namespace = fst path && td.td_name = snd path
-	| TypeRef tr ->
-		tr.tr_namespace = fst path && tr.tr_name = snd path
-	| TypeSpec ts -> (match follow ts.ts_signature with
-	| SClass c | SValueType c ->
-		is_type path c
-	| SGenericInst(s,_) -> (match follow s with
-		| SClass c | SValueType c ->
-			is_type path c
-		| _ -> false)
-	| _ -> false)
-	| _ -> assert false
-
-let rec get_path type_def_or_ref = match type_def_or_ref with
-	| TypeDef td -> (match td.td_extra_enclosing with
-		| None ->
-			td.td_namespace,[], td.td_name
-		| Some t2 ->
-			let ns, nested = match get_path (TypeDef t2) with
-				| ns,nested, name ->
-					ns, nested @ [name]
-			in
-			ns,nested, td.td_name)
-	| TypeRef tr -> (match tr.tr_resolution_scope with
-		| TypeRef tr2 ->
-			let ns, nested = match get_path (TypeRef tr2) with
-				| ns,nested, name ->
-					ns, nested @ [name]
-			in
-			ns,nested, tr.tr_name
-		| _ ->
-			tr.tr_namespace,[],tr.tr_name)
-	| TypeSpec ts -> (match follow ts.ts_signature with
-	| SClass c | SValueType c ->
-		get_path c
-	| SGenericInst(s,_) -> (match follow s with
-		| SClass c | SValueType c ->
-			get_path c
-		| _ -> [],[],"")
-	| _ -> [],[],"")
-	| _ -> assert false
-
-let constant_s = function
-	| IBool true -> "true"
-	| IBool false -> "false"
-	| IChar chr -> "'" ^ Char.escaped (Char.chr chr) ^ "'"
-	| IByte i ->
-		Printf.sprintf "(byte) 0x%x" i
-	| IShort i ->
-		Printf.sprintf "(short) 0x%x" i
-	| IInt i ->
-		Printf.sprintf "0x%lx" i
-	| IInt64 i ->
-		Printf.sprintf "0x%Lx" i
-	| IFloat32 f ->
-		Printf.sprintf "%ff" f
-	| IFloat64 f ->
-		Printf.sprintf "%fd" f
-	| IString s -> "\"" ^ s ^ "\""
-	| INull -> "null"
-
-let path_s = function
-	| [],[], s -> s
-	| ns,[], s -> String.concat "." ns ^ "." ^ s
-	| [],enc, s -> String.concat "@" enc ^ "." ^ s
-	| ns,enc,s -> String.concat "." ns ^ "." ^ String.concat "@" enc ^ "." ^ s
-
-let rec ilsig_s = function
-	| SBoxed -> "boxed"
-	| SEnum e -> "enum " ^ e
-	| SType -> "System.Type"
-	| SVoid -> "void"
-	| SBool -> "bool"
-	| SChar -> "char"
-	| SInt8 -> "int8"
-	| SUInt8 -> "uint8"
-	| SInt16 -> "int16"
-	| SUInt16 -> "uint16"
-	| SInt32 -> "int32"
-	| SUInt32 -> "uint32"
-	| SInt64 -> "int64"
-	| SUInt64 -> "uint64"
-	| SFloat32 -> "float"
-	| SFloat64 -> "double"
-	| SString -> "string"
-	| SPointer s -> ilsig_s s ^ "*"
-	| SManagedPointer s -> ilsig_s s ^ "&"
-	| SValueType td -> "valuetype " ^ path_s (get_path td)
-	| SClass cl -> "classtype " ^ path_s (get_path cl)
-	| STypeParam t | SMethodTypeParam t -> "!" ^ string_of_int t
-	| SArray (s,opts) ->
-		ilsig_s s ^ "[" ^ String.concat "," (List.map (function
-			| Some i,None when i <> 0 ->
-				string_of_int i ^ "..."
-			| None, Some i when i <> 0 ->
-				string_of_int i
-			| Some s, Some b when b = 0 && s <> 0 ->
-				string_of_int s ^ "..."
-			| Some s, Some b when s <> 0 || b <> 0 ->
-				let b = if b > 0 then b - 1 else b in
-				string_of_int s ^ "..." ^ string_of_int (s + b)
-			| _ ->
-				""
-		) (Array.to_list opts)) ^ "]"
-	| SGenericInst (t,tl) ->
-		"generic " ^ (ilsig_s t) ^ "<" ^ String.concat ", " (List.map ilsig_s tl) ^ ">"
-	| STypedReference -> "typedreference"
-	| SIntPtr -> "native int"
-	| SUIntPtr -> "native unsigned int"
-	| SFunPtr (callconv,ret,args) ->
-		"function " ^ ilsig_s ret ^ "(" ^ String.concat ", " (List.map ilsig_s args) ^ ")"
-	| SObject -> "object"
-	| SVector s -> ilsig_s s ^ "[]"
-	| SReqModifier (_,s) -> "modreq() " ^ ilsig_s s
-	| SOptModifier (_,s) -> "modopt() " ^ ilsig_s s
-	| SSentinel -> "..."
-	| SPinned s -> "pinned " ^ ilsig_s s
-
-let rec instance_s = function
-	| InstConstant c -> constant_s c
-	| InstBoxed b -> "boxed " ^ instance_s b
-	| InstType t -> "Type " ^ t
-	| InstArray il -> "[" ^ String.concat ", " (List.map instance_s il) ^ "]"
-	| InstEnum e -> "Enum " ^ string_of_int e
-
-let named_attribute_s (is_prop,name,inst) =
-	(if is_prop then
-		"/*prop*/ "
-	else
-		"")
-	^ name ^ " = " ^ instance_s inst
-
-let attributes_s (il,nal) =
-	"(" ^ (String.concat ", " (List.map instance_s il)) ^ (if nal <> [] then ", " ^ (String.concat ", " (List.map named_attribute_s nal)) else "") ^")"
-
-let meta_root m : meta_root = match m with
-	| Module r -> Obj.magic r
-	| TypeRef r -> Obj.magic r
-	| TypeDef r -> Obj.magic r
-	| FieldPtr r -> Obj.magic r
-	| Field r -> Obj.magic r
-	| MethodPtr r -> Obj.magic r
-	| Method r -> Obj.magic r
-	| ParamPtr r -> Obj.magic r
-	| Param r -> Obj.magic r
-	| InterfaceImpl r -> Obj.magic r
-	| MemberRef r -> Obj.magic r
-	| Constant r -> Obj.magic r
-	| CustomAttribute r -> Obj.magic r
-	| FieldMarshal r -> Obj.magic r
-	| DeclSecurity r -> Obj.magic r
-	| ClassLayout r -> Obj.magic r
-	| FieldLayout r -> Obj.magic r
-	| StandAloneSig r -> Obj.magic r
-	| EventMap r -> Obj.magic r
-	| EventPtr r -> Obj.magic r
-	| Event r -> Obj.magic r
-	| PropertyMap r -> Obj.magic r
-	| PropertyPtr r -> Obj.magic r
-	| Property r -> Obj.magic r
-	| MethodSemantics r -> Obj.magic r
-	| MethodImpl r -> Obj.magic r
-	| ModuleRef r -> Obj.magic r
-	| TypeSpec r -> Obj.magic r
-	| ImplMap r -> Obj.magic r
-	| FieldRVA r -> Obj.magic r
-	| ENCLog r -> Obj.magic r
-	| ENCMap r -> Obj.magic r
-	| Assembly r -> Obj.magic r
-	| AssemblyProcessor r -> Obj.magic r
-	| AssemblyOS r -> Obj.magic r
-	| AssemblyRef r -> Obj.magic r
-	| AssemblyRefProcessor r -> Obj.magic r
-	| AssemblyRefOS r -> Obj.magic r
-	| File r -> Obj.magic r
-	| ExportedType r -> Obj.magic r
-	| ManifestResource r -> Obj.magic r
-	| NestedClass r -> Obj.magic r
-	| GenericParam r -> Obj.magic r
-	| MethodSpec r -> Obj.magic r
-	| GenericParamConstraint r -> Obj.magic r
-	| _ -> assert false
-
-let meta_root_ptr p : meta_root_ptr = match p with
-	| FieldPtr r -> Obj.magic r
-	| MethodPtr r -> Obj.magic r
-	| ParamPtr r -> Obj.magic r
-	| EventPtr r -> Obj.magic r
-	| _ -> assert false
-
-let rec ilsig_norm = function
-	| SVoid -> LVoid
-	| SBool -> LBool
-	| SChar -> LChar
-	| SInt8 -> LInt8
-	| SUInt8 -> LUInt8
-	| SInt16 -> LInt16
-	| SUInt16 -> LUInt16
-	| SInt32 -> LInt32
-	| SUInt32 -> LUInt32
-	| SInt64 -> LInt64
-	| SUInt64 -> LUInt64
-	| SFloat32 -> LFloat32
-	| SFloat64 -> LFloat64
-	| SString -> LString
-	| SPointer p -> LPointer (ilsig_norm p)
-	| SManagedPointer p -> LManagedPointer (ilsig_norm p)
-	| SValueType v -> LValueType (get_path v, [])
-	| SClass v -> LClass (get_path v, [])
-	| STypeParam i -> LTypeParam i
-	| SArray (t, opts) -> LArray(ilsig_norm t, opts)
-	| SGenericInst (p,args) -> (match follow p with
-		| SClass v ->
-			LClass(get_path v, List.map ilsig_norm args)
-		| SValueType v ->
-			LValueType(get_path v, List.map ilsig_norm args)
-		| _ -> assert false)
-	| STypedReference -> LTypedReference
-	| SIntPtr -> LIntPtr
-	| SUIntPtr -> LUIntPtr
-	| SFunPtr(conv,ret,args) -> LMethod(conv,ilsig_norm ret,List.map ilsig_norm args)
-	| SObject -> LObject
-	| SVector s -> LVector (ilsig_norm s)
-	| SMethodTypeParam i -> LMethodTypeParam i
-	| SReqModifier (_,s) -> ilsig_norm s
-	| SOptModifier (_,s) -> ilsig_norm s
-	| SSentinel -> LSentinel
-	| SPinned s -> ilsig_norm s
-	| SType -> LClass( (["System"],[],"Type"), [])
-	| SBoxed -> LObject
-	| SEnum e ->
-		let lst = String.nsplit e "." in
-		let rev = List.rev lst in
-		match rev with
-		| hd :: tl -> LValueType( (List.rev tl,[],hd), [] )
-		| _ -> assert false
-
-let ilsig_t s =
-	{
-		snorm = ilsig_norm s;
-		ssig = s;
-	}
-
-let ilsig_of_tdef_ref = function
-	| TypeDef td ->
-		SClass (TypeDef td)
-	| TypeRef tr ->
-		SClass (TypeRef tr)
-	| TypeSpec ts ->
-		ts.ts_signature
-	| s ->
-		(* error ("Invalid tdef_or_ref: " ^ ilsig_s s) *)
-		error "Invalid tdef_or_ref"
-
-let convert_field ctx f =
-	let constant = List.fold_left (fun c -> function
-		| Constant c ->
-			Some c.c_value
-		| _ ->
-			c
-	) None (Hashtbl.find_all ctx.il_relations (IField, f.f_id))
-	in
-	{
-		fname = f.f_name;
-		fflags = f.f_flags;
-		fsig = ilsig_t f.f_signature;
-		fconstant = constant;
-	}
-
-let convert_generic ctx gp =
-	let constraints = List.fold_left (fun c -> function
-		| GenericParamConstraint gc ->
-			ilsig_t (ilsig_of_tdef_ref gc.gc_constraint) :: c
-		| _ ->
-			c
-	) [] (Hashtbl.find_all ctx.il_relations (IGenericParam, gp.gp_id))
-	in
-	{
-		tnumber = gp.gp_number;
-		tflags = gp.gp_flags;
-		tname = gp.gp_name;
-		tconstraints = constraints;
-	}
-
-let convert_method ctx m =
-	let msig = ilsig_t m.m_signature in
-	let ret, margs = match follow msig.ssig with
-	| SFunPtr (_,ret,args) ->
-		(* print_endline m.m_name; *)
-		(* print_endline (Printf.sprintf "%d vs %d" (List.length args) (List.length m.m_param_list)); *)
-		(* print_endline (String.concat ", " (List.map (fun p ->string_of_int p.p_sequence ^ ":" ^ p.p_name) m.m_param_list)); *)
-		(* print_endline (String.concat ", " (List.map (ilsig_s) args)); *)
-		(* print_endline "\n"; *)
-		(* TODO: find out WHY this happens *)
-		let param_list = List.filter (fun p -> p.p_sequence > 0) m.m_param_list in
-		if List.length param_list <> List.length args then
-			let i = ref 0 in
-			ilsig_t ret, List.map (fun s ->
-				incr i; "arg" ^ (string_of_int !i), { pf_io = []; pf_reserved = [] }, ilsig_t s) args
-		else
-			ilsig_t ret, List.map2 (fun p s ->
-				p.p_name, p.p_flags, ilsig_t s
-			) param_list args
-	| _ -> assert false
-	in
-
-	let override, types, semantics =
-		List.fold_left (fun (override,types,semantics) -> function
-		| MethodImpl mi ->
-			let declaring = match mi.mi_method_declaration with
-				| MemberRef mr ->
-					Some (get_path mr.memr_class, mr.memr_name)
-				| Method m -> (match m.m_declaring with
-					| Some td ->
-						Some (get_path (TypeDef td), m.m_name)
-					| None -> override)
-				| _ -> override
-			in
-			declaring, types, semantics
-		| GenericParam gp ->
-			override, (convert_generic ctx gp) :: types, semantics
-		| MethodSemantics ms ->
-			override, types, ms.ms_semantic @ semantics
-		| _ ->
-			override,types, semantics
-		) (None,[],[]) (Hashtbl.find_all ctx.il_relations (IMethod, m.m_id))
-	in
-	{
-		mname = m.m_name;
-		mflags = m.m_flags;
-		msig = msig;
-		margs = margs;
-		mret = ret;
-		moverride = override;
-		mtypes = types;
-		msemantics = semantics;
-	}
-
-let convert_prop ctx prop =
-	let name = prop.prop_name in
-	let flags = prop.prop_flags in
-	let psig = ilsig_t prop.prop_type in
-	let pget, pset =
-		List.fold_left (fun (get,set) -> function
-			| MethodSemantics ms when List.mem SGetter ms.ms_semantic ->
-				assert (get = None);
-				Some (ms.ms_method.m_name, ms.ms_method.m_flags), set
-			| MethodSemantics ms when List.mem SSetter ms.ms_semantic ->
-				assert (set = None);
-				get, Some (ms.ms_method.m_name,ms.ms_method.m_flags)
-			| _ -> get,set
-		)
-		(None,None)
-		(Hashtbl.find_all ctx.il_relations (IProperty, prop.prop_id))
-	in
-	{
-		pname = name;
-		psig = psig;
-		pflags = flags;
-		pget = pget;
-		pset = pset;
-	}
-
-let convert_event ctx event =
-	let name = event.e_name in
-	let flags = event.e_flags in
-	let esig = ilsig_of_tdef_ref event.e_event_type in
-	let esig = ilsig_t esig in
-	let add, remove, eraise =
-		List.fold_left (fun (add, remove, eraise) -> function
-			| MethodSemantics ms when List.mem SAddOn ms.ms_semantic ->
-				assert (add = None);
-				Some (ms.ms_method.m_name, ms.ms_method.m_flags), remove, eraise
-			| MethodSemantics ms when List.mem SRemoveOn ms.ms_semantic ->
-				assert (remove = None);
-				add, Some (ms.ms_method.m_name,ms.ms_method.m_flags), eraise
-			| MethodSemantics ms when List.mem SFire ms.ms_semantic ->
-				assert (eraise = None);
-				add, remove, Some (ms.ms_method.m_name, ms.ms_method.m_flags)
-			| _ -> add, remove, eraise
-		)
-		(None,None,None)
-		(Hashtbl.find_all ctx.il_relations (IEvent, event.e_id))
-	in
-	{
-		ename = name;
-		eflags = flags;
-		esig = esig;
-		eadd = add;
-		eremove = remove;
-		eraise = eraise;
-	}
-
-let convert_class ctx path =
-	let td = Hashtbl.find ctx.il_typedefs path in
-	let cpath = get_path (TypeDef td) in
-	let cflags = td.td_flags in
-	let csuper = Option.map (fun e -> ilsig_t (ilsig_of_tdef_ref e)) td.td_extends in
-	let cfields = List.map (convert_field ctx) td.td_field_list in
-	let cmethods = List.map (convert_method ctx) td.td_method_list in
-	let enclosing = Option.map (fun t -> get_path (TypeDef t)) td.td_extra_enclosing in
-	let impl, types, nested, props, events, attrs =
-		List.fold_left (fun (impl,types,nested,props,events,attrs) -> function
-			| InterfaceImpl ii ->
-				(ilsig_t (ilsig_of_tdef_ref ii.ii_interface)) :: impl,types,nested, props, events, attrs
-			| GenericParam gp ->
-				(impl, (convert_generic ctx gp) :: types, nested, props,events, attrs)
-			| NestedClass nc ->
-				assert (nc.nc_enclosing.td_id = td.td_id);
-				(impl,types,(get_path (TypeDef nc.nc_nested)) :: nested, props, events, attrs)
-			| PropertyMap pm ->
-				assert (props = []);
-				impl,types,nested,List.map (convert_prop ctx) pm.pm_property_list, events, attrs
-			| EventMap em ->
-				assert (events = []);
-				(impl,types,nested,props,List.map (convert_event ctx) em.em_event_list, attrs)
-			| CustomAttribute a ->
-				impl,types,nested,props,events,(a :: attrs)
-			| _ ->
-				(impl,types,nested,props,events,attrs)
-		)
-		([],[],[],[],[],[])
-		(Hashtbl.find_all ctx.il_relations (ITypeDef, td.td_id))
-	in
-	{
-		cpath = cpath;
-		cflags = cflags;
-		csuper = csuper;
-		cfields = cfields;
-		cmethods = cmethods;
-		cevents = events;
-		cprops = props;
-		cimplements = impl;
-		ctypes = types;
-		cenclosing = enclosing;
-		cnested = nested;
-		cattrs = attrs;
-	}

+ 0 - 78
libs/ilib/ilMetaWriter.ml

@@ -1,78 +0,0 @@
-(*
- *  This file is part of ilLib
- *  Copyright (c)2004-2013 Haxe Foundation
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *)
-
-open PeData;;
-open PeReader;;
-open IlMeta;;
-open IO;;
-
-(* encoding helpers *)
-
-let int_of_type_def_vis = function
-	(* visibility flags - mask 0x7 *)
-	| VPrivate -> 0x0 (* 0x0 *)
-	| VPublic -> 0x1 (* 0x1 *)
-	| VNestedPublic -> 0x2 (* 0x2 *)
-	| VNestedPrivate -> 0x3 (* 0x3 *)
-	| VNestedFamily -> 0x4 (* 0x4 *)
-	| VNestedAssembly -> 0x5 (* 0x5 *)
-	| VNestedFamAndAssem -> 0x6 (* 0x6 *)
-	| VNestedFamOrAssem -> 0x7 (* 0x7 *)
-
-let int_of_type_def_layout = function
-	(* layout flags - mask 0x18 *)
-	| LAuto -> 0x0 (* 0x0 *)
-	| LSequential -> 0x8 (* 0x8 *)
-	| LExplicit -> 0x10 (* 0x10 *)
-
-let int_of_type_def_semantics props = List.fold_left (fun acc prop ->
-		(match prop with
-		(* semantics flags - mask 0x5A0 *)
-		| SInterface -> 0x20 (* 0x20 *)
-		| SAbstract -> 0x80 (* 0x80 *)
-		| SSealed -> 0x100 (* 0x100 *)
-		| SSpecialName -> 0x400 (* 0x400 *)
-		) lor acc
-	) 0 props
-
-let int_of_type_def_impl props = List.fold_left (fun acc prop ->
-		(match prop with
-		(* type implementation flags - mask 0x103000 *)
-		| IImport -> 0x1000 (* 0x1000 *)
-		| ISerializable -> 0x2000 (* 0x2000 *)
-		| IBeforeFieldInit -> 0x00100000 (* 0x00100000 *)
-		) lor acc
-	) 0 props
-
-let int_of_type_def_string = function
-	(* string formatting flags - mask 0x00030000 *)
-	| SAnsi -> 0x0 (* 0x0 *)
-	| SUnicode -> 0x00010000 (* 0x00010000 *)
-	| SAutoChar -> 0x00020000 (* 0x00020000 *)
-
-let int_of_type_def_flags f =
-	int_of_type_def_vis f.tdf_vis
-		lor
-	int_of_type_def_layout f.tdf_layout
-		lor
-	int_of_type_def_semantics f.tdf_semantics
-		lor
-	int_of_type_def_impl f.tdf_impl
-		lor
-	int_of_type_def_string f.tdf_string

+ 0 - 546
libs/ilib/peData.ml

@@ -1,546 +0,0 @@
-(*
- *  This file is part of ilLib
- *  Copyright (c)2004-2013 Haxe Foundation
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *)
-
-(*
-	This data is based on the
-		Microsoft Portable Executable and Common Object File Format Specification
-	Revision 8.3
-*)
-
-type machine_type =
-	| TUnknown (* 0 - unmanaged PE files only *)
-	| Ti386 (* 0x014c - i386 *)
-	| TR3000 (* 0x0162 - R3000 MIPS Little Endian *)
-	| TR4000 (* 0x0166 - R4000 MIPS Little Endian *)
-	| TR10000 (* 0x0168 - R10000 MIPS Little Endian *)
-	| TWCeMipsV2 (* 0x0169 - MIPS Little Endian running MS Windows CE 2 *)
-	| TAlpha (* 0x0184 - Alpha AXP *)
-	| TSh3 (* 0x01a2 - SH3 Little Endian *)
-	| TSh3Dsp (* 0x01a3 SH3DSP Little Endian *)
-	| TSh3e (* 0x01a4 SH3E Little Endian *)
-	| TSh4 (* 0x01a6 SH4 Little Endian *)
-	| TSh5 (* 0x01a8 SH5 *)
-	| TArm (* 0x1c0 ARM Little Endian *)
-	| TArmN (* 0x1c4 ARMv7 (or higher) Thumb mode only Little Endian *)
-	| TArm64 (* 0xaa64 - ARMv8 in 64-bit mode *)
-	| TEbc (* 0xebc - EFI byte code *)
-	| TThumb (* 0x1c2 ARM processor with Thumb decompressor *)
-	| TAm33 (* 0x1d3 AM33 processor *)
-	| TPowerPC (* 0x01f0 IBM PowerPC Little Endian *)
-	| TPowerPCFP (* 0x01f1 IBM PowerPC with FPU *)
-	| TItanium64 (* 0x0200 Intel IA64 (Itanium) *)
-	| TMips16 (* 0x0266 MIPS *)
-	| TAlpha64 (* 0x0284 Alpha AXP64 *)
-	| TMipsFpu (* 0x0366 MIPS with FPU *)
-	| TMipsFpu16 (* 0x0466 MIPS16 with FPU *)
-	| TTriCore (* 0x0520 Infineon *)
-	| TAmd64 (* 0x8664 AMD x64 and Intel E64T *)
-	| TM32R (* 0x9041 M32R *)
-
-type coff_prop =
-	| RelocsStripped (* 0x1 *)
-		(* image file only. Indicates the file contains no base relocations and *)
-		(* must be loaded at its preferred base address. Should not be set for MPE files *)
-	| ExecutableImage (* 0x2 *)
-		(* Indicates that the file is an image file (EXE or DLL). Should be set for MPE files *)
-	| LineNumsStripped (* 0x4 *)
-		(* COFF line numbers have been removed. This flag should not be set for MPE files *)
-		(* because they do not use the debug info embedded in the PE file itself. They are saved on PDB files *)
-	| LocalSymsStripped (* 0x8 *)
-		(* COFF symbol table entries for local symbols have been removed. It should be set for MPE files *)
-	| AgressiveWsTrim (* 0x10 *)
-		(* Agressively trim the working set. This flag should not be set for pure-IL MPE files *)
-	| LargeAddressAware (* 0x20 *)
-		(* Application can handle addresses beyond the 2GB range. This flag should not be set for *)
-		(* pure-IL MPE files of versions 1 and 1.1, but can be set for v2.0 files *)
-	| BytesReversedLO (* 0x80 *)
-		(* Little endian. This flag should not be set for pure-IL MPE files *)
-	| Machine32Bit (* 0x100 *)
-		(* Machine is based on 32-bit architecture. This flag is usually set by the current *)
-		(* versions of code generators producing PE files. V2.0+ can produce 64-bit specific images *)
-		(* which don't have this flag set *)
-	| DebugStripped (* 0x200 *)
-		(* Debug information has been removed from the image file *)
-	| RemovableRunFromSwap (* 0x400 *)
-		(* If the image file is on removable media, copy and run it from swap file. *)
-		(* This flag should no be set for pure-IL MPE files *)
-	| NetRunFromSwap (* 0x800 *)
-		(* If the image file is on a network, copy and run it from the swap file. *)
-		(* This flag should no be set for pure-IL MPE files *)
-	| FileSystem (* 0x1000 *)
-		(* The image file is a system file (for example, a device driver) *)
-		(* This flag should not be set for pure-IL MPE files *)
-	| FileDll (* 0x2000 *)
-		(* This image file is a DLL rather than an EXE. It cannot be directly run. *)
-	| UpSystemOnly (* 0x4000 *)
-		(* The image file should be run on an uniprocessor machine only. *)
-		(* This flag should not be set for pure-IL MPE files *)
-	| BytesReversedHI (* 0x8000 *)
-		(* Big endian *)
-		(* This flag should not be set for pure-IL MPE files *)
-
-(* represents a virtual address pointer. It's 64-bit on 64-bit executables, and 32-bit otherwise *)
-type pointer = int64
-
-(* represents a memory index address on the target architecture. It's 64-bit on 64-bit executables, and 32-bit otherwise *)
-type size_t = pointer
-
-(* relative virtual address. *)
-(* it's always 32-bit - which means that PE/COFF files are still limited to the 4GB size *)
-type rva = int32
-
-(* represents a PE file-bound memory index *)
-type size_t_file = int32
-
-(* represents a file offset *)
-(* there's no point in defining it as int32, as file seek operations need an int *)
-type pointer_file = int
-
-type coff_header = {
-	coff_machine : machine_type; (* offset 0 - size 2 . *)
-		(* If the managed PE file is intended for various machine types (AnyCPU), it should be Ti386 *)
-	coff_nsections : int; (* O2S2 *)
-	coff_timestamp : int32; (* O4S4 *)
-	coff_symbol_table_pointer : rva; (* O8S4 *)
-		(* File pointer of the COFF symbol table. In managed PE files, it is 0 *)
-	coff_nsymbols : int; (* O12S4 *)
-		(* Number of entries in the COFF symbol table. Should be 0 in managed PE files *)
-	coff_optheader_size: int; (* O16S2 *)
-		(* Size of the PE header *)
-	coff_props : coff_prop list;
-}
-
-let coff_default_exe_props = [ ExecutableImage; LineNumsStripped; LocalSymsStripped; (* Machine32Bit; *) ]
-
-let coff_default_dll_props = [ ExecutableImage; LineNumsStripped; LocalSymsStripped; (* Machine32Bit; *) FileDll ]
-
-type pe_magic =
-	| P32 (* 0x10b *)
-	| PRom (* 0x107 *)
-	| P64 (* 0x20b - called PE32+ on the docs *)
-		(* allows 64-bit address space while limiting the image size to 2 gb *)
-
-type subsystem =
-	| SUnknown (* 0 *)
-	| SNative (* 1 *)
-		(* Device drivers and native windows processes *)
-	| SWGui (* 2 *)
-		(* Windows GUI subsystem *)
-	| SWCui (* 3 *)
-		(* Windows character subsystem *)
-	| SPCui (* 7 *)
-		(* Posix character subsystem *)
-	| SWCeGui (* 9 *)
-		(* Windows CE subsystem *)
-	| SEfi (* 10 *)
-		(* EFI application *)
-	| SEfiBoot (* 11 *)
-		(* EFI driver with boot services *)
-	| SEfiRuntime (* 12 *)
-		(* EFI driver with run-time services *)
-	| SEfiRom (* 13 *)
-		(* EFI ROM Image *)
-	| SXbox (* 14 *)
-
-type dll_prop =
-	| DDynamicBase (* 0x0040 *)
-		(* DLL can be relocated at load time *)
-	| DForceIntegrity (* 0x0080 *)
-		(* Code integrity checks are enforced *)
-	| DNxCompat (* 0x0100 *)
-		(* Image is NX compatible *)
-	| DNoIsolation (* 0x0200 *)
-		(* Isolation-aware, but do not isolate the image *)
-	| DNoSeh (* 0x0400 *)
-		(* No structured exception handling *)
-	| DNoBind (* 0x0800 *)
-		(* Do not bind the image *)
-	| DWdmDriver (* 0x2000 *)
-		(* A WDM driver *)
-	| DTerminalServer (* 0x8000 *)
-		(* Terminal server aware *)
-
-type directory_type =
-	| ExportTable (* .edata *)
-		(* contains information about four other tables, which hold data describing *)
-		(* unmanaged exports of the PE file. ILAsm and VC++ linker are capable of exposing *)
-		(* the managed PE file as unmanaged exports *)
-	| ImportTable (* .idata *)
-		(* data on unmanaged imports consumed by the PE file. Only the VC++ linker makes *)
-		(* use of this table, by marking the imported unmanaged external functions used by *)
-		(* the unmanaged native code embedded in the same assembly. Other compilers only *)
-		(* contain a single entry - that of the CLR entry function *)
-	| ResourceTable (* .rsrc *)
-		(* unmanaged resources embedded in the PE file. Managed resources don't use this *)
-	| ExceptionTable (* .pdata *)
-		(* unmanaged exceptions only *)
-	| CertificateTable
-		(* points to a table of attribute certificates, used for file authentication *)
-		(* the first field of this entry is a file pointer rather than an RVA *)
-	| RelocTable (* .reloc *)
-		(* relocation table. We need to be aware of it if we use native TLS. *)
-		(* only the VC++ linker uses native TLS' *)
-	| DebugTable
-		(* unmanaged debug data starting address and size. A managed PE file doesn't carry *)
-		(* embedded debug data, so this data is either all zero or points to a 30-byte debug dir entry *)
-		(* of type 2 (IMAGE_DEBUG_TYPE_CODEVIEW), which in turn points to a CodeView-style header, containing *)
-		(* the path to the PDB debug file. *)
-	| ArchitectureTable
-		(* for i386, Itanium64 or AMD64, this data is set to all zeros *)
-	| GlobalPointer
-		(* the RVA of the value to be stored in the global pointer register. Size must be 0. *)
-		(* if the target architecture (e.g. i386 or AMD64) don't use the concept of a global pointer, *)
-		(* it is set to all zeros *)
-	| TlsTable (* .tls *)
-		(* The thread-local storage data. Only the VC++ linker and IL assembler produce code that use it *)
-	| LoadConfigTable
-		(* data specific to Windows NT OS *)
-	| BoundImportTable
-		(* array of bound import descriptors, each of which describes a DLL this image was bound *)
-		(* at link-time, along with time stamps of the bindings. Iff they are up-to-date, the OS loader *)
-		(* uses these bindings as a "shortcut" for API import *)
-	| ImportAddressTable
-		(* referenced from the Import Directory table (data directory 1) *)
-	| DelayImport
-		(* delay-load imports are DLLs described as implicit imports but loaded as explicit imports *)
-		(* (via calls to the LoadLibrary API) *)
-	| ClrRuntimeHeader (* .cormeta *)
-		(* pointer to the clr_runtime_header *)
-	| Reserved
-		(* must be zero *)
-	| Custom of int
-
-let directory_type_info = function
-	| ExportTable -> 0, "ExportTable"
-	| ImportTable -> 1, "ImportTable"
-	| ResourceTable -> 2, "ResourceTable"
-	| ExceptionTable -> 3, "ExceptionTable"
-	| CertificateTable -> 4, "CertificateTable"
-	| RelocTable -> 5, "RelocTable"
-	| DebugTable -> 6, "DebugTable"
-	| ArchitectureTable -> 7, "ArchTable"
-	| GlobalPointer -> 8, "GlobalPointer"
-	| TlsTable -> 9, "TlsTable"
-	| LoadConfigTable -> 10, "LoadConfigTable"
-	| BoundImportTable -> 11, "BuildImportTable"
-	| ImportAddressTable -> 12, "ImportAddressTable"
-	| DelayImport -> 13, "DelayImport"
-	| ClrRuntimeHeader -> 14, "ClrRuntimeHeader"
-	| Reserved -> 15, "Reserved"
-	| Custom i -> i, "Custom" ^ (string_of_int i)
-
-let directory_type_of_int = function
-	| 0 -> ExportTable
-	| 1 -> ImportTable
-	| 2 -> ResourceTable
-	| 3 -> ExceptionTable
-	| 4 -> CertificateTable
-	| 5 -> RelocTable
-	| 6 -> DebugTable
-	| 7 -> ArchitectureTable
-	| 8 -> GlobalPointer
-	| 9 -> TlsTable
-	| 10 -> LoadConfigTable
-	| 11 -> BoundImportTable
-	| 12 -> ImportAddressTable
-	| 13 -> DelayImport
-	| 14 -> ClrRuntimeHeader
-	| 15 -> Reserved
-	| i -> Custom i
-
-type section_prop =
-	| SNoPad (* 0x8 *)
-		(* the section should not be padded to the next boundary. *)
-		(* OBSOLETE - replaced by SAlign1Bytes *)
-	| SHasCode (* 0x20 *)
-		(* the section contains executable code *)
-	| SHasIData (* 0x40 *)
-		(* contains initialized data *)
-	| SHasData (* 0x80 *)
-		(* contains uninitialized data *)
-	| SHasLinkInfo (* 0x200 *)
-		(* contains comments or other information. only valid for object files *)
-	| SLinkRemove (* 0x1000 *)
-		(* this will not become part of the image. only valid for object files *)
-	| SGlobalRel (* 0x8000 *)
-		(* contains data referenced through the global pointer (GP) *)
-	| SHas16BitMem (* 0x20000 *)
-		(* for ARM architecture. The section contains Thumb code *)
-	| SAlign1Bytes (* 0x100000 *)
-		(* align data on a 1-byte boundary. valid only for object files *)
-	| SAlign2Bytes (* 0x200000 *)
-	| SAlign4Bytes (* 0x300000 *)
-	| SAlign8Bytes (* 0x400000 *)
-	| SAlign16Bytes (* 0x500000 *)
-	| SAlign32Bytes (* 0x600000 *)
-	| SAlign64Bytes (* 0x700000 *)
-	| SAlign128Bytes (* 0x800000 *)
-	| SAlign256Bytes (* 0x900000 *)
-	| SAlign512Bytes (* 0xA00000 *)
-	| SAlign1024Bytes (* 0xB00000 *)
-	| SAlign2048Bytes (* 0xC00000 *)
-	| SAlign4096Bytes (* 0xD00000 *)
-	| SAlign8192Bytes (* 0xE00000 *)
-	| SHasExtRelocs (* 0x1000000 *)
-		(* section contains extended relocations *)
-	| SCanDiscard (* 0x02000000 *)
-		(* section can be discarded as needed *)
-	| SNotCached (* 0x04000000 *)
-		(* section cannot be cached *)
-	| SNotPaged (* 0x08000000 *)
-		(* section is not pageable *)
-	| SShared (* 0x10000000 *)
-		(* section can be shared in memory *)
-	| SExec (* 0x20000000 *)
-		(* section can be executed as code *)
-	| SRead (* 0x40000000 *)
-		(* section can be read *)
-	| SWrite (* 0x80000000 *)
-		(* section can be written to *)
-
-type pe_section = {
-	s_name : string;
-		(* an 8-byte, null-padded UTF-8 encoded string *)
-	s_vsize : size_t_file;
-		(* the total size of the section when loaded into memory. *)
-		(* if less than s_rawsize, the section is zero-padded *)
-		(* should be set to 0 on object files *)
-	s_vaddr : rva;
-		(* the RVA of the beginning of the section *)
-	s_raw_size : size_t_file;
-		(* the size of the initialized data on disk, rounded up to a multiple *)
-		(* of the file alignment value. If it's less than s_vsize, it should be *)
-		(* zero filled. It may happen that rawsize is greater than vsize. *)
-	s_raw_pointer : pointer_file;
-		(* the file pointer to the first page of the section within the COFF file *)
-		(* on executable images, this must be a multiple of file aignment value. *)
-		(* for object files, it should be aligned on a 4byte boundary *)
-	s_reloc_pointer : pointer_file;
-		(* the file pointer to the beginning of relocation entries for this section *)
-		(* this is set to zero for executable images or if there are no relocations *)
-	s_line_num_pointer : pointer_file;
-		(* the file pointer to the beginning of line-number entries for this section *)
-		(* must be 0 : COFF debugging image is deprecated *)
-	s_nrelocs : int;
-		(* number of relocation entries *)
-	s_nline_nums : int;
-		(* number of line number entries *)
-	s_props : section_prop list;
-		(* properties of the section *)
-}
-
-(* The size of the PE header is not fixed. It depends on the number of data directories defined in the header *)
-(* and is specified in the optheader_size in the COFF header *)
-(* object files don't have this; but it's required for image files *)
-type pe_header = {
-	pe_coff_header : coff_header;
-	(* Standard fields *)
-	pe_magic : pe_magic;
-	pe_major : int;
-	pe_minor : int;
-	pe_code_size : int;
-		(* size of the code section (.text) or the sum of all code sections, *)
-		(* if multiple sections exist. The IL assembler always emits a single code section *)
-	pe_init_size : int;
-	pe_uinit_size : int;
-	pe_entry_addr : rva;
-		(* RVA of the beginning of the entry point function. For unmanaged DLLs, this can be 0 *)
-		(* For managed PE files, this always points to the CLR invocation stub *)
-	pe_base_code : rva;
-		(* The address that is relative to the image base of the beginning-of-code section *)
-		(* when it's loaded into memory *)
-	pe_base_data : rva;
-		(* The address that is relative to the image base of the beginning-of-data section *)
-		(* when it's loaded into memory *)
-
-	(* COFF Windows extension *)
-	pe_image_base : pointer;
-		(* The preferred address of the first byte of image when loaded into memory. *)
-		(* Should be a multiple of 64K *)
-	pe_section_alignment : int;
-		(* The alignment in bytes of sections when they are loaded into memory *)
-		(* It must be greater than or equal to FileAlignment. The default is the page size *)
-		(* for the architecture *)
-		(* x86 MPE files should have an alignment of 8KB, even though only 4KB would be needed *)
-		(* for compatibility with 64-bits *)
-	pe_file_alignment : int;
-		(* The alignment factor in bytes that is used to align the raw data of sections *)
-		(* in the image file. The value should be a POT between 512 and 64K. *)
-		(* If secion_alignment is less than architecture's page size, file_alignment must match *)
-		(* secion_alignment *)
-	pe_major_osver : int;
-	pe_minor_osver : int;
-	pe_major_imgver : int;
-	pe_minor_imgver : int;
-	pe_major_subsysver : int;
-	pe_minor_subsysver : int;
-	pe_image_size : int;
-		(* the size of the image in bytes, as the image is loaded into memory *)
-		(* must be a multiple of section_alignment *)
-	pe_headers_size : int;
-		(* the combined size of an MSDOS stub, PE header, and section headers *)
-		(* rounded up to a multiple of FileAlignment *)
-	pe_checksum : int32;
-	pe_subsystem : subsystem;
-	pe_dll_props : dll_prop list;
-		(* in MPE files of v1.0, always set to 0; In MPE of v1.1 and later, *)
-		(* always set to 0x400 (DNoSeh) *)
-	pe_stack_reserve : size_t;
-		(* the size of the stack to reserve. Only pe_stack_commit is committed *)
-	pe_stack_commit : size_t;
-		(* the size of the stack to commit *)
-	pe_heap_reserve : size_t;
-		(* the size of the local heap space to reserve. Only pe_heap_commit is committed *)
-	pe_heap_commit : size_t;
-		(* the size of the heap to commit *)
-	pe_ndata_dir : int;
-		(* the number of data-directory entries in the remainder of the optional header *)
-		(* should be at least 16. Although is possible to emit more than 16 data directories, *)
-		(* all existing managed compilers emit exactly 16 data directories, with the last never *)
-		(* used (reserved) *)
-	pe_data_dirs : (rva * size_t_file) array;
-		(* data directories are RVA's that point to sections on the PE that have special significance *)
-		(* see directory_type docs *)
-
-	(* sections *)
-	pe_sections : pe_section array;
-}
-
-(* raw .idata table *)
-(* not used : only here for documentation purposes *)
-type idata_table_raw = {
-	impr_lookup_table : rva;
-		(* the RVA of the lookup table *)
-	impr_timestamp : int32;
-		(* on bound images, it's set to the timestamp of the DLL *)
-	impr_fchain : int32;
-		(* the index of the first forwarder reference - which are references *)
-		(* that are both imported and exported *)
-	impr_name : rva;
-		(* the RVA to an ASCII string that contains the name of the DLL *)
-	impr_address_table : rva;
-		(* RVA of the import address table. The contents are identical to the imp_lookup_table *)
-		(* until the image is bound *)
-}
-
-(* a symbol lookup can happen either by name, or by ordinal. *)
-(* lookup by name happens to be an extra indirection, as the loader *)
-(* uses the name to look up the export ordinal anyway. *)
-(* Most (if not all) MPE will do a lookup by name, though *)
-type symbol_lookup =
-	| SName of int * string
-	| SOrdinal of int
-
-type idata_table = {
-	imp_name : string;
-		(* ASCII string that contains the name of the DLL *)
-	imp_imports : symbol_lookup list;
-}
-
-type clr_flag =
-	| FIlOnly (* 0x1 *)
-		(* the image file contains IL code only, with no embedded native unmanaged code *)
-		(* this can cause some problems on WXP+, because the .reloc section is ignored when this flag is set *)
-		(* e.g. if native TLS support is used. In this case the VC++ compiler unsets this flag *)
-	| F32BitRequired (* 0x2 *)
-		(* the file can be only loaded into a 32-bit process *)
-	| FIlLibrary (* 0x4 *)
-		(* obsolete *)
-	| FSigned (* 0x8 *)
-		(* the image file is protected with a strong name signature *)
-	| FNativeEntry (* 0x10 *)
-		(* the executable's entry point is an unmanaged method. *)
-		(* the EntryPointToken / EntryPointRVA field of the CLR header *)
-		(* contains the RVA of this native method *)
-	| FTrackDebug (* 0x10000 *)
-		(* the CLR loader is required to track debug information about the methods. This flag is not used *)
-
-type clr_header = {
-	clr_cb : int;
-		(* size of header *)
-	clr_major : int;
-	clr_minor : int;
-
-	(* symbol table and startup information *)
-	clr_meta : rva * size_t_file;
-	clr_flags : clr_flag list;
-	clr_entry_point : rva;
-		(* metadata identifier (token) of the entry point for the image file *)
-		(* can be 0 for DLL images. This field identifies a method belonging to this module *)
-		(* or a module containing the entry point method. This field may contain RVA of the *)
-		(* embedded native entry point method, if FNativeEntry flag is set *)
-
-	(* binding information *)
-	clr_res : rva * size_t_file;
-		(* RVA of managed resources *)
-	clr_sig : rva * size_t_file;
-		(* RVA of the hash data for this PE file, used by the loader for binding and versioning *)
-
-	(* regular fixup and binding information *)
-	clr_codeman : rva * size_t_file;
-		(* code manager table - RESERVED and should be 0 *)
-	clr_vtable_fix : rva * size_t_file;
-		(* RVA of an array of vtable fixups. Only VC++ linker and IL assembler produce data in this array *)
-	clr_export_address : rva * size_t_file;
-		(* rva of addresses of jump thunks. obsolete and should be set to 0 *)
-}
-
-(* unused structure: documentation purposes only *)
-type clr_stream_header = {
-	str_offset : pointer_file;
-		(* the (relative to the start of metadata) offset in the file for this stream *)
-	str_size : size_t_file;
-		(* the size of the stream in bytes *)
-	str_name : string;
-		(* name of the stream - a zero-terminated ASCII string no longer than 31 characters (plus 0 terminator) *)
-		(* if the stream name is smaller, it can be reduced - but must be padded to the 4-byte boundary *)
-}
-
-(* unused structure: documentation purposes only *)
-type clr_meta_table = {
-	(* storage signature *)
-	meta_magic : string;
-		(* always BSJB *)
-	meta_major : int;
-	meta_minor : int;
-	(* meta_extra : int; *)
-		(* reserved; always 0 *)
-	meta_ver : string;
-		(* encoded by first passing its length *)
-
-	(* storage header *)
-	(* meta_flags : int; *)
-		(* reserved; always 0 *)
-	meta_nstreams : int;
-		(* number of streams *)
-	meta_strings_stream : clr_stream_header;
-		(* #Strings: a string heap containing the names of metadata items *)
-	meta_blob_stream : clr_stream_header;
-		(* #Blob: blob heap containing internal metadata binary object, such as default values, signatures, etc *)
-	meta_guid_stream : clr_stream_header;
-		(* #GUID: a GUID heap *)
-	meta_us_stream : clr_stream_header;
-		(* #US: user-defined strings *)
-	meta_meta_stream : clr_stream_header;
-		(* may be either: *)
-			(* #~: compressed (optimized) metadata stream *)
-			(* #-: uncompressed (unoptimized) metadata stream *)
-	meta_streams : clr_stream_header list;
-		(* custom streams *)
-}

+ 0 - 184
libs/ilib/peDataDebug.ml

@@ -1,184 +0,0 @@
-(*
- *  This file is part of ilLib
- *  Copyright (c)2004-2013 Haxe Foundation
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *)
-open PeData;;
-open Printf;;
-
-let machine_type_s m = match m with
-	| TUnknown -> "TUnknown"
-	| Ti386 -> "Ti386"
-	| TR3000 -> "TR3000"
-	| TR4000 -> "TR4000"
-	| TR10000 -> "TR10000"
-	| TWCeMipsV2 -> "TWCeMipsV2"
-	| TAlpha -> "TAlpha"
-	| TSh3 -> "TSh3"
-	| TSh3Dsp -> "TSh3Dsp"
-	| TSh3e -> "TSh3e"
-	| TSh4 -> "TSh4"
-	| TSh5 -> "TSh5"
-	| TArm -> "TArm"
-	| TArmN -> "TArmN"
-	| TArm64 -> "TArm64"
-	| TEbc -> "TEbc"
-	| TThumb -> "TThumb"
-	| TAm33 -> "TAm33"
-	| TPowerPC -> "TPowerPC"
-	| TPowerPCFP -> "TPowerPCFP"
-	| TItanium64 -> "TItanium64"
-	| TMips16 -> "TMips16"
-	| TAlpha64 -> "TAlpha64"
-	| TMipsFpu -> "TMipsFpu"
-	| TMipsFpu16 -> "TMipsFpu16"
-	| TTriCore -> "TTriCore"
-	| TAmd64 -> "TAmd64"
-	| TM32R -> "TM32R"
-
-let coff_prop_s p = match p with
-	| RelocsStripped -> "RelocsStripped"
-	| ExecutableImage -> "ExecutableImage"
-	| LineNumsStripped -> "LineNumsStripped"
-	| LocalSymsStripped -> "LocalSymsStripped"
-	| AgressiveWsTrim -> "AgressiveWsTrim"
-	| LargeAddressAware -> "LargeAddressAware"
-	| BytesReversedLO -> "BytesReversedLO"
-	| Machine32Bit -> "Machine32Bit"
-	| DebugStripped -> "DebugStripped"
-	| RemovableRunFromSwap -> "RemovableRunFromSwap"
-	| NetRunFromSwap -> "NetRunFromSwap"
-	| FileSystem -> "FileSystem"
-	| FileDll -> "FileDll"
-	| UpSystemOnly -> "UpSystemOnly"
-	| BytesReversedHI -> "BytesReversedHI"
-
-let coff_header_s h =
-	sprintf "#COFF_HEADER\n\tmachine: %s\n\tnsections: %d\n\ttimestamp: %ld\n\tsymbol_tbl_pointer: %ld\n\tnsymbols: %d\n\toptheader_size: %x\n\tprops: [%s]\n"
-		(machine_type_s h.coff_machine)
-		h.coff_nsections
-		h.coff_timestamp
-		h.coff_symbol_table_pointer
-		h.coff_nsymbols
-		h.coff_optheader_size
-		(String.concat ", " (List.map coff_prop_s h.coff_props))
-
-let pe_magic_s = function
-	| P32 -> "P32"
-	| PRom -> "PRom"
-	| P64 -> "P64"
-
-let subsystem_s = function
-	| SUnknown -> "SUnknown" (* 0 *)
-	| SNative -> "SNative" (* 1 *)
-	| SWGui -> "SWGui" (* 2 *)
-	| SWCui -> "SWCui" (* 3 *)
-	| SPCui -> "SPCui" (* 7 *)
-	| SWCeGui -> "SWCeGui" (* 9 *)
-	| SEfi -> "SEfi" (* 10 *)
-	| SEfiBoot -> "SEfiBoot" (* 11 *)
-	| SEfiRuntime -> "SEfiRuntime" (* 12 *)
-	| SEfiRom -> "SEfiRom" (* 13 *)
-	| SXbox -> "SXbox" (* 14 *)
-
-let dll_prop_s = function
-	| DDynamicBase -> "DDynamicBase" (* 0x0040 *)
-	| DForceIntegrity -> "DForceIntegrity" (* 0x0080 *)
-	| DNxCompat -> "DNxCompat" (* 0x0100 *)
-	| DNoIsolation -> "DNoIsolation" (* 0x0200 *)
-	| DNoSeh -> "DNoSeh" (* 0x0400 *)
-	| DNoBind -> "DNoBind" (* 0x0800 *)
-	| DWdmDriver -> "DWdmDriver" (* 0x2000 *)
-	| DTerminalServer -> "DTerminalServer" (* 0x8000 *)
-
-let section_prop_s = function
-	| SNoPad -> "SNoPad"
-	| SHasCode -> "SHasCode"
-	| SHasIData -> "SHasIData"
-	| SHasData -> "SHasData"
-	| SHasLinkInfo -> "SHasLinkInfo"
-	| SLinkRemove -> "SLinkRemove"
-	| SGlobalRel -> "SGlobalRel"
-	| SHas16BitMem -> "SHas16BitMem"
-	| SAlign1Bytes -> "SAlign1Bytes"
-	| SAlign2Bytes -> "SAlign2Bytes"
-	| SAlign4Bytes -> "SAlign4Bytes"
-	| SAlign8Bytes -> "SAlign8Bytes"
-	| SAlign16Bytes -> "SAlign16Bytes"
-	| SAlign32Bytes -> "SAlign32Bytes"
-	| SAlign64Bytes -> "SAlign64Bytes"
-	| SAlign128Bytes -> "SAlign128Bytes"
-	| SAlign256Bytes -> "SAlign256Bytes"
-	| SAlign512Bytes -> "SAlign512Bytes"
-	| SAlign1024Bytes -> "SAlign1024Bytes"
-	| SAlign2048Bytes -> "SAlign2048Bytes"
-	| SAlign4096Bytes -> "SAlign4096Bytes"
-	| SAlign8192Bytes -> "SAlign8192Bytes"
-	| SHasExtRelocs -> "SHasExtRelocs"
-	| SCanDiscard -> "SCanDiscard"
-	| SNotCached -> "SNotCached"
-	| SNotPaged -> "SNotPaged"
-	| SShared -> "SShared"
-	| SExec -> "SExec"
-	| SRead -> "SRead"
-	| SWrite -> "SWrite"
-
-let pe_section_s s =
-	Printf.sprintf "\t%s :\n\t\trva: %lx\n\t\traw size: %lx\n\t\tprops: [%s]"
-		s.s_name
-		s.s_vaddr
-		s.s_raw_size
-		(String.concat ", " (List.map section_prop_s s.s_props))
-
-let data_dirs_s a =
-	let lst = Array.to_list (Array.mapi (fun i (r,l) ->
-		let _,s = directory_type_info (directory_type_of_int i) in
-		Printf.sprintf "%s: %lx (%lx)" s r l
-	) a) in
-	String.concat "\n\t\t" lst
-
-let pe_header_s h =
-	sprintf "#PE_HEADER\n\tmagic: %s\n\tmajor.minor %d.%d\n\tsubsystem: %s\n\tdll props: [%s]\n\tndata_dir: %i\n\t\t%s\n#SECTIONS\n%s"
-		(pe_magic_s h.pe_magic)
-		h.pe_major h.pe_minor
-		(subsystem_s h.pe_subsystem)
-		(String.concat ", " (List.map dll_prop_s h.pe_dll_props))
-		h.pe_ndata_dir
-		(data_dirs_s h.pe_data_dirs)
-		(String.concat "\n" (List.map pe_section_s (Array.to_list h.pe_sections)))
-
-let symbol_lookup_s = function
-	| SName (hint,s) -> "SName(" ^ string_of_int hint ^ ", " ^ s ^ ")"
-	| SOrdinal i -> "SOrdinal(" ^ string_of_int i ^ ")"
-
-let idata_table_s t =
-	sprintf "#IMPORT %s:\n\t%s"
-		t.imp_name
-		(String.concat "\n\t" (List.map symbol_lookup_s t.imp_imports))
-
-let clr_flag_s = function
-	| FIlOnly -> "FIlOnly" (* 0x1 *)
-	| F32BitRequired -> "F32BitRequired" (* 0x2 *)
-	| FIlLibrary -> "FIlLibrary" (* 0x4 *)
-	| FSigned -> "FSigned" (* 0x8 *)
-	| FNativeEntry -> "FNativeEntry" (* 0x10 *)
-	| FTrackDebug -> "FTrackDebug" (* 0x10000 *)
-
-let clr_header_s h =
-	sprintf "#CLR v%d.%d\n\tflags: %s"
-		h.clr_major
-		h.clr_minor
-		(String.concat ", " (List.map clr_flag_s h.clr_flags))

+ 0 - 493
libs/ilib/peReader.ml

@@ -1,493 +0,0 @@
-(*
- *  This file is part of ilLib
- *  Copyright (c)2004-2013 Haxe Foundation
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *)
-
-open PeData;;
-open IO;;
-open ExtString;;
-open ExtList;;
-
-exception Error_message of string
-
-type reader_ctx = {
-	ch : Pervasives.in_channel;
-	i : IO.input;
-	verbose : bool;
-}
-
-type ctx = {
-	r : reader_ctx;
-	pe_header : pe_header;
-	read_word : IO.input -> pointer;
-}
-
-let error msg = raise (Error_message msg)
-
-let seek r pos =
-	seek_in r.ch pos
-
-let pos r =
-	Pervasives.pos_in r.ch
-
-let info r msg =
-	if r.verbose then
-		print_endline (msg())
-
-let machine_type_of_int i = match i with
-	| 0x0 -> TUnknown (* 0 - unmanaged PE files only *)
-	| 0x014c -> Ti386 (* 0x014c - i386 *)
-	| 0x0162 -> TR3000 (* 0x0162 - R3000 MIPS Little Endian *)
-	| 0x0166 -> TR4000 (* 0x0166 - R4000 MIPS Little Endian *)
-	| 0x0168 -> TR10000 (* 0x0168 - R10000 MIPS Little Endian *)
-	| 0x0169 -> TWCeMipsV2 (* 0x0169 - MIPS Litlte Endian running MS Windows CE 2 *)
-	| 0x0184 -> TAlpha (* 0x0184 - Alpha AXP *)
-	| 0x01a2 -> TSh3 (* 0x01a2 - SH3 Little Endian *)
-	| 0x01a3 -> TSh3Dsp (* 0x01a3 SH3DSP Little Endian *)
-	| 0x01a4 -> TSh3e (* 0x01a4 SH3E Little Endian *)
-	| 0x01a6 -> TSh4 (* 0x01a6 SH4 Little Endian *)
-	| 0x01a8 -> TSh5
-	| 0x01c0 -> TArm (* 0x1c0 ARM Little Endian *)
-	| 0x01c2 -> TThumb (* 0x1c2 ARM processor with Thumb decompressor *)
-	| 0x01c4 -> TArmN (* 0x1c0 ARM Little Endian *)
-	| 0xaa64 -> TArm64
-	| 0xebc -> TEbc
-	| 0x01d3 -> TAm33 (* 0x1d3 AM33 processor *)
-	| 0x01f0 -> TPowerPC (* 0x01f0 IBM PowerPC Little Endian *)
-	| 0x01f1 -> TPowerPCFP (* 0x01f1 IBM PowerPC with FPU *)
-	| 0x0200 -> TItanium64 (* 0x0200 Intel IA64 (Itanium( *)
-	| 0x0266 -> TMips16 (* 0x0266 MIPS *)
-	| 0x0284 -> TAlpha64 (* 0x0284 Alpha AXP64 *)
-	| 0x0366 -> TMipsFpu (* 0x0366 MIPS with FPU *)
-	| 0x0466 -> TMipsFpu16 (* 0x0466 MIPS16 with FPU *)
-	| 0x0520 -> TTriCore (* 0x0520 Infineon *)
-	| 0x8664 -> TAmd64 (* 0x8664 AMD x64 and Intel E64T *)
-	| 0x9041 -> TM32R (* 0x9041 M32R *)
-	| _ -> assert false
-
-let coff_props_of_int iprops = List.fold_left (fun acc i ->
-	if (iprops land i) = i then (match i with
-		| 0x1 -> RelocsStripped (* 0x1 *)
-		| 0x2 -> ExecutableImage (* 0x2 *)
-		| 0x4 -> LineNumsStripped (* 0x4 *)
-		| 0x8 -> LocalSymsStripped (* 0x8 *)
-		| 0x10 -> AgressiveWsTrim (* 0x10 *)
-		| 0x20 -> LargeAddressAware (* 0x20 *)
-		| 0x80 -> BytesReversedLO (* 0x80 *)
-		| 0x100 -> Machine32Bit (* 0x100 *)
-		| 0x200 -> DebugStripped (* 0x200 *)
-		| 0x400 -> RemovableRunFromSwap (* 0x400 *)
-		| 0x800 -> NetRunFromSwap (* 0x800 *)
-		| 0x1000 -> FileSystem (* 0x1000 *)
-		| 0x2000 -> FileDll (* 0x2000 *)
-		| 0x4000 -> UpSystemOnly (* 0x4000 *)
-		| 0x8000 -> BytesReversedHI (* 0x8000 *)
-		| _ -> assert false) :: acc
-	else
-		acc) [] [0x1;0x2;0x4;0x8;0x10;0x20;0x80;0x100;0x200;0x400;0x800;0x1000;0x2000;0x4000;0x8000]
-
-let section_props_of_int32 props = List.fold_left (fun acc i ->
-	if (Int32.logand props i) = i then (match i with
-		| 0x8l -> SNoPad
-		| 0x20l -> SHasCode
-		| 0x40l -> SHasIData
-		| 0x80l -> SHasData
-		| 0x200l -> SHasLinkInfo
-		| 0x1000l -> SLinkRemove
-		| 0x8000l -> SGlobalRel
-		| 0x20000l -> SHas16BitMem
-		| 0x100000l -> SAlign1Bytes
-		| 0x200000l -> SAlign2Bytes
-		| 0x300000l -> SAlign4Bytes
-		| 0x400000l -> SAlign8Bytes
-		| 0x500000l -> SAlign16Bytes
-		| 0x600000l -> SAlign32Bytes
-		| 0x700000l -> SAlign64Bytes
-		| 0x800000l -> SAlign128Bytes
-		| 0x900000l -> SAlign256Bytes
-		| 0xA00000l -> SAlign512Bytes
-		| 0xB00000l -> SAlign1024Bytes
-		| 0xC00000l -> SAlign2048Bytes
-		| 0xD00000l -> SAlign4096Bytes
-		| 0xE00000l -> SAlign8192Bytes
-		| 0x1000000l -> SHasExtRelocs
-		| 0x02000000l -> SCanDiscard
-		| 0x04000000l -> SNotCached
-		| 0x08000000l -> SNotPaged
-		| 0x10000000l -> SShared
-		| 0x20000000l -> SExec
-		| 0x40000000l -> SRead
-		| 0x80000000l -> SWrite
-		| _ -> assert false) :: acc
-	else
-		acc) [] [ 0x8l;  0x20l;  0x40l;  0x80l;  0x200l;  0x1000l;  0x8000l;  0x20000l;  0x100000l;  0x200000l;  0x300000l;  0x400000l;  0x500000l;  0x600000l;  0x700000l;  0x800000l;  0x900000l;  0xA00000l;  0xB00000l;  0xC00000l;  0xD00000l;  0xE00000l;  0x1000000l;  0x02000000l;  0x04000000l;  0x08000000l;  0x10000000l;  0x20000000l;  0x40000000l;  0x80000000l; ]
-
-let subsystem_of_int i = match i with
-	|  0 -> SUnknown (* 0 *)
-	|  1 -> SNative (* 1 *)
-	|  2 -> SWGui (* 2 *)
-	|  3 -> SWCui (* 3 *)
-	|  7 -> SPCui (* 7 *)
-	|  9 -> SWCeGui (* 9 *)
-	|  10 -> SEfi (* 10 *)
-	|  11 -> SEfiBoot (* 11 *)
-	|  12 -> SEfiRuntime (* 12 *)
-	|  13 -> SEfiRom (* 13 *)
-	|  14 -> SXbox (* 14 *)
-	| _ -> error ("Unknown subsystem " ^ string_of_int i)
-
-let dll_props_of_int iprops = List.fold_left (fun acc i ->
-	if (iprops land i) = i then (match i with
-		| 0x0040  -> DDynamicBase (* 0x0040 *)
-		| 0x0080  -> DForceIntegrity (* 0x0080 *)
-		| 0x0100  -> DNxCompat (* 0x0100 *)
-		| 0x0200  -> DNoIsolation (* 0x0200 *)
-		| 0x0400  -> DNoSeh (* 0x0400 *)
-		| 0x0800  -> DNoBind (* 0x0800 *)
-		| 0x2000  -> DWdmDriver (* 0x2000 *)
-		| 0x8000  -> DTerminalServer (* 0x8000 *)
-		| _ -> assert false) :: acc
-	else
-		acc) [] [0x40;0x80;0x100;0x200;0x400;0x800;0x2000;0x8000]
-
-let pe_magic_of_int i = match i with
-	| 0x10b -> P32
-	| 0x107 -> PRom
-	| 0x20b -> P64
-	| _ -> error ("Unknown PE magic number: " ^ string_of_int i)
-
-let clr_flags_of_int iprops = List.fold_left (fun acc i ->
-	if (iprops land i) = i then (match i with
-		| 0x1 -> FIlOnly (* 0x1 *)
-		| 0x2 -> F32BitRequired (* 0x2 *)
-		| 0x4 -> FIlLibrary (* 0x4 *)
-		| 0x8 -> FSigned (* 0x8 *)
-		| 0x10 -> FNativeEntry (* 0x10 *)
-		| 0x10000 -> FTrackDebug (* 0x10000 *)
-		| _ -> assert false) :: acc
-	else
-		acc) [] [0x1;0x2;0x4;0x8;0x10;0x10000]
-
-let get_dir dir ctx =
-	let idx,name = directory_type_info dir in
-	try
-		ctx.pe_header.pe_data_dirs.(idx)
-	with
-		| Invalid_argument _ ->
-			error (Printf.sprintf "The directory '%s' of index '%i' is required but is missing on this file" name idx)
-
-let read_rva = read_real_i32
-
-let read_word is64 i =
-	if is64 then read_i64 i else Int64.logand (Int64.of_int32 (read_real_i32 i)) 0xFFFFFFFFL
-
-let read_coff_header i =
-	let machine = machine_type_of_int (read_ui16 i) in
-	let nsections = read_ui16 i in
-	let stamp = read_real_i32 i in
-	let symbol_table_pointer = read_rva i in
-	let nsymbols = read_i32 i in
-	let optheader_size = read_ui16 i in
-	let props = read_ui16 i in
-	let props = coff_props_of_int (props) in
-	{
-		coff_machine = machine;
-		coff_nsections = nsections;
-		coff_timestamp = stamp;
-		coff_symbol_table_pointer = symbol_table_pointer;
-		coff_nsymbols = nsymbols;
-		coff_optheader_size = optheader_size;
-		coff_props = props;
-	}
-
-let read_pe_header r header =
-	let i = r.i in
-	let sections_offset = (pos r) + header.coff_optheader_size in
-	let magic = pe_magic_of_int (read_ui16 i) in
-	let major = read_byte i in
-	let minor = read_byte i in
-	let code_size = read_i32 i in
-	let init_size = read_i32 i in
-	let uinit_size = read_i32 i in
-	let entry_addr = read_rva i in
-	let base_code = read_rva i in
-	let base_data, read_word = match magic with
-	| P32 | PRom ->
-		read_rva i, read_word false
-	| P64 ->
-		Int32.zero, read_word true
-	in
-
-	(* COFF Windows extension *)
-	let image_base = read_word i in
-	let section_alignment = read_i32 i in
-	let file_alignment = read_i32 i in
-	let major_osver = read_ui16 i in
-	let minor_osver = read_ui16 i in
-	let major_imgver = read_ui16 i in
-	let minor_imgver = read_ui16 i in
-	let major_subsysver = read_ui16 i in
-	let minor_subsysver = read_ui16 i in
-	ignore (read_i32 i); (* reserved *)
-	let image_size = read_i32 i in
-	let headers_size = read_i32 i in
-	let checksum = read_real_i32 i in
-	let subsystem = subsystem_of_int (read_ui16 i) in
-	let dll_props = dll_props_of_int (read_ui16 i) in
-	let stack_reserve = read_word i in
-	let stack_commit = read_word i in
-	let heap_reserve = read_word i in
-	let heap_commit = read_word i in
-	ignore (read_i32 i); (* reserved *)
-	let ndata_dir = read_i32 i in
-	let data_dirs = Array.init ndata_dir (fun n ->
-		let addr = read_rva i in
-		let size = read_rva i in
-		addr,size)
-	in
-	(* sections *)
-	let nsections = header.coff_nsections in
-	seek r sections_offset;
-	let sections = Array.init nsections (fun n ->
-		let name = nread_string i 8 in
-		let name = try
-			let index = String.index name '\x00' in
-			String.sub name 0 index
-		with | Not_found ->
-				name
-		in
-		(*TODO check for slash names *)
-		let vsize = read_rva i in
-		let vaddr = read_rva i in
-		let raw_size = read_rva i in
-		let raw_pointer = read_i32 i in
-		let reloc_pointer = read_i32 i in
-		let line_num_pointer = read_i32 i in
-		let nrelocs = read_ui16 i in
-		let nline_nums = read_ui16 i in
-		let props = section_props_of_int32 (read_rva i) in
-		{
-			s_name = name;
-			s_vsize =vsize;
-			s_vaddr =vaddr;
-			s_raw_size =raw_size;
-			s_raw_pointer =raw_pointer;
-			s_reloc_pointer =reloc_pointer;
-			s_line_num_pointer =line_num_pointer;
-			s_nrelocs =nrelocs;
-			s_nline_nums =nline_nums;
-			s_props =props;
-		}
-	) in
-	{
-		pe_coff_header = header;
-		pe_magic = magic;
-		pe_major = major;
-		pe_minor = minor;
-		pe_code_size = code_size;
-		pe_init_size = init_size;
-		pe_uinit_size = uinit_size;
-		pe_entry_addr = entry_addr;
-		pe_base_code = base_code;
-		pe_base_data = base_data;
-		pe_image_base = image_base;
-		pe_section_alignment = section_alignment;
-		pe_file_alignment = file_alignment;
-		pe_major_osver = major_osver;
-		pe_minor_osver = minor_osver;
-		pe_major_imgver = major_imgver;
-		pe_minor_imgver = minor_imgver;
-		pe_major_subsysver = major_subsysver;
-		pe_minor_subsysver = minor_subsysver;
-		pe_image_size = image_size;
-		pe_headers_size = headers_size;
-		pe_checksum = checksum;
-		pe_subsystem = subsystem;
-		pe_dll_props = dll_props;
-		pe_stack_reserve = stack_reserve;
-		pe_stack_commit = stack_commit;
-		pe_heap_reserve = heap_reserve;
-		pe_heap_commit = heap_commit;
-		pe_ndata_dir = ndata_dir;
-		pe_data_dirs = data_dirs;
-		pe_sections = sections;
-	}
-
-let create_r ch props =
-	let verbose = PMap.mem "IL_VERBOSE" props in
-	let i = IO.input_channel ch in
-	{
-		ch = ch;
-		i = i;
-		verbose = verbose;
-	}
-
-(* converts an RVA into a file offset. *)
-let convert_rva ctx rva =
-	let sections = ctx.pe_header.pe_sections in
-	let nsections = Array.length sections in
-	let sec =
-		(* linear search. TODO maybe binary search for many sections? *)
-		let rec loop n =
-			if n >= nsections then error (Printf.sprintf "The RVA %lx is outside sections bounds!" rva);
-			let sec = sections.(n) in
-			if rva >= sec.s_vaddr && (rva < (Int32.add sec.s_vaddr sec.s_raw_size)) then
-				sec
-			else
-				loop (n+1)
-		in
-		loop 0
-	in
-	let diff = Int32.to_int (Int32.sub rva sec.s_vaddr) in
-	sec.s_raw_pointer + diff
-
-let seek_rva ctx rva = seek ctx.r (convert_rva ctx rva)
-
-let read_cstring i =
-	let ret = Buffer.create 8 in
-	let rec loop () =
-		let chr = read i in
-		if chr = '\x00' then
-			Buffer.contents ret
-		else begin
-			Buffer.add_char ret chr;
-			loop()
-		end
-	in
-	loop()
-
-(* reads import data *)
-let read_idata ctx = match get_dir ImportTable ctx with
-	| 0l,_ | _,0l ->
-		[]
-	| rva,size ->
-		seek_rva ctx rva;
-		let i = ctx.r.i in
-		let rec loop acc =
-			let lookup_table = read_rva i in
-			if lookup_table = Int32.zero then
-				acc
-			else begin
-				let timestamp = read_real_i32 i in
-				let fchain = read_real_i32 i in
-				let name_rva = read_rva i in
-				let addr_table = read_rva i in
-				ignore addr_table; ignore fchain; ignore timestamp;
-				loop ((lookup_table,name_rva) :: acc)
-			end
-		in
-		let tables = loop [] in
-		List.rev_map (function (lookup_table,name_rva) ->
-			seek_rva ctx lookup_table;
-			let is_64 = ctx.pe_header.pe_magic = P64 in
-			let imports_data = if not is_64 then
-				let rec loop acc =
-					let flags = read_real_i32 i in
-					if flags = Int32.zero then
-						acc
-					else begin
-						let is_ordinal = Int32.logand flags 0x80000000l = 0x80000000l in
-						loop ( (is_ordinal, if is_ordinal then Int32.logand flags 0xFFFFl else Int32.logand flags 0x7FFFFFFFl) :: acc )
-					end
-				in
-				loop []
-			else
-				let rec loop acc =
-					let flags = read_i64 i in
-					if flags = Int64.zero then
-						acc
-					else begin
-						let is_ordinal = Int64.logand flags 0x8000000000000000L = 0x8000000000000000L in
-						loop ( (is_ordinal, Int64.to_int32 (if is_ordinal then Int64.logand flags 0xFFFFL else Int64.logand flags 0x7FFFFFFFL)) :: acc )
-					end
-				in
-				loop []
-			in
-			let imports = List.rev_map (function
-				| true, ord ->
-					SOrdinal (Int32.to_int ord)
-				| false, rva ->
-					seek_rva ctx rva;
-					let hint = read_ui16 i in
-					SName (hint, read_cstring i)
-			) imports_data in
-			seek_rva ctx name_rva;
-			let name = read_cstring i in
-			{
-				imp_name = name;
-				imp_imports = imports;
-			}
-		) tables
-
-let has_clr_header ctx = match get_dir ClrRuntimeHeader ctx with
-	| 0l,_ | _,0l ->
-		false
-	| _ ->
-		true
-
-let read_clr_header ctx = match get_dir ClrRuntimeHeader ctx with
-	| 0l,_ | _,0l ->
-		error "This PE file does not have managed content"
-	| rva,size ->
-		seek_rva ctx rva;
-		let i = ctx.r.i in
-		let cb = read_i32 i in
-		let major = read_ui16 i in
-		let minor = read_ui16 i in
-		let read_tbl i =
-			let rva = read_rva i in
-			let size = read_real_i32 i in
-			rva,size
-		in
-		let meta = read_tbl i in
-		let corflags = clr_flags_of_int (read_i32 i) in
-		let entry_point = read_rva i in
-		let res = read_tbl i in
-		let clrsig = read_tbl i in
-		let codeman = read_tbl i in
-		let vtable_fix = read_tbl i in
-		let export_addr = read_tbl i in
-		{
-			clr_cb = cb;
-			clr_major = major;
-			clr_minor = minor;
-			clr_meta = meta;
-			clr_flags = corflags;
-			clr_entry_point = entry_point;
-			clr_res = res;
-			clr_sig = clrsig;
-			clr_codeman = codeman;
-			clr_vtable_fix = vtable_fix;
-			clr_export_address = export_addr;
-		}
-
-let read r =
-	let i = r.i in
-	if read i <> 'M' || read i <> 'Z' then
-		error "MZ magic header not found: Is the target file really a PE?";
-	seek r 0x3c;
-	let pe_sig_offset = read_i32 i in
-	seek r pe_sig_offset;
-	if really_nread_string i 4 <> "PE\x00\x00" then
-		error "Invalid PE header signature: PE expected";
-	let header = read_coff_header i in
-	let pe_header = read_pe_header r header in
-	{
-		r = r;
-		pe_header = pe_header;
-		read_word = read_word (pe_header.pe_magic = P64);
-	}

+ 0 - 158
libs/ilib/peWriter.ml

@@ -1,158 +0,0 @@
-(*
- *  This file is part of ilLib
- *  Copyright (c)2004-2013 Haxe Foundation
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *)
-
-open PeData;;
-open IO;;
-open ExtString;;
-open ExtList;;
-
-exception Error_message of string
-
-let error msg = raise (Error_message msg)
-
-type 'a writer_ctx = {
-	out : 'a IO.output;
-}
-
-let int_of_machine_type t = match t with
-	| TUnknown -> 0x0 (* 0 - unmanaged PE files only *)
-	| Ti386 -> 0x014c (* 0x014c - i386 *)
-	| TR3000 -> 0x0162 (* 0x0162 - R3000 MIPS Little Endian *)
-	| TR4000 -> 0x0166 (* 0x0166 - R4000 MIPS Little Endian *)
-	| TR10000 -> 0x0168 (* 0x0168 - R10000 MIPS Little Endian *)
-	| TWCeMipsV2 -> 0x0169 (* 0x0169 - MIPS Litlte Endian running MS Windows CE 2 *)
-	| TAlpha -> 0x0184 (* 0x0184 - Alpha AXP *)
-	| TSh3 -> 0x01a2 (* 0x01a2 - SH3 Little Endian *)
-	| TSh3Dsp -> 0x01a3 (* 0x01a3 SH3DSP Little Endian *)
-	| TSh3e -> 0x01a4 (* 0x01a4 SH3E Little Endian *)
-	| TSh4 -> 0x01a6 (* 0x01a6 SH4 Little Endian *)
-	| TSh5 -> 0x01a8
-	| TArm -> 0x01c0 (* 0x1c0 ARM Little Endian *)
-	| TArmN -> 0x01c4 (* 0x1c0 ARM Little Endian *)
-	| TArm64 -> 0xaa64 (* 0x1c0 ARM Little Endian *)
-	| TEbc -> 0xebc
-	| TThumb -> 0x01c2 (* 0x1c2 ARM processor with Thumb decompressor *)
-	| TAm33 -> 0x01d3 (* 0x1d3 AM33 processor *)
-	| TPowerPC -> 0x01f0 (* 0x01f0 IBM PowerPC Little Endian *)
-	| TPowerPCFP -> 0x01f1 (* 0x01f1 IBM PowerPC with FPU *)
-	| TItanium64 -> 0x0200 (* 0x0200 Intel IA64 (Itanium( *)
-	| TMips16 -> 0x0266 (* 0x0266 MIPS *)
-	| TAlpha64 -> 0x0284 (* 0x0284 Alpha AXP64 *)
-	| TMipsFpu -> 0x0366 (* 0x0366 MIPS with FPU *)
-	| TMipsFpu16 -> 0x0466 (* 0x0466 MIPS16 with FPU *)
-	| TTriCore -> 0x0520 (* 0x0520 Infineon *)
-	| TAmd64 -> 0x8664 (* 0x8664 AMD x64 and Intel E64T *)
-	| TM32R -> 0x9041 (* 0x9041 M32R *)
-
-let int_of_coff_props props = List.fold_left (fun acc prop ->
-		(match prop with
-			| RelocsStripped -> 0x1 (* 0x1 *)
-			| ExecutableImage -> 0x2 (* 0x2 *)
-			| LineNumsStripped -> 0x4 (* 0x4 *)
-			| LocalSymsStripped -> 0x8 (* 0x8 *)
-			| AgressiveWsTrim -> 0x10 (* 0x10 *)
-			| LargeAddressAware -> 0x20 (* 0x20 *)
-			| BytesReversedLO -> 0x80 (* 0x80 *)
-			| Machine32Bit -> 0x100 (* 0x100 *)
-			| DebugStripped -> 0x200 (* 0x200 *)
-			| RemovableRunFromSwap -> 0x400 (* 0x400 *)
-			| NetRunFromSwap -> 0x800 (* 0x800 *)
-			| FileSystem -> 0x1000 (* 0x1000 *)
-			| FileDll -> 0x2000 (* 0x2000 *)
-			| UpSystemOnly -> 0x4000 (* 0x4000 *)
-			| BytesReversedHI -> 0x8000 (* 0x8000 *)
-		) lor acc
-	) 0 props
-
-let int32_of_section_prop props = List.fold_left (fun acc prop ->
-		Int32.logor (match prop with
-			| SNoPad ->  0x8l (* 0x8 *)
-			| SHasCode ->  0x20l (* 0x20 *)
-			| SHasIData ->  0x40l (* 0x40 *)
-			| SHasData ->  0x80l (* 0x80 *)
-			| SHasLinkInfo ->  0x200l (* 0x200 *)
-			| SLinkRemove ->  0x1000l (* 0x1000 *)
-			| SGlobalRel ->  0x8000l (* 0x8000 *)
-			| SHas16BitMem ->  0x20000l (* 0x20000 *)
-			| SAlign1Bytes ->  0x100000l (* 0x100000 *)
-			| SAlign2Bytes ->  0x200000l (* 0x200000 *)
-			| SAlign4Bytes ->  0x300000l (* 0x300000 *)
-			| SAlign8Bytes ->  0x400000l (* 0x400000 *)
-			| SAlign16Bytes ->  0x500000l (* 0x500000 *)
-			| SAlign32Bytes ->  0x600000l (* 0x600000 *)
-			| SAlign64Bytes ->  0x700000l (* 0x700000 *)
-			| SAlign128Bytes ->  0x800000l (* 0x800000 *)
-			| SAlign256Bytes ->  0x900000l (* 0x900000 *)
-			| SAlign512Bytes ->  0xA00000l (* 0xA00000 *)
-			| SAlign1024Bytes ->  0xB00000l (* 0xB00000 *)
-			| SAlign2048Bytes ->  0xC00000l (* 0xC00000 *)
-			| SAlign4096Bytes ->  0xD00000l (* 0xD00000 *)
-			| SAlign8192Bytes ->  0xE00000l (* 0xE00000 *)
-			| SHasExtRelocs ->  0x1000000l (* 0x1000000 *)
-			| SCanDiscard ->  0x02000000l (* 0x02000000 *)
-			| SNotCached ->  0x04000000l (* 0x04000000 *)
-			| SNotPaged ->  0x08000000l (* 0x08000000 *)
-			| SShared ->  0x10000000l (* 0x10000000 *)
-			| SExec ->  0x20000000l (* 0x20000000 *)
-			| SRead ->  0x40000000l (* 0x40000000 *)
-			| SWrite ->  0x80000000l (* 0x80000000 *)
-		) acc
-	) 0l props
-
-let int_of_pe_magic m = match m with
-	| P32 -> 0x10b
-	| PRom -> 0x107
-	| P64 -> 0x20b
-
-let int_of_subsystem s = match s with
-	|  SUnknown -> 0 (* 0 *)
-	|  SNative -> 1 (* 1 *)
-	|  SWGui -> 2 (* 2 *)
-	|  SWCui -> 3 (* 3 *)
-	|  SPCui -> 7 (* 7 *)
-	|  SWCeGui -> 9 (* 9 *)
-	|  SEfi -> 10 (* 10 *)
-	|  SEfiBoot -> 11 (* 11 *)
-	|  SEfiRuntime -> 12 (* 12 *)
-	|  SEfiRom -> 13 (* 13 *)
-	|  SXbox -> 14 (* 14 *)
-
-let int_of_dll_props props = List.fold_left (fun acc prop ->
-		(match prop with
-		| DDynamicBase -> 0x0040 (* 0x0040 *)
-		| DForceIntegrity -> 0x0080 (* 0x0080 *)
-		| DNxCompat -> 0x0100 (* 0x0100 *)
-		| DNoIsolation -> 0x0200 (* 0x0200 *)
-		| DNoSeh -> 0x0400 (* 0x0400 *)
-		| DNoBind -> 0x0800 (* 0x0800 *)
-		| DWdmDriver -> 0x2000 (* 0x2000 *)
-		| DTerminalServer -> 0x8000 (* 0x8000 *)
-		) lor acc
-	) 0 props
-
-let int_of_clr_flags props = List.fold_left (fun acc prop ->
-		(match prop with
-		| FIlOnly ->  0x1  (* 0x1 *)
-		| F32BitRequired ->  0x2  (* 0x2 *)
-		| FIlLibrary ->  0x4  (* 0x4 *)
-		| FSigned ->  0x8  (* 0x8 *)
-		| FNativeEntry ->  0x10  (* 0x10 *)
-		| FTrackDebug ->  0x10000  (* 0x10000 *)
-		) lor acc
-	) 0 props

+ 0 - 22
libs/javalib/Makefile

@@ -1,22 +0,0 @@
-OCAMLOPT=ocamlopt
-OCAMLC=ocamlc
-SRC=jData.ml jReader.ml jWriter.ml
-
-all: bytecode native
-
-native: javalib.cmxa
-bytecode: javalib.cma
-
-javalib.cmxa: $(SRC)
-	ocamlfind $(OCAMLOPT) -g -package extlib -safe-string -a -o javalib.cmxa $(SRC)
-
-javalib.cma: $(SRC)
-	ocamlfind $(OCAMLC) -g -package extlib -safe-string -a -o javalib.cma $(SRC)
-
-clean:
-	rm -rf javalib.cmxa javalib.cma javalib.lib javalib.a $(wildcard *.cmx) $(wildcard *.obj) $(wildcard *.o) $(wildcard *.cmi) $(wildcard *.cmo)
-
-.PHONY: all bytecode native clean
-
-Makefile: ;
-$(SRC): ;

+ 0 - 7
libs/javalib/dune

@@ -1,7 +0,0 @@
-(include_subdirs no)
-
-(library
-	(name javalib)
-	(libraries extlib)
-	(wrapped false)
-)

+ 0 - 250
libs/javalib/jData.ml

@@ -1,250 +0,0 @@
-(*
- *  This file is part of JavaLib
- *  Copyright (c)2004-2012 Nicolas Cannasse and Caue Waneck
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *)
-
-type jpath = (string list) * string
-
-type jversion = int * int (* minor + major *)
-
-(** unqualified names cannot have the characters '.', ';', '[' or '/' *)
-type unqualified_name = string
-
-type jwildcard =
-  | WExtends (* + *)
-  | WSuper (* -  *)
-  | WNone
-
-type jtype_argument =
-  | TType of jwildcard * jsignature
-  | TAny (* * *)
-
-and jsignature =
-  | TByte (* B *)
-  | TChar (* C *)
-  | TDouble (* D *)
-  | TFloat (* F *)
-  | TInt (* I *)
-  | TLong (* J *)
-  | TShort (* S *)
-  | TBool (* Z *)
-  | TObject of jpath * jtype_argument list (* L Classname *)
-  | TObjectInner of (string list) * (string * jtype_argument list) list (* L Classname ClassTypeSignatureSuffix *)
-  | TArray of jsignature * int option (* [ *)
-  | TMethod of jmethod_signature (* ( *)
-  | TTypeParameter of string (* T *)
-
-(* ( jsignature list ) ReturnDescriptor (| V | jsignature) *)
-and jmethod_signature = jsignature list * jsignature option
-
-(* InvokeDynamic-specific: Method handle *)
-type reference_type =
-  | RGetField (* constant must be ConstField *)
-  | RGetStatic (* constant must be ConstField *)
-  | RPutField (* constant must be ConstField *)
-  | RPutStatic (* constant must be ConstField *)
-  | RInvokeVirtual (* constant must be Method *)
-  | RInvokeStatic (* constant must be Method *)
-  | RInvokeSpecial (* constant must be Method *)
-  | RNewInvokeSpecial (* constant must be Method with name <init> *)
-  | RInvokeInterface (* constant must be InterfaceMethod *)
-
-(* TODO *)
-type bootstrap_method = int
-
-type jconstant =
-  (** references a class or an interface - jpath must be encoded as StringUtf8 *)
-  | ConstClass of jpath (* tag = 7 *)
-  (** field reference *)
-  | ConstField of (jpath * unqualified_name * jsignature) (* tag = 9 *)
-  (** method reference; string can be special "<init>" and "<clinit>" values *)
-  | ConstMethod of (jpath * unqualified_name * jmethod_signature) (* tag = 10 *)
-  (** interface method reference *)
-  | ConstInterfaceMethod of (jpath * unqualified_name * jmethod_signature) (* tag = 11 *)
-  (** constant values *)
-  | ConstString of string  (* tag = 8 *)
-  | ConstInt of int32 (* tag = 3 *)
-  | ConstFloat of float (* tag = 4 *)
-  | ConstLong of int64 (* tag = 5 *)
-  | ConstDouble of float (* tag = 6 *)
-  (** name and type: used to represent a field or method, without indicating which class it belongs to *)
-  | ConstNameAndType of unqualified_name * jsignature
-  (** UTF8 encoded strings. Note that when reading/writing, take into account Utf8 modifications of java *)
-  (* (http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.7) *)
-  | ConstUtf8 of string
-  (** invokeDynamic-specific *)
-  | ConstMethodHandle of (reference_type * jconstant) (* tag = 15 *)
-  | ConstMethodType of jmethod_signature (* tag = 16 *)
-  | ConstInvokeDynamic of (bootstrap_method * unqualified_name * jsignature) (* tag = 18 *)
-  | ConstUnusable
-
-type jcode = unit (* TODO *)
-
-type jaccess_flag =
-  | JPublic (* 0x0001 *)
-  | JPrivate (* 0x0002 *)
-  | JProtected (* 0x0004 *)
-  | JStatic (* 0x0008 *)
-  | JFinal (* 0x0010 *)
-  | JSynchronized (* 0x0020 *)
-  | JVolatile (* 0x0040 *)
-  | JTransient (* 0x0080 *)
-  (** added if created by the compiler *)
-  | JSynthetic (* 0x1000 *)
-  | JEnum (* 0x4000 *)
-  | JUnusable (* should not be present *)
-  (** class flags *)
-  | JSuper (* 0x0020 *)
-  | JInterface (* 0x0200 *)
-  | JAbstract (* 0x0400 *)
-  | JAnnotation (* 0x2000 *)
-  (** method flags *)
-  | JBridge (* 0x0040 *)
-  | JVarArgs (* 0x0080 *)
-  | JNative (* 0x0100 *)
-  | JStrict (* 0x0800 *)
-
-type jaccess = jaccess_flag list
-
-(* type parameter name, extends signature, implements signatures *)
-type jtypes = (string * jsignature option * jsignature list) list
-
-type jannotation = {
-  ann_type : jsignature;
-  ann_elements : (string * jannotation_value) list;
-}
-
-and jannotation_value =
-  | ValConst of jsignature * jconstant (* B, C, D, E, F, I, J, S, Z, s *)
-  | ValEnum of jsignature * string (* e *)
-  | ValClass of jsignature (* c *) (* V -> Void *)
-  | ValAnnotation of jannotation (* @ *)
-  | ValArray of jannotation_value list (* [ *)
-
-type jattribute =
-  | AttrDeprecated
-  | AttrVisibleAnnotations of jannotation list
-  | AttrInvisibleAnnotations of jannotation list
-  | AttrUnknown of string * string
-
-type jfield_kind =
-  | JKField
-  | JKMethod
-
-type jfield = {
-  jf_name : string;
-  jf_kind : jfield_kind;
-  (* signature, as used by the vm *)
-  jf_vmsignature : jsignature;
-  (* actual signature, as used in java code *)
-  jf_signature : jsignature;
-  jf_throws : jsignature list;
-  jf_types : jtypes;
-  jf_flags : jaccess;
-  jf_attributes : jattribute list;
-  jf_constant : jconstant option;
-  jf_code : jcode option;
-}
-
-type jclass = {
-  cversion : jversion;
-  cpath : jpath;
-  csuper : jsignature;
-  cflags : jaccess;
-  cinterfaces : jsignature list;
-  cfields : jfield list;
-  cmethods : jfield list;
-  cattributes : jattribute list;
-
-  cinner_types : (jpath * jpath option * string option * jaccess) list;
-  ctypes : jtypes;
-}
-
-(* reading/writing *)
-type utf8ref = int
-type classref = int
-type nametyperef = int
-type dynref = int
-type bootstrapref = int
-
-type jconstant_raw =
-  | KClass of utf8ref (* 7 *)
-  | KFieldRef of (classref * nametyperef) (* 9 *)
-  | KMethodRef of (classref * nametyperef) (* 10 *)
-  | KInterfaceMethodRef of (classref * nametyperef) (* 11 *)
-  | KString of utf8ref (* 8 *)
-  | KInt of int32 (* 3 *)
-  | KFloat of float (* 4 *)
-  | KLong of int64 (* 5 *)
-  | KDouble of float (* 6 *)
-  | KNameAndType of (utf8ref * utf8ref) (* 12 *)
-  | KUtf8String of string (* 1 *)
-  | KMethodHandle of (reference_type * dynref) (* 15 *)
-  | KMethodType of utf8ref (* 16 *)
-  | KInvokeDynamic of (bootstrapref * nametyperef) (* 18 *)
-  | KUnusable
-
-(* jData debugging *)
-let is_override_attrib = (function
-    (* TODO: pass anotations as @:meta *)
-    | AttrVisibleAnnotations ann ->
-      List.exists (function
-        | { ann_type = TObject( (["java";"lang"], "Override"), [] ) } ->
-            true
-        | _ -> false
-      ) ann
-    | _ -> false
-  )
-
-let is_override field =
-  List.exists is_override_attrib field.jf_attributes
-
-let path_s = function
-  | (pack,name) -> String.concat "." (pack @ [name])
-
-let rec s_sig = function
-  | TByte (* B *) -> "byte"
-  | TChar (* C *) -> "char"
-  | TDouble (* D *) -> "double"
-  | TFloat (* F *) -> "float"
-  | TInt (* I *) -> "int"
-  | TLong (* J *) -> "long"
-  | TShort (* S *) -> "short"
-  | TBool (* Z *) -> "bool"
-  | TObject(path,args) -> path_s  path ^ s_args args
-  | TObjectInner (sl, sjargl) -> String.concat "." sl ^ "." ^ (String.concat "." (List.map (fun (s,arg) -> s ^ s_args arg) sjargl))
-  | TArray (s,i) -> s_sig s ^ "[" ^ (match i with | None -> "" | Some i -> string_of_int i) ^ "]"
-  | TMethod (sigs, sopt) -> (match sopt with | None -> "" | Some s -> s_sig s ^ " ") ^ "(" ^ String.concat ", " (List.map s_sig sigs) ^ ")"
-  | TTypeParameter s -> s
-
-and s_args = function
-  | [] -> ""
-  | args -> "<" ^ String.concat ", " (List.map (fun t ->
-      match t with
-      | TAny -> "*"
-      | TType (wc, s) ->
-        (match wc with
-          | WNone -> ""
-          | WExtends -> "+"
-          | WSuper -> "-") ^
-        (s_sig s))
-    args) ^ ">"
-
-let s_field f = (if is_override f then "override " else "") ^ s_sig f.jf_signature ^ " " ^ f.jf_name
-
-let s_fields fs = "{ \n\t" ^ String.concat "\n\t" (List.map s_field fs) ^ "\n}"
-

+ 0 - 597
libs/javalib/jReader.ml

@@ -1,597 +0,0 @@
-(*
- *  This file is part of JavaLib
- *  Copyright (c)2004-2012 Nicolas Cannasse and Caue Waneck
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *)
-open JData;;
-open IO.BigEndian;;
-open ExtString;;
-open ExtList;;
-
-exception Error_message of string
-
-let error msg = raise (Error_message msg)
-
-let get_reference_type i constid =
-  match i with
-  | 1 -> RGetField
-  | 2 -> RGetStatic
-  | 3 -> RPutField
-  | 4 -> RPutStatic
-  | 5 -> RInvokeVirtual
-  | 6 -> RInvokeStatic
-  | 7 -> RInvokeSpecial
-  | 8 -> RNewInvokeSpecial
-  | 9 -> RInvokeInterface
-  | _ -> error (string_of_int constid ^ ": Invalid reference type " ^ string_of_int i)
-
-let parse_constant max idx ch =
-  let cid = IO.read_byte ch in
-  let error() = error (string_of_int idx ^ ": Invalid constant " ^ string_of_int cid) in
-  let index() =
-    let n = read_ui16 ch in
-    if n = 0 || n >= max then error();
-    n
-  in
-  match cid with
-  | 7 ->
-    KClass (index())
-  | 9 ->
-    let n1 = index() in
-    let n2 = index() in
-    KFieldRef (n1,n2)
-  | 10 ->
-    let n1 = index() in
-    let n2 = index() in
-    KMethodRef (n1,n2)
-  | 11 ->
-    let n1 = index() in
-    let n2 = index() in
-    KInterfaceMethodRef (n1,n2)
-  | 8 ->
-    KString (index())
-  | 3 ->
-    KInt (read_real_i32 ch)
-  | 4 ->
-    let f = Int32.float_of_bits (read_real_i32 ch) in
-    KFloat f
-  | 5 ->
-    KLong (read_i64 ch)
-  | 6 ->
-    KDouble (read_double ch)
-  | 12 ->
-    let n1 = index() in
-    let n2 = index() in
-    KNameAndType (n1, n2)
-  | 1 ->
-    let len = read_ui16 ch in
-    let str = IO.nread_string ch len in
-    (* TODO: correctly decode modified UTF8 *)
-    KUtf8String str
-  | 15 ->
-    let reft = get_reference_type (IO.read_byte ch) idx in
-    let dynref = index() in
-    KMethodHandle (reft, dynref)
-  | 16 ->
-    KMethodType (index())
-  | 18 ->
-    let bootstrapref = read_ui16 ch in (* not index *)
-    let nametyperef = index() in
-    KInvokeDynamic (bootstrapref, nametyperef)
-  | n ->
-    error()
-
-let expand_path s =
-  let rec loop remaining acc =
-    match remaining with
-    | name :: [] -> List.rev acc, name
-    | v :: tl -> loop tl (v :: acc)
-    | _ -> assert false
-  in
-  loop (String.nsplit s "/") []
-
-let rec parse_type_parameter_part s =
-  match s.[0] with
-  | '*' -> TAny, 1
-  | c ->
-    let wildcard, i = match c with
-      | '+' -> WExtends, 1
-      | '-' -> WSuper, 1
-      | _ -> WNone, 0
-    in
-    let jsig, l = parse_signature_part (String.sub s i (String.length s - 1)) in
-    (TType (wildcard, jsig), l + i)
-
-and parse_signature_part s =
-  let len = String.length s in
-  if len = 0 then raise Exit;
-  match s.[0] with
-  | 'B' -> TByte, 1
-  | 'C' -> TChar, 1
-  | 'D' -> TDouble, 1
-  | 'F' -> TFloat, 1
-  | 'I' -> TInt, 1
-  | 'J' -> TLong, 1
-  | 'S' -> TShort, 1
-  | 'Z' -> TBool, 1
-  | 'L' ->
-    (try
-      let orig_s = s in
-      let rec loop start i acc =
-        match s.[i] with
-        | '/' -> loop (i + 1) (i + 1) (String.sub s start (i - start) :: acc)
-        | ';' | '.' -> List.rev acc, (String.sub s start (i - start)), [], (i)
-        | '<' ->
-          let name = String.sub s start (i - start) in
-          let rec loop_params i acc =
-            let s = String.sub s i (len - i) in
-            match s.[0] with
-            | '>' -> List.rev acc, i + 1
-            | _ ->
-              let tp, l = parse_type_parameter_part s in
-              loop_params (l + i) (tp :: acc)
-          in
-          let params, _end = loop_params (i + 1) [] in
-          List.rev acc, name, params, (_end)
-        | _ -> loop start (i+1) acc
-      in
-      let pack, name, params, _end = loop 1 1 [] in
-      let rec loop_inner i acc =
-        match s.[i] with
-        | '.' ->
-          let pack, name, params, _end = loop (i+1) (i+1) [] in
-          if pack <> [] then error ("Inner types must not define packages. For '" ^ orig_s ^ "'.");
-          loop_inner _end ( (name,params) :: acc )
-        | ';' -> List.rev acc, i + 1
-        | c -> error ("End of complex type signature expected after type parameter. Got '" ^ Char.escaped c ^ "' for '" ^ orig_s ^ "'." );
-      in
-      let inners, _end = loop_inner _end [] in
-      match inners with
-      | [] -> TObject((pack,name), params), _end
-      | _ -> TObjectInner( pack, (name,params) :: inners ), _end
-    with
-      Invalid_string -> raise Exit)
-  | '[' ->
-    let p = ref 1 in
-    while !p < String.length s && s.[!p] >= '0' && s.[!p] <= '9' do
-      incr p;
-    done;
-    let size = (if !p > 1 then Some (int_of_string (String.sub s 1 (!p - 1))) else None) in
-    let s , l = parse_signature_part (String.sub s !p (String.length s - !p)) in
-    TArray (s,size) , l + !p
-  | '(' ->
-    let p = ref 1 in
-    let args = ref [] in
-    while !p < String.length s && s.[!p] <> ')' do
-      let a , l = parse_signature_part (String.sub s !p (String.length s - !p)) in
-      args := a :: !args;
-      p := !p + l;
-    done;
-    incr p;
-    if !p >= String.length s then raise Exit;
-    let ret , l = (match s.[!p] with 'V' -> None , 1 | _ ->
-      let s, l = parse_signature_part (String.sub s !p (String.length s - !p)) in
-      Some s, l
-    ) in
-    TMethod (List.rev !args,ret) , !p + l
-  | 'T' ->
-    (try
-      let s1 , _ = String.split s ";" in
-      let len = String.length s1 in
-      TTypeParameter (String.sub s1 1 (len - 1)) , len + 1
-    with
-      Invalid_string -> raise Exit)
-  | _ ->
-    raise Exit
-
-let parse_signature s =
-  try
-    let sign , l = parse_signature_part s in
-    if String.length s <> l then raise Exit;
-    sign
-  with
-    Exit -> error ("Invalid signature '" ^ s ^ "'")
-
-let parse_method_signature s =
-  match parse_signature s with
-  | (TMethod m) -> m
-  | _ -> error ("Unexpected signature '" ^ s ^ "'. Expecting method")
-
-let parse_formal_type_params s =
-  match s.[0] with
-  | '<' ->
-    let rec read_id i =
-      match s.[i] with
-      | ':' | '>' -> i
-      | _ -> read_id (i + 1)
-    in
-    let len = String.length s in
-    let rec parse_params idx acc =
-      let idi = read_id (idx + 1) in
-      let id = String.sub s (idx + 1) (idi - idx - 1) in
-      (* next must be a : *)
-      (match s.[idi] with | ':' -> () | _ -> error ("Invalid formal type signature character: " ^ Char.escaped s.[idi] ^ " ; from " ^ s));
-      let ext, l = match s.[idi + 1] with
-        | ':' | '>' -> None, idi + 1
-        | _ ->
-          let sgn, l = parse_signature_part (String.sub s (idi + 1) (len - idi - 1)) in
-          Some sgn, l + idi + 1
-      in
-      let rec loop idx acc =
-        match s.[idx] with
-        | ':' ->
-          let ifacesig, ifacei = parse_signature_part (String.sub s (idx + 1) (len - idx - 1)) in
-          loop (idx + ifacei + 1) (ifacesig :: acc)
-        | _ -> acc, idx
-      in
-      let ifaces, idx = loop l [] in
-      let acc = (id, ext, ifaces) :: acc in
-      if s.[idx] = '>' then List.rev acc, idx + 1 else parse_params (idx - 1) acc
-    in
-    parse_params 0 []
-  | _ -> [], 0
-
-let parse_throws s =
-  let len = String.length s in
-  let rec loop idx acc =
-    if idx > len then raise Exit
-    else if idx = len then acc, idx
-    else match s.[idx] with
-    | '^' ->
-      let tsig, l = parse_signature_part (String.sub s (idx+1) (len - idx - 1)) in
-      loop (idx + l + 1) (tsig :: acc)
-    | _ -> acc, idx
-  in
-  loop 0 []
-
-let parse_complete_method_signature s =
-  try
-    let len = String.length s in
-    let tparams, i = parse_formal_type_params s in
-    let sign, l = parse_signature_part (String.sub s i (len - i)) in
-    let throws, l2 = parse_throws (String.sub s (i+l) (len - i - l)) in
-    if (i + l + l2) <> len then raise Exit;
-
-    match sign with
-    | TMethod msig -> tparams, msig, throws
-    | _ -> raise Exit
-  with
-    Exit -> error ("Invalid method extended signature '" ^ s ^ "'")
-
-
-let rec expand_constant consts i =
-  let unexpected i = error (string_of_int i ^ ": Unexpected constant type") in
-  let expand_path n = match Array.get consts n with
-    | KUtf8String s -> expand_path s
-    | _ -> unexpected n
-  in
-  let expand_cls n = match expand_constant consts n with
-    | ConstClass p -> p
-    | _ -> unexpected n
-  in
-  let expand_nametype n = match expand_constant consts n with
-    | ConstNameAndType (s,jsig) -> s, jsig
-    | _ -> unexpected n
-  in
-  let expand_string n = match Array.get consts n with
-    | KUtf8String s -> s
-    | _ -> unexpected n
-  in
-  let expand_nametype_m n = match expand_nametype n with
-    | (n, TMethod m) -> n, m
-    | _ -> unexpected n
-  in
-  let expand ncls nt = match expand_cls ncls, expand_nametype nt with
-    | path, (n, m) -> path, n, m
-  in
-  let expand_m ncls nt = match expand_cls ncls, expand_nametype_m nt with
-    | path, (n, m) -> path, n, m
-  in
-
-  match Array.get consts i with
-  | KClass utf8ref ->
-    ConstClass (expand_path utf8ref)
-  | KFieldRef (classref, nametyperef) ->
-    ConstField (expand classref nametyperef)
-  | KMethodRef (classref, nametyperef) ->
-    ConstMethod (expand_m classref nametyperef)
-  | KInterfaceMethodRef (classref, nametyperef) ->
-    ConstInterfaceMethod (expand_m classref nametyperef)
-  | KString utf8ref ->
-    ConstString (expand_string utf8ref)
-  | KInt i32 ->
-    ConstInt i32
-  | KFloat f ->
-    ConstFloat f
-  | KLong i64 ->
-    ConstLong i64
-  | KDouble d ->
-    ConstDouble d
-  | KNameAndType (n, t) ->
-    ConstNameAndType(expand_string n, parse_signature (expand_string t))
-  | KUtf8String s ->
-    ConstUtf8 s (* TODO: expand UTF8 characters *)
-  | KMethodHandle (reference_type, dynref) ->
-    ConstMethodHandle (reference_type, expand_constant consts dynref)
-  | KMethodType utf8ref ->
-    ConstMethodType (parse_method_signature (expand_string utf8ref))
-  | KInvokeDynamic (bootstrapref, nametyperef) ->
-    let n, t = expand_nametype nametyperef in
-    ConstInvokeDynamic(bootstrapref, n, t)
-  | KUnusable ->
-    ConstUnusable
-
-let parse_access_flags ch all_flags =
-  let fl = read_ui16 ch in
-  let flags = ref [] in
-  let fbit = ref 0 in
-  List.iter (fun f ->
-    if fl land (1 lsl !fbit) <> 0 then begin
-      flags := f :: !flags;
-      if f = JUnusable then error ("Unusable flag: " ^ string_of_int fl)
-    end;
-    incr fbit
-  ) all_flags;
-  (*if fl land (0x4000 - (1 lsl !fbit)) <> 0 then error ("Invalid access flags " ^ string_of_int fl);*)
-  !flags
-
-let get_constant c n =
-  if n < 1 || n >= Array.length c then error ("Invalid constant index " ^ string_of_int n);
-  match c.(n) with
-  | ConstUnusable -> error "Unusable constant index";
-  | x -> x
-
-let get_class consts ch =
-  match get_constant consts (read_ui16 ch) with
-  | ConstClass n -> n
-  | _ -> error "Invalid class index"
-
-let get_string consts ch =
-  let i = read_ui16 ch in
-  match get_constant consts i with
-  | ConstUtf8 s -> s
-  | _ -> error ("Invalid string index " ^ string_of_int i)
-
-let rec parse_element_value consts ch =
-  let tag = IO.read_byte ch in
-  match Char.chr tag with
-  | 'B' | 'C' | 'D' | 'F' | 'I' | 'J' | 'S' | 'Z' | 's' ->
-    let jsig = match (Char.chr tag) with
-      | 's' ->
-        TObject( (["java";"lang"],"String"), [] )
-      | tag ->
-        fst (parse_signature_part (Char.escaped tag))
-    in
-    ValConst(jsig, get_constant consts (read_ui16 ch))
-  | 'e' ->
-    let path = parse_signature (get_string consts ch) in
-    let name = get_string consts ch in
-    ValEnum (path, name)
-  | 'c' ->
-    let name = get_string consts ch in
-    let jsig = if name = "V" then
-      TObject(([], "Void"), [])
-    else
-      parse_signature name
-    in
-    ValClass jsig
-  | '@' ->
-    ValAnnotation (parse_annotation consts ch)
-  | '[' ->
-    let num_vals = read_ui16 ch in
-    ValArray (List.init (num_vals) (fun _ -> parse_element_value consts ch))
-  | tag -> error ("Invalid element value: '" ^  Char.escaped tag ^ "'")
-
-and parse_ann_element consts ch =
-  let name = get_string consts ch in
-  let element_value = parse_element_value consts ch in
-  name, element_value
-
-and parse_annotation consts ch =
-  let anntype = parse_signature (get_string consts ch) in
-  let count = read_ui16 ch in
-  {
-    ann_type = anntype;
-    ann_elements = List.init count (fun _ -> parse_ann_element consts ch)
-  }
-
-let parse_attribute on_special consts ch =
-  let aname = get_string consts ch in
-  let error() = error ("Malformed attribute " ^ aname) in
-  let alen = read_i32 ch in
-  match aname with
-  | "Deprecated" ->
-    if alen <> 0 then error();
-    Some (AttrDeprecated)
-  | "RuntimeVisibleAnnotations" ->
-    let anncount = read_ui16 ch in
-    Some (AttrVisibleAnnotations (List.init anncount (fun _ -> parse_annotation consts ch)))
-  | "RuntimeInvisibleAnnotations" ->
-    let anncount = read_ui16 ch in
-    Some (AttrInvisibleAnnotations (List.init anncount (fun _ -> parse_annotation consts ch)))
-  | _ ->
-    let do_default () =
-      Some (AttrUnknown (aname,IO.nread_string ch alen))
-    in
-    match on_special with
-    | None -> do_default()
-    | Some fn -> fn consts ch aname alen do_default
-
-let parse_attributes ?on_special consts ch count =
-  let rec loop i acc =
-    if i >= count then List.rev acc
-    else match parse_attribute on_special consts ch with
-    | None -> loop (i + 1) acc
-    | Some attrib -> loop (i + 1) (attrib :: acc)
-  in
-  loop 0 []
-
-let parse_field kind consts ch =
-  let all_flags = match kind with
-    | JKField ->
-      [JPublic; JPrivate; JProtected; JStatic; JFinal; JUnusable; JVolatile; JTransient; JSynthetic; JEnum]
-    | JKMethod ->
-      [JPublic; JPrivate; JProtected; JStatic; JFinal; JSynchronized; JBridge; JVarArgs; JNative; JUnusable; JAbstract; JStrict; JSynthetic]
-  in
-  let acc = ref (parse_access_flags ch all_flags) in
-  let name = get_string consts ch in
-  let sign = parse_signature (get_string consts ch) in
-
-  let jsig = ref sign in
-  let throws = ref [] in
-  let types = ref [] in
-  let constant = ref None in
-  let code = ref None in
-
-  let attrib_count = read_ui16 ch in
-  let attribs = parse_attributes ~on_special:(fun _ _ aname alen do_default ->
-    match kind, aname with
-    | JKField, "ConstantValue" ->
-      constant := Some (get_constant consts (read_ui16 ch));
-      None
-    | JKField, "Synthetic" ->
-      if not (List.mem JSynthetic !acc) then acc := !acc @ [JSynthetic];
-      None
-    | JKField, "Signature" ->
-      let s = get_string consts ch in
-      jsig := parse_signature s;
-      None
-    | JKMethod, "Code" -> (* TODO *)
-      do_default()
-    | JKMethod, "Exceptions" ->
-      let num = read_ui16 ch in
-      throws := List.init num (fun _ -> TObject(get_class consts ch,[]));
-      None
-    | JKMethod, "Signature" ->
-      let s = get_string consts ch in
-      let tp, sgn, thr = parse_complete_method_signature s in
-      if thr <> [] then throws := thr;
-      types := tp;
-      jsig := TMethod(sgn);
-      None
-    | _ -> do_default()
-  ) consts ch attrib_count in
-  {
-    jf_name = name;
-    jf_kind = kind;
-    (* signature, as used by the vm *)
-    jf_vmsignature = sign;
-    (* actual signature, as used in java code *)
-    jf_signature = !jsig;
-    jf_throws = !throws;
-    jf_types = !types;
-    jf_flags = !acc;
-    jf_attributes = attribs;
-    jf_constant = !constant;
-    jf_code = !code;
-  }
-
-let parse_class ch =
-  if read_real_i32 ch <> 0xCAFEBABEl then error "Invalid header";
-  let minorv = read_ui16 ch in
-  let majorv = read_ui16 ch in
-  let constant_count = read_ui16 ch in
-  let const_big = ref true in
-  let consts = Array.init constant_count (fun idx ->
-    if !const_big then begin
-      const_big := false;
-      KUnusable
-    end else
-      let c = parse_constant constant_count idx ch in
-      (match c with KLong _ | KDouble _ -> const_big := true | _ -> ());
-      c
-  ) in
-  let consts = Array.mapi (fun i _ -> expand_constant consts i) consts in
-  let flags = parse_access_flags ch [JPublic; JUnusable; JUnusable; JUnusable; JFinal; JSuper; JUnusable; JUnusable; JUnusable; JInterface; JAbstract; JUnusable; JSynthetic; JAnnotation; JEnum] in
-  let this = get_class consts ch in
-  let super_idx = read_ui16 ch in
-  let super = match super_idx with
-    | 0 -> TObject((["java";"lang"], "Object"), []);
-    | idx -> match get_constant consts idx with
-      | ConstClass path -> TObject(path,[])
-      | _ -> error "Invalid super index"
-  in
-  let interfaces = List.init (read_ui16 ch) (fun _ -> TObject (get_class consts ch, [])) in
-  let fields = List.init (read_ui16 ch) (fun _ -> parse_field JKField consts ch) in
-  let methods = List.init (read_ui16 ch) (fun _ -> parse_field JKMethod consts ch) in
-
-  let inner = ref [] in
-  let types = ref [] in
-  let super = ref super in
-  let interfaces = ref interfaces in
-
-  let attribs = read_ui16 ch in
-  let attribs = parse_attributes ~on_special:(fun _ _ aname alen do_default ->
-    match aname with
-    | "InnerClasses" ->
-      let count = read_ui16 ch in
-      let classes = List.init count (fun _ ->
-        let inner_ci = get_class consts ch in
-        let outeri = read_ui16 ch in
-        let outer_ci = match outeri with
-          | 0 -> None
-          | _ -> match get_constant consts outeri with
-          | ConstClass n -> Some n
-          | _ -> error "Invalid class index"
-        in
-
-        let inner_namei = read_ui16 ch in
-        let inner_name = match inner_namei with
-          | 0 -> None
-          | _ -> match get_constant consts inner_namei with
-          | ConstUtf8 s -> Some s
-          | _ -> error ("Invalid string index " ^ string_of_int inner_namei)
-        in
-        let flags = parse_access_flags ch [JPublic; JPrivate; JProtected; JStatic; JFinal; JUnusable; JUnusable; JUnusable; JUnusable; JInterface; JAbstract; JSynthetic; JAnnotation; JEnum] in
-        inner_ci, outer_ci, inner_name, flags
-      ) in
-      inner := classes;
-      None
-    | "Signature" ->
-      let s = get_string consts ch in
-      let formal, idx = parse_formal_type_params s in
-      types := formal;
-      let s = String.sub s idx (String.length s - idx) in
-      let len = String.length s in
-      let sup, idx = parse_signature_part s in
-      let rec loop idx acc =
-        if idx = len then
-          acc
-        else begin
-          let s = String.sub s idx (len - idx) in
-          let iface, i2 = parse_signature_part s in
-          loop (idx + i2) (iface :: acc)
-        end
-      in
-      interfaces := loop idx [];
-      super := sup;
-      None
-    | _ -> do_default()
-  ) consts ch attribs in
-  IO.close_in ch;
-  {
-    cversion = majorv, minorv;
-    cpath = this;
-    csuper = !super;
-    cflags = flags;
-    cinterfaces = !interfaces;
-    cfields = fields;
-    cmethods = methods;
-    cattributes = attribs;
-    cinner_types = !inner;
-    ctypes = !types;
-  }
-

+ 0 - 289
libs/javalib/jWriter.ml

@@ -1,289 +0,0 @@
-(*
- *  This file is part of JavaLib
- *  Copyright (c)2004-2012 Nicolas Cannasse and Caue Waneck
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *)
-open JData;;
-open IO.BigEndian;;
-open IO;;
-open ExtString;;
-open ExtList;;
-
-exception Writer_error_message of string
-
-type context = {
-  cpool : unit IO.output;
-  mutable ccount : int;
-  ch : string IO.output;
-  mutable constants : (jconstant,int) PMap.t;
-}
-
-let error msg = raise (Writer_error_message msg)
-
-let get_reference_type i =
-  match i with
-  | RGetField ->  1
-  | RGetStatic ->  2
-  | RPutField ->  3
-  | RPutStatic ->  4
-  | RInvokeVirtual ->  5
-  | RInvokeStatic ->  6
-  | RInvokeSpecial ->  7
-  | RNewInvokeSpecial ->  8
-  | RInvokeInterface ->  9
-
-let encode_path ctx (pack,name) =
-  String.concat "/" (pack @ [name])
-
-let rec encode_param ctx ch param =
-  match param with
-  | TAny -> write_byte ch (Char.code '*')
-  | TType(w, s) ->
-    (match w with
-    | WExtends -> write_byte ch (Char.code '+')
-    | WSuper -> write_byte ch (Char.code '-')
-    | WNone -> ());
-    encode_sig_part ctx ch s
-
-and encode_sig_part ctx ch jsig = match jsig with
-  | TByte -> write_byte ch (Char.code 'B')
-  | TChar -> write_byte ch (Char.code 'C')
-  | TDouble -> write_byte ch (Char.code 'D')
-  | TFloat -> write_byte ch (Char.code 'F')
-  | TInt -> write_byte ch (Char.code 'I')
-  | TLong -> write_byte ch (Char.code 'J')
-  | TShort -> write_byte ch (Char.code 'S')
-  | TBool -> write_byte ch (Char.code 'Z')
-  | TObject(path, params) ->
-    write_byte ch (Char.code 'L');
-    write_string ch (encode_path ctx path);
-    if params <> [] then begin
-      write_byte ch (Char.code '<');
-      List.iter (encode_param ctx ch) params;
-      write_byte ch (Char.code '>')
-    end;
-    write_byte ch (Char.code ';')
-  | TObjectInner(pack, inners) ->
-    write_byte ch (Char.code 'L');
-    List.iter (fun p ->
-      write_string ch p;
-      write_byte ch (Char.code '/')
-    ) pack;
-
-    let first = ref true in
-    List.iter (fun (name,params) ->
-      (if !first then first := false else write_byte ch (Char.code '.'));
-      write_string ch name;
-      if params <> [] then begin
-        write_byte ch (Char.code '<');
-        List.iter (encode_param ctx ch) params;
-        write_byte ch (Char.code '>')
-      end;
-    ) inners;
-    write_byte ch (Char.code ';')
-  | TArray(s,size) ->
-    write_byte ch (Char.code '[');
-    (match size with
-    | Some size ->
-      write_string ch (string_of_int size);
-    | None -> ());
-    encode_sig_part ctx ch s
-  | TMethod(args, ret) ->
-    write_byte ch (Char.code '(');
-    List.iter (encode_sig_part ctx ch) args;
-    (match ret with
-      | None -> write_byte ch (Char.code 'V')
-      | Some jsig -> encode_sig_part ctx ch jsig)
-  | TTypeParameter name ->
-    write_byte ch (Char.code 'T');
-    write_string ch name;
-    write_byte ch (Char.code ';')
-
-let encode_sig ctx jsig =
-  let buf = IO.output_string() in
-  encode_sig_part ctx buf jsig;
-  close_out buf
-
-let write_utf8 ch s =
-  String.iter (fun c ->
-    let c = Char.code c in
-    if c = 0 then begin
-      write_byte ch 0xC0;
-      write_byte ch 0x80
-    end else
-      write_byte ch c
-  ) s
-
-let rec const ctx c =
-  try
-    PMap.find c ctx.constants
-  with
-  | Not_found ->
-    let ret = ctx.ccount in
-    (match c with
-    (** references a class or an interface - jpath must be encoded as StringUtf8 *)
-    | ConstClass path -> (* tag = 7 *)
-        write_byte ctx.cpool 7;
-        write_ui16 ctx.cpool (const ctx (ConstUtf8 (encode_path ctx path)))
-    (** field reference *)
-    | ConstField (jpath, unqualified_name, jsignature) (* tag = 9 *) ->
-        write_byte ctx.cpool 9;
-        write_ui16 ctx.cpool (const ctx (ConstClass jpath));
-        write_ui16 ctx.cpool (const ctx (ConstNameAndType (unqualified_name, jsignature)))
-    (** method reference; string can be special "<init>" and "<clinit>" values *)
-    | ConstMethod (jpath, unqualified_name, jmethod_signature) (* tag = 10 *) ->
-        write_byte ctx.cpool 10;
-        write_ui16 ctx.cpool (const ctx (ConstClass jpath));
-        write_ui16 ctx.cpool (const ctx (ConstNameAndType (unqualified_name, TMethod jmethod_signature)))
-    (** interface method reference *)
-    | ConstInterfaceMethod (jpath, unqualified_name, jmethod_signature) (* tag = 11 *) ->
-        write_byte ctx.cpool 11;
-        write_ui16 ctx.cpool (const ctx (ConstClass jpath));
-        write_ui16 ctx.cpool (const ctx (ConstNameAndType (unqualified_name, TMethod jmethod_signature)))
-    (** constant values *)
-    | ConstString s  (* tag = 8 *) ->
-        write_byte ctx.cpool 8;
-        write_ui16 ctx.cpool (const ctx (ConstUtf8 s))
-    | ConstInt i (* tag = 3 *) ->
-        write_byte ctx.cpool 3;
-        write_real_i32 ctx.cpool i
-    | ConstFloat f (* tag = 4 *) ->
-        write_byte ctx.cpool 4;
-        (match classify_float f with
-        | FP_normal | FP_subnormal | FP_zero ->
-            write_real_i32 ctx.cpool (Int32.bits_of_float f)
-        | FP_infinite when f > 0.0 ->
-            write_real_i32 ctx.cpool 0x7f800000l
-        | FP_infinite ->
-            write_real_i32 ctx.cpool 0xff800000l
-        | FP_nan ->
-            write_real_i32 ctx.cpool 0x7f800001l)
-    | ConstLong i (* tag = 5 *) ->
-        write_byte ctx.cpool 5;
-        write_i64 ctx.cpool i;
-    | ConstDouble d (* tag = 6 *) ->
-        write_byte ctx.cpool 6;
-        write_double ctx.cpool d;
-        ctx.ccount <- ctx.ccount + 1
-    (** name and type: used to represent a field or method, without indicating which class it belongs to *)
-    | ConstNameAndType (unqualified_name, jsignature) ->
-        write_byte ctx.cpool 12;
-        write_ui16 ctx.cpool (const ctx (ConstUtf8 (unqualified_name)));
-        write_ui16 ctx.cpool (const ctx (ConstUtf8 (encode_sig ctx jsignature)))
-    (** UTF8 encoded strings. Note that when reading/writing, take into account Utf8 modifications of java *)
-    (* (http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.7) *)
-    | ConstUtf8 s ->
-        write_byte ctx.cpool 1;
-        write_ui16 ctx.cpool (String.length s);
-        write_utf8 ctx.cpool s
-    (** invokeDynamic-specific *)
-    | ConstMethodHandle (reference_type, jconstant) (* tag = 15 *) ->
-        write_byte ctx.cpool 15;
-        write_byte ctx.cpool (get_reference_type reference_type);
-        write_ui16 ctx.cpool (const ctx jconstant)
-    | ConstMethodType jmethod_signature (* tag = 16 *) ->
-        write_byte ctx.cpool 16;
-        write_ui16 ctx.cpool (const ctx (ConstUtf8 (encode_sig ctx (TMethod jmethod_signature))))
-    | ConstInvokeDynamic (bootstrap_method, unqualified_name, jsignature) (* tag = 18 *) ->
-        write_byte ctx.cpool 18;
-        write_ui16 ctx.cpool bootstrap_method;
-        write_ui16 ctx.cpool (const ctx (ConstNameAndType(unqualified_name, jsignature)))
-    | ConstUnusable -> assert false);
-    ctx.ccount <- ret + 1;
-    ret
-
-let write_const ctx ch cconst =
-  write_ui16 ch (const ctx cconst)
-;;
-
-let write_formal_type_params ctx ch tparams =
-  write_byte ch (Char.code '<');
-  List.iter (fun (name,ext,impl) ->
-    write_string ch name;
-    (match ext with
-    | None -> ()
-    | Some jsig ->
-      write_byte ch (Char.code ':');
-      write_string ch (encode_sig ctx jsig));
-    List.iter (fun jsig ->
-      write_byte ch (Char.code ':');
-      write_string ch (encode_sig ctx jsig)
-    ) impl
-  ) tparams;
-  write_byte ch (Char.code '>');
-;;
-
-let write_complete_method_signature ctx ch (tparams : jtypes) msig throws =
-  if tparams <> [] then write_formal_type_params ctx ch tparams;
-  write_string ch (encode_sig ctx (TMethod(msig)));
-  if throws <> [] then List.iter (fun jsig ->
-    write_byte ch (Char.code '^');
-    write_string ch (encode_sig ctx jsig)
-  ) throws
-;;
-
-let write_access_flags ctx ch all_flags flags =
-  let value = List.fold_left (fun acc flag ->
-    try
-      acc lor (Hashtbl.find all_flags flag)
-    with Not_found ->
-      error ("Not found flag: " ^ (string_of_int (Obj.magic flag)))
-  ) 0 flags in
-  write_ui16 ch value
-;;
-
-let rec write_ann_element ctx ch (name,eval) =
-  write_const ctx ch (ConstUtf8 name);
-  write_element_value ctx ch eval
-
-and write_annotation ctx ch ann =
-  write_const ctx ch (ConstUtf8 (encode_sig ctx ann.ann_type));
-  write_ui16 ch (List.length ann.ann_elements);
-  List.iter (write_ann_element ctx ch) ann.ann_elements
-
-and write_element_value ctx ch value = match value with
-  | ValConst(jsig, cconst) -> (match jsig with
-    | TObject((["java";"lang"],"String"), []) ->
-      write_byte ch (Char.code 's')
-    | TByte | TChar | TDouble | TFloat | TInt | TLong | TShort | TBool ->
-      write_string ch (encode_sig ctx jsig)
-    | _ ->
-      let s = encode_sig ctx jsig in
-      error ("Invalid signature " ^ s ^ " for constant value"));
-    write_ui16 ch (const ctx cconst)
-  | ValEnum(jsig,name) ->
-    write_byte ch (Char.code 'e');
-    write_const ctx ch (ConstUtf8 (encode_sig ctx jsig));
-    write_const ctx ch (ConstUtf8 name)
-  | ValClass(jsig) ->
-    write_byte ch (Char.code 'c');
-    let esig = match jsig with
-      | TObject(([],"Void"),[])
-      | TObject((["java";"lang"],"Void"),[]) ->
-        "V"
-      | _ ->
-        encode_sig ctx jsig
-    in
-    write_const ctx ch (ConstUtf8 (esig))
-  | ValAnnotation ann ->
-    write_byte ch (Char.code '@');
-    write_annotation ctx ch ann
-  | ValArray(lvals) ->
-    write_byte ch (Char.code '[');
-    write_ui16 ch (List.length lvals);
-    List.iter (write_element_value ctx ch) lvals
-;;
-

+ 4 - 4
libs/mbedtls/dune

@@ -2,8 +2,8 @@
 
 (library
 	(name mbedtls)
-	(c_names
-		mbedtls_stubs
-	)
+	(foreign_stubs
+		(language c)
+		(names mbedtls_stubs))
 	(wrapped false)
-)
+)

+ 7 - 1
libs/neko/dune

@@ -1,7 +1,13 @@
 (include_subdirs no)
 
+(env
+	(_
+		(flags (-w -27))
+	)
+)
+
 (library
 	(name neko)
 	(libraries extlib)
 	(wrapped false)
-)
+)

+ 2 - 2
libs/neko/ncompile.ml

@@ -673,8 +673,8 @@ and compile_builtin ctx tail b el p =
 			write ctx (Call 1);
 			(* // insert an infinite loop in order to
 			// comply with bytecode checker *)
-			let _ = jmp ctx in
-			()
+			let _jmp = jmp ctx in
+			ignore(_jmp)
 		) dtraps;
 	| ("goto" , _) ->
 		error "Invalid $goto statement" p

+ 0 - 0
libs/objsize/alloc.c → libs/objsize/alloc.h


+ 1 - 1
libs/objsize/bitarray.c → libs/objsize/bitarray.h

@@ -14,7 +14,7 @@ void PRF(_set)(TYPE arr[], size_t i, TYPE val);
 
 #define ALLOC_TYPE unsigned char
 #define ALLOC_PRF(x) ALPRF(x)
-#include "alloc.c"
+#include "alloc.h"
 
 
 size_t wordalign(size_t n)

+ 28 - 5
libs/objsize/c_objsize.c

@@ -7,11 +7,16 @@
 
 
 #define PRF(x) bitarray##x
-#include "bitarray.c"
+#include "bitarray.h"
 
 #include "util.h"
 
 #include <caml/memory.h>
+#include <caml/version.h>
+
+#if OCAML_VERSION_MAJOR >= 5
+#include <caml/address_class.h>
+#endif
 
 // FROM byterun/gc.h
 #define Caml_white (0 << 8)
@@ -38,6 +43,7 @@
 #define In_static_data 4
 #define In_code_area 8
 
+#if OCAML_VERSION_MAJOR < 5
 #ifdef ARCH_SIXTYFOUR
 
 // 64 bits: Represent page table as a sparse hash table
@@ -63,6 +69,23 @@ CAMLextern unsigned char * caml_page_table[Pagetable1_size];
 
 #define Is_in_heap_or_young(a) (Classify_addr(a) & (In_heap | In_young))
 
+void store_explicit(header_t hd, value v, int col)
+ {
+  Hd_val(v) = Coloredhd_hd(hd, col);
+ }
+
+#else
+
+void store_explicit(header_t hd, value v, int col)
+ {
+  atomic_store_explicit(
+	Hp_atomic_val(v),
+	Coloredhd_hd(hd, col),
+	memory_order_release);
+ }
+
+#endif
+
 //--------------------------------------------------------
 
 
@@ -352,7 +375,7 @@ void c_rec_objsize(value v, size_t depth)
 
   DBG(printf("COL: w %08lx %i\n", v, col));
 
-  Hd_val(v) = Coloredhd_hd(hd, Col_blue);
+  store_explicit(hd, v, Col_blue);
 
   if (Tag_val(v) < No_scan_tag)
    {
@@ -378,7 +401,7 @@ void restore_colors(value v)
 
   col = readcolor();
   DBG(printf("COL: r %08lx %i\n", v, col));
-  Hd_val(v) = Coloredhd_hd(Hd_val(v), col);
+  store_explicit(Hd_val(v), v, col);
 
   if (Tag_val(v) < No_scan_tag)
    {
@@ -417,7 +440,7 @@ int c_objsize(value v, value scan, value reach, size_t* headers, size_t* data, s
 	head = Field(head,1);
 	if( col == Col_blue ) continue;
 	writecolor(col);
-	Hd_val(v) = Coloredhd_hd(hd, Col_blue);
+	store_explicit(hd, v, Col_blue);
  }
 
  acc_data = 0;
@@ -444,7 +467,7 @@ int c_objsize(value v, value scan, value reach, size_t* headers, size_t* data, s
 	head = Field(head,1);
 	if( Colornum_hd(Hd_val(v)) != Col_blue ) continue;
 	col = readcolor();
-	Hd_val(v) = Coloredhd_hd(Hd_val(v), col);
+	store_explicit(Hd_val(v), v, col);
  }
 
   while( COND_BLOCK(reach) ) {

+ 3 - 4
libs/objsize/dune

@@ -2,8 +2,7 @@
 
 (library
 	(name objsize)
-	(c_names c_objsize)
-	(c_flags (-I../../../../libs/objsize)) ; TODO: This is stupid
+	(foreign_stubs (language c) (names c_objsize) (flags -O1 -W -Wall -Werror -fPIC))
+	(flags :standard -warn-error -a+8)
 	(wrapped false)
-	(modules objsize)
-)
+	(modules objsize))

+ 0 - 66
libs/ocamake/ocamake.dsp

@@ -1,66 +0,0 @@
-# Microsoft Developer Studio Project File - Name="ocamake" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) External Target" 0x0106
-
-CFG=ocamake - Win32 Native code
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "ocamake.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "ocamake.mak" CFG="ocamake - Win32 Native code"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "ocamake - Win32 Native code" (based on "Win32 (x86) External Target")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir ""
-# PROP BASE Intermediate_Dir ""
-# PROP BASE Cmd_Line "ocamake -opt ocamake.dsp -o ocamake.exe"
-# PROP BASE Rebuild_Opt "-all"
-# PROP BASE Target_File "ocamake_opt.exe"
-# PROP BASE Bsc_Name ""
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ""
-# PROP Intermediate_Dir ""
-# PROP Cmd_Line "ocamake str.cmxa unix.cmxa -opt ocamake.dsp -o ocadbg.exe"
-# PROP Rebuild_Opt "-all"
-# PROP Target_File "ocadbg.exe"
-# PROP Bsc_Name ""
-# PROP Target_Dir ""
-# Begin Target
-
-# Name "ocamake - Win32 Native code"
-
-!IF  "$(CFG)" == "ocamake - Win32 Native code"
-
-!ENDIF 
-
-# Begin Group "ML Files"
-
-# PROP Default_Filter "ml;mly;mll"
-# Begin Source File
-
-SOURCE=.\ocamake.ml
-# End Source File
-# End Group
-# Begin Group "MLI Files"
-
-# PROP Default_Filter "mli"
-# End Group
-# End Target
-# End Project

+ 0 - 29
libs/ocamake/ocamake.dsw

@@ -1,29 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "ocamake"=.\ocamake.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-

+ 0 - 94
libs/ocamake/ocamake.html

@@ -1,94 +0,0 @@
-<html>
-<body bgcolor="#ffffff" link="Black" vlink="Black">
-<center><b><font color="#000099" size="+2">OCamake</font></b></center>
-<br>
-<font color="#777777">
-	OCamake - Copyright (c)2002-2003 Nicolas Cannasse & Motion Twin.<br>
-	The last version of this software can be found at : <a href="http://tech.motion-twin.com">http://tech.motion-twin.com</a><br><br>
-	This software is provided "AS IS" without any warranty of any kind, merchantability or fitness for a particular purpose. You should use it at your own risks, as the author and his company won't be responsible for any problem that the usage of this software could raise.
-</font>
-<br>
-<br>
-
-<ul>
-
-<li><b><font color="#000099">Introduction:</font></b><br>
-<br>
-OCamake is an automatic compiler for the Objective Caml language. It removes pain from the user which does not need anymore to write a Makefile. OCamake can work either as an application which compile your program or as a Makefile generator (using the <code>-mak</code> flag). OCamake has also special features for integration under Microsoft Visual Studio.
-<br>
-<br>
-<li><b><font color="#000099">Installation:</font></b><br>
-<br>
-OCamake is a source-only distribution, so you need to compile it first. Type the following command-line:<br>
-&nbsp;&nbsp;<code>ocamlc unix.cma str.cma ocamake.ml -o ocamake.exe</code><br>
-This should produce a file "<code>ocamake.exe</code>". Copy this file in your <code>ocaml/bin</code> directory.<br>
-<br>
-<li><b><font color="#000099">Usage:</font></b><br>
-<br>
-To compile your project, simply call OCamake with the files you want to compile:<br>
-&nbsp;&nbsp;<code>ocamake *.ml *.mli</code><br>
-<br>
-To remove all intermediate files that have been produced by the compiler :<br>
-&nbsp;&nbsp;<code>ocamake -clean *.ml *.mli</code><br>
-<br>
-To generate a Makefile:<br>
-&nbsp;&nbsp;<code>ocamake -mak *.ml *.mli</code><br>
-&nbsp;&nbsp;<code>make all</code><br>
-&nbsp;&nbsp;<code>...</code><br>
-&nbsp;&nbsp;<code>make clean</code><br>
-<br>
-(Windows users can use <code>nmake</code> instead of make and should use <code>nmake wclean</code> to remove intermediate files)
-<br>
-<br>
-<li><b><font color="#000099">Features:</font></b><br>
-<br>
-OCamake works with the following files :
-<ul>
-	<li><code>ml, mli</code> : theses files are added to the list of files to build
-	<li><code>cmo, cmx, cma, cmxa, dll, so, lib, a, o, obj</code> : theses files are added to the library list
-	<li><code>mll, mly</code> : theses files are compiled using <code>ocamllex</code> and <code>ocamlyacc</code>, and their result are added to the list of files to build.
-	<li><code>dsp, vcproj</code> (Visual Studio Project) : all the files included in the project are added to the ocamake file list.
-</ul>
-<br>
-Once the final file list is made, OCamake run <code>ocamldep</code> to build module dependencies tree, and then build and link the tree in the good order (for more information on the algorithm used, see sources).
-Only modified sources files or files with one dependency modified are rebuilt.<br>
-<br>
-If one <code>dsp</code> file has been found or if the <code>-epp</code> flag has been set, then all compilation errors are processed by OCamake to transform them into a Visual Studio compatible format.<br>
-If one <code>dsp</code> file has been found or if the <code>-cpp</code> flag has been set, the character ranges in Ocaml errors are replaced by the corresponding expression found in the source file.
-<br>
-<br>
-<li><b><font color="#000099">Options:</font></b><br>
-<br>
-The following command-line options are available :
-<ul>
-	<li><code>-clean</code> : delete all the intermediate and ouput files for the target build.
-	<li><code>-mak</code> : generate a <code>Makefile</code> for this project (<i>still experimental</i>).
-	<li><code>-opt</code> : turn on native compilation.
-	<li><code>-a</code> : build a library (<code>cma or cmxa</code>).
-	<li><code>-o &lt;output&gt;</code> : set the output file for the project.
-	<li><code>-all</code> : rebuild the entire project.
-	<li><code>-cpp</code> : convert characters range in errors to file expression.
-	<li><code>-epp</code> : use MSVC error messages format.
-	<li><code>-g</code> : compile and link in debug mode.
-	<li><code>-pp &lt;command&gt;</code> : pipe source through preprocessor.
-	<li><code>-cp &lt;flag&gt;</code> : add this flag to the compiler command line paramaters.
-	<li><code>-lp &lt;flag&gt;</code> : add this flag to the linker command line paramaters.
-	<li><code>-I &lt;path&gt;</code> : add the path to the list of include directories.
-	<li><code>-n &lt;file&gt;</code> : remove that file from the file list : this can be useful when you want to have all the files but one (<code>ocamake -n myfile.ml *.ml *.mli</code>).
-	<li><code>-v</code> : verbose mode - this print all the commands that ocamake is running in order to build the project.
-	<li><code>-P &lt;file&gt;</code> : add priority to a given file when having cycle between modules.
-</ul>
-<br>
-<li><b><font color="#000099">Licence:</font></b><br>
-<br>
-The full source code of OCamake is included, so you can modify, use, and redistribute it as you want for any usage conform to the licence. This code is under the LGPL (GNU Lesser General Public Licence), you can get more information on www.gnu.org.<br>
-<br>
-<li><b><font color="#000099">Author:</font></b><br>
-<br>
-Nicolas Cannasse <a href="mailto:[email protected]">[email protected]</a><br>
-Website : <a href="http://tech.motion-twin.com">http://tech.motion-twin.com</a><br>
-Thanks to <a href="http://www.lexifi.com">Lexifi</a>.
-<br>
-<br>
-</body>
-</html>

+ 0 - 661
libs/ocamake/ocamake.ml

@@ -1,661 +0,0 @@
-(* ************************************************************************ *)
-(*                                                                          *)
-(* OCAMAKE - OCaml Automatic compilation                                    *)
-(*      (c)2002 Nicolas Cannasse                                            *)
-(*      (c)2002 Motion-Twin                                                 *)
-(*                                                                          *)
-(* Last version : http://tech.motion-twin.com                               *)
-(*                                                                          *)
-(* ************************************************************************ *)
-open Unix
-open Printf
-open Arg
-
-type compile_mode =
-	| CM_DEFAULT
-	| CM_BYTE
-	| CM_OPT
-
-type file_ext =
-	| ML | MLI | MLL | MLY
-	| CMO | CMX | CMA | CMXA
-	| DLL | SO | EXE | LIB
-	| CMI | O | OBJ | A
-
-type file = {
-	name : string;
-	ext : file_ext;
-	target : string;
-	deps : string list;
-}
-
-(* ************************************************************************ *)
-(* GLOBALS *)
-
-let verbose = ref false (* print command calls in verbose mode *)
-let project_name = ref None (* for VC++ DSP *)
-let error_process = ref false (* VC++ error message processing *)
-let chars_process = ref false (* replace chars range in errors by file data *)
-
-(* ************************************************************************ *)
-(* USEFUL FUNCTIONS *)
-
-let if_some f opt def =
-	match opt with
-	| None -> def
-	| Some v -> f v
-
-let print str = print_endline str; flush Pervasives.stdout
-
-let (???) file =
-	failwith ("Don't know what to do with file " ^ file)
-
-let str_suffix = function
-	| ML -> "ml" | MLI -> "mli" | MLL -> "mll" | MLY -> "mly" | CMO -> "cmo"
-	| CMX -> "cmx" | CMA -> "cma" | CMXA -> "cmxa" | DLL -> "dll" | SO -> "so"
-	| EXE -> "exe" | CMI -> "cmi" | O -> "o" | A -> "a" | OBJ -> "obj"
-	| LIB -> "lib"
-
-let unescape file =
-	let l = String.length file in
-	if l >= 2 && file.[0] = '"' && file.[l-1] = '"' then String.sub file 1 (l-2) else file
-
-let extension file =
-	let rsplit_char str ch =
-		let p = String.rindex str ch in
-		let len = String.length str in
-		(String.sub str 0 p, String.sub str (p + 1) (len - p - 1))	
-	in
-	let file = unescape file in
-	let s = try snd(rsplit_char file '.') with Not_found -> "" in
-	String.uppercase s
-
-let (+!) file suff =
-	let base = Filename.chop_extension file in
-	base ^ "." ^ str_suffix suff
-
-let filter_all_in func ic =
-	let rec treat acc =
-	try
-		match func (input_line ic) with
-		| None -> treat acc
-		| Some data -> treat (data :: acc)
-	with
-		End_of_file -> close_in ic; acc
-	in
-	List.rev (treat [])
-
-let rec remove_duplicates = function
-	| [] -> []
-	| item :: q when List.exists ((=) item) q -> remove_duplicates q
-	| item :: q -> item :: remove_duplicates q
-
-let file_time fname =
-	try (Unix.stat fname).st_mtime with Unix_error _ -> 0.
-
-let flatten = String.concat " "
-
-let escape str =
-	try
-		ignore(String.index str ' ');
-		"\"" ^ str ^ "\"";
-	with Not_found -> str
-
-let delete_file file =
-	try Sys.remove file with Sys_error _ -> ()
-
-let check_existence (ext,name) =
-	match ext with
-	| ML | MLI ->
-		if not (Sys.file_exists name) then
-			failwith ("No such file : "^(escape name))
-	| _ -> ()
-		(* Others files can be found in Ocaml stdlib or
-		   user -I paths *)
-
-exception Found_pos of int
-
-let print_errors output msg =
-	let split str sep =
-		let find_sub str sub =
-			let len = String.length sub in
-			try
-				for i = 0 to String.length str - len do
-					if String.sub str i len = sub then raise (Found_pos i);
-				done;
-				raise Not_found
-			with Found_pos i -> i 
-		in
-		let p = find_sub str sep in
-		let len = String.length sep in
-		let slen = String.length str in
-		(String.sub str 0 p, String.sub str (p + len) (slen - p - len))
-	in
-	let process_chars file chars line =
-		let cmin, cmax = split chars "-" in
-		let cmin, cmax = int_of_string cmin, int_of_string cmax in
-		if cmax > cmin then begin
-			let f = open_in file in
-			for i = 1 to line-1 do ignore(input_line f) done;
-			seek_in f ((pos_in f)+cmin);
-			let s = String.create (cmax - cmin) in
-			ignore(input f s 0 (cmax - cmin));
-			prerr_endline (try
-					(String.sub s 0 (String.index s '\n'))^"..."
-				with
-					Not_found -> s);
-		end
-	in
-	let printer =
-		(match !error_process , !chars_process with
-		| true , _ -> (function line ->
-			try
-				let data, chars = split line ", characters " in
-				let data, lnumber = split data "\", line " in
-				let _, file = split data "File \"" in
-				prerr_string (file ^ "(" ^ lnumber ^ ") : ");
-				let chars, _ = split chars ":" in
-				if !chars_process then
-					(try process_chars file chars (int_of_string lnumber) with _ -> raise Not_found)
- 			with
-				Not_found ->
-					prerr_endline line)
-		| false , true -> (function line ->
-			try
-				let edata, chars = split line ", characters " in
-				let data, lnumber = split edata "\", line " in
-				let _, file = split data "File \"" in
-				let chars, _ = split chars ":" in
-				prerr_string (edata^" : ");
-				if !chars_process then
-					process_chars file chars (int_of_string lnumber);
- 			with
-				Not_found ->
-					prerr_endline line)
-
-		| false , false ->
-		      prerr_endline)
-	in
-	List.iter printer output;
-	failwith msg
-
-let exec ?(stdout=false) ?(outfirst=false) cmd errmsg =
-	if !verbose then print cmd;
-	let pout, pin, perr = open_process_full cmd (Unix.environment()) in
-	let read = filter_all_in (fun s -> Some s) in
-	let data, edata = 
-	(* this is made to prevent the program lock when one
-	   buffer is full and the process is waiting for us
-	   to read it before exiting... while we're reading
-	   the other output buffer ! *)
-	(if outfirst then
-		let d = read pout in
-		let ed = read perr in
-		d,ed
-	else	
-		let ed = read perr in
-		let d = read pout in
-		d,ed) in
-	match close_process_full (pout, pin, perr) with
-	| WEXITED 0 -> data,edata
-	| WEXITED exitcode -> print_errors (if stdout then edata @ data else edata) errmsg
-	| _ -> failwith "Build aborted by signal"
-
-(* ************************************************************************ *)
-(* DEPENDENCIES *)
-
-let line_regexp = Str.regexp "^\\([0-9A-Za-z:_\\./\\\\-]+\\.cm[oi]\\):\\( .*\\)$"
-let dep_regexp = Str.regexp " \\([0-9A-Za-z:_\\./\\\\-]+\\.cm[oi]\\)"
-
-let build_graph opt paramlist files =
-	let srcfiles = List.filter (fun (e,_) ->
-		match e with
-		| ML | MLI -> true
-		| _ -> false) files in
-	let get_name (_,f) = escape f in
-	let file_names = flatten (List.map get_name srcfiles) in
-	let params = flatten paramlist in
-	let command = sprintf "ocamldep %s %s" params file_names in	
-	let output,_ = exec command "Failed to make dependencies" ~outfirst:true in
-	let data = String.concat "\n" output in	
-	let data = Str.global_replace (Str.regexp "\\\\\r\n") "" data in (* win *)
-	let data = Str.global_replace (Str.regexp "\\\\\n") "" data in (* unix *)		
-	let rec get_deps data p =
-		try
-			let newp = Str.search_forward dep_regexp data p in
-			let file = Str.matched_group 1 data in
-			if opt && extension file = "CMO" then 
-				(file +! CMX)::(get_deps data (newp+1))
-			else
-				file::(get_deps data (newp+1))
-		with
-			Not_found -> []
-	in
-	let rec get_lines p =		
-		try
-			let newp = Str.search_forward line_regexp data p in	
-			let file = Str.matched_group 1 data in			
-			let lines = get_deps (Str.matched_group 2 data) 0 in			
-			(Filename.basename file,lines)::(get_lines (newp+1))
-		with
-			Not_found -> []
-	in
-	let lines = get_lines 0 in
-	let init_infos (ext,fname) =
-		let deptarget = Filename.basename (match ext with
-			| ML ->  fname +! CMO
-			| MLI -> fname +! CMI
-			| _ -> fname) in
-		let target = (match ext with
-			| ML -> fname +! (if opt then CMX else CMO)
-			| MLI -> fname +! CMI
-			| _ -> fname) in
-		{
-			name = fname;
-			ext = ext;
-			target = target;
-			deps =
-				(try
-					snd (List.find (fun (n,_) -> n = deptarget) lines)
-				with
-					Not_found -> []);
-		}
-	in	
-	let deps = List.map init_infos files in
-	match !verbose with
-	| false -> deps
-	| true ->
-		let print_dep d =
-			let dl = String.concat " " (List.map Filename.basename d.deps) in
-			printf "%s: %s\n" (Filename.basename d.target) dl;
-		in
-		List.iter print_dep deps;
-		deps
-
-let rec graph_topological_sort all g priority acc =
-	let has_dep where dep =	
-		List.exists (fun f -> Filename.basename f.target =
-							Filename.basename dep) where
-	in
-	let modified a b = (file_time a) < (file_time b) in
-	let is_free file = not(List.exists (has_dep g) file.deps) in
-	let rec has_priority = function
-		| [] -> raise Not_found
-		| x :: l ->
-			try
-				List.find (fun f -> x = (Filename.basename f.name)) g
-			with
-				Not_found -> has_priority l
-	in
-	let to_build file =
-		all || (* rebuild all *)
-		List.exists (has_dep acc) file.deps || (* a dep is rebuild *)
-		List.exists (modified file.target) file.deps || (* dep modified *)
-		(file_time file.target) < (file_time file.name) (* is modified *)
-	in
-	match g with
-	| [] -> acc
-	| _ ->
-		let free,g = List.partition is_free g in
-		match free with 
-		| [] ->
-			(try
-				let free = has_priority priority in
-				let g = List.filter ((<>) free) g in
-				if to_build free then
-					graph_topological_sort all g priority (acc@[free])
-				else
-					graph_topological_sort all g priority acc;
-			with Not_found ->
-				List.iter (fun f -> prerr_endline f.name) g;
-				failwith "Cycle detected in file dependencies !")
-		| _ ->
-			let to_build = List.filter to_build free in
-			graph_topological_sort all g priority (acc@to_build)
-
-(* ************************************************************************ *)
-(* COMPILATION *)
-
-let compile ?(precomp=false) opt paramlist f =
-	try
-		let command = (match f.ext with
-		| ML | MLI ->
-			let params = flatten paramlist in
-			let compiler = (if opt then "ocamlopt" else "ocamlc") in
-			sprintf "%s -c %s %s" compiler params (escape f.name)
-		| MLL when precomp -> "ocamllex " ^ (escape f.name)
-		| MLY when precomp -> "ocamlyacc " ^ (escape f.name)
-		| _ -> raise Exit) in
-		print (Filename.basename (unescape f.name));
-		let stdout,stderr = exec command "Build failed" in
-		try
-			print_errors (stderr@stdout) "";
-		with
-			Failure _ -> ()
-	with
-		Exit -> ()
-
-let pre_compile all (ext,name) =
-	match ext with
-	| MLL | MLY ->
-		let time = file_time name in
-		if time = 0. then failwith ("No such file : "^(escape name));
-		if all || (file_time (name +! ML)) < time then
-			compile ~precomp:true false [] {
-				name = name;
-				ext = ext;
-				deps = [];
-				target = "";
-			}
-	| _ -> () (* other files type does not need pre-compilation *)
-
-let clean_targets opt acc (ext,name) =	
-	match ext with
-	| MLY ->
-		(name +! ML) :: (name +! MLI) :: acc
-	| MLL ->
-		(name +! ML) :: acc
-	| ML when opt ->
-		(name +! (if Sys.os_type = "Win32" then OBJ else O)) :: (name +! CMX) :: (name +! CMI) :: acc
-	| ML ->
-		(name +! CMO) :: (name +! CMI) :: acc
-	| MLI ->
-		(name +! CMI) :: acc
-	| _ ->
-		acc
-
-(*
-	In order to link, we need to order the CMO files.
-	We currently have a ML/MLI dependency graph (in fact, tree) generated
-	by ocamldep.
-
-	To build the CMO list, we are reducing the dep-tree into one graph merging
-	corresponding ML & MLI nodes. ML-ML edges are keeped, ML-MLI edges
-	become ML-ML edges only if they do not create a cycle in the reduced
-	graph.
-
-	Then we sort the graph using topological ordering.
-*)
-let graph_reduce opt g =
-	let ext = (if opt then CMX else CMO) in
-	let rec path_exists g a b =
-		if a = b then true else
-		try
-			let f = List.find (fun f -> f.target = a) g in
-			List.exists (fun d -> path_exists g d b) f.deps
-		with
-			Not_found -> false
-	in
-	let rec deps_reduce f g = function		
-		| [] -> []
-		| dep::deps ->
-			match extension dep with
-			| "CMI" when not(path_exists g (dep +! ext) f.target) ->				
-				(dep +! ext)::(deps_reduce f g deps)
-			| "CMO" | "CMX" ->
-				dep::(deps_reduce f g deps)
-			| _ -> deps_reduce f g deps
-	in
-	let rec do_reduce g acc =
-		match g with
-		| [] -> acc
-		| f::g' ->			
-			let f = { f with deps = deps_reduce f (g@acc) f.deps } in
-			do_reduce g' (f::acc)
-	in
-	do_reduce g []	
-
-let is_lib f = match f.ext with
-	| CMA | CMXA | CMO | CMX | DLL | SO | LIB | A | O | OBJ -> true
-	| _ -> false
-
-let link opt paramlist files priority output =
-	print "Linking...";
-	let sources = List.filter (fun f -> f.ext = ML) files in
-	let libs = List.filter is_lib files in
-	let sources = graph_topological_sort true (graph_reduce opt sources) priority [] in
-	let lparams = flatten (List.map (fun f -> escape f.name) libs) in
-	let sparams = flatten (List.map (fun f -> escape f.target) sources) in
-	let params = flatten paramlist in
-	let cc = (if opt then "ocamlopt" else "ocamlc") in
-	let cmd = sprintf "%s %s %s %s -o %s" cc params lparams sparams output in
-	ignore(exec ~stdout:true cmd "Linking failed")
-
-(* ************************************************************************ *)
-(* FILE PROCESSING *)
-
-let dsp_get_files dsp_file =
-	let get_file line =
-		if String.length line > 7 && String.sub line 0 7 = "SOURCE=" then
-			Some (unescape (String.sub line 7 (String.length line-7)))
-		else
-			None
-	in
-	filter_all_in get_file (open_in dsp_file)
-
-let vcproj_get_files vcp_file =
-	let get_file line =
-		let len = String.length line in
-		let p = ref 0 in
-		while !p < len && (line.[!p] = ' ' || line.[!p] = '\t') do
-			incr p;
-		done;
-		let line = String.sub line !p (len - !p) in		
-		if String.length line > 13 && String.sub line 0 13 = "RelativePath=" then begin
-			let str = String.sub line 13 (String.length line - 14) in
-			Some (unescape str)
-		end else
-			None
-	in
-	filter_all_in get_file (open_in vcp_file)
-
-let rec list_files errors file =
-	match extension file with
-	| "ML" -> [(ML,file)]
-	| "MLI" -> [(MLI,file)]
-	| "VCPROJ" ->
-		project_name := Some (Filename.basename file);
-		error_process := true;
-		chars_process := true;
-		List.concat (List.map (list_files false) (vcproj_get_files file))
-	| "DSP" ->
-		project_name := Some (Filename.basename file);
-		error_process := true;
-		chars_process := true;
-		List.concat (List.map (list_files false) (dsp_get_files file))
-	| "CMA" -> [(CMA,file)]
-	| "CMXA" -> [(CMXA,file)]
-	| "CMX" -> [(CMX,file)]	
-	| "CMO" -> [(CMO,file)]
-	| "DLL" -> [(DLL,file)]
-	| "LIB" -> [(LIB,file)]
-	| "A" -> [(A,file)]
-	| "O" -> [(O,file)]
-	| "OBJ" -> [(OBJ,file)]
-	| "SO" -> [(SO,file)]
-	| "MLY" -> [(MLY,file);(ML,file +! ML);(MLI,file +! MLI)]
-	| "MLL" -> [(MLL,file);(ML,file +! ML)]	
-	| _ -> if errors then ??? file else []
-
-let rec get_compile_mode cm = function
-	| [] -> cm
-	| (ext,name)::files ->
-		let error() = failwith "Mixed bytecode and native compilation files." in
-		match ext with
-		| ML | MLI | MLL | MLY | DLL | SO ->
-			get_compile_mode cm files
-		| CMA | CMO ->
-			if cm = CM_OPT then error() else get_compile_mode CM_BYTE files
-		| CMXA | CMX | A | O | OBJ | LIB ->
-			if cm = CM_BYTE then error() else get_compile_mode CM_OPT files
-		| EXE | CMI ->
-			assert false
-
-let rec get_output_file islib cm =
-	match !project_name,islib,cm with
-	| None, _ , _ -> None
-	| Some name,false,_ -> Some (name +! EXE)
-	| Some name,true,CM_OPT -> Some (name +! CMXA)
-	| Some name,true,_ -> Some (name +! CMA)
-
-(* ************************************************************************ *)
-(* MAIN *)
-
-;;
-try
-
-let usage =
-	"OCAMAKE v1.4 - Copyright (C)2002-2005 Nicolas Cannasse"
-	^"\r\nLast version : http://tech.motion-twin.com" in
-let compile_mode = ref CM_DEFAULT in
-let compile_cma = ref false in
-let do_clean = ref false in
-let gen_make = ref false in
-let rebuild_all = ref false in
-let output_file = ref None in
-let preprocessor = ref None in
-let argfiles = ref [] in
-let paths = ref [] in
-let cflags = ref [] in
-let lflags = ref [] in
-let remf = ref [] in
-let priority = ref [] in
-let arg_spec = [
-  ("-all", Unit (fun () -> rebuild_all := true), ": rebuild all files");
-  ("-o", String (fun f -> output_file := Some f), "<file> : set output");
-  ("-a", Unit (fun () -> compile_cma := true), ": build a library");
-  ("-opt", Unit (fun () -> compile_mode := CM_OPT), ": native compilation");
-  ("-clean", Unit (fun () -> do_clean := true), ": delete intermediate files");
-  ("-I", String (fun p -> paths := p::!paths), "<path> : additional path");
-  ("-v", Unit (fun () -> verbose := true), ": turn on verbose mode");
-  ("-n", String (fun f -> remf := f::!remf),"<file>: don't compile this file");
-  ("-mak", Unit (fun () -> gen_make := true), ": generate Makefile");
-  ("-lp", String (fun f -> lflags := f::!lflags), "<p> : linker parameter");
-  ("-cp", String (fun f -> cflags := f::!cflags), "<p> : compiler parameter");
-  ("-pp", String (fun c -> preprocessor := Some c), "<cmd> : preprocessor");
-  ("-epp", Unit (fun() -> error_process := true), ": use MSVC error messages format");
-  ("-cpp", Unit (fun() -> chars_process := true), ": convert characters range in errors to file expression");
-  ("-g", Unit (fun () -> lflags := "-g"::!lflags; cflags := "-g"::!cflags), ": compile/link in debug mode");
-  ("-P", String (fun f -> priority := f::!priority), ": give linking priority to a file when linking ordering failed");
-] in
-Arg.parse arg_spec (fun arg -> argfiles := arg :: !argfiles) usage;
-let files = List.concat (List.map (list_files true) (List.rev !argfiles)) in
-let files = List.filter (fun (_,f) ->
-	let name = Filename.basename f in
-	not(List.exists (fun f -> Filename.basename f = name) !remf)) files in
-let compile_mode = get_compile_mode !compile_mode files in
-let output_file , compile_mode = (match !output_file with
-	| None -> get_output_file !compile_cma compile_mode , compile_mode
-	| Some file ->
-		match extension file , compile_mode with
-		| "CMA" , CM_OPT
-		| "CMXA", CM_BYTE -> failwith "Mixed bytecode and native compilation files."
-		| "CMA" , _ ->
-			compile_cma := true;
-			Some file , CM_BYTE
-		| "CMXA" , _ ->
-			compile_cma := true;
-			Some file , CM_OPT
-		| _ , _ ->
-			Some file , compile_mode)
-in
-let opt = (compile_mode = CM_OPT) in
-if !compile_cma then lflags := "-a"::!lflags;
-match files with
-  | [] -> Arg.usage arg_spec usage
-  | _ ->
-	let files = remove_duplicates files in
-	let get_path (_,f) = "-I " ^ escape (Filename.dirname f) in
-	let paths = List.map (fun p -> "-I " ^ (escape p)) !paths in
-	let paths = remove_duplicates (paths@(List.map get_path files)) in
-	let p4param = if_some (fun cmd -> "-pp " ^ (escape cmd)) !preprocessor "" in
-	match !do_clean,!gen_make with
-	| true,true ->
-		failwith "Cannot have -mak & -clean at the same time"
-	| false,false ->
-		if_some delete_file output_file ();
-		List.iter (pre_compile !rebuild_all) files;
-		List.iter check_existence files;
-		let g = build_graph opt (p4param::paths) files in
-		let files = graph_topological_sort !rebuild_all g [] [] in
-		List.iter (compile opt (!cflags @ p4param::paths)) files;
-		if_some (link opt (!lflags @ paths) g (List.rev !priority)) output_file ();
-		print "Done";
-	| true,false ->
-		print "Cleaning...";
-		if_some delete_file output_file ();
-		let to_clean = List.fold_left (clean_targets opt) [] files in
-		List.iter delete_file to_clean;
-		if opt && !compile_cma then
-			if_some (fun f -> delete_file (f +! (if Sys.os_type = "Win32" then LIB else A))) output_file ();
-	| false,true ->
-		List.iter (pre_compile !rebuild_all) files;
-		let g = build_graph opt (p4param::paths) files in
-		let out = open_out "Makefile" in
-		let fprint s = output_string out (s^"\n") in
-		let genmak f =
-			let ext = if opt then CMX else CMO in
-			match f.ext with
-			| MLL ->
-				fprint ((f.name +! ext)^": "^(f.name +! ML)^"\n")
-			| MLY ->
-				fprint ((f.name +! ext)^": "^(f.name +! ML)^"\n");
-				fprint ((f.name +! CMI)^": "^(f.name +! ML)^" "^(f.name +! MLI)^"\n")
-			| _ when f.deps <> [] ->
-				fprint (f.target^": "^(flatten f.deps)^"\n")
-			| _ ->
-				()
-		in
-		let compiles = graph_topological_sort true g [] [] in
-		let libs = List.filter is_lib compiles in
-		let cmos = List.filter (fun f -> f.ext = ML) compiles in
-		fprint "# Makefile generated by OCamake ";
-		fprint "# http://tech.motion-twin.com";
-		fprint ".SUFFIXES : .ml .mli .cmo .cmi .cmx .mll .mly";
-		fprint "";
-		fprint ("ALL_CFLAGS= $(CFLAGS) "^(flatten (!cflags @ p4param::paths)));
-		fprint ("LIBS="^(flatten (List.map (fun f -> f.name) libs)));
-		let targets = flatten (List.map (fun f -> f.target) cmos) in
-		(match output_file with
-		| None ->
-			fprint "";
-			fprint ("all: "^targets^"\n");
-		| Some out ->
-			fprint ("LFLAGS= -o "^out^" "^(flatten (!lflags @ paths)));
-			fprint "";
-			fprint ("all: "^out^"\n");
-			fprint (out^": "^targets);
-			(* I need to reuse the list of targets since $^ is for Make and $** for NMake *)
-			fprint ("\t"^(if opt then "ocamlopt" else "ocamlc")^" $(LFLAGS) $(LIBS) "^targets^"\n"));
-		List.iter genmak g;
-		fprint "";
-		fprint "clean:";
-		let cleanfiles = flatten (List.fold_left (clean_targets opt) [] files) in
-		if_some (fun o ->
-				fprint ("\trm -f "^o);
-				if opt && !compile_cma then fprint ("\trm -f "^(o +! LIB)^" "^(o +! A));
-			) output_file ();
-		fprint ("\trm -f "^cleanfiles);
-		fprint "";
-		fprint "wclean:";
-		if_some (fun o ->
-				fprint ("\t-@del "^o^" 2>NUL");
-				if opt && !compile_cma then fprint ("\t-@del "^(o +! LIB)^" "^(o +! A)^" 2>NUL");
-		) output_file ();
-		fprint ("\t-@del "^cleanfiles^" 2>NUL");
-		fprint "";
-		fprint "# SUFFIXES";
-		fprint ".ml.cmo:\n\tocamlc $(ALL_CFLAGS) -c $<\n";
-		fprint ".ml.cmx:\n\tocamlopt $(ALL_CFLAGS) -c $<\n";
-		fprint ".mli.cmi:\n\tocamlc $(ALL_CFLAGS) $<\n";
-		fprint ".mll.ml:\n\tocamllex $<\n";
-		fprint ".mly.ml:\n\tocamlyacc $<\n";
-		close_out out
-with
-	Failure msg ->
-		Pervasives.flush Pervasives.stdout;
-		prerr_endline msg;
-		Pervasives.flush Pervasives.stderr;
-		exit 1;
-
-(* ************************************************************************ *)

+ 0 - 28
libs/pcre/Makefile

@@ -1,28 +0,0 @@
-ALL_CFLAGS = $(CFLAGS) -I pcre
-LIBS =
-OCAMLOPT=ocamlopt
-OCAMLC=ocamlc
-SRC = pcre.ml pcre_stubs.c
-
-all: bytecode native
-
-bytecode: pcre.cma
-
-native: pcre.cmxa
-
-pcre.cma: pcre_stubs.o pcre.ml
-	$(OCAMLC) -safe-string -a -o pcre.cma $(LIBS) pcre.ml
-
-pcre.cmxa: pcre.ml pcre_stubs.o
-	$(OCAMLOPT) -safe-string -a -o pcre.cmxa $(LIBS) pcre.ml
-
-pcre_stubs.o: pcre_stubs.c
-	$(OCAMLC) -safe-string $(ALL_CFLAGS) pcre_stubs.c
-
-clean:
-	rm -f pcre.cma pcre.cmi pcre.cmx pcre.cmxa pcre.o pcre.obj pcre_stubs.obj pcre_stubs.o
-	rm -f pcre.a libpcre.a libpcre.lib pcre.cmo
-
-.PHONY: all bytecode native clean
-Makefile: ;
-$(SRC): ;

+ 0 - 7
libs/pcre/dune

@@ -1,7 +0,0 @@
-(include_subdirs no)
-
-(library
-	(name pcre)
-	(c_names pcre_stubs)
-	(wrapped false)
-)

+ 0 - 737
libs/pcre/pcre_stubs.c

@@ -1,737 +0,0 @@
-/*
-   PCRE-OCAML - Perl Compatibility Regular Expressions for OCaml
-
-   Copyright (C) 1999-  Markus Mottl
-   email: [email protected]
-   WWW:   http://www.ocaml.info
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#if defined(_WIN32)
-#  define snprintf _snprintf
-#  if defined(_DLL)
-#    define PCREextern __declspec(dllexport)
-#  else
-#    define PCREextern
-#  endif
-#endif
-
-#if _WIN64
-  typedef long long *ovec_dst_ptr;
-#else
-  typedef long *ovec_dst_ptr;
-#endif
-
-#if __GNUC__ >= 3
-# define inline inline __attribute__ ((always_inline))
-# define __unused __attribute__ ((unused))
-#else
-# define __unused
-# define inline
-#endif
-
-#include <ctype.h>
-#include <string.h>
-#include <stdio.h>
-
-#include <caml/mlvalues.h>
-#include <caml/alloc.h>
-#include <caml/memory.h>
-#include <caml/fail.h>
-#include <caml/callback.h>
-
-#include "pcre.h"
-
-/* Error codes as defined for pcre 7.9, undefined in pcre 4.5 */
-#ifndef PCRE_ERROR_PARTIAL
-#define PCRE_ERROR_PARTIAL        (-12)
-#endif
-#ifndef PCRE_ERROR_BADPARTIAL
-#define PCRE_ERROR_BADPARTIAL     (-13)
-#endif
-#ifndef PCRE_ERROR_RECURSIONLIMIT
-#define PCRE_ERROR_RECURSIONLIMIT (-21)
-#endif
-
-typedef const unsigned char *chartables;  /* Type of chartable sets */
-
-/* Contents of callout data */
-struct cod {
-  long subj_start;        /* Start of subject string */
-  value *v_substrings_p;  /* Pointer to substrings matched so far */
-  value *v_cof_p;         /* Pointer to callout function */
-  value v_exn;            /* Possible exception raised by callout function */
-};
-
-/* Cache for exceptions */
-static value *pcre_exc_Error         = NULL;  /* Exception [Error] */
-static value *pcre_exc_Backtrack     = NULL;  /* Exception [Backtrack] */
-
-/* Cache for polymorphic variants */
-static value var_Start_only;   /* Variant [`Start_only] */
-static value var_ANCHORED;     /* Variant [`ANCHORED] */
-static value var_Char;         /* Variant [`Char char] */
-static value var_Not_studied;  /* Variant [`Not_studied] */
-static value var_Studied;      /* Variant [`Studied] */
-static value var_Optimal;      /* Variant [`Optimal] */
-
-static value None = Val_int(0);
-
-/* Converts subject offsets from C-integers to OCaml-Integers.
-
-   This is a bit tricky, because there are 32- and 64-bit platforms around
-   and OCaml chooses the larger possibility for representing integers when
-   available (also in arrays) - not so the PCRE!
-*/
-static inline void copy_ovector(
-  long subj_start, const int *ovec_src, ovec_dst_ptr ovec_dst, int subgroups2)
-{
-  if (subj_start == 0)
-    while (subgroups2--) {
-      *ovec_dst = Val_int(*ovec_src);
-      --ovec_src; --ovec_dst;
-    }
-  else
-    while (subgroups2--) {
-      *ovec_dst = Val_long(*ovec_src + subj_start);
-      --ovec_src; --ovec_dst;
-    }
-}
-
-/* Callout handler */
-static int pcre_callout_handler(pcre_callout_block* cb)
-{
-  struct cod *cod = (struct cod *) cb->callout_data;
-
-  if (cod != NULL) {
-    /* Callout is available */
-    value v_res;
-
-    /* Set up parameter array */
-    value v_callout_data = caml_alloc_small(8, 0);
-
-    const value v_substrings = *cod->v_substrings_p;
-
-    const int capture_top = cb->capture_top;
-    int subgroups2 = capture_top << 1;
-    const int subgroups2_1 = subgroups2 - 1;
-
-    const int *ovec_src = cb->offset_vector + subgroups2_1;
-    ovec_dst_ptr ovec_dst = &Field(Field(v_substrings, 1), 0) + subgroups2_1;
-    long subj_start = cod->subj_start;
-
-    copy_ovector(subj_start, ovec_src, ovec_dst, subgroups2);
-
-    Field(v_callout_data, 0) = Val_int(cb->callout_number);
-    Field(v_callout_data, 1) = v_substrings;
-    Field(v_callout_data, 2) = Val_int(cb->start_match + subj_start);
-    Field(v_callout_data, 3) = Val_int(cb->current_position + subj_start);
-    Field(v_callout_data, 4) = Val_int(capture_top);
-    Field(v_callout_data, 5) = Val_int(cb->capture_last);
-    Field(v_callout_data, 6) = Val_int(cb->pattern_position);
-    Field(v_callout_data, 7) = Val_int(cb->next_item_length);
-
-    /* Perform callout */
-    v_res = caml_callback_exn(*cod->v_cof_p, v_callout_data);
-
-    if (Is_exception_result(v_res)) {
-      /* Callout raised an exception */
-      const value v_exn = Extract_exception(v_res);
-      if (Field(v_exn, 0) == *pcre_exc_Backtrack) return 1;
-      cod->v_exn = v_exn;
-      return PCRE_ERROR_CALLOUT;
-    }
-  }
-
-  return 0;
-}
-
-/* Fetchs the named OCaml-values + caches them and
-   calculates + caches the variant hash values */
-CAMLprim value pcre_ocaml_init(value __unused v_unit)
-{
-  pcre_exc_Error     = caml_named_value("Pcre.Error");
-  pcre_exc_Backtrack = caml_named_value("Pcre.Backtrack");
-
-  var_Start_only  = caml_hash_variant("Start_only");
-  var_ANCHORED    = caml_hash_variant("ANCHORED");
-  var_Char        = caml_hash_variant("Char");
-  var_Not_studied = caml_hash_variant("Not_studied");
-  var_Studied     = caml_hash_variant("Studied");
-  var_Optimal     = caml_hash_variant("Optimal");
-
-  pcre_callout = &pcre_callout_handler;
-
-  return Val_unit;
-}
-
-/* Finalizing deallocation function for chartable sets */
-static void pcre_dealloc_tables(value v_table)
-{ (pcre_free)((void *) Field(v_table, 1)); }
-
-/* Finalizing deallocation function for compiled regular expressions */
-static void pcre_dealloc_regexp(value v_rex)
-{
-  void *extra = (void *) Field(v_rex, 2);
-  (pcre_free)((void *) Field(v_rex, 1));
-  if (extra != NULL)
-#ifdef PCRE_STUDY_JIT_COMPILE
-    pcre_free_study(extra);
-#else
-    pcre_free(extra);
-#endif
-}
-
-/* Makes OCaml-string from PCRE-version */
-CAMLprim value pcre_version_stub(value __unused v_unit)
-{
-  return caml_copy_string((char *) pcre_version());
-}
-
-
-/* Raising exceptions */
-
-static inline void raise_pcre_error(value v_arg) Noreturn;
-static inline void raise_partial() Noreturn;
-static inline void raise_bad_partial() Noreturn;
-static inline void raise_bad_utf8() Noreturn;
-static inline void raise_bad_utf8_offset() Noreturn;
-static inline void raise_match_limit() Noreturn;
-static inline void raise_recursion_limit() Noreturn;
-static inline void raise_bad_pattern(const char *msg, int pos) Noreturn;
-static inline void raise_internal_error(char *msg) Noreturn;
-
-static inline void raise_pcre_error(value v_arg)
-{ caml_raise_with_arg(*pcre_exc_Error, v_arg); }
-
-static inline void raise_partial() { raise_pcre_error(Val_int(0)); }
-static inline void raise_bad_partial() { raise_pcre_error(Val_int(1)); }
-static inline void raise_bad_utf8() { raise_pcre_error(Val_int(2)); }
-static inline void raise_bad_utf8_offset() { raise_pcre_error(Val_int(3)); }
-static inline void raise_match_limit() { raise_pcre_error(Val_int(4)); }
-static inline void raise_recursion_limit() { raise_pcre_error(Val_int(5)); }
-
-static inline void raise_bad_pattern(const char *msg, int pos)
-{
-  CAMLparam0();
-  CAMLlocal1(v_msg);
-  value v_arg;
-  v_msg = caml_copy_string(msg);
-  v_arg = caml_alloc_small(2, 0);
-  Field(v_arg, 0) = v_msg;
-  Field(v_arg, 1) = Val_int(pos);
-  raise_pcre_error(v_arg);
-  CAMLnoreturn;
-}
-
-static inline void raise_internal_error(char *msg)
-{
-  CAMLparam0();
-  CAMLlocal1(v_msg);
-  value v_arg;
-  v_msg = caml_copy_string(msg);
-  v_arg = caml_alloc_small(1, 1);
-  Field(v_arg, 0) = v_msg;
-  raise_pcre_error(v_arg);
-  CAMLnoreturn;
-}
-
-/* PCRE pattern compilation */
-
-/* Makes compiled regular expression from compilation options, an optional
-   value of chartables and the pattern string */
-CAMLprim value pcre_compile_stub(value v_opt, value v_tables, value v_pat)
-{
-  value v_rex;  /* Final result -> value of type [regexp] */
-  const char *error = NULL;  /* pointer to possible error message */
-  int error_ofs = 0;  /* offset in the pattern at which error occurred */
-
-  /* If v_tables = [None], then pointer to tables is NULL, otherwise
-     set it to the appropriate value */
-  chartables tables =
-    (v_tables == None) ? NULL : (chartables) Field(Field(v_tables, 0), 1);
-
-  /* Compiles the pattern */
-  pcre *regexp = pcre_compile(String_val(v_pat), Int_val(v_opt), &error,
-                              &error_ofs, tables);
-
-  /* Raises appropriate exception with [BadPattern] if the pattern
-     could not be compiled */
-  if (regexp == NULL) raise_bad_pattern(error, error_ofs);
-
-  /* GC will do a full cycle every 1_000_000 regexp allocations (a typical
-     regexp probably consumes less than 100 bytes -> maximum of 100_000_000
-     bytes unreclaimed regexps) */
-  v_rex = caml_alloc_final(4, pcre_dealloc_regexp, 1, 1000000);
-
-  /* Field[1]: compiled regular expression (Field[0] is finalizing
-     function! See above!) */
-  Field(v_rex, 1) = (value) regexp;
-
-  /* Field[2]: extra information about regexp when it has been studied
-     successfully */
-  Field(v_rex, 2) = (value) NULL;
-
-  /* Field[3]: If 0 -> regexp has not yet been studied
-                  1 -> regexp has already been studied */
-  Field(v_rex, 3) = 0;
-
-  return v_rex;
-}
-
-/* Studies a regexp */
-CAMLprim value pcre_study_stub(value v_rex)
-{
-  /* If it has not yet been studied */
-  if (! (int) Field(v_rex, 3)) {
-    const char *error = NULL;
-    pcre_extra *extra = pcre_study((pcre *) Field(v_rex, 1), 0, &error);
-    if (error != NULL) caml_invalid_argument((char *) error);
-    Field(v_rex, 2) = (value) extra;
-    Field(v_rex, 3) = Val_int(1);
-  }
-  return v_rex;
-}
-
-/* Sets a match limit recursion for a regular expression imperatively */
-CAMLprim value pcre_set_imp_match_limit_recursion_stub(value v_rex, value v_lim)
-{
-  pcre_extra *extra = (pcre_extra *) Field(v_rex, 2);
-  if (extra == NULL) {
-    extra = pcre_malloc(sizeof(pcre_extra));
-    extra->flags = PCRE_EXTRA_MATCH_LIMIT_RECURSION;
-    Field(v_rex, 2) = (value) extra;
-  } else {
-    unsigned long *flags_ptr = &extra->flags;
-    *flags_ptr = PCRE_EXTRA_MATCH_LIMIT_RECURSION | *flags_ptr;
-  }
-  extra->match_limit_recursion = Int_val(v_lim);
-  return v_rex;
-}
-
-/* Gets the match limit recursion of a regular expression if it exists */
-CAMLprim value pcre_get_match_limit_recursion_stub(value v_rex)
-{
-  pcre_extra *extra = (pcre_extra *) Field(v_rex, 2);
-  if (extra == NULL) return None;
-  if (extra->flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) {
-    value v_lim = Val_int(extra->match_limit_recursion);
-    value v_res = caml_alloc_small(1, 0);
-    Field(v_res, 0) = v_lim;
-    return v_res;
-  }
-  return None;
-}
-
-/* Sets a match limit for a regular expression imperatively */
-CAMLprim value pcre_set_imp_match_limit_stub(value v_rex, value v_lim)
-{
-  pcre_extra *extra = (pcre_extra *) Field(v_rex, 2);
-  if (extra == NULL) {
-    extra = pcre_malloc(sizeof(pcre_extra));
-    extra->flags = PCRE_EXTRA_MATCH_LIMIT;
-    Field(v_rex, 2) = (value) extra;
-  } else {
-    unsigned long *flags_ptr = &extra->flags;
-    *flags_ptr = PCRE_EXTRA_MATCH_LIMIT | *flags_ptr;
-  }
-  extra->match_limit = Int_val(v_lim);
-  return v_rex;
-}
-
-/* Gets the match limit of a regular expression if it exists */
-CAMLprim value pcre_get_match_limit_stub(value v_rex)
-{
-  pcre_extra *extra = (pcre_extra *) Field(v_rex, 2);
-  if (extra == NULL) return None;
-  if (extra->flags & PCRE_EXTRA_MATCH_LIMIT) {
-    value v_lim = Val_int(extra->match_limit);
-    value v_res = caml_alloc_small(1, 0);
-    Field(v_res, 0) = v_lim;
-    return v_res;
-  }
-  return None;
-}
-
-/* Performs the call to the pcre_fullinfo function */
-static inline int pcre_fullinfo_stub(value v_rex, int what, void *where)
-{
-  return pcre_fullinfo((pcre *) Field(v_rex, 1), (pcre_extra *) Field(v_rex, 2),
-                       what, where);
-}
-
-/* Some stubs for info-functions */
-
-/* Generic macro for getting integer results from pcre_fullinfo */
-#define make_info(tp, cnv, name, option) \
-  CAMLprim value pcre_##name##_stub(value v_rex) \
-  { \
-    tp options; \
-    const int ret = pcre_fullinfo_stub(v_rex, PCRE_INFO_##option, &options); \
-    if (ret != 0) raise_internal_error("pcre_##name##_stub"); \
-    return cnv(options); \
-  }
-
-make_info(unsigned long, Val_long, options, OPTIONS)
-make_info(size_t, Val_long, size, SIZE)
-make_info(size_t, Val_long, studysize, STUDYSIZE)
-make_info(int, Val_int, capturecount, CAPTURECOUNT)
-make_info(int, Val_int, backrefmax, BACKREFMAX)
-make_info(int, Val_int, namecount, NAMECOUNT)
-make_info(int, Val_int, nameentrysize, NAMEENTRYSIZE)
-
-CAMLprim value pcre_firstbyte_stub(value v_rex)
-{
-  int firstbyte;
-  const int ret = pcre_fullinfo_stub(v_rex, PCRE_INFO_FIRSTBYTE, &firstbyte);
-
-  if (ret != 0) raise_internal_error("pcre_firstbyte_stub");
-
-  switch (firstbyte) {
-    case -1 : return var_Start_only; break;  /* [`Start_only] */
-    case -2 : return var_ANCHORED; break;    /* [`ANCHORED] */
-    default :
-      if (firstbyte < 0 )  /* Should not happen */
-        raise_internal_error("pcre_firstbyte_stub");
-      else {
-        value v_firstbyte;
-        /* Allocates the non-constant constructor [`Char of char] and fills
-           in the appropriate value */
-        v_firstbyte = caml_alloc_small(2, 0);
-        Field(v_firstbyte, 0) = var_Char;
-        Field(v_firstbyte, 1) = Val_int(firstbyte);
-        return v_firstbyte;
-      }
-  }
-}
-
-CAMLprim value pcre_firsttable_stub(value v_rex)
-{
-  const unsigned char *ftable;
-
-  int ret =
-    pcre_fullinfo_stub(v_rex, PCRE_INFO_FIRSTTABLE, (void *) &ftable);
-
-  if (ret != 0) raise_internal_error("pcre_firsttable_stub");
-
-  if (ftable == NULL) return None;
-  else {
-    value v_res, v_res_str;
-    char *ptr;
-    int i;
-
-    Begin_roots1(v_rex);
-      v_res_str = caml_alloc_string(32);
-    End_roots();
-
-    ptr = String_val(v_res_str);
-    for (i = 0; i <= 31; ++i) { *ptr = *ftable; ++ptr; ++ftable; }
-
-    Begin_roots1(v_res_str);
-      /* Allocates [Some string] from firsttable */
-      v_res = caml_alloc_small(1, 0);
-    End_roots();
-
-    Field(v_res, 0) = v_res_str;
-
-    return v_res;
-  }
-}
-
-CAMLprim value pcre_lastliteral_stub(value v_rex)
-{
-  int lastliteral;
-  const int ret = pcre_fullinfo_stub(v_rex, PCRE_INFO_LASTLITERAL,
-                                        &lastliteral);
-
-  if (ret != 0) raise_internal_error("pcre_lastliteral_stub");
-
-  if (lastliteral == -1) return None;
-  if (lastliteral < 0) raise_internal_error("pcre_lastliteral_stub");
-  else {
-    /* Allocates [Some char] */
-    value v_res = caml_alloc_small(1, 0);
-    Field(v_res, 0) = Val_int(lastliteral);
-    return v_res;
-  }
-}
-
-CAMLprim value pcre_study_stat_stub(value v_rex)
-{
-  /* Generates the appropriate constant constructor [`Optimal] or
-     [`Studied] if regexp has already been studied */
-  if (Field(v_rex, 3))
-    return ((pcre_extra *) Field(v_rex, 2) == NULL) ? var_Optimal : var_Studied;
-
-  return var_Not_studied;  /* otherwise [`Not_studied] */
-}
-
-static inline void handle_exec_error(char *loc, const int ret) Noreturn;
-
-static inline void handle_exec_error(char *loc, const int ret)
-{
-  switch (ret) {
-    /* Dedicated exceptions */
-    case PCRE_ERROR_NOMATCH : caml_raise_not_found();
-    case PCRE_ERROR_PARTIAL : raise_partial();
-    case PCRE_ERROR_MATCHLIMIT : raise_match_limit();
-    case PCRE_ERROR_BADPARTIAL : raise_bad_partial();
-    case PCRE_ERROR_BADUTF8 : raise_bad_utf8();
-    case PCRE_ERROR_BADUTF8_OFFSET : raise_bad_utf8_offset();
-    case PCRE_ERROR_RECURSIONLIMIT : raise_recursion_limit();
-    /* Unknown error */
-    default : {
-      char err_buf[100];
-      snprintf(err_buf, 100, "%s: unhandled PCRE error code: %d", loc, ret);
-      raise_internal_error(err_buf);
-    }
-  }
-}
-
-static inline void handle_pcre_exec_result(
-  int *ovec, value v_ovec, long ovec_len, long subj_start, int ret)
-{
-  ovec_dst_ptr ocaml_ovec = (ovec_dst_ptr) &Field(v_ovec, 0);
-  const int subgroups2 = ret * 2;
-  const int subgroups2_1 = subgroups2 - 1;
-  const int *ovec_src = ovec + subgroups2_1;
-  ovec_dst_ptr ovec_clear_stop = ocaml_ovec + (ovec_len * 2) / 3;
-  ovec_dst_ptr ovec_dst = ocaml_ovec + subgroups2_1;
-  copy_ovector(subj_start, ovec_src, ovec_dst, subgroups2);
-  while (++ovec_dst < ovec_clear_stop) *ovec_dst = -1;
-}
-
-/* Executes a pattern match with runtime options, a regular expression, a
-   matching position, the start of the the subject string, a subject string,
-   a number of subgroup offsets, an offset vector and an optional callout
-   function */
-CAMLprim value pcre_exec_stub(value v_opt, value v_rex, value v_pos,
-                              value v_subj_start, value v_subj,
-                              value v_ovec, value v_maybe_cof)
-{
-  int ret;
-  long
-    pos = Long_val(v_pos),
-    len = caml_string_length(v_subj),
-    subj_start = Long_val(v_subj_start);
-  long ovec_len = Wosize_val(v_ovec);
-
-  if (pos > len || pos < subj_start)
-    caml_invalid_argument("Pcre.pcre_exec_stub: illegal position");
-
-  if (subj_start > len || subj_start < 0)
-    caml_invalid_argument("Pcre.pcre_exec_stub: illegal subject start");
-
-  pos -= subj_start;
-  len -= subj_start;
-
-  {
-    const pcre *code = (pcre *) Field(v_rex, 1);  /* Compiled pattern */
-    const pcre_extra *extra = (pcre_extra *) Field(v_rex, 2);  /* Extra info */
-    const char *ocaml_subj =
-      String_val(v_subj) + subj_start;  /* Subject string */
-    const int opt = Int_val(v_opt);  /* Runtime options */
-
-    /* Special case when no callout functions specified */
-    if (v_maybe_cof == None) {
-      int *ovec = (int *) &Field(v_ovec, 0);
-
-      /* Performs the match */
-      ret = pcre_exec(code, extra, ocaml_subj, len, pos, opt, ovec, ovec_len);
-
-      if (ret < 0) handle_exec_error("pcre_exec_stub", ret);
-      else handle_pcre_exec_result(ovec, v_ovec, ovec_len, subj_start, ret);
-    }
-
-    /* There are callout functions */
-    else {
-      value v_cof = Field(v_maybe_cof, 0);
-      value v_substrings;
-      char *subj = caml_stat_alloc(sizeof(char) * len);
-      int *ovec = caml_stat_alloc(sizeof(int) * ovec_len);
-      struct cod cod = { 0, (value *) NULL, (value *) NULL, (value) NULL };
-      struct pcre_extra new_extra =
-#ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
-# ifdef PCRE_EXTRA_MARK
-#  ifdef PCRE_EXTRA_EXECUTABLE_JIT
-        { PCRE_EXTRA_CALLOUT_DATA, NULL, 0, NULL, NULL, 0, NULL, NULL };
-#  else
-        { PCRE_EXTRA_CALLOUT_DATA, NULL, 0, NULL, NULL, 0, NULL };
-#  endif
-# else
-        { PCRE_EXTRA_CALLOUT_DATA, NULL, 0, NULL, NULL, 0 };
-# endif
-#else
-        { PCRE_EXTRA_CALLOUT_DATA, NULL, 0, NULL, NULL };
-#endif
-
-      cod.subj_start = subj_start;
-      memcpy(subj, ocaml_subj, len);
-
-      Begin_roots4(v_rex, v_cof, v_substrings, v_ovec);
-        Begin_roots1(v_subj);
-          v_substrings = caml_alloc_small(2, 0);
-        End_roots();
-
-        Field(v_substrings, 0) = v_subj;
-        Field(v_substrings, 1) = v_ovec;
-
-        cod.v_substrings_p = &v_substrings;
-        cod.v_cof_p = &v_cof;
-        new_extra.callout_data = &cod;
-
-        if (extra == NULL) {
-          ret = pcre_exec(code, &new_extra, subj, len, pos, opt, ovec,
-                          ovec_len);
-        }
-        else {
-          new_extra.flags = PCRE_EXTRA_CALLOUT_DATA | extra->flags;
-          new_extra.study_data = extra->study_data;
-          new_extra.match_limit = extra->match_limit;
-          new_extra.tables = extra->tables;
-#ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
-          new_extra.match_limit_recursion = extra->match_limit_recursion;
-#endif
-
-          ret = pcre_exec(code, &new_extra, subj, len, pos, opt, ovec,
-                          ovec_len);
-        }
-
-        caml_stat_free(subj);
-      End_roots();
-
-      if (ret < 0) {
-        caml_stat_free(ovec);
-        if (ret == PCRE_ERROR_CALLOUT) caml_raise(cod.v_exn);
-        else handle_exec_error("pcre_exec_stub(callout)", ret);
-      } else {
-        handle_pcre_exec_result(ovec, v_ovec, ovec_len, subj_start, ret);
-        caml_stat_free(ovec);
-      }
-    }
-  }
-
-  return Val_unit;
-}
-
-/* Byte-code hook for pcre_exec_stub
-   Needed, because there are more than 5 arguments */
-CAMLprim value pcre_exec_stub_bc(value *argv, int __unused argn)
-{
-  return pcre_exec_stub(argv[0], argv[1], argv[2], argv[3],
-                        argv[4], argv[5], argv[6]);
-}
-
-/* Generates a new set of chartables for the current locale (see man
-   page of PCRE */
-CAMLprim value pcre_maketables_stub(value __unused v_unit)
-{
-  /* GC will do a full cycle every 1_000_000 table set allocations (one
-     table set consumes 864 bytes -> maximum of 864_000_000 bytes unreclaimed
-     table sets) */
-  const value v_res = caml_alloc_final(2, pcre_dealloc_tables, 1, 1000000);
-  Field(v_res, 1) = (value) pcre_maketables();
-  return v_res;
-}
-
-/* Wraps around the isspace-function */
-CAMLprim value pcre_isspace_stub(value v_c)
-{
-  return Val_bool(isspace(Int_val(v_c)));
-}
-
-/* Returns number of substring associated with a name */
-CAMLprim value pcre_get_stringnumber_stub(value v_rex, value v_name)
-{
-  const int ret = pcre_get_stringnumber((pcre *) Field(v_rex, 1),
-                                        String_val(v_name));
-  if (ret == PCRE_ERROR_NOSUBSTRING)
-    caml_invalid_argument("Named string not found");
-
-  return Val_int(ret);
-}
-
-/* Returns array of names of named substrings in a regexp */
-CAMLprim value pcre_names_stub(value v_rex)
-{
-  CAMLparam0();
-  CAMLlocal1(v_res);
-  int name_count;
-  int entry_size;
-  const char *tbl_ptr;
-  int i;
-
-  int ret = pcre_fullinfo_stub(v_rex, PCRE_INFO_NAMECOUNT, &name_count);
-  if (ret != 0) raise_internal_error("pcre_names_stub: namecount");
-
-  ret = pcre_fullinfo_stub(v_rex, PCRE_INFO_NAMEENTRYSIZE, &entry_size);
-  if (ret != 0) raise_internal_error("pcre_names_stub: nameentrysize");
-
-  ret = pcre_fullinfo_stub(v_rex, PCRE_INFO_NAMETABLE, &tbl_ptr);
-  if (ret != 0) raise_internal_error("pcre_names_stub: nametable");
-
-  v_res = caml_alloc(name_count, 0);
-
-  for (i = 0; i < name_count; ++i) {
-    value v_name = caml_copy_string(tbl_ptr + 2);
-    Store_field(v_res, i, v_name);
-    tbl_ptr += entry_size;
-  }
-
-  CAMLreturn(v_res);
-}
-
-/* Generic stub for getting integer results from pcre_config */
-static inline int pcre_config_int(int what)
-{
-  int ret;
-  pcre_config(what, (void *) &ret);
-  return ret;
-}
-
-/* Generic stub for getting long integer results from pcre_config */
-static inline int pcre_config_long(int what)
-{
-  long ret;
-  pcre_config(what, (void *) &ret);
-  return ret;
-}
-
-/* Some stubs for config-functions */
-
-/* Returns boolean indicating UTF8-support */
-CAMLprim value pcre_config_utf8_stub(value __unused v_unit)
-{ return Val_bool(pcre_config_int(PCRE_CONFIG_UTF8)); }
-
-/* Returns character used as newline */
-CAMLprim value pcre_config_newline_stub(value __unused v_unit)
-{ return Val_int(pcre_config_int(PCRE_CONFIG_NEWLINE)); }
-
-/* Returns number of bytes used for internal linkage of regular expressions */
-CAMLprim value pcre_config_link_size_stub(value __unused v_unit)
-{ return Val_int(pcre_config_int(PCRE_CONFIG_LINK_SIZE)); }
-
-/* Returns boolean indicating use of stack recursion */
-CAMLprim value pcre_config_stackrecurse_stub(value __unused v_unit)
-{ return Val_bool(pcre_config_int(PCRE_CONFIG_STACKRECURSE)); }
-
-/* Returns default limit for calls to internal matching function */
-CAMLprim value pcre_config_match_limit_stub(value __unused v_unit)
-{ return Val_long(pcre_config_long(PCRE_CONFIG_MATCH_LIMIT)); }
-
-/* Returns default limit for calls to internal matching function */
-CAMLprim value pcre_config_match_limit_recursion_stub(value __unused v_unit)
-{ return Val_long(pcre_config_long(PCRE_CONFIG_MATCH_LIMIT_RECURSION)); }

+ 28 - 0
libs/pcre2/Makefile

@@ -0,0 +1,28 @@
+ALL_CFLAGS = $(CFLAGS) -I pcre2
+LIBS =
+OCAMLOPT=ocamlopt
+OCAMLC=ocamlc
+SRC = pcre2.ml pcre2_stubs.c
+
+all: bytecode native
+
+bytecode: pcre2.cma
+
+native: pcre2.cmxa
+
+pcre2.cma: pcre2_stubs.o pcre2.ml
+	$(OCAMLC) -safe-string -a -o pcre2.cma $(LIBS) pcre2.ml
+
+pcre2.cmxa: pcre2.ml pcre2_stubs.o
+	$(OCAMLOPT) -safe-string -a -o pcre2.cmxa $(LIBS) pcre2.ml
+
+pcre2_stubs.o: pcre2_stubs.c
+	$(OCAMLC) -safe-string $(ALL_CFLAGS) pcre2_stubs.c
+
+clean:
+	rm -f pcre2.cma pcre2.cmi pcre2.cmx pcre2.cmxa pcre2.o pcre2.obj pcre2_stubs.obj pcre2_stubs.o
+	rm -f pcre2.a libpcre2-8.a libpcre2-8.lib pcre2.cmo
+
+.PHONY: all bytecode native clean
+Makefile: ;
+$(SRC): ;

+ 9 - 0
libs/pcre2/dune

@@ -0,0 +1,9 @@
+(include_subdirs no)
+
+(library
+	(name pcre2)
+	(foreign_stubs
+		(language c)
+		(names pcre2_stubs))
+	(wrapped false)
+)

+ 309 - 194
libs/pcre/pcre.ml → libs/pcre2/pcre2.ml

@@ -1,16 +1,20 @@
 (*
-   PCRE-OCAML - Perl Compatibility Regular Expressions for OCaml
+   PCRE2-OCAML - Perl Compatibility Regular Expressions for OCaml
+
    Copyright (C) 1999-  Markus Mottl
    email: [email protected]
    WWW:   http://www.ocaml.info
+
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.
+
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.
+
    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
@@ -18,17 +22,14 @@
 
 (* Public exceptions and their registration with the C runtime *)
 
-let string_copy str = str
-let buffer_add_subbytes = Buffer.add_subbytes
-
 type error =
   | Partial
-  | BadPartial
   | BadPattern of string * int
-  | BadUTF8
-  | BadUTF8Offset
+  | BadUTF
+  | BadUTFOffset
   | MatchLimit
-  | RecursionLimit
+  | DepthLimit
+  | WorkspaceSize
   | InternalError of string
 
 exception Error of error
@@ -36,87 +37,141 @@ exception Backtrack
 exception Regexp_or of string * error
 
 (* Puts exceptions into global C-variables for fast retrieval *)
-external pcre_ocaml_init : unit -> unit = "pcre_ocaml_init"
+external pcre2_ocaml_init : unit -> unit = "pcre2_ocaml_init"
 
 (* Registers exceptions with the C runtime and caches polymorphic variants *)
 let () =
-  Callback.register_exception "Pcre.Error" (Error (InternalError ""));
-  Callback.register_exception "Pcre.Backtrack" Backtrack;
-  pcre_ocaml_init ()
+  Callback.register_exception "Pcre2.Error" (Error (InternalError ""));
+  Callback.register_exception "Pcre2.Backtrack" Backtrack;
+  pcre2_ocaml_init ()
 
 
 (* Compilation and runtime flags and their conversion functions *)
 
-type icflag = int
-type irflag = int
+type icflag = int64
+type irflag = int64
 
 (* Compilation flags *)
 
 type cflag =
   [
+  | `ALLOW_EMPTY_CLASS
+  | `ALT_BSUX
+  | `ALT_CIRCUMFLEX
+  | `ALT_VERBNAMES
+  | `ANCHORED
+  | `AUTO_CALLOUT
   | `CASELESS
-  | `MULTILINE
+  | `DOLLAR_ENDONLY
   | `DOTALL
+  | `DUPNAMES
+  | `ENDANCHORED
   | `EXTENDED
-  | `ANCHORED
-  | `DOLLAR_ENDONLY
-  | `EXTRA
-  | `UNGREEDY
-  | `UTF8
-  | `NO_UTF8_CHECK
-  | `NO_AUTO_CAPTURE
-  | `AUTO_CALLOUT
+  | `EXTENDED_MORE
   | `FIRSTLINE
+  | `LITERAL
+  | `MATCH_INVALID_UTF
+  | `MATCH_UNSET_BACKREF
+  | `MULTILINE
+  | `NEVER_BACKSLASH_C
+  | `NEVER_UCP
+  | `NEVER_UTF
+  | `NO_AUTO_CAPTURE
+  | `NO_AUTO_POSSESS
+  | `NO_DOTSTAR_ANCHOR
+  | `NO_START_OPTIMIZE
+  | `NO_UTF_CHECK
   | `UCP
+  | `UNGREEDY
+  | `USE_OFFSET_LIMIT
+  | `UTF
   ]
 
 let int_of_cflag = function
-  | `CASELESS -> 0x0001
-  | `MULTILINE -> 0x0002
-  | `DOTALL -> 0x0004
-  | `EXTENDED -> 0x0008
-  | `ANCHORED -> 0x0010
-  | `DOLLAR_ENDONLY -> 0x0020
-  | `EXTRA -> 0x0040
-  | `UNGREEDY -> 0x0200
-  | `UTF8 -> 0x0800
-  | `NO_AUTO_CAPTURE -> 0x1000
-  | `NO_UTF8_CHECK -> 0x2000
-  | `AUTO_CALLOUT -> 0x4000
-  | `FIRSTLINE -> 0x40000
-  | `UCP -> 0x20000000
-
-let coll_icflag icflag flag = int_of_cflag flag lor icflag
-let cflags flags = List.fold_left coll_icflag 0 flags
+  | `ALLOW_EMPTY_CLASS -> 0x00000001L
+  | `ALT_BSUX -> 0x00000002L
+  | `AUTO_CALLOUT -> 0x00000004L
+  | `CASELESS -> 0x00000008L
+  | `DOLLAR_ENDONLY -> 0x00000010L
+  | `DOTALL -> 0x00000020L
+  | `DUPNAMES -> 0x00000040L
+  | `EXTENDED -> 0x00000080L
+  | `FIRSTLINE -> 0x00000100L
+  | `MATCH_UNSET_BACKREF -> 0x00000200L
+  | `MULTILINE -> 0x00000400L
+  | `NEVER_UCP -> 0x00000800L
+  | `NEVER_UTF -> 0x00001000L
+  | `NO_AUTO_CAPTURE -> 0x00002000L
+  | `NO_AUTO_POSSESS -> 0x00004000L
+  | `NO_DOTSTAR_ANCHOR -> 0x00008000L
+  | `NO_START_OPTIMIZE -> 0x00010000L
+  | `UCP -> 0x00020000L
+  | `UNGREEDY -> 0x00040000L
+  | `UTF -> 0x00080000L
+  | `NEVER_BACKSLASH_C -> 0x00100000L
+  | `ALT_CIRCUMFLEX -> 0x00200000L
+  | `ALT_VERBNAMES -> 0x00400000L
+  | `USE_OFFSET_LIMIT -> 0x00800000L
+  | `EXTENDED_MORE -> 0x01000000L
+  | `LITERAL -> 0x02000000L
+  | `MATCH_INVALID_UTF -> 0x04000000L
+  | `ENDANCHORED -> 0x20000000L
+  | `NO_UTF_CHECK -> 0x40000000L
+  | `ANCHORED -> 0x80000000L
+
+
+let coll_icflag icflag flag = Int64.logor (int_of_cflag flag) icflag
+let cflags flags = List.fold_left coll_icflag 0L flags
 
 let cflag_of_int = function
-  | 0x0001 -> `CASELESS
-  | 0x0002 -> `MULTILINE
-  | 0x0004 -> `DOTALL
-  | 0x0008 -> `EXTENDED
-  | 0x0010 -> `ANCHORED
-  | 0x0020 -> `DOLLAR_ENDONLY
-  | 0x0040 -> `EXTRA
-  | 0x0200 -> `UNGREEDY
-  | 0x0800 -> `UTF8
-  | 0x1000 -> `NO_AUTO_CAPTURE
-  | 0x2000 -> `NO_UTF8_CHECK
-  | 0x4000 -> `AUTO_CALLOUT
-  | 0x40000 -> `FIRSTLINE
-  | 0x20000000 -> `UCP
-  | _ -> failwith "Pcre.cflag_list: unknown compilation flag"
+  | 0x00000001L -> `ALLOW_EMPTY_CLASS
+  | 0x00000002L -> `ALT_BSUX
+  | 0x00000004L -> `AUTO_CALLOUT
+  | 0x00000008L -> `CASELESS
+  | 0x00000010L -> `DOLLAR_ENDONLY
+  | 0x00000020L -> `DOTALL
+  | 0x00000040L -> `DUPNAMES
+  | 0x00000080L -> `EXTENDED
+  | 0x00000100L -> `FIRSTLINE
+  | 0x00000200L -> `MATCH_UNSET_BACKREF
+  | 0x00000400L -> `MULTILINE
+  | 0x00000800L -> `NEVER_UCP
+  | 0x00001000L -> `NEVER_UTF
+  | 0x00002000L -> `NO_AUTO_CAPTURE
+  | 0x00004000L -> `NO_AUTO_POSSESS
+  | 0x00008000L -> `NO_DOTSTAR_ANCHOR
+  | 0x00010000L -> `NO_START_OPTIMIZE
+  | 0x00020000L -> `UCP
+  | 0x00040000L -> `UNGREEDY
+  | 0x00080000L -> `UTF
+  | 0x00100000L -> `NEVER_BACKSLASH_C
+  | 0x00200000L -> `ALT_CIRCUMFLEX
+  | 0x00400000L -> `ALT_VERBNAMES
+  | 0x00800000L -> `USE_OFFSET_LIMIT
+  | 0x01000000L -> `EXTENDED_MORE
+  | 0x02000000L -> `LITERAL
+  | 0x04000000L -> `MATCH_INVALID_UTF
+  | 0x20000000L -> `ENDANCHORED
+  | 0x40000000L -> `NO_UTF_CHECK
+  | 0x80000000L -> `ANCHORED
+  | _ -> failwith "Pcre2.cflag_list: unknown compilation flag"
 
 let all_cflags =
   [
-    0x0001; 0x0002; 0x0004; 0x0008; 0x0010; 0x0020;
-    0x0040; 0x0200; 0x0800; 0x1000; 0x2000; 0x4000; 0x40000;
-	0x20000000
+    0x00000001L; 0x00000002L; 0x00000004L; 0x00000008L;
+    0x00000010L; 0x00000020L; 0x00000040L; 0x00000080L;
+    0x00000100L; 0x00000200L; 0x00000400L; 0x00000800L;
+    0x00001000L; 0x00002000L; 0x00004000L; 0x00008000L;
+    0x00010000L; 0x00020000L; 0x00040000L; 0x00080000L;
+    0x00100000L; 0x00200000L; 0x00400000L; 0x00800000L;
+    0x01000000L; 0x02000000L; 0x04000000L;
+    0x20000000L; 0x40000000L; 0x80000000L;
   ]
 
 let cflag_list icflags =
   let coll flag_list flag =
-    if icflags land flag <> 0 then cflag_of_int flag :: flag_list
-    else flag_list in
+    if Int64.equal (Int64.logand icflags flag) 0L then flag_list
+    else cflag_of_int flag :: flag_list in
   List.fold_left coll [] all_cflags
 
 
@@ -125,144 +180,180 @@ let cflag_list icflags =
 type rflag =
   [
   | `ANCHORED
+  | `COPY_MATCHED_SUBJECT
+  | `DFA_RESTART
+  | `DFA_SHORTEST
+  | `ENDANCHORED
   | `NOTBOL
   | `NOTEOL
   | `NOTEMPTY
-  | `PARTIAL
+  | `NOTEMPTY_ATSTART
+  | `NO_JIT
+  | `NO_UTF_CHECK
+  | `PARTIAL_HARD
+  | `PARTIAL_SOFT
   ]
 
 let int_of_rflag = function
-  | `ANCHORED -> 0x0010
-  | `NOTBOL -> 0x0080
-  | `NOTEOL -> 0x0100
-  | `NOTEMPTY -> 0x0400
-  | `PARTIAL -> 0x8000
-
-let coll_irflag irflag flag = int_of_rflag flag lor irflag
-let rflags flags = List.fold_left coll_irflag 0 flags
+  | `NOTBOL -> 0x00000001L
+  | `NOTEOL -> 0x00000002L
+  | `NOTEMPTY ->  0x00000004L
+  | `NOTEMPTY_ATSTART -> 0x00000008L
+  | `PARTIAL_SOFT -> 0x00000010L
+  | `PARTIAL_HARD -> 0x00000020L
+  | `DFA_RESTART -> 0x00000040L
+  | `DFA_SHORTEST -> 0x00000080L
+  | `NO_JIT -> 0x00002000L
+  | `COPY_MATCHED_SUBJECT -> 0x00004000L
+  | `ENDANCHORED -> 0x20000000L
+  | `NO_UTF_CHECK -> 0x40000000L
+  | `ANCHORED -> 0x80000000L
+
+let coll_irflag irflag flag = Int64.logor (int_of_rflag flag) irflag
+let rflags flags = List.fold_left coll_irflag 0L flags
 
 let rflag_of_int = function
-  | 0x0010 -> `ANCHORED
-  | 0x0080 -> `NOTBOL
-  | 0x0100 -> `NOTEOL
-  | 0x0400 -> `NOTEMPTY
-  | 0x8000 -> `PARTIAL
-  | _ -> failwith "Pcre.rflag_list: unknown runtime flag"
-
-let all_rflags = [0x0010; 0x0080; 0x0100; 0x0400; 0x8000]
+  | 0x00000001L -> `NOTBOL
+  | 0x00000002L -> `NOTEOL
+  | 0x00000004L -> `NOTEMPTY
+  | 0x00000008L -> `NOTEMPTY_ATSTART
+  | 0x00000010L -> `PARTIAL_SOFT
+  | 0x00000020L -> `PARTIAL_HARD
+  | 0x00000040L -> `DFA_RESTART
+  | 0x00000080L -> `DFA_SHORTEST
+  | 0x00002000L -> `NO_JIT
+  | 0x00004000L -> `COPY_MATCHED_SUBJECT
+  | 0x20000000L -> `ENDANCHORED
+  | 0x40000000L -> `NO_UTF_CHECK
+  | 0x80000000L -> `ANCHORED
+  | _ -> failwith "Pcre2.rflag_list: unknown runtime flag"
+
+let all_rflags =
+  [
+    0x00000001L; 0x00000002L; 0x00000004L; 0x00000008L;
+    0x00000010L; 0x00000020L; 0x00000040L; 0x00000080L;
+    0x00002000L; 0x00004000L;
+    0x20000000L; 0x40000000L; 0x80000000L;
+  ]
 
 let rflag_list irflags =
   let coll flag_list flag =
-    if irflags land flag <> 0 then rflag_of_int flag :: flag_list
-    else flag_list in
+    if Int64.equal (Int64.logand irflags flag) 0L then flag_list
+    else rflag_of_int flag :: flag_list in
   List.fold_left coll [] all_rflags
 
 
-(* Information on the PCRE-configuration (build-time options) *)
+(* Information on the PCRE2-configuration (build-time options) *)
 
-external pcre_version : unit -> string = "pcre_version_stub"
+external pcre2_version : unit -> string = "pcre2_version_stub"
 
-external pcre_config_utf8 : unit -> bool = "pcre_config_utf8_stub" [@@noalloc]
+external pcre2_config_unicode : unit -> bool
+  = "pcre2_config_unicode_stub" [@@noalloc]
 
-external pcre_config_newline :
-  unit -> char = "pcre_config_newline_stub" [@@noalloc]
+external pcre2_config_newline : unit -> char
+  = "pcre2_config_newline_stub" [@@noalloc]
 
-external pcre_config_link_size :
-  unit -> int = "pcre_config_link_size_stub" [@@noalloc]
+external pcre2_config_link_size : unit -> (int [@untagged])
+  = "pcre2_config_link_size_stub_bc" "pcre2_config_link_size_stub" [@@noalloc]
 
-external pcre_config_match_limit :
-  unit -> int = "pcre_config_match_limit_stub" [@@noalloc]
+external pcre2_config_match_limit : unit -> (int [@untagged])
+  = "pcre2_config_match_limit_stub_bc" "pcre2_config_match_limit_stub"
+  [@@noalloc]
 
-external pcre_config_match_limit_recursion :
-  unit -> int = "pcre_config_match_limit_recursion_stub" [@@noalloc]
+external pcre2_config_depth_limit : unit -> (int [@untagged])
+  = "pcre2_config_depth_limit_stub_bc" "pcre2_config_depth_limit_stub"
+  [@@noalloc]
 
-external pcre_config_stackrecurse :
-  unit -> bool = "pcre_config_stackrecurse_stub" [@@noalloc]
+external pcre2_config_stackrecurse :
+  unit -> bool = "pcre2_config_stackrecurse_stub" [@@noalloc]
 
-let version = pcre_version ()
-let config_utf8 = pcre_config_utf8 ()
-let config_newline = pcre_config_newline ()
-let config_link_size = pcre_config_link_size ()
-let config_match_limit = pcre_config_match_limit ()
-let config_match_limit_recursion = pcre_config_match_limit_recursion ()
-let config_stackrecurse = pcre_config_stackrecurse ()
+let version = pcre2_version ()
+let config_unicode = pcre2_config_unicode ()
+let config_newline = pcre2_config_newline ()
+let config_link_size = pcre2_config_link_size ()
+let config_match_limit = pcre2_config_match_limit ()
+let config_depth_limit = pcre2_config_depth_limit ()
+let config_stackrecurse = pcre2_config_stackrecurse ()
 
 
 (* Information on patterns *)
 
-type firstbyte_info =
+type firstcodeunit_info =
   [ `Char of char
   | `Start_only
   | `ANCHORED ]
 
-type study_stat =
-  [ `Not_studied
-  | `Studied
-  | `Optimal ]
-
 type regexp
 
-external options : regexp -> icflag = "pcre_options_stub"
-external size : regexp -> int = "pcre_size_stub"
-external studysize : regexp -> int = "pcre_studysize_stub"
-external capturecount : regexp -> int = "pcre_capturecount_stub"
-external backrefmax : regexp -> int = "pcre_backrefmax_stub"
-external namecount : regexp -> int = "pcre_namecount_stub"
-external names : regexp -> string array = "pcre_names_stub"
-external nameentrysize : regexp -> int = "pcre_nameentrysize_stub"
-external firstbyte : regexp -> firstbyte_info = "pcre_firstbyte_stub"
-external firsttable : regexp -> string option = "pcre_firsttable_stub"
-external lastliteral : regexp -> char option = "pcre_lastliteral_stub"
-external study_stat : regexp -> study_stat = "pcre_study_stat_stub" [@@noalloc]
+external options : regexp -> (icflag [@unboxed])
+  = "pcre2_argoptions_stub_bc" "pcre2_argoptions_stub"
+
+external size : regexp -> (int [@untagged])
+  = "pcre2_size_stub_bc" "pcre2_size_stub"
+
+external capturecount : regexp -> (int [@untagged])
+  = "pcre2_capturecount_stub_bc" "pcre2_capturecount_stub"
 
+external backrefmax : regexp -> (int [@untagged])
+  = "pcre2_backrefmax_stub_bc" "pcre2_backrefmax_stub"
+
+external namecount : regexp -> (int [@untagged])
+  = "pcre2_namecount_stub_bc" "pcre2_namecount_stub"
+
+external nameentrysize : regexp -> (int [@untagged])
+  = "pcre2_nameentrysize_stub_bc" "pcre2_nameentrysize_stub"
+
+external names : regexp -> string array = "pcre2_names_stub"
+external firstcodeunit : regexp -> firstcodeunit_info = "pcre2_firstcodeunit_stub"
+external lastcodeunit : regexp -> char option = "pcre2_lastcodeunit_stub"
 
 (* Compilation of patterns *)
 
 type chtables
 
-external maketables : unit -> chtables = "pcre_maketables_stub"
+external maketables : unit -> chtables = "pcre2_maketables_stub"
 
-(*  Internal use only! *)
-external pcre_study : regexp -> unit = "pcre_study_stub"
+external compile : (icflag [@unboxed]) -> chtables option -> string -> regexp
+  = "pcre2_compile_stub_bc" "pcre2_compile_stub"
 
-external compile :
-  icflag -> chtables option -> string -> regexp = "pcre_compile_stub"
-
-external get_match_limit : regexp -> int option = "pcre_get_match_limit_stub"
+(* external get_match_limit : regexp -> int option = "pcre2_get_match_limit_stub" *)
 
 (* Internal use only! *)
-external set_imp_match_limit :
-  regexp -> int -> regexp = "pcre_set_imp_match_limit_stub" [@@noalloc]
+external set_imp_match_limit : regexp -> (int [@untagged]) -> regexp
+  = "pcre2_set_imp_match_limit_stub_bc" "pcre2_set_imp_match_limit_stub"
+  [@@noalloc]
 
-external get_match_limit_recursion :
-  regexp -> int option = "pcre_get_match_limit_recursion_stub"
+(* external get_depth_limit :
+  regexp -> int option = "pcre2_get_depth_limit_stub" *)
 
 (* Internal use only! *)
-external set_imp_match_limit_recursion :
-  regexp -> int -> regexp = "pcre_set_imp_match_limit_recursion_stub" [@@noalloc]
+external set_imp_depth_limit : regexp -> (int [@untagged]) -> regexp
+  = "pcre2_set_imp_depth_limit_stub_bc" "pcre2_set_imp_depth_limit_stub"
+  [@@noalloc]
 
+(* TODO implement jit using new pcre2_jit_compile api *)
 let regexp
-      ?(study = true) ?limit ?limit_recursion
-      ?(iflags = 0) ?flags ?chtables pat =
+      (* ?(jit_compile = false) *)
+      ?limit ?depth_limit
+      ?(iflags = 0L) ?flags ?chtables pat =
   let rex =
     match flags with
     | Some flag_list -> compile (cflags flag_list) chtables pat
     | _ -> compile iflags chtables pat
   in
-  if study then pcre_study rex;
   let rex =
     match limit with
     | None -> rex
     | Some lim -> set_imp_match_limit rex lim
   in
-  match limit_recursion with
+  match depth_limit with
   | None -> rex
-  | Some lim -> set_imp_match_limit_recursion rex lim
+  | Some lim -> set_imp_depth_limit rex lim
 
 let regexp_or
-      ?study ?limit ?limit_recursion ?(iflags = 0) ?flags ?chtables pats =
+      (* ?jit_compile *) ?limit ?depth_limit ?(iflags = 0L) ?flags ?chtables pats =
   let check pat =
-    try ignore (regexp ~study:false ~iflags ?flags ?chtables pat)
+    try ignore (regexp ~iflags ?flags ?chtables pat)
     with Error error -> raise (Regexp_or (pat, error))
   in
   List.iter check pats;
@@ -270,7 +361,7 @@ let regexp_or
     let cnv pat = "(?:" ^ pat ^ ")" in
     String.concat "|" (List.rev (List.rev_map cnv pats))
   in
-  regexp ?study ?limit ?limit_recursion ~iflags ?flags ?chtables big_pat
+  regexp (* ?jit_compile *) ?limit ?depth_limit ~iflags ?flags ?chtables big_pat
 
 let bytes_unsafe_blit_string str str_ofs bts bts_ofs len =
   let str_bts = Bytes.unsafe_of_string str in
@@ -301,7 +392,7 @@ let quote s =
 (* Matching of patterns and subpattern extraction *)
 
 (* Default regular expression when none is provided by the user *)
-let def_rex = regexp "\\s+"
+let def_rex = regexp (* ~jit_compile:true *) "\\s+"
 
 type substrings = string * int array
 
@@ -325,7 +416,7 @@ let num_of_subs (_, ovector) = Array.length ovector / 3
 
 let get_offset_start ovector str_num =
   if str_num < 0 || str_num >= Array.length ovector / 3 then
-    invalid_arg "Pcre.get_offset_start: illegal offset";
+    invalid_arg "Pcre2.get_offset_start: illegal offset";
   let offset = str_num lsl 1 in
   offset, Array.unsafe_get ovector offset
 
@@ -370,8 +461,10 @@ let get_opt_substrings ?(full_match = true) (_, ovector as substrings) =
     let len = (Array.length ovector / 3) - 1 in
     Array.init len (fun n -> unsafe_get_opt_substring substrings (n + 1))
 
-external get_stringnumber :
-  regexp -> string -> int = "pcre_get_stringnumber_stub"
+external get_stringnumber : regexp -> string -> (int [@untagged])
+  =
+  "pcre2_substring_number_from_name_stub_bc"
+  "pcre2_substring_number_from_name_stub"
 
 let get_named_substring rex name substrings =
   get_substring substrings (get_stringnumber rex name)
@@ -379,48 +472,68 @@ let get_named_substring rex name substrings =
 let get_named_substring_ofs rex name substrings =
   get_substring_ofs substrings (get_stringnumber rex name)
 
-external unsafe_pcre_exec :
-  irflag ->
+external unsafe_pcre2_match :
+  (irflag [@unboxed]) ->
   regexp ->
-  pos : int ->
-  subj_start : int ->
+  pos : (int [@untagged]) ->
+  subj_start : (int [@untagged]) ->
   subj : string ->
   int array ->
   callout option ->
-  unit = "pcre_exec_stub_bc" "pcre_exec_stub"
+  unit = "pcre2_match_stub_bc" "pcre2_match_stub"
 
 let make_ovector rex =
   let subgroups1 = capturecount rex + 1 in
   let subgroups2 = subgroups1 lsl 1 in
   subgroups2, Array.make (subgroups1 + subgroups2) 0
 
-let pcre_exec ?(iflags = 0) ?flags ?(rex = def_rex) ?pat ?(pos = 0)
+external unsafe_pcre2_dfa_match :
+  (irflag [@unboxed]) ->
+  regexp ->
+  pos : (int [@untagged]) ->
+  subj_start : (int [@untagged]) ->
+  subj : string ->
+  int array ->
+  callout option ->
+  workspace : int array ->
+  unit = "pcre2_dfa_match_stub_bc" "pcre2_match_stub0"
+
+let pcre2_dfa_match ?(iflags = 0L) ?flags ?(rex = def_rex) ?pat ?(pos = 0)
+                  ?callout ?(workspace = Array.make 20 0) subj =
+  let rex = match pat with Some str -> regexp str | _ -> rex in
+  let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
+  let _, ovector = make_ovector rex in
+  unsafe_pcre2_dfa_match
+    iflags rex ~pos ~subj_start:0 ~subj ovector callout ~workspace;
+  ovector
+
+let pcre2_match ?(iflags = 0L) ?flags ?(rex = def_rex) ?pat ?(pos = 0)
               ?callout subj =
   let rex = match pat with Some str -> regexp str | _ -> rex in
   let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
   let _, ovector = make_ovector rex in
-  unsafe_pcre_exec iflags rex ~pos ~subj_start:0 ~subj ovector callout;
+  unsafe_pcre2_match iflags rex ~pos ~subj_start:0 ~subj ovector callout;
   ovector
 
 let exec ?iflags ?flags ?rex ?pat ?pos ?callout subj =
-  subj, pcre_exec ?iflags ?flags ?rex ?pat ?pos ?callout subj
+  subj, pcre2_match ?iflags ?flags ?rex ?pat ?pos ?callout subj
 
 let next_match ?iflags ?flags ?rex ?pat ?(pos = 0) ?callout (subj, ovector) =
   let pos = Array.unsafe_get ovector 1 + pos in
   let subj_len = String.length subj in
   if pos < 0 || pos > subj_len then
-    invalid_arg "Pcre.next_match: illegal offset";
-  subj, pcre_exec ?iflags ?flags ?rex ?pat ~pos ?callout subj
+    invalid_arg "Pcre2.next_match: illegal offset";
+  subj, pcre2_match ?iflags ?flags ?rex ?pat ~pos ?callout subj
 
 let rec copy_lst ar n = function
   | [] -> ar
   | h :: t -> Array.unsafe_set ar n h; copy_lst ar (n - 1) t
 
-let exec_all ?(iflags = 0) ?flags ?(rex = def_rex) ?pat ?pos ?callout subj =
+let exec_all ?(iflags = 0L) ?flags ?(rex = def_rex) ?pat ?pos ?callout subj =
   let rex = match pat with Some str -> regexp str | _ -> rex in
   let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
   let (_, ovector as sstrs) = exec ~iflags ~rex ?pos ?callout subj in
-  let null_flags = iflags lor 0x0400 in
+  let null_flags = Int64.logor iflags 0x00000004L in (* `NOTEMPTY *)
   let subj_len = String.length subj in
   let rec loop pos (subj, ovector as sstrs) n lst =
     let maybe_ovector =
@@ -428,8 +541,8 @@ let exec_all ?(iflags = 0) ?flags ?(rex = def_rex) ?pat ?pos ?callout subj =
         let first = Array.unsafe_get ovector 0 in
         if first = pos && Array.unsafe_get ovector 1 = pos then
           if pos = subj_len then None
-          else Some (pcre_exec ~iflags:null_flags ~rex ~pos ?callout subj)
-        else Some (pcre_exec ~iflags ~rex ~pos ?callout subj)
+          else Some (pcre2_match ~iflags:null_flags ~rex ~pos ?callout subj)
+        else Some (pcre2_match ~iflags ~rex ~pos ?callout subj)
       with Not_found -> None in
     match maybe_ovector with
     | Some ovector ->
@@ -454,7 +567,7 @@ let extract_all_opt ?iflags ?flags ?rex ?pat ?pos ?full_match ?callout subj =
   Array.map (get_opt_substrings ?full_match) many_sstrs
 
 let pmatch ?iflags ?flags ?rex ?pat ?pos ?callout subj =
-  try ignore (pcre_exec ?iflags ?flags ?rex ?pat ?pos ?callout subj); true
+  try ignore (pcre2_match ?iflags ?flags ?rex ?pat ?pos ?callout subj); true
   with Not_found -> false
 
 
@@ -559,7 +672,7 @@ let calc_trans_lst subgroups2 ovector subj templ subst_lst =
         return_lst (subj, !ix, Array.unsafe_get ovector (!pos + 1) - !ix) in
   List.fold_left coll (0, []) subst_lst
 
-let replace ?(iflags = 0) ?flags ?(rex = def_rex) ?pat
+let replace ?(iflags = 0L) ?flags ?(rex = def_rex) ?pat
             ?(pos = 0) ?(itempl = def_subst) ?templ ?callout subj =
   let rex = match pat with Some str -> regexp str | _ -> rex in
   let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
@@ -568,17 +681,17 @@ let replace ?(iflags = 0) ?flags ?(rex = def_rex) ?pat
     | Some str -> subst str
     | _ -> itempl in
   let subj_len = String.length subj in
-  if pos < 0 || pos > subj_len then invalid_arg "Pcre.replace: illegal offset";
+  if pos < 0 || pos > subj_len then invalid_arg "Pcre2.replace: illegal offset";
   let subgroups2, ovector = make_ovector rex in
   let nsubs = (subgroups2 lsr 1) - 1 in
   if max_br > nsubs then
-    failwith "Pcre.replace: backreference denotes nonexistent subpattern";
-  if with_lp && nsubs = 0 then failwith "Pcre.replace: no backreferences";
+    failwith "Pcre2.replace: backreference denotes nonexistent subpattern";
+  if with_lp && nsubs = 0 then failwith "Pcre2.replace: no backreferences";
   let rec loop full_len trans_lsts cur_pos =
     if
       cur_pos > subj_len ||
       try
-        unsafe_pcre_exec
+        unsafe_pcre2_match
           iflags rex ~pos:cur_pos ~subj_start:0 ~subj
           ovector callout;
         false
@@ -617,19 +730,19 @@ let replace ?(iflags = 0) ?flags ?(rex = def_rex) ?pat
       else loop full_len trans_lsts last in
   loop 0 [] pos
 
-let qreplace ?(iflags = 0) ?flags ?(rex = def_rex) ?pat
+let qreplace ?(iflags = 0L) ?flags ?(rex = def_rex) ?pat
              ?(pos = 0) ?(templ = "") ?callout subj =
   let rex = match pat with Some str -> regexp str | _ -> rex in
   let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
   let subj_len = String.length subj in
-  if pos < 0 || pos > subj_len then invalid_arg "Pcre.qreplace: illegal offset";
+  if pos < 0 || pos > subj_len then invalid_arg "Pcre2.qreplace: illegal offset";
   let templ_len = String.length templ in
   let _, ovector = make_ovector rex in
   let rec loop full_len subst_lst cur_pos =
     if
       cur_pos > subj_len ||
       try
-        unsafe_pcre_exec
+        unsafe_pcre2_match
           iflags rex ~pos:cur_pos ~subj_start:0 ~subj ovector callout;
         false
       with Not_found -> true
@@ -666,18 +779,18 @@ let qreplace ?(iflags = 0) ?flags ?(rex = def_rex) ?pat
       else loop full_len subst_lst last in
   loop 0 [] pos
 
-let substitute_substrings ?(iflags = 0) ?flags ?(rex = def_rex) ?pat
+let substitute_substrings ?(iflags = 0L) ?flags ?(rex = def_rex) ?pat
                           ?(pos = 0) ?callout ~subst subj =
   let rex = match pat with Some str -> regexp str | _ -> rex in
   let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
   let subj_len = String.length subj in
-  if pos < 0 || pos > subj_len then invalid_arg "Pcre.substitute: illegal offset";
+  if pos < 0 || pos > subj_len then invalid_arg "Pcre2.substitute: illegal offset";
   let _, ovector = make_ovector rex in
   let rec loop full_len subst_lst cur_pos =
     if
       cur_pos > subj_len ||
       try
-        unsafe_pcre_exec
+        unsafe_pcre2_match
           iflags rex ~pos:cur_pos ~subj_start:0 ~subj ovector callout;
         false
       with Not_found -> true
@@ -719,7 +832,7 @@ let substitute ?iflags ?flags ?rex ?pat ?pos ?callout ~subst:str_subst subj =
     str_subst (string_unsafe_sub subj first (last - first)) in
   substitute_substrings ?iflags ?flags ?rex ?pat ?pos ?callout ~subst subj
 
-let replace_first ?(iflags = 0) ?flags ?(rex = def_rex) ?pat ?(pos = 0)
+let replace_first ?(iflags = 0L) ?flags ?(rex = def_rex) ?pat ?(pos = 0)
                   ?(itempl = def_subst) ?templ ?callout subj =
   let rex = match pat with Some str -> regexp str | _ -> rex in
   let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
@@ -730,10 +843,10 @@ let replace_first ?(iflags = 0) ?flags ?(rex = def_rex) ?pat ?(pos = 0)
   let subgroups2, ovector = make_ovector rex in
   let nsubs = (subgroups2 lsr 1) - 1 in
   if max_br > nsubs then
-    failwith "Pcre.replace_first: backreference denotes nonexistent subpattern";
-  if with_lp && nsubs = 0 then failwith "Pcre.replace_first: no backreferences";
+    failwith "Pcre2.replace_first: backreference denotes nonexistent subpattern";
+  if with_lp && nsubs = 0 then failwith "Pcre2.replace_first: no backreferences";
   try
-    unsafe_pcre_exec iflags rex ~pos ~subj_start:0 ~subj ovector callout;
+    unsafe_pcre2_match iflags rex ~pos ~subj_start:0 ~subj ovector callout;
     let res_len, trans_lst =
       calc_trans_lst subgroups2 ovector subj templ subst_lst in
     let first = Array.unsafe_get ovector 0 in
@@ -746,15 +859,15 @@ let replace_first ?(iflags = 0) ?flags ?(rex = def_rex) ?pat ?(pos = 0)
     let ofs = List.fold_left coll first trans_lst in
     bytes_unsafe_blit_string subj last res ofs rest;
     Bytes.unsafe_to_string res
-  with Not_found -> string_copy subj
+  with Not_found -> subj
 
-let qreplace_first ?(iflags = 0) ?flags ?(rex = def_rex) ?pat
+let qreplace_first ?(iflags = 0L) ?flags ?(rex = def_rex) ?pat
                    ?(pos = 0) ?(templ = "") ?callout subj =
   let rex = match pat with Some str -> regexp str | _ -> rex in
   let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
   let _, ovector = make_ovector rex in
   try
-    unsafe_pcre_exec iflags rex ~pos ~subj_start:0 ~subj ovector callout;
+    unsafe_pcre2_match iflags rex ~pos ~subj_start:0 ~subj ovector callout;
     let first = Array.unsafe_get ovector 0 in
     let last = Array.unsafe_get ovector 1 in
     let len = String.length templ in
@@ -765,15 +878,15 @@ let qreplace_first ?(iflags = 0) ?flags ?(rex = def_rex) ?pat
     bytes_unsafe_blit_string templ 0 res first len;
     bytes_unsafe_blit_string subj last res postfix_start rest;
     Bytes.unsafe_to_string res
-  with Not_found -> string_copy subj
+  with Not_found -> subj
 
-let substitute_substrings_first ?(iflags = 0) ?flags ?(rex = def_rex) ?pat
+let substitute_substrings_first ?(iflags = 0L) ?flags ?(rex = def_rex) ?pat
                                 ?(pos = 0) ?callout ~subst subj =
   let rex = match pat with Some str -> regexp str | _ -> rex in
   let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
   let _, ovector = make_ovector rex in
   try
-    unsafe_pcre_exec iflags rex ~pos ~subj_start:0 ~subj ovector callout;
+    unsafe_pcre2_match iflags rex ~pos ~subj_start:0 ~subj ovector callout;
     let subj_len = String.length subj in
     let prefix_len = Array.unsafe_get ovector 0 in
     let last = Array.unsafe_get ovector 1 in
@@ -786,7 +899,7 @@ let substitute_substrings_first ?(iflags = 0) ?flags ?(rex = def_rex) ?pat
     bytes_unsafe_blit_string templ 0 res prefix_len templ_len;
     bytes_unsafe_blit_string subj last res postfix_start postfix_len;
     Bytes.unsafe_to_string res
-  with Not_found -> string_copy subj
+  with Not_found -> subj
 
 let substitute_first ?iflags ?flags ?rex ?pat ?pos
                      ?callout ~subst:str_subst subj =
@@ -803,7 +916,7 @@ let substitute_first ?iflags ?flags ?rex ?pat ?pos
 let internal_psplit flags rex max pos callout subj =
   let subj_len = String.length subj in
   if subj_len = 0 then []
-  else if max = 1 then [string_copy subj]
+  else if max = 1 then [subj]
   else
     let subgroups2, ovector = make_ovector rex in
 
@@ -831,7 +944,7 @@ let internal_psplit flags rex max pos callout subj =
         if cnt = 0 then
           if prematch &&
             try
-              unsafe_pcre_exec
+              unsafe_pcre2_match
                 flags rex ~pos ~subj_start:pos ~subj ovector callout;
               true
             with Not_found -> false
@@ -845,7 +958,7 @@ let internal_psplit flags rex max pos callout subj =
         else
           if
             try
-              unsafe_pcre_exec
+              unsafe_pcre2_match
                 flags rex ~pos ~subj_start:pos ~subj ovector callout;
               false
             with Not_found -> true
@@ -859,8 +972,9 @@ let internal_psplit flags rex max pos callout subj =
                 if len = 0 then "" :: strs
                 else if
                   try
-                    unsafe_pcre_exec
-                      (flags lor 0x0410) rex ~pos ~subj_start:pos ~subj
+                    unsafe_pcre2_match
+                      (* `ANCHORED | `NOTEMPTY *)
+                      (Int64.logor flags 0x80000004L) rex ~pos ~subj_start:pos ~subj
                       ovector callout;
                     true
                   with Not_found -> false
@@ -880,13 +994,13 @@ let internal_psplit flags rex max pos callout subj =
 
 let rec strip_all_empty = function "" :: t -> strip_all_empty t | l -> l
 
-external isspace : char -> bool = "pcre_isspace_stub" [@@noalloc]
+external isspace : char -> bool = "pcre2_isspace_stub" [@@noalloc]
 
 let rec find_no_space ix len str =
   if ix = len || not (isspace (String.unsafe_get str ix)) then ix
   else find_no_space (ix + 1) len str
 
-let split ?(iflags = 0) ?flags ?rex ?pat ?(pos = 0) ?(max = 0) ?callout subj =
+let split ?(iflags = 0L) ?flags ?rex ?pat ?(pos = 0) ?(max = 0) ?callout subj =
   let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
   let res =
     match pat, rex with
@@ -895,7 +1009,7 @@ let split ?(iflags = 0) ?flags ?rex ?pat ?(pos = 0) ?(max = 0) ?callout subj =
     | _ ->
         (* special case for Perl-splitting semantics *)
         let len = String.length subj in
-        if pos > len || pos < 0 then failwith "Pcre.split: illegal offset";
+        if pos > len || pos < 0 then failwith "Pcre2.split: illegal offset";
         let new_pos = find_no_space pos len subj in
         internal_psplit iflags def_rex max new_pos callout subj in
   List.rev (if max = 0 then strip_all_empty res else res)
@@ -915,13 +1029,13 @@ let rec strip_all_empty_full = function
   | Delim _ :: rest -> strip_all_empty_full rest
   | l -> l
 
-let full_split ?(iflags = 0) ?flags ?(rex = def_rex) ?pat
+let full_split ?(iflags = 0L) ?flags ?(rex = def_rex) ?pat
                ?(pos = 0) ?(max = 0) ?callout subj =
   let rex = match pat with Some str -> regexp str | _ -> rex in
   let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
   let subj_len = String.length subj in
   if subj_len = 0 then []
-  else if max = 1 then [Text (string_copy subj)]
+  else if max = 1 then [Text (subj)]
   else
     let subgroups2, ovector = make_ovector rex in
 
@@ -952,7 +1066,7 @@ let full_split ?(iflags = 0) ?flags ?(rex = def_rex) ?pat
         if cnt = 0 then
           if prematch &&
             try
-              unsafe_pcre_exec
+              unsafe_pcre2_match
                 iflags rex ~pos ~subj_start:pos ~subj ovector callout;
                true
             with Not_found -> false
@@ -970,7 +1084,7 @@ let full_split ?(iflags = 0) ?flags ?(rex = def_rex) ?pat
         else
           if
             try
-              unsafe_pcre_exec
+              unsafe_pcre2_match
                 iflags rex ~pos ~subj_start:pos ~subj ovector callout;
               false
             with Not_found -> true
@@ -987,8 +1101,9 @@ let full_split ?(iflags = 0) ?flags ?(rex = def_rex) ?pat
                   let empty_groups = handle_subgroups [] in
                   if
                     try
-                      unsafe_pcre_exec
-                        (iflags lor 0x0410) rex ~pos ~subj_start:pos ~subj
+                      unsafe_pcre2_match
+                        (* `ANCHORED | `NOTEMPTY *)
+                        (Int64.logor iflags 0x80000004L) rex ~pos ~subj_start:pos ~subj
                         ovector callout;
                       true
                     with Not_found -> false
@@ -1031,4 +1146,4 @@ let foreach_file filenames f =
     let file = open_in filename in
     try f filename file; close_in file
     with exn -> close_in file; raise exn in
-  List.iter do_with_file filenames
+  List.iter do_with_file filenames

+ 794 - 0
libs/pcre2/pcre2_stubs.c

@@ -0,0 +1,794 @@
+/*
+   PCRE2-OCAML - Perl Compatibility Regular Expressions for OCaml
+
+   Copyright (C) 1999-  Markus Mottl
+   email: [email protected]
+   WWW:   http://www.ocaml.info
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#if defined(_WIN32)
+#  define snprintf _snprintf
+#  if defined(_DLL)
+#    define PCREextern __declspec(dllexport)
+#  else
+#    define PCREextern
+#  endif
+#endif
+
+#if _WIN64
+  typedef long long *caml_int_ptr;
+#else
+  typedef long *caml_int_ptr;
+#endif
+
+#if __GNUC__ >= 3
+# define __unused __attribute__ ((unused))
+#else
+# define __unused
+#endif
+
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <caml/mlvalues.h>
+#include <caml/alloc.h>
+#include <caml/memory.h>
+#include <caml/fail.h>
+#include <caml/callback.h>
+#include <caml/custom.h>
+
+#define PCRE2_CODE_UNIT_WIDTH 8
+
+#include <pcre2.h>
+
+typedef const unsigned char *chartables;  /* Type of chartable sets */
+
+/* Contents of callout data */
+struct cod {
+  long subj_start;        /* Start of subject string */
+  value *v_substrings_p;  /* Pointer to substrings matched so far */
+  value *v_cof_p;         /* Pointer to callout function */
+  value v_exn;            /* Possible exception raised by callout function */
+};
+
+/* Cache for exceptions */
+static const value *pcre2_exc_Error     = NULL;  /* Exception [Error] */
+static const value *pcre2_exc_Backtrack = NULL;  /* Exception [Backtrack] */
+
+/* Cache for polymorphic variants */
+static value var_Start_only;   /* Variant [`Start_only] */
+static value var_ANCHORED;     /* Variant [`ANCHORED] */
+static value var_Char;         /* Variant [`Char char] */
+
+static value None = Val_int(0);
+
+/* Data associated with OCaml values of PCRE regular expression */
+struct pcre2_ocaml_regexp { pcre2_code *rex; pcre2_match_context *mcontext; };
+
+#define Pcre2_ocaml_regexp_val(v) \
+  ((struct pcre2_ocaml_regexp *) Data_custom_val(v))
+
+#define get_rex(v) Pcre2_ocaml_regexp_val(v)->rex
+#define get_mcontext(v) Pcre2_ocaml_regexp_val(v)->mcontext
+
+#define set_rex(v, r) Pcre2_ocaml_regexp_val(v)->rex = r
+#define set_mcontext(v, c) Pcre2_ocaml_regexp_val(v)->mcontext = c
+
+/* Data associated with OCaml values of PCRE tables */
+struct pcre2_ocaml_tables { chartables tables; };
+
+#define Pcre2_ocaml_tables_val(v) \
+  ((struct pcre2_ocaml_tables *) Data_custom_val(v))
+
+#define get_tables(v) Pcre2_ocaml_tables_val(v)->tables
+#define set_tables(v, t) Pcre2_ocaml_tables_val(v)->tables = t
+
+/* Converts subject offsets from C-integers to OCaml-Integers.
+
+   This is a bit tricky, because there are 32- and 64-bit platforms around
+   and OCaml chooses the larger possibility for representing integers when
+   available (also in arrays) - not so the PCRE!
+*/
+static inline void copy_ovector(
+  long subj_start, const size_t* ovec_src, caml_int_ptr ovec_dst, uint32_t subgroups2)
+{
+  if (subj_start == 0)
+    while (subgroups2--) {
+      *ovec_dst = Val_int(*ovec_src);
+      --ovec_src; --ovec_dst;
+    }
+  else
+    while (subgroups2--) {
+      *ovec_dst = Val_long(*ovec_src + subj_start);
+      --ovec_src; --ovec_dst;
+    }
+}
+
+/* Callout handler */
+static int pcre2_callout_handler(pcre2_callout_block* cb, struct cod* cod)
+{
+  if (cod != NULL) {
+    /* Callout is available */
+    value v_res;
+
+    /* Set up parameter array */
+    value v_callout_data = caml_alloc_small(8, 0);
+
+    const value v_substrings = *cod->v_substrings_p;
+
+    const uint32_t capture_top = cb->capture_top;
+    uint32_t subgroups2 = capture_top << 1;
+    const uint32_t subgroups2_1 = subgroups2 - 1;
+
+    const size_t *ovec_src = cb->offset_vector + subgroups2_1;
+    caml_int_ptr ovec_dst = &Field(Field(v_substrings, 1), 0) + subgroups2_1;
+    long subj_start = cod->subj_start;
+
+    copy_ovector(subj_start, ovec_src, ovec_dst, subgroups2);
+
+    Field(v_callout_data, 0) = Val_int(cb->callout_number);
+    Field(v_callout_data, 1) = v_substrings;
+    Field(v_callout_data, 2) = Val_int(cb->start_match + subj_start);
+    Field(v_callout_data, 3) = Val_int(cb->current_position + subj_start);
+    Field(v_callout_data, 4) = Val_int(capture_top);
+    Field(v_callout_data, 5) = Val_int(cb->capture_last);
+    Field(v_callout_data, 6) = Val_int(cb->pattern_position);
+    Field(v_callout_data, 7) = Val_int(cb->next_item_length);
+
+    /* Perform callout */
+    v_res = caml_callback_exn(*cod->v_cof_p, v_callout_data);
+
+    if (Is_exception_result(v_res)) {
+      /* Callout raised an exception */
+      const value v_exn = Extract_exception(v_res);
+      if (Field(v_exn, 0) == *pcre2_exc_Backtrack) return 1;
+      cod->v_exn = v_exn;
+      return PCRE2_ERROR_CALLOUT;
+    }
+  }
+
+  return 0;
+}
+
+/* Fetches the named OCaml-values + caches them and
+   calculates + caches the variant hash values */
+CAMLprim value pcre2_ocaml_init(value __unused v_unit)
+{
+  pcre2_exc_Error     = caml_named_value("Pcre2.Error");
+  pcre2_exc_Backtrack = caml_named_value("Pcre2.Backtrack");
+
+  var_Start_only  = caml_hash_variant("Start_only");
+  var_ANCHORED    = caml_hash_variant("ANCHORED");
+  var_Char        = caml_hash_variant("Char");
+
+  return Val_unit;
+}
+
+/* Finalizing deallocation function for chartable sets */
+static void pcre2_dealloc_tables(value v_tables)
+{
+#if PCRE2_MINOR >= 34
+  pcre2_maketables_free(NULL, get_tables(v_tables));
+#else
+  free((void*)get_tables(v_tables));
+#endif
+}
+
+/* Finalizing deallocation function for compiled regular expressions */
+static void pcre2_dealloc_regexp(value v_rex)
+{
+  pcre2_code_free(get_rex(v_rex));
+  pcre2_match_context_free(get_mcontext(v_rex));
+}
+
+
+/* Raising exceptions */
+
+CAMLnoreturn_start
+static inline void raise_pcre2_error(value v_arg)
+CAMLnoreturn_end;
+
+CAMLnoreturn_start
+static inline void raise_partial()
+CAMLnoreturn_end;
+
+CAMLnoreturn_start
+static inline void raise_bad_utf()
+CAMLnoreturn_end;
+
+CAMLnoreturn_start
+static inline void raise_bad_utf_offset()
+CAMLnoreturn_end;
+
+CAMLnoreturn_start
+static inline void raise_match_limit()
+CAMLnoreturn_end;
+
+CAMLnoreturn_start
+static inline void raise_depth_limit()
+CAMLnoreturn_end;
+
+CAMLnoreturn_start
+static inline void raise_workspace_size()
+CAMLnoreturn_end;
+
+CAMLnoreturn_start
+static inline void raise_bad_pattern(int code, size_t pos)
+CAMLnoreturn_end;
+
+CAMLnoreturn_start
+static inline void raise_internal_error(char *msg)
+CAMLnoreturn_end;
+
+static inline void raise_pcre2_error(value v_arg)
+{ caml_raise_with_arg(*pcre2_exc_Error, v_arg); }
+
+static inline void raise_partial() { raise_pcre2_error(Val_int(0)); }
+static inline void raise_bad_utf() { raise_pcre2_error(Val_int(1)); }
+static inline void raise_bad_utf_offset() { raise_pcre2_error(Val_int(2)); }
+static inline void raise_match_limit() { raise_pcre2_error(Val_int(3)); }
+static inline void raise_depth_limit() { raise_pcre2_error(Val_int(4)); }
+static inline void raise_workspace_size() { raise_pcre2_error(Val_int(5)); }
+
+static inline void raise_bad_pattern(int code, size_t pos)
+{
+  CAMLparam0();
+  CAMLlocal1(v_msg);
+  value v_arg;
+  v_msg = caml_alloc_string(128);
+  pcre2_get_error_message(code, (PCRE2_UCHAR *)String_val(v_msg), 128);
+  v_arg = caml_alloc_small(2, 0);
+  Field(v_arg, 0) = v_msg;
+  Field(v_arg, 1) = Val_int(pos);
+  raise_pcre2_error(v_arg);
+  CAMLnoreturn;
+}
+
+static inline void raise_internal_error(char *msg)
+{
+  CAMLparam0();
+  CAMLlocal1(v_msg);
+  value v_arg;
+  v_msg = caml_copy_string(msg);
+  v_arg = caml_alloc_small(1, 1);
+  Field(v_arg, 0) = v_msg;
+  raise_pcre2_error(v_arg);
+  CAMLnoreturn;
+}
+
+/* PCRE pattern compilation */
+
+static struct custom_operations regexp_ops = {
+  "pcre2_ocaml_regexp",
+  pcre2_dealloc_regexp,
+  custom_compare_default,
+  custom_hash_default,
+  custom_serialize_default,
+  custom_deserialize_default,
+  custom_compare_ext_default
+};
+
+/* Makes compiled regular expression from compilation options, an optional
+   value of chartables and the pattern string */
+
+CAMLprim value pcre2_compile_stub(int64_t v_opt, value v_tables, value v_pat)
+{
+  value v_rex;  /* Final result -> value of type [regexp] */
+  int error_code = 0;  /* error code for potential error */
+  size_t error_ofs = 0;  /* offset in the pattern at which error occurred */
+  size_t length = caml_string_length(v_pat);
+
+  pcre2_compile_context* ccontext = NULL;
+  /* If v_tables = [None], then pointer to tables is NULL, otherwise
+     set it to the appropriate value */
+  if (v_tables != None) {
+    ccontext = pcre2_compile_context_create(NULL);
+    pcre2_set_character_tables(ccontext, get_tables(Field(v_tables, 0)));
+  }
+
+  /* Compiles the pattern */
+  pcre2_code* regexp = pcre2_compile((PCRE2_SPTR)String_val(v_pat), length, v_opt,
+                                     &error_code, &error_ofs, ccontext);
+
+  pcre2_compile_context_free(ccontext);
+
+  /* Raises appropriate exception with [BadPattern] if the pattern
+     could not be compiled */
+  if (regexp == NULL) raise_bad_pattern(error_code, error_ofs);
+
+  /* GC will do a full cycle every 1_000_000 regexp allocations (a typical
+     regexp probably consumes less than 100 bytes -> maximum of 100_000_000
+     bytes unreclaimed regexps) */
+  v_rex =
+    caml_alloc_custom(&regexp_ops,
+      sizeof(struct pcre2_ocaml_regexp), 1, 1000000);
+
+  set_rex(v_rex, regexp);
+  set_mcontext(v_rex, pcre2_match_context_create(NULL));
+
+  return v_rex;
+}
+
+CAMLprim value pcre2_compile_stub_bc(value v_opt, value v_tables, value v_pat)
+{
+  return pcre2_compile_stub(Int64_val(v_opt), v_tables, v_pat);
+}
+
+/* Gets the depth limit of a regular expression if it exists */
+/* CAMLprim value pcre2_get_depth_limit_stub(value v_rex); */
+
+/* Gets the match limit of a regular expression if it exists */
+/* CAMLprim value pcre2_get_match_limit_stub(value v_rex); */
+
+
+/* Sets a match limit for a regular expression imperatively */
+
+CAMLprim value pcre2_set_imp_match_limit_stub(value v_rex, intnat v_lim) {
+  pcre2_match_context* mcontext = get_mcontext(v_rex);
+  pcre2_set_match_limit(mcontext, v_lim);
+  return v_rex;
+}
+
+CAMLprim value pcre2_set_imp_match_limit_stub_bc(value v_rex, value v_lim)
+{
+  return pcre2_set_imp_match_limit_stub(v_rex, Int_val(v_lim));
+}
+
+
+/* Sets a depth limit for a regular expression imperatively */
+
+CAMLprim value pcre2_set_imp_depth_limit_stub(value v_rex, intnat v_lim) {
+  pcre2_match_context* mcontext = get_mcontext(v_rex);
+  pcre2_set_depth_limit(mcontext, v_lim);
+  return v_rex;
+}
+
+CAMLprim value pcre2_set_imp_depth_limit_stub_bc(value v_rex, value v_lim)
+{
+  return pcre2_set_imp_depth_limit_stub(v_rex, Int_val(v_lim));
+}
+
+
+/* Performs the call to the pcre2_pattern_info function */
+static inline int pcre2_pattern_info_stub(value v_rex, int what, void* where)
+{
+  return pcre2_pattern_info(get_rex(v_rex), what, where);
+}
+
+/* Some stubs for info-functions */
+
+/* Generic macro for getting integer results from pcre2_pattern_info */
+#define make_intnat_info(tp, name, option) \
+  CAMLprim intnat pcre2_##name##_stub(value v_rex) \
+  { \
+    tp options; \
+    const int ret = pcre2_pattern_info_stub(v_rex, PCRE2_INFO_##option, &options); \
+    if (ret != 0) raise_internal_error("pcre2_##name##_stub"); \
+    return options; \
+  } \
+  \
+  CAMLprim value pcre2_##name##_stub_bc(value v_rex) \
+  { return Val_int(pcre2_##name##_stub(v_rex)); }
+
+make_intnat_info(size_t, size, SIZE)
+make_intnat_info(int, capturecount, CAPTURECOUNT)
+make_intnat_info(int, backrefmax, BACKREFMAX)
+make_intnat_info(int, namecount, NAMECOUNT)
+make_intnat_info(int, nameentrysize, NAMEENTRYSIZE)
+
+CAMLprim int64_t pcre2_argoptions_stub(value v_rex)
+{
+  uint32_t options;
+  const int ret = pcre2_pattern_info_stub(v_rex, PCRE2_INFO_ARGOPTIONS, &options);
+  if (ret != 0) raise_internal_error("pcre2_argoptions_stub");
+  return (int64_t)options;
+}
+
+CAMLprim value pcre2_argoptions_stub_bc(value v_rex)
+{
+  CAMLparam1(v_rex);
+  CAMLreturn(caml_copy_int64(pcre2_argoptions_stub(v_rex)));
+}
+
+CAMLprim value pcre2_firstcodeunit_stub(value v_rex)
+{
+  uint32_t firstcodetype;
+  const int ret = pcre2_pattern_info_stub(v_rex, PCRE2_INFO_FIRSTCODETYPE, &firstcodetype);
+
+  if (ret != 0) raise_internal_error("pcre2_firstcodeunit_stub");
+
+  switch (firstcodetype) {
+    case 2 : return var_Start_only; break;  /* [`Start_only] */
+    case 0 : return var_ANCHORED; break;    /* [`ANCHORED] */
+    case 1: {
+      uint32_t firstcodeunit;
+      const int ret = pcre2_pattern_info_stub(v_rex, PCRE2_INFO_FIRSTCODEUNIT, &firstcodeunit);
+      if (ret != 0) raise_internal_error("pcre2_firstcodeunit_stub");
+
+      value v_firstbyte;
+      /* Allocates the non-constant constructor [`Char of char] and fills
+         in the appropriate value */
+      v_firstbyte = caml_alloc_small(2, 0);
+      Field(v_firstbyte, 0) = var_Char;
+      Field(v_firstbyte, 1) = Val_int(firstcodeunit);
+
+      return v_firstbyte;
+      break;
+    }
+    default: /* Should not happen */
+      raise_internal_error("pcre2_firstcodeunit_stub");
+  }
+}
+
+CAMLprim value pcre2_lastcodeunit_stub(value v_rex)
+{
+  uint32_t lastcodetype;
+  const int ret =
+    pcre2_pattern_info_stub(v_rex, PCRE2_INFO_LASTCODETYPE, &lastcodetype);
+
+  if (ret != 0) raise_internal_error("pcre2_lastcodeunit_stub");
+
+  if (lastcodetype == 0) return None;
+  if (lastcodetype != 1) raise_internal_error("pcre2_lastcodeunit_stub");
+  else {
+    /* Allocates [Some char] */
+    value v_res = caml_alloc_small(1, 0);
+    uint32_t lastcodeunit;
+    const int ret = pcre2_pattern_info_stub(v_rex, PCRE2_INFO_LASTCODEUNIT, &lastcodeunit);
+    if (ret != 0) raise_internal_error("pcre2_lastcodeunit_stub");
+    Field(v_res, 0) = Val_int(lastcodeunit);
+    return v_res;
+  }
+}
+
+CAMLnoreturn_start
+static inline void handle_match_error(char *loc, const int ret)
+CAMLnoreturn_end;
+
+static inline void handle_match_error(char *loc, const int ret)
+{
+  switch (ret) {
+    /* Dedicated exceptions */
+    case PCRE2_ERROR_NOMATCH : caml_raise_not_found();
+    case PCRE2_ERROR_PARTIAL : raise_partial();
+    case PCRE2_ERROR_MATCHLIMIT : raise_match_limit();
+    case PCRE2_ERROR_BADUTFOFFSET : raise_bad_utf_offset();
+    case PCRE2_ERROR_DEPTHLIMIT : raise_depth_limit();
+    case PCRE2_ERROR_DFA_WSSIZE : raise_workspace_size();
+    default : {
+      if (PCRE2_ERROR_UTF8_ERR21 <= ret && ret <= PCRE2_ERROR_UTF8_ERR1)
+        raise_bad_utf();
+      /* Unknown error */
+      char err_buf[100];
+      snprintf(err_buf, 100, "%s: unhandled PCRE2 error code: %d", loc, ret);
+      raise_internal_error(err_buf);
+    }
+  }
+}
+
+static inline void handle_pcre2_match_result(
+  size_t *ovec, value v_ovec, size_t ovec_len, long subj_start, uint32_t ret)
+{
+  caml_int_ptr ocaml_ovec = (caml_int_ptr) &Field(v_ovec, 0);
+  const uint32_t subgroups2 = ret * 2;
+  const uint32_t subgroups2_1 = subgroups2 - 1;
+  const size_t *ovec_src = ovec + subgroups2_1;
+  caml_int_ptr ovec_clear_stop = ocaml_ovec + (ovec_len * 2) / 3;
+  caml_int_ptr ovec_dst = ocaml_ovec + subgroups2_1;
+  copy_ovector(subj_start, ovec_src, ovec_dst, subgroups2);
+  while (++ovec_dst < ovec_clear_stop) *ovec_dst = -1;
+}
+
+/* Executes a pattern match with runtime options, a regular expression, a
+   matching position, the start of the the subject string, a subject string,
+   a number of subgroup offsets, an offset vector and an optional callout
+   function */
+
+CAMLprim value pcre2_match_stub0(
+    int64_t v_opt, value v_rex, intnat v_pos, intnat v_subj_start, value v_subj,
+    value v_ovec, value v_maybe_cof, value v_workspace)
+{
+  int ret;
+  int is_dfa = v_workspace != (value) NULL;
+  long
+    pos = v_pos,
+    subj_start = v_subj_start;
+  size_t
+    ovec_len = Wosize_val(v_ovec),
+    len = caml_string_length(v_subj);
+
+  if (pos > (long)len || pos < subj_start)
+    caml_invalid_argument("Pcre2.pcre2_match_stub: illegal position");
+
+  if (subj_start > (long)len || subj_start < 0)
+    caml_invalid_argument("Pcre2.pcre2_match_stub: illegal subject start");
+
+  pos -= subj_start;
+  len -= subj_start;
+
+  {
+    const pcre2_code *code = get_rex(v_rex);  /* Compiled pattern */
+    pcre2_match_context* mcontext = get_mcontext(v_rex);  /* Match context */
+    PCRE2_SPTR ocaml_subj = (PCRE2_SPTR)String_val(v_subj) + subj_start;  /* Subject string */
+
+    pcre2_match_data* match_data = pcre2_match_data_create_from_pattern(code, NULL);
+
+    /* Special case when no callout functions specified */
+    if (v_maybe_cof == None) {
+      /* Performs the match */
+      if (is_dfa)
+        ret =
+          pcre2_dfa_match(code, ocaml_subj, len, pos, v_opt, match_data, mcontext,
+              (int *) &Field(v_workspace, 0), Wosize_val(v_workspace));
+      else
+        ret = pcre2_match(code, ocaml_subj, len, pos, v_opt, match_data, mcontext);
+
+      size_t *ovec = pcre2_get_ovector_pointer(match_data);
+
+      if (ret < 0) {
+        pcre2_match_data_free(match_data);
+        handle_match_error("pcre2_match_stub", ret);
+      } else {
+        handle_pcre2_match_result(ovec, v_ovec, ovec_len, subj_start, ret);
+      }
+    }
+
+    /* There are callout functions */
+    else {
+      value v_cof = Field(v_maybe_cof, 0);
+      value v_substrings;
+      PCRE2_UCHAR* subj = caml_stat_alloc(sizeof(char) * len);
+      int workspace_len;
+      int *workspace;
+      struct cod cod = { 0, (value *) NULL, (value *) NULL, (value) NULL };
+      pcre2_match_context* new_mcontext = pcre2_match_context_copy(mcontext);
+
+      pcre2_set_callout(new_mcontext, (int (*)(pcre2_callout_block_8*, void*))&pcre2_callout_handler, &cod);
+
+      cod.subj_start = subj_start;
+      memcpy(subj, ocaml_subj, len);
+
+      Begin_roots4(v_rex, v_cof, v_substrings, v_ovec);
+        Begin_roots1(v_subj);
+          v_substrings = caml_alloc_small(2, 0);
+        End_roots();
+
+        Field(v_substrings, 0) = v_subj;
+        Field(v_substrings, 1) = v_ovec;
+
+        cod.v_substrings_p = &v_substrings;
+        cod.v_cof_p = &v_cof;
+
+        if (is_dfa) {
+          workspace_len = Wosize_val(v_workspace);
+          workspace = caml_stat_alloc(sizeof(int) * workspace_len);
+          ret =
+            pcre2_dfa_match(code, subj, len, pos, v_opt, match_data, new_mcontext,
+                (int *) &Field(v_workspace, 0), workspace_len);
+        } else
+          ret =
+            pcre2_match(code, subj, len, pos, v_opt, match_data, new_mcontext);
+
+        caml_stat_free(subj);
+      End_roots();
+
+      pcre2_match_context_free(new_mcontext);
+      size_t* ovec = pcre2_get_ovector_pointer(match_data);
+      if (ret < 0) {
+        if (is_dfa) caml_stat_free(workspace);
+        pcre2_match_data_free(match_data);
+        if (ret == PCRE2_ERROR_CALLOUT) caml_raise(cod.v_exn);
+        else handle_match_error("pcre2_match_stub(callout)", ret);
+      } else {
+        handle_pcre2_match_result(ovec, v_ovec, ovec_len, subj_start, ret);
+        if (is_dfa) {
+          caml_int_ptr ocaml_workspace_dst =
+            (caml_int_ptr) &Field(v_workspace, 0);
+          const int *workspace_src = workspace;
+          const int *workspace_src_stop = workspace + workspace_len;
+          while (workspace_src != workspace_src_stop) {
+            *ocaml_workspace_dst = *workspace_src;
+            ocaml_workspace_dst++;
+            workspace_src++;
+          }
+          caml_stat_free(workspace);
+        }
+      }
+    }
+    pcre2_match_data_free(match_data);
+  }
+
+  return Val_unit;
+}
+
+CAMLprim value pcre2_match_stub(
+    int64_t v_opt, value v_rex, intnat v_pos, intnat v_subj_start, value v_subj,
+    value v_ovec, value v_maybe_cof)
+{
+  return pcre2_match_stub0(v_opt, v_rex, v_pos, v_subj_start, v_subj,
+                         v_ovec, v_maybe_cof, (value) NULL);
+}
+
+/* Byte-code hook for pcre2_match_stub
+   Needed, because there are more than 5 arguments */
+CAMLprim value pcre2_match_stub_bc(value *argv, int __unused argn)
+{
+  return
+    pcre2_match_stub0(
+        Int64_val(argv[0]), argv[1], Int_val(argv[2]), Int_val(argv[3]),
+        argv[4], argv[5], argv[6], (value) NULL);
+}
+
+/* Byte-code hook for pcre2_dfa_match_stub
+   Needed, because there are more than 5 arguments */
+CAMLprim value pcre2_dfa_match_stub_bc(value *argv, int __unused argn)
+{
+  return
+    pcre2_match_stub0(
+        Int64_val(argv[0]), argv[1], Int_val(argv[2]), Int_val(argv[3]),
+        argv[4], argv[5], argv[6], argv[7]);
+}
+
+static struct custom_operations tables_ops = {
+  "pcre2_ocaml_tables",
+  pcre2_dealloc_tables,
+  custom_compare_default,
+  custom_hash_default,
+  custom_serialize_default,
+  custom_deserialize_default,
+  custom_compare_ext_default
+};
+
+/* Generates a new set of chartables for the current locale (see man
+   page of PCRE */
+CAMLprim value pcre2_maketables_stub(value __unused v_unit)
+{
+  /* GC will do a full cycle every 1_000_000 table set allocations (one
+     table set consumes 864 bytes -> maximum of 864_000_000 bytes unreclaimed
+     table sets) */
+  const value v_tables =
+    caml_alloc_custom(
+      &tables_ops, sizeof(struct pcre2_ocaml_tables), 1, 1000000);
+  set_tables(v_tables, pcre2_maketables(NULL));
+  return v_tables;
+}
+
+/* Wraps around the isspace-function */
+CAMLprim value pcre2_isspace_stub(value v_c)
+{
+  return Val_bool(isspace(Int_val(v_c)));
+}
+
+
+/* Returns number of substring associated with a name */
+
+CAMLprim intnat pcre2_substring_number_from_name_stub(value v_rex, value v_name)
+{
+  const int ret = pcre2_substring_number_from_name(get_rex(v_rex), (PCRE2_SPTR)String_val(v_name));
+  if (ret == PCRE2_ERROR_NOSUBSTRING)
+    caml_invalid_argument("Named string not found");
+
+  return ret;
+}
+
+CAMLprim value pcre2_substring_number_from_name_stub_bc(value v_rex, value v_name)
+{
+  return Val_int(pcre2_substring_number_from_name_stub(v_rex, v_name));
+}
+
+
+/* Returns array of names of named substrings in a regexp */
+CAMLprim value pcre2_names_stub(value v_rex)
+{
+  CAMLparam1(v_rex);
+  CAMLlocal1(v_res);
+  uint32_t name_count;
+  uint32_t entry_size;
+  const char *tbl_ptr;
+  uint32_t i;
+
+  int ret = pcre2_pattern_info_stub(v_rex, PCRE2_INFO_NAMECOUNT, &name_count);
+  if (ret != 0) raise_internal_error("pcre2_names_stub: namecount");
+
+  ret = pcre2_pattern_info_stub(v_rex, PCRE2_INFO_NAMEENTRYSIZE, &entry_size);
+  if (ret != 0) raise_internal_error("pcre2_names_stub: nameentrysize");
+
+  ret = pcre2_pattern_info_stub(v_rex, PCRE2_INFO_NAMETABLE, &tbl_ptr);
+  if (ret != 0) raise_internal_error("pcre2_names_stub: nametable");
+
+  v_res = caml_alloc(name_count, 0);
+
+  for (i = 0; i < name_count; ++i) {
+    value v_name = caml_copy_string(tbl_ptr + 2);
+    Store_field(v_res, i, v_name);
+    tbl_ptr += entry_size;
+  }
+
+  CAMLreturn(v_res);
+}
+
+/* Generic stub for getting integer results from pcre2_config */
+static inline int pcre2_config_int(int what)
+{
+  int ret;
+  pcre2_config(what, (void *) &ret);
+  return ret;
+}
+
+/* Generic stub for getting long integer results from pcre2_config */
+static inline long pcre2_config_long(int what)
+{
+  long ret;
+  pcre2_config(what, (void *) &ret);
+  return ret;
+}
+
+
+/* Some stubs for config-functions */
+
+/* Makes OCaml-string from PCRE-version */
+CAMLprim value pcre2_version_stub(value __unused v_unit) {
+  CAMLparam1(v_unit);
+  CAMLlocal1(v_version);
+  v_version = caml_alloc_string(32);
+
+  pcre2_config(PCRE2_CONFIG_VERSION, (void *)String_val(v_version));
+
+  CAMLreturn(v_version);
+}
+
+/* Returns boolean indicating unicode support */
+CAMLprim value pcre2_config_unicode_stub(value __unused v_unit)
+{ return Val_bool(pcre2_config_int(PCRE2_CONFIG_UNICODE)); }
+
+
+/* Returns character used as newline */
+CAMLprim value pcre2_config_newline_stub(value __unused v_unit)
+{ return Val_int(pcre2_config_int(PCRE2_CONFIG_NEWLINE)); }
+
+
+/* Returns number of bytes used for internal linkage of regular expressions */
+
+CAMLprim intnat pcre2_config_link_size_stub(value __unused v_unit)
+{ return pcre2_config_int(PCRE2_CONFIG_LINKSIZE); }
+
+CAMLprim value pcre2_config_link_size_stub_bc(value v_unit)
+{ return Val_int(pcre2_config_link_size_stub(v_unit)); }
+
+
+/* Returns default limit for calls to internal matching function */
+
+CAMLprim intnat pcre2_config_match_limit_stub(value __unused v_unit)
+{ return pcre2_config_long(PCRE2_CONFIG_MATCHLIMIT); }
+
+CAMLprim value pcre2_config_match_limit_stub_bc(value v_unit)
+{ return Val_int(pcre2_config_match_limit_stub(v_unit)); }
+
+
+/* Returns default limit for depth of nested backtracking  */
+
+CAMLprim intnat pcre2_config_depth_limit_stub(value __unused v_unit)
+{ return pcre2_config_long(PCRE2_CONFIG_DEPTHLIMIT); }
+
+CAMLprim value pcre2_config_depth_limit_stub_bc(value v_unit)
+{ return Val_int(pcre2_config_depth_limit_stub(v_unit)); }
+
+
+/* Returns boolean indicating use of stack recursion */
+CAMLprim intnat pcre2_config_stackrecurse_stub(value __unused v_unit)
+{ return Val_bool(pcre2_config_int(PCRE2_CONFIG_STACKRECURSE)); }

+ 1 - 0
libs/swflib/as3.mli

@@ -16,6 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  *)
+open Extlib_leftovers
 
 type 'a index
 type 'a index_nz

+ 1 - 0
libs/swflib/as3code.ml

@@ -16,6 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  *)
+open Extlib_leftovers
 open IO
 open As3
 

+ 1 - 0
libs/swflib/as3hl.mli

@@ -16,6 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  *)
+open Extlib_leftovers
 open As3
 
 type hl_ident = string

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно